Skip to content

Commit

Permalink
Add source information as path of the information
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
psibi committed Nov 17, 2024
1 parent 5db910f commit aad53df
Show file tree
Hide file tree
Showing 14 changed files with 1,235 additions and 930 deletions.
25 changes: 22 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ most Windows users.)
<tr>
<td><a href=https://www.npmjs.com/>npm</a></td>
<td><a href=https://www.npmjs.com/package/rust-just>rust-just</a></td>
<td><code>npm install rust-just</code></td>
<td><code>npm install -g rust-just</code></td>
</tr>
<tr>
<td><a href=https://pypi.org/>PyPI</a></td>
Expand Down Expand Up @@ -1851,6 +1851,24 @@ for details.
`requirement`, e.g., `">=0.1.0"`, returning `"true"` if so and `"false"`
otherwise.

#### Style

- `style(name)`<sup>master</sup> - Return a named terminal display attribute
escape sequence used by `just`. Unlike terminal display attribute escape
sequence constants, which contain standard colors and styles, `style(name)`
returns an escape sequence used by `just` itself, and can be used to make
recipe output match `just`'s own output.

Recognized values for `name` are `'command'`, for echoed recipe lines,
`error`, and `warning`.

For example, to style an error message:

```just
scary:
@echo '{{ style("error") }}OH NO{{ NORMAL }}'
```

##### XDG Directories<sup>1.23.0</sup>

These functions return paths to user-specific directories for things like
Expand Down Expand Up @@ -2755,8 +2773,9 @@ scripts interpreted by `COMMAND`. This avoids some of the issues with shebang
recipes, such as the use of `cygpath` on Windows, the need to use
`/usr/bin/env`, and inconsistences in shebang line splitting across Unix OSs.

Recipes with an empty `[script]` attribute are executed with the value of
`set script-interpreter := […]`<sup>1.33.0</sup>, defaulting to `sh -eu`.
Recipes with an empty `[script]` attribute are executed with the value of `set
script-interpreter := []`<sup>1.33.0</sup>, defaulting to `sh -eu`, and *not*
the value of `set shell`.

The body of the recipe is evaluated, written to disk in the temporary
directory, and run by passing its path as an argument to `COMMAND`.
Expand Down
16 changes: 16 additions & 0 deletions README.中文.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,22 @@ list:
<code>asdf install just &lt;version&gt;</code>
</td>
</tr>
<tr>
<td><a href="https://packaging.python.org/tutorials/installing-packages">Various</a></td>
<td><a href="https://pypi.org">PyPI</a></td>
<td><a href="https://pypi.org/project/rust-just">rust-just</a></td>
<td>
<code>pipx install rust-just</code><br>
</td>
</tr>
<tr>
<td><a href="https://docs.npmjs.com/packages-and-modules/getting-packages-from-the-registry">Various</a></td>
<td><a href="https://www.npmjs.com">npm</a></td>
<td><a href="https://www.npmjs.com/package/rust-just">rust-just</a></td>
<td>
<code>npm install -g rust-just</code><br>
</td>
</tr>
<tr>
<td><a href="https://debian.org">Debian</a> and <a href="https://ubuntu.com">Ubuntu</a> derivatives</td>
<td><a href="https://mpr.makedeb.org">MPR</a></td>
Expand Down
3 changes: 2 additions & 1 deletion src/analyzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
Expand Down
3 changes: 1 addition & 2 deletions src/color.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ impl Color {
Self::default()
}

#[cfg(test)]
pub(crate) fn always() -> Self {
Self {
use_color: UseColor::Always,
Expand Down Expand Up @@ -67,7 +66,7 @@ impl Color {
}

pub(crate) fn doc_backtick(self) -> Self {
self.restyle(Style::new().fg(White).on(Black))
self.restyle(Style::new().fg(Cyan))
}

pub(crate) fn error(self) -> Self {
Expand Down
15 changes: 15 additions & 0 deletions src/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ pub(crate) fn get(name: &str) -> Option<Function> {
"snakecase" => Unary(snakecase),
"source_directory" => Nullary(source_directory),
"source_file" => Nullary(source_file),
"style" => Unary(style),
"titlecase" => Unary(titlecase),
"trim" => Unary(trim),
"trim_end" => Unary(trim_end),
Expand Down Expand Up @@ -623,6 +624,20 @@ fn source_file(context: Context) -> FunctionResult {
})
}

fn style(context: Context, s: &str) -> FunctionResult {
match s {
"command" => Ok(
Color::always()
.command(context.evaluator.context.config.command_color)
.prefix()
.to_string(),
),
"error" => Ok(Color::always().error().prefix().to_string()),
"warning" => Ok(Color::always().warning().prefix().to_string()),
_ => Err(format!("unknown style: `{s}`")),
}
}

fn titlecase(_context: Context, s: &str) -> FunctionResult {
Ok(s.to_title_case())
}
Expand Down
1 change: 0 additions & 1 deletion src/justfile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
2 changes: 1 addition & 1 deletion src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ impl<'src> Node<'src> for UnresolvedRecipe<'src> {
t.push_mut("quiet");
}

if let Some(doc) = self.doc {
if let Some(doc) = &self.doc {
t.push_mut(Tree::string(doc));
}

Expand Down
8 changes: 8 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,6 +936,14 @@ impl<'run, 'src> Parser<'run, 'src> {

let private = name.lexeme().starts_with('_') || attributes.contains(&Attribute::Private);

let mut doc = doc.map(ToOwned::to_owned);

for attribute in &attributes {
if let Attribute::Doc(attribute_doc) = attribute {
doc = attribute_doc.as_ref().map(|doc| doc.cooked.clone());
}
}

Ok(Recipe {
shebang: shebang || script,
attributes,
Expand Down
15 changes: 11 additions & 4 deletions src/recipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub(crate) struct Recipe<'src, D = Dependency<'src>> {
pub(crate) attributes: BTreeSet<Attribute<'src>>,
pub(crate) body: Vec<Line<'src>>,
pub(crate) dependencies: Vec<D>,
pub(crate) doc: Option<&'src str>,
pub(crate) doc: Option<String>,
#[serde(skip)]
pub(crate) file_depth: u32,
#[serde(skip)]
Expand Down Expand Up @@ -465,7 +465,8 @@ impl<'src, D> Recipe<'src, D> {
return doc.as_ref().map(|s| s.cooked.as_ref());
}
}
self.doc

self.doc.as_deref()
}

pub(crate) fn subsequents(&self) -> impl Iterator<Item = &D> {
Expand All @@ -475,8 +476,14 @@ impl<'src, D> Recipe<'src, D> {

impl<'src, D: Display> ColorDisplay for Recipe<'src, D> {
fn fmt(&self, f: &mut Formatter, color: Color) -> fmt::Result {
if let Some(doc) = self.doc {
writeln!(f, "# {doc}")?;
if !self
.attributes
.iter()
.any(|attribute| matches!(attribute, Attribute::Doc(_)))
{
if let Some(doc) = &self.doc {
writeln!(f, "# {doc}")?;
}
}

for attribute in &self.attributes {
Expand Down
24 changes: 24 additions & 0 deletions tests/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1096,3 +1096,27 @@ fn multi_argument_attribute() {
)
.run();
}

#[test]
fn doc_attribute_suppresses_comment() {
Test::new()
.justfile(
"
set unstable
# COMMENT
[doc('ATTRIBUTE')]
foo:
",
)
.arg("--dump")
.stdout(
"
set unstable := true
[doc('ATTRIBUTE')]
foo:
",
)
.run();
}
75 changes: 75 additions & 0 deletions tests/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,3 +1183,78 @@ bar:
.args(["foo", "bar"])
.run();
}

#[test]
fn style_command_default() {
Test::new()
.justfile(
r#"
foo:
@echo '{{ style("command") }}foo{{NORMAL}}'
"#,
)
.stdout("\x1b[1mfoo\x1b[0m\n")
.run();
}

#[test]
fn style_command_non_default() {
Test::new()
.justfile(
r#"
foo:
@echo '{{ style("command") }}foo{{NORMAL}}'
"#,
)
.args(["--command-color", "red"])
.stdout("\x1b[1;31mfoo\x1b[0m\n")
.run();
}

#[test]
fn style_error() {
Test::new()
.justfile(
r#"
foo:
@echo '{{ style("error") }}foo{{NORMAL}}'
"#,
)
.stdout("\x1b[1;31mfoo\x1b[0m\n")
.run();
}

#[test]
fn style_warning() {
Test::new()
.justfile(
r#"
foo:
@echo '{{ style("warning") }}foo{{NORMAL}}'
"#,
)
.stdout("\x1b[1;33mfoo\x1b[0m\n")
.run();
}

#[test]
fn style_unknown() {
Test::new()
.justfile(
r#"
foo:
@echo '{{ style("hippo") }}foo{{NORMAL}}'
"#,
)
.stderr(
r#"
error: Call to function `style` failed: unknown style: `hippo`
——▶ justfile:2:13
2 │ @echo '{{ style("hippo") }}foo{{NORMAL}}'
│ ^^^^^
"#,
)
.status(EXIT_FAILURE)
.run();
}
Loading

0 comments on commit aad53df

Please sign in to comment.