1
1
mirror of https://github.com/casey/just.git synced 2024-11-25 07:06:23 +03:00

Add source information as path of the information

Motivation: To add support for module integration in justl which is an
Emacs extension for driving justfiles within Emacs.

This would allow me to easily discover the file locations of different
just modules and allow the ability to individually open justl buffers
for them within the editor.
This commit is contained in:
Sibi Prabakaran 2024-11-16 17:42:17 +05:30
parent 084a2d2de3
commit 516fac504c
No known key found for this signature in database
GPG Key ID: D19E3E0EBB557613
4 changed files with 1036 additions and 894 deletions

View File

@ -182,6 +182,7 @@ impl<'run, 'src> Analyzer<'run, 'src> {
unstable_features.insert(UnstableFeature::ScriptInterpreterSetting);
}
let source = root.canonicalize().unwrap();
let root = paths.get(root).unwrap();
Ok(Justfile {
@ -205,7 +206,7 @@ impl<'run, 'src> Analyzer<'run, 'src> {
name,
recipes,
settings,
source: root.into(),
source,
unexports: self.unexports,
unstable_features,
warnings: self.warnings,

View File

@ -23,7 +23,6 @@ pub(crate) struct Justfile<'src> {
pub(crate) name: Option<Name<'src>>,
pub(crate) recipes: Table<'src, Rc<Recipe<'src>>>,
pub(crate) settings: Settings<'src>,
#[serde(skip)]
pub(crate) source: PathBuf,
pub(crate) unexports: HashSet<String>,
#[serde(skip)]

View File

@ -1,22 +1,30 @@
use super::*;
fn case(justfile: &str, value: Value) {
fn case<F: Fn(&Path) -> Value>(justfile: &str, value: F) {
Test::new()
.justfile(justfile)
.args(["--dump", "--dump-format", "json"])
.stdout(format!("{}\n", serde_json::to_string(&value).unwrap()))
.stdout_with_tempdir(|dir| format!("{}\n", serde_json::to_string(&value(dir.path())).unwrap()))
.run();
}
#[test]
fn alias() {
case(
let test = Test::new().justfile(
"
alias f := foo
foo:
",
json!({
);
let source = test
.tempdir
.path()
.join("justfile")
.to_str()
.unwrap()
.to_owned();
let json = json!({
"first": "foo",
"doc": null,
"aliases": {
@ -66,14 +74,18 @@ fn alias() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
});
test
.args(["--dump", "--dump-format", "json"])
.stdout(format!("{}\n", serde_json::to_string(&json).unwrap()))
.run();
}
#[test]
fn assignment() {
case(
"foo := 'bar'",
case("foo := 'bar'", |dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {
@ -110,8 +122,9 @@ fn assignment() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
})
});
}
#[test]
@ -122,6 +135,8 @@ fn private_assignment() {
[private]
bar := 'bar'
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {
@ -164,7 +179,9 @@ fn private_assignment() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -176,6 +193,8 @@ fn body() {
bar
abc{{ 'xyz' }}def
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -222,7 +241,9 @@ fn body() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -233,6 +254,8 @@ fn dependencies() {
foo:
bar: foo
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -292,7 +315,9 @@ fn dependencies() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -316,6 +341,8 @@ fn dependency_argument() {
replace('a', 'b', 'c')
)
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"first": "foo",
@ -400,7 +427,9 @@ fn dependency_argument() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -414,6 +443,8 @@ fn duplicate_recipes() {
foo:
foo bar:
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"first": "foo",
"doc": null,
@ -470,7 +501,9 @@ fn duplicate_recipes() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -482,6 +515,8 @@ fn duplicate_variables() {
x := 'foo'
x := 'bar'
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {
@ -518,14 +553,16 @@ fn duplicate_variables() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
#[test]
fn doc_comment() {
case(
"# hello\nfoo:",
case("# hello\nfoo:", |dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"first": "foo",
@ -569,14 +606,15 @@ fn doc_comment() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
})
});
}
#[test]
fn empty_justfile() {
case(
"",
case("", |dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -606,8 +644,9 @@ fn empty_justfile() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
})
});
}
#[test]
@ -621,6 +660,8 @@ fn parameters() {
e *x:
f $x:
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"first": "a",
@ -764,7 +805,9 @@ fn parameters() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -776,6 +819,8 @@ fn priors() {
b: a && c
c:
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -855,14 +900,16 @@ fn priors() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
#[test]
fn private() {
case(
"_foo:",
case("_foo:", |dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -906,14 +953,15 @@ fn private() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
})
});
}
#[test]
fn quiet() {
case(
"@foo:",
case("@foo:", |dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -957,8 +1005,9 @@ fn quiet() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
})
});
}
#[test]
@ -977,6 +1026,8 @@ fn settings() {
foo:
#!bar
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -1023,7 +1074,9 @@ fn settings() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -1034,6 +1087,8 @@ fn shebang() {
foo:
#!bar
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -1077,14 +1132,16 @@ fn shebang() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
#[test]
fn simple() {
case(
"foo:",
case("foo:", |dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -1128,8 +1185,9 @@ fn simple() {
},
"unexports": [],
"warnings": [],
}),
);
"source": source,
})
});
}
#[test]
@ -1139,6 +1197,8 @@ fn attribute() {
[no-exit-message]
foo:
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -1182,7 +1242,9 @@ fn attribute() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
@ -1199,7 +1261,10 @@ fn module() {
"foo.just": "bar:",
})
.args(["--dump", "--dump-format", "json"])
.stdout(format!(
.stdout_with_tempdir(|dir| {
let source = dir.path().join("justfile").to_str().unwrap().to_owned();
let foo_just = dir.path().join("foo.just").to_str().unwrap().to_owned();
format!(
"{}\n",
serde_json::to_string(&json!({
"aliases": {},
@ -1251,6 +1316,7 @@ fn module() {
},
"unexports": [],
"warnings": [],
"source": foo_just
},
},
"recipes": {},
@ -1275,9 +1341,11 @@ fn module() {
},
"unexports": [],
"warnings": [],
"source": source
}))
.unwrap()
))
)
})
.run();
}
@ -1294,7 +1362,10 @@ fn module_group() {
"foo.just": "bar:",
})
.args(["--dump", "--dump-format", "json"])
.stdout(format!(
.stdout_with_tempdir(|dir| {
let source = dir.path().join("justfile").to_str().unwrap().to_owned();
let foo_just = dir.path().join("foo.just").to_str().unwrap().to_owned();
format!(
"{}\n",
serde_json::to_string(&json!({
"aliases": {},
@ -1346,6 +1417,7 @@ fn module_group() {
},
"unexports": [],
"warnings": [],
"source": foo_just,
},
},
"recipes": {},
@ -1370,9 +1442,11 @@ fn module_group() {
},
"unexports": [],
"warnings": [],
"source": source,
}))
.unwrap()
))
)
})
.run();
}
@ -1383,6 +1457,8 @@ fn recipes_with_private_attribute_are_private() {
[private]
foo:
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
@ -1426,7 +1502,68 @@ fn recipes_with_private_attribute_are_private() {
},
"unexports": [],
"warnings": [],
}),
"source": source,
})
},
);
}
#[test]
fn doc_attribute_overrides_comment() {
case(
"
# COMMENT
[doc('ATTRIBUTE')]
foo:
",
|dir| {
let source = dir.join("justfile").to_str().unwrap().to_owned();
json!({
"aliases": {},
"assignments": {},
"first": "foo",
"doc": null,
"groups": [],
"modules": {},
"recipes": {
"foo": {
"attributes": [{"doc": "ATTRIBUTE"}],
"body": [],
"dependencies": [],
"doc": "ATTRIBUTE",
"name": "foo",
"namepath": "foo",
"parameters": [],
"priors": 0,
"private": false,
"quiet": false,
"shebang": false,
}
},
"settings": {
"allow_duplicate_recipes": false,
"allow_duplicate_variables": false,
"dotenv_filename": null,
"dotenv_load": false,
"dotenv_path": null,
"dotenv_required": false,
"export": false,
"fallback": false,
"ignore_comments": false,
"positional_arguments": false,
"quiet": false,
"shell": null,
"tempdir" : null,
"unstable": false,
"windows_powershell": false,
"windows_shell": null,
"working_directory" : null,
},
"unexports": [],
"warnings": [],
"source": source
})
},
);
}

View File

@ -167,6 +167,11 @@ impl Test {
self
}
pub(crate) fn stdout_with_tempdir(mut self, stdout_fn: impl Fn(&TempDir) -> String) -> Self {
self.stdout = stdout_fn(&self.tempdir);
self
}
pub(crate) fn stdout_regex(mut self, stdout_regex: impl AsRef<str>) -> Self {
self.stdout_regex = Some(Regex::new(&format!("^{}$", stdout_regex.as_ref())).unwrap());
self