Add justfile_directory()
and justfile()
(#569)
Add `justfile()` function, returning the current justfile, and `justfile_directory(), returning its parent directory.
This commit is contained in:
parent
eeb603160a
commit
61ab53dbc1
@ -402,13 +402,11 @@ impl Config {
|
||||
|
||||
match &self.subcommand {
|
||||
Dump => self.dump(justfile),
|
||||
Evaluate { overrides } => {
|
||||
self.run(justfile, &search.working_directory, overrides, &Vec::new())
|
||||
}
|
||||
Evaluate { overrides } => self.run(justfile, &search, overrides, &Vec::new()),
|
||||
Run {
|
||||
arguments,
|
||||
overrides,
|
||||
} => self.run(justfile, &search.working_directory, overrides, arguments),
|
||||
} => self.run(justfile, &search, overrides, arguments),
|
||||
List => self.list(justfile),
|
||||
Show { ref name } => self.show(&name, justfile),
|
||||
Summary => self.summary(justfile),
|
||||
@ -561,7 +559,7 @@ impl Config {
|
||||
fn run(
|
||||
&self,
|
||||
justfile: Justfile,
|
||||
working_directory: &Path,
|
||||
search: &Search,
|
||||
overrides: &BTreeMap<String, String>,
|
||||
arguments: &[String],
|
||||
) -> Result<(), i32> {
|
||||
@ -569,7 +567,7 @@ impl Config {
|
||||
warn!("Failed to set CTRL-C handler: {}", error)
|
||||
}
|
||||
|
||||
let result = justfile.run(&self, working_directory, overrides, arguments);
|
||||
let result = justfile.run(&self, search, overrides, arguments);
|
||||
|
||||
if !self.quiet {
|
||||
result.eprint(self.color)
|
||||
|
@ -6,7 +6,7 @@ pub(crate) struct Evaluator<'src: 'run, 'run> {
|
||||
dotenv: &'run BTreeMap<String, String>,
|
||||
scope: Scope<'src, 'run>,
|
||||
settings: &'run Settings<'run>,
|
||||
working_directory: &'run Path,
|
||||
search: &'run Search,
|
||||
}
|
||||
|
||||
impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
@ -16,7 +16,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
dotenv: &'run BTreeMap<String, String>,
|
||||
overrides: Scope<'src, 'run>,
|
||||
settings: &'run Settings<'run>,
|
||||
working_directory: &'run Path,
|
||||
search: &'run Search,
|
||||
) -> RunResult<'src, Scope<'src, 'run>> {
|
||||
let mut evaluator = Evaluator {
|
||||
scope: overrides,
|
||||
@ -24,7 +24,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
config,
|
||||
dotenv,
|
||||
settings,
|
||||
working_directory,
|
||||
search,
|
||||
};
|
||||
|
||||
for assignment in assignments.values() {
|
||||
@ -67,9 +67,9 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
}
|
||||
Expression::Call { thunk } => {
|
||||
let context = FunctionContext {
|
||||
invocation_directory: &self.config.invocation_directory,
|
||||
working_directory: &self.working_directory,
|
||||
dotenv: self.dotenv,
|
||||
invocation_directory: &self.config.invocation_directory,
|
||||
search: self.search,
|
||||
};
|
||||
|
||||
use Thunk::*;
|
||||
@ -127,7 +127,7 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
|
||||
cmd.arg(raw);
|
||||
|
||||
cmd.current_dir(self.working_directory);
|
||||
cmd.current_dir(&self.search.working_directory);
|
||||
|
||||
cmd.export(self.dotenv, &self.scope);
|
||||
|
||||
@ -167,15 +167,15 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
arguments: &[&str],
|
||||
scope: &'run Scope<'src, 'run>,
|
||||
settings: &'run Settings,
|
||||
working_directory: &'run Path,
|
||||
search: &'run Search,
|
||||
) -> RunResult<'src, Scope<'src, 'run>> {
|
||||
let mut evaluator = Evaluator {
|
||||
assignments: None,
|
||||
scope: Scope::child(scope),
|
||||
search,
|
||||
settings,
|
||||
dotenv,
|
||||
config,
|
||||
working_directory,
|
||||
};
|
||||
|
||||
let mut scope = Scope::child(scope);
|
||||
@ -211,15 +211,15 @@ impl<'src, 'run> Evaluator<'src, 'run> {
|
||||
dotenv: &'run BTreeMap<String, String>,
|
||||
scope: &'run Scope<'src, 'run>,
|
||||
settings: &'run Settings,
|
||||
working_directory: &'run Path,
|
||||
search: &'run Search,
|
||||
) -> Evaluator<'src, 'run> {
|
||||
Evaluator {
|
||||
assignments: None,
|
||||
scope: Scope::child(scope),
|
||||
search,
|
||||
settings,
|
||||
dotenv,
|
||||
config,
|
||||
working_directory,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::common::*;
|
||||
|
||||
use target;
|
||||
use Function::*;
|
||||
|
||||
pub(crate) enum Function {
|
||||
Nullary(fn(&FunctionContext) -> Result<String, String>),
|
||||
@ -10,15 +11,14 @@ pub(crate) enum Function {
|
||||
|
||||
lazy_static! {
|
||||
pub(crate) static ref TABLE: BTreeMap<&'static str, Function> = vec![
|
||||
("arch", Function::Nullary(arch)),
|
||||
("os", Function::Nullary(os)),
|
||||
("os_family", Function::Nullary(os_family)),
|
||||
("env_var", Function::Unary(env_var)),
|
||||
("env_var_or_default", Function::Binary(env_var_or_default)),
|
||||
(
|
||||
"invocation_directory",
|
||||
Function::Nullary(invocation_directory)
|
||||
),
|
||||
("arch", Nullary(arch)),
|
||||
("os", Nullary(os)),
|
||||
("os_family", Nullary(os_family)),
|
||||
("justfile_directory", Nullary(justfile_directory)),
|
||||
("justfile", Nullary(justfile)),
|
||||
("invocation_directory", Nullary(invocation_directory)),
|
||||
("env_var", Unary(env_var)),
|
||||
("env_var_or_default", Binary(env_var_or_default)),
|
||||
]
|
||||
.into_iter()
|
||||
.collect();
|
||||
@ -26,7 +26,6 @@ lazy_static! {
|
||||
|
||||
impl Function {
|
||||
pub(crate) fn argc(&self) -> usize {
|
||||
use self::Function::*;
|
||||
match *self {
|
||||
Nullary(_) => 0,
|
||||
Unary(_) => 1,
|
||||
@ -48,8 +47,44 @@ fn os_family(_context: &FunctionContext) -> Result<String, String> {
|
||||
}
|
||||
|
||||
fn invocation_directory(context: &FunctionContext) -> Result<String, String> {
|
||||
Platform::to_shell_path(context.working_directory, context.invocation_directory)
|
||||
.map_err(|e| format!("Error getting shell path: {}", e))
|
||||
Platform::to_shell_path(
|
||||
&context.search.working_directory,
|
||||
context.invocation_directory,
|
||||
)
|
||||
.map_err(|e| format!("Error getting shell path: {}", e))
|
||||
}
|
||||
|
||||
fn justfile(context: &FunctionContext) -> Result<String, String> {
|
||||
context
|
||||
.search
|
||||
.justfile
|
||||
.to_str()
|
||||
.map(str::to_owned)
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"Justfile path is not valid unicode: {}",
|
||||
context.search.justfile.to_string_lossy()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn justfile_directory(context: &FunctionContext) -> Result<String, String> {
|
||||
let justfile_directory = context.search.justfile.parent().ok_or_else(|| {
|
||||
format!(
|
||||
"Could not resolve justfile directory. Justfile `{}` had no parent.",
|
||||
context.search.justfile.display()
|
||||
)
|
||||
})?;
|
||||
|
||||
justfile_directory
|
||||
.to_str()
|
||||
.map(str::to_owned)
|
||||
.ok_or_else(|| {
|
||||
format!(
|
||||
"Justfile directory is not valid unicode: {}",
|
||||
justfile_directory.to_string_lossy()
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
fn env_var(context: &FunctionContext, key: &str) -> Result<String, String> {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::common::*;
|
||||
|
||||
pub(crate) struct FunctionContext<'run> {
|
||||
pub(crate) invocation_directory: &'run Path,
|
||||
pub(crate) working_directory: &'run Path,
|
||||
pub(crate) dotenv: &'run BTreeMap<String, String>,
|
||||
pub(crate) invocation_directory: &'run Path,
|
||||
pub(crate) search: &'run Search,
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ impl<'src> Justfile<'src> {
|
||||
None
|
||||
}
|
||||
|
||||
pub(crate) fn run(
|
||||
&'src self,
|
||||
config: &'src Config,
|
||||
working_directory: &'src Path,
|
||||
overrides: &'src BTreeMap<String, String>,
|
||||
arguments: &'src [String],
|
||||
) -> RunResult<'src, ()> {
|
||||
pub(crate) fn run<'run>(
|
||||
&'run self,
|
||||
config: &'run Config,
|
||||
search: &'run Search,
|
||||
overrides: &'run BTreeMap<String, String>,
|
||||
arguments: &'run [String],
|
||||
) -> RunResult<'run, ()> {
|
||||
let argvec: Vec<&str> = if !arguments.is_empty() {
|
||||
arguments.iter().map(|argument| argument.as_str()).collect()
|
||||
} else if let Some(recipe) = self.first() {
|
||||
@ -105,7 +105,7 @@ impl<'src> Justfile<'src> {
|
||||
&dotenv,
|
||||
scope,
|
||||
&self.settings,
|
||||
working_directory,
|
||||
search,
|
||||
)?
|
||||
};
|
||||
|
||||
@ -172,12 +172,12 @@ impl<'src> Justfile<'src> {
|
||||
settings: &self.settings,
|
||||
config,
|
||||
scope,
|
||||
working_directory,
|
||||
search,
|
||||
};
|
||||
|
||||
let mut ran = BTreeSet::new();
|
||||
for (recipe, arguments) in grouped {
|
||||
self.run_recipe(&context, recipe, arguments, &dotenv, &mut ran)?
|
||||
self.run_recipe(&context, recipe, arguments, &dotenv, &search, &mut ran)?
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -203,6 +203,7 @@ impl<'src> Justfile<'src> {
|
||||
recipe: &Recipe<'src>,
|
||||
arguments: &[&'run str],
|
||||
dotenv: &BTreeMap<String, String>,
|
||||
search: &'run Search,
|
||||
ran: &mut BTreeSet<Vec<String>>,
|
||||
) -> RunResult<'src, ()> {
|
||||
let scope = Evaluator::evaluate_parameters(
|
||||
@ -212,16 +213,11 @@ impl<'src> Justfile<'src> {
|
||||
arguments,
|
||||
&context.scope,
|
||||
context.settings,
|
||||
context.working_directory,
|
||||
search,
|
||||
)?;
|
||||
|
||||
let mut evaluator = Evaluator::recipe_evaluator(
|
||||
context.config,
|
||||
dotenv,
|
||||
&scope,
|
||||
context.settings,
|
||||
context.working_directory,
|
||||
);
|
||||
let mut evaluator =
|
||||
Evaluator::recipe_evaluator(context.config, dotenv, &scope, context.settings, search);
|
||||
|
||||
for Dependency { recipe, arguments } in &recipe.dependencies {
|
||||
let mut invocation = vec![recipe.name().to_owned()];
|
||||
@ -236,11 +232,11 @@ impl<'src> Justfile<'src> {
|
||||
.skip(1)
|
||||
.map(String::as_ref)
|
||||
.collect::<Vec<&str>>();
|
||||
self.run_recipe(context, recipe, &arguments, dotenv, ran)?;
|
||||
self.run_recipe(context, recipe, &arguments, dotenv, search, ran)?;
|
||||
}
|
||||
}
|
||||
|
||||
recipe.run(context, dotenv, scope)?;
|
||||
recipe.run(context, dotenv, scope, search)?;
|
||||
|
||||
let mut invocation = Vec::new();
|
||||
invocation.push(recipe.name().to_owned());
|
||||
|
@ -69,6 +69,7 @@ impl<'src, D> Recipe<'src, D> {
|
||||
context: &RecipeContext<'src, 'run>,
|
||||
dotenv: &BTreeMap<String, String>,
|
||||
scope: Scope<'src, 'run>,
|
||||
search: &'run Search,
|
||||
) -> RunResult<'src, ()> {
|
||||
let config = &context.config;
|
||||
|
||||
@ -82,13 +83,8 @@ impl<'src, D> Recipe<'src, D> {
|
||||
);
|
||||
}
|
||||
|
||||
let mut evaluator = Evaluator::recipe_evaluator(
|
||||
context.config,
|
||||
dotenv,
|
||||
&scope,
|
||||
context.settings,
|
||||
context.working_directory,
|
||||
);
|
||||
let mut evaluator =
|
||||
Evaluator::recipe_evaluator(context.config, dotenv, &scope, context.settings, search);
|
||||
|
||||
if self.shebang {
|
||||
let mut evaluated_lines = vec![];
|
||||
@ -166,12 +162,16 @@ impl<'src, D> Recipe<'src, D> {
|
||||
})?;
|
||||
|
||||
// create a command to run the script
|
||||
let mut command =
|
||||
Platform::make_shebang_command(&path, context.working_directory, interpreter, argument)
|
||||
.map_err(|output_error| RuntimeError::Cygpath {
|
||||
recipe: self.name(),
|
||||
output_error,
|
||||
})?;
|
||||
let mut command = Platform::make_shebang_command(
|
||||
&path,
|
||||
&context.search.working_directory,
|
||||
interpreter,
|
||||
argument,
|
||||
)
|
||||
.map_err(|output_error| RuntimeError::Cygpath {
|
||||
recipe: self.name(),
|
||||
output_error,
|
||||
})?;
|
||||
|
||||
command.export(dotenv, &scope);
|
||||
|
||||
@ -248,7 +248,7 @@ impl<'src, D> Recipe<'src, D> {
|
||||
|
||||
let mut cmd = context.settings.shell_command(config);
|
||||
|
||||
cmd.current_dir(context.working_directory);
|
||||
cmd.current_dir(&context.search.working_directory);
|
||||
|
||||
cmd.arg(command);
|
||||
|
||||
|
@ -3,6 +3,6 @@ use crate::common::*;
|
||||
pub(crate) struct RecipeContext<'src: 'run, 'run> {
|
||||
pub(crate) config: &'run Config,
|
||||
pub(crate) scope: Scope<'src, 'run>,
|
||||
pub(crate) working_directory: &'run Path,
|
||||
pub(crate) search: &'run Search,
|
||||
pub(crate) settings: &'run Settings<'src>,
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ use crate::common::*;
|
||||
|
||||
use std::path::Component;
|
||||
|
||||
const FILENAME: &str = "justfile";
|
||||
pub(crate) const FILENAME: &str = "justfile";
|
||||
const PROJECT_ROOT_CHILDREN: &[&str] = &[".bzr", ".git", ".hg", ".svn", "_darcs"];
|
||||
|
||||
pub(crate) struct Search {
|
||||
|
@ -20,6 +20,16 @@ pub(crate) fn config(args: &[&str]) -> Config {
|
||||
Config::from_matches(&matches).unwrap()
|
||||
}
|
||||
|
||||
pub(crate) fn search(config: &Config) -> Search {
|
||||
let working_directory = config.invocation_directory.clone();
|
||||
let justfile = working_directory.join(crate::search::FILENAME);
|
||||
|
||||
Search {
|
||||
working_directory,
|
||||
justfile,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) use test_utilities::{tempdir, unindent};
|
||||
|
||||
macro_rules! analysis_error {
|
||||
@ -80,15 +90,15 @@ macro_rules! run_error {
|
||||
} => {
|
||||
#[test]
|
||||
fn $name() {
|
||||
let config = &$crate::testing::config(&$args);
|
||||
let current_dir = std::env::current_dir().unwrap();
|
||||
let config = $crate::testing::config(&$args);
|
||||
let search = $crate::testing::search(&config);
|
||||
|
||||
if let Subcommand::Run{ overrides, arguments } = &config.subcommand {
|
||||
match $crate::compiler::Compiler::compile(&$crate::testing::unindent($src))
|
||||
.expect("Expected successful compilation")
|
||||
.run(
|
||||
config,
|
||||
¤t_dir,
|
||||
&config,
|
||||
&search,
|
||||
&overrides,
|
||||
&arguments,
|
||||
).expect_err("Expected runtime error") {
|
||||
|
Loading…
Reference in New Issue
Block a user