ronantakizawa/codereview-bench huggingface dataset:
Repository: casey/just
File: src/subcommand.rs (Rust)

Code before:

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    if config.dry_run {
      use std::io::Read as _;
      let mut current_content = String::new();
      let mut file = File::open(&search.justfile).map_err(|e| Error::Load {
        path: search.justfile.clone(),
        io_error: e,
      })?;
      file
        .read_to_string(&mut current_content)
        .map_err(|e| Error::Load {
          path: search.justfile.clone(),
          io_error: e,
        })?;

      if current_content != format!("{}", ast) {
        Err(Error::NotWellFormatted {
          justfile: search.justfile.clone(),
        })
      } else {
        if config.verbosity.loud() {
          eprintln!("Justfile `{}` is well-formatted.", search.justfile.display());
        }
        Ok(())
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| write!(file, "{}", ast))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {

Review comment (suggestion):
```suggestion
      if src != ast.to_string() {
```

Code after:

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    let src_formatted = ast.to_string();
    if config.check {
      if src == src_formatted {
        Ok(())
      } else {
        print!(
          "{}",
          similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None)
        );
        Err(Error::FormatCheckFoundDiff)
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| file.write_all(&src_formatted.as_bytes()))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {
    let search = Search::init(&config.search_config, &config.invocation_directory)?;

    if search.justfile.is_file() {
      Err(Error::InitExists {
        justfile: search.justfile,
      })
    } else if let Err(io_error) = fs::write(&search.justfile, INIT_JUSTFILE) {
      Err(Error::WriteJustfile {
        justfile: search.justfile,
        io_error,
      })
    } else {
      if config.verbosity.loud() {
Repository: casey/just
File: src/error.rs (Rust)

Code before:
            "Recipe `{}` could not be run because of an IO error while launching `sh`: {}",
            recipe, io_error
          ),
        }?;
      }
      Load { io_error, path } => {
        write!(
          f,
          "Failed to read justfile at `{}`: {}",
          path.display(),
          io_error
        )?;
      }
      NoChoosableRecipes => {
        write!(f, "Justfile contains no choosable recipes.")?;
      }
      NoRecipes => {
        write!(f, "Justfile contains no recipes.")?;
      }
      NotWellFormatted { justfile } => {
        write!(
          f,
          "Justfile `{}` is not well-formatted.",
          justfile.display()
        )?;
      }
      RegexCompile { source } => {
        write!(f, "{}", source)?;
      }
      Search { search_error } => Display::fmt(search_error, f)?,
      Shebang {
        recipe,
        command,
        argument,
        io_error,
      } => {
        if let Some(argument) = argument {
          write!(
            f,
            "Recipe `{}` with shebang `#!{} {}` execution error: {}",
            recipe, command, argument, io_error
          )?;
        } else {
          write!(
            f,
            "Recipe `{}` with shebang `#!{}` execution error: {}",
            recipe, command, io_error
          )?;
        }
      }
      Signal {

Review comment (suggestion):
```suggestion
      FormatCheckFoundDiff => {
        write!(
          f,
          "Diff found in justfile.",
        )?;
      }
```

Code after:
            f,
            "Recipe `{}` could not be run because of an IO error while launching the shell: {}",
            recipe, io_error
          ),
        }?;
      }
      Load { io_error, path } => {
        write!(
          f,
          "Failed to read justfile at `{}`: {}",
          path.display(),
          io_error
        )?;
      }
      NoChoosableRecipes => {
        write!(f, "Justfile contains no choosable recipes.")?;
      }
      NoRecipes => {
        write!(f, "Justfile contains no recipes.")?;
      }
      RegexCompile { source } => {
        write!(f, "{}", source)?;
      }
      Search { search_error } => Display::fmt(search_error, f)?,
      Shebang {
        recipe,
        command,
        argument,
        io_error,
      } => {
        if let Some(argument) = argument {
          write!(
            f,
            "Recipe `{}` with shebang `#!{} {}` execution error: {}",
            recipe, command, argument, io_error
          )?;
        } else {
          write!(
            f,
            "Recipe `{}` with shebang `#!{}` execution error: {}",
            recipe, command, io_error
          )?;
        }
      }
      Signal {
        recipe,
        line_number,
        signal,
      } => {
        if let Some(n) = line_number {
          write!(
Repository: casey/just
File: src/subcommand.rs (Rust)

Code before:
    let editor = env::var_os("VISUAL")
      .or_else(|| env::var_os("EDITOR"))
      .unwrap_or_else(|| "vim".into());

    let error = Command::new(&editor)
      .current_dir(&search.working_directory)
      .arg(&search.justfile)
      .status();

    let status = match error {
      Err(io_error) => return Err(Error::EditorInvoke { editor, io_error }),
      Ok(status) => status,
    };

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    if config.dry_run {
      let new_src = ast.to_string();
      if src != new_src {
        use prettydiff::diff_words;
        println!("Formatting diff:\n\n{}", diff_words(&src, &new_src));
        Err(Error::FormatCheckFoundDiff)
      } else {
        if config.verbosity.loud() {
          eprintln!("No format difference found.");
        }
        Ok(())
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| write!(file, "{}", ast))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }


Review comment (suggestion):
```suggestion
      let src_formatted = ast.to_string();
```

Code after:
    let editor = env::var_os("VISUAL")
      .or_else(|| env::var_os("EDITOR"))
      .unwrap_or_else(|| "vim".into());

    let error = Command::new(&editor)
      .current_dir(&search.working_directory)
      .arg(&search.justfile)
      .status();

    let status = match error {
      Err(io_error) => return Err(Error::EditorInvoke { editor, io_error }),
      Ok(status) => status,
    };

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    let src_formatted = ast.to_string();
    if config.check {
      if src == src_formatted {
        Ok(())
      } else {
        print!(
          "{}",
          similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None)
        );
        Err(Error::FormatCheckFoundDiff)
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| file.write_all(&src_formatted.as_bytes()))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {
Repository: casey/just
File: src/subcommand.rs (Rust)

Code before:
      .or_else(|| env::var_os("EDITOR"))
      .unwrap_or_else(|| "vim".into());

    let error = Command::new(&editor)
      .current_dir(&search.working_directory)
      .arg(&search.justfile)
      .status();

    let status = match error {
      Err(io_error) => return Err(Error::EditorInvoke { editor, io_error }),
      Ok(status) => status,
    };

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    if config.dry_run {
      let new_src = ast.to_string();
      if src != new_src {
        use prettydiff::diff_words;
        println!("Formatting diff:\n\n{}", diff_words(&src, &new_src));
        Err(Error::FormatCheckFoundDiff)
      } else {
        if config.verbosity.loud() {
          eprintln!("No format difference found.");
        }
        Ok(())
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| write!(file, "{}", ast))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {

Review comment (suggestion):
```suggestion
      if src != src_formatted {
```

Code after:
      .or_else(|| env::var_os("EDITOR"))
      .unwrap_or_else(|| "vim".into());

    let error = Command::new(&editor)
      .current_dir(&search.working_directory)
      .arg(&search.justfile)
      .status();

    let status = match error {
      Err(io_error) => return Err(Error::EditorInvoke { editor, io_error }),
      Ok(status) => status,
    };

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    let src_formatted = ast.to_string();
    if config.check {
      if src == src_formatted {
        Ok(())
      } else {
        print!(
          "{}",
          similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None)
        );
        Err(Error::FormatCheckFoundDiff)
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| file.write_all(&src_formatted.as_bytes()))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {
    let search = Search::init(&config.search_config, &config.invocation_directory)?;
Repository: casey/just
File: src/subcommand.rs (Rust)

Code before:

    let error = Command::new(&editor)
      .current_dir(&search.working_directory)
      .arg(&search.justfile)
      .status();

    let status = match error {
      Err(io_error) => return Err(Error::EditorInvoke { editor, io_error }),
      Ok(status) => status,
    };

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    if config.dry_run {
      let new_src = ast.to_string();
      if src != new_src {
        use prettydiff::diff_words;
        println!("Formatting diff:\n\n{}", diff_words(&src, &new_src));
        Err(Error::FormatCheckFoundDiff)
      } else {
        if config.verbosity.loud() {
          eprintln!("No format difference found.");
        }
        Ok(())
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| write!(file, "{}", ast))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {
    let search = Search::init(&config.search_config, &config.invocation_directory)?;


Review comment (suggestion):
Since it's only used once, it's fine to not have a use statement at all:

```suggestion
        println!("Formatting diff:\n\n{}", prettydiff::diff_words(&src, &new_src));
```

Code after:

    let error = Command::new(&editor)
      .current_dir(&search.working_directory)
      .arg(&search.justfile)
      .status();

    let status = match error {
      Err(io_error) => return Err(Error::EditorInvoke { editor, io_error }),
      Ok(status) => status,
    };

    if !status.success() {
      return Err(Error::EditorStatus { editor, status });
    }

    Ok(())
  }

  fn format(config: &Config, ast: Ast, src: &str, search: &Search) -> Result<(), Error<'static>> {
    config.require_unstable("The `--fmt` command is currently unstable.")?;

    let src_formatted = ast.to_string();
    if config.check {
      if src == src_formatted {
        Ok(())
      } else {
        print!(
          "{}",
          similar::udiff::unified_diff(similar::Algorithm::Patience, &src, &src_formatted, 2, None)
        );
        Err(Error::FormatCheckFoundDiff)
      }
    } else if let Err(io_error) =
      File::create(&search.justfile).and_then(|mut file| file.write_all(&src_formatted.as_bytes()))
    {
      Err(Error::WriteJustfile {
        justfile: search.justfile.clone(),
        io_error,
      })
    } else {
      if config.verbosity.loud() {
        eprintln!("Wrote justfile to `{}`", search.justfile.display());
      }
      Ok(())
    }
  }

  fn init(config: &Config) -> Result<(), Error<'static>> {
    let search = Search::init(&config.search_config, &config.invocation_directory)?;

    if search.justfile.is_file() {
Repository: casey/just
File: tests/fmt.rs (Rust)

Code before:
use crate::common::*;

test! {
  name: unstable_not_passed,
  justfile: "",
  args: ("--fmt"),
  stderr: "
    error: The `--fmt` command is currently unstable. \
    Invoke `just` with the `--unstable` flag to enable unstable features.
  ",
  status: EXIT_FAILURE,
}

test! {
  name: dry_run_ok,
  justfile: "",
  args: ("--unstable", "--fmt", "--dry-run"),
  status: EXIT_SUCCESS,
}

test! {
  name: dry_run_found_diff,
  justfile: "x:=``\n",
  args: ("--unstable", "--fmt", "--dry-run"),
  stdout: "
  @@ -1 +1 @@
  -x:=``
  +x := ``\n
  ",
  stderr: "
    error: Formatted justfile differs from original.
  ",
  status: EXIT_FAILURE,
}

#[test]
fn unstable_passed() {
  let tmp = tempdir();

  let justfile = tmp.path().join("justfile");

  fs::write(&justfile, "x    :=    'hello'   ").unwrap();

Review comment (suggestion):
I think this should be a more complicated justfile that has no diff, so at least one assignment and one recipe, with some text in the body.

Code after:
use crate::common::*;

test! {
  name: unstable_not_passed,
  justfile: "",
  args: ("--fmt"),
  stderr: "
    error: The `--fmt` command is currently unstable. \
    Invoke `just` with the `--unstable` flag to enable unstable features.
  ",
  status: EXIT_FAILURE,
}

test! {
  name: check_without_fmt,
  justfile: "",
  args: ("--check"),
  stderr_regex: "error: The following required arguments were not provided:
    --fmt
(.|\\n)+",
  status: EXIT_FAILURE,
}

test! {
  name: dry_run_ok,
  justfile: r#"
# comment   with   spaces

export x := `backtick
with
lines`

recipe: deps
    echo "$x"

deps:
    echo {{ x }}
    echo '$x'
"#,
  args: ("--unstable", "--fmt", "--check"),
  status: EXIT_SUCCESS,
}
Repository: casey/just
File: src/justfile.rs (Rust)

Code before:
  // recipes variables are not available in subsequent lines and execution stops
  // when a line fails.
  run_error! {
    name: run_shebang,
    src: "
      a:
        #!/usr/bin/env sh
        code=200
          x() { return $code; }
            x
              x
    ",
    args: ["a"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "a");
      assert_eq!(code, 200);
      assert_eq!(line_number, None);
    }
  }

  run_error! {
    name: code_error,
    src: "
      set windows-powershell
      fail:
        @exit 100
    ",
    args: ["fail"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "fail");
      assert_eq!(code, 100);
      assert_eq!(line_number, Some(3));
    }
  }

  #[cfg(target_os = "linux")]
  run_error! {
    name: run_args,
    src: r#"
      a return code:
        @x() { {{return}} {{code + "0"}}; }; x

Review comment (suggestion):
This test is unrelated to this PR, so should be reverted. This PR should add additional tests, not change existing tests.

Code after:
  // recipes variables are not available in subsequent lines and execution stops
  // when a line fails.
  run_error! {
    name: run_shebang,
    src: "
      a:
        #!/usr/bin/env sh
        code=200
          x() { return $code; }
            x
              x
    ",
    args: ["a"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "a");
      assert_eq!(code, 200);
      assert_eq!(line_number, None);
    }
  }

  run_error! {
    name: code_error,
    src: "
      fail:
        @exit 100
    ",
    args: ["fail"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "fail");
      assert_eq!(code, 100);
      assert_eq!(line_number, Some(2));
    }
  }

  run_error! {
    name: run_args,
    src: r#"
      a return code:
        @x() { {{return}} {{code + "0"}}; }; x
    "#,
    args: ["a", "return", "15"],
Repository: casey/just
File: src/justfile.rs (Rust)

Code before:
      assert_eq!(code, 100);
      assert_eq!(line_number, Some(3));
    }
  }

  #[cfg(target_os = "linux")]
  run_error! {
    name: run_args,
    src: r#"
      a return code:
        @x() { {{return}} {{code + "0"}}; }; x
    "#,
    args: ["a", "return", "15"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "a");
      assert_eq!(code, 150);
      assert_eq!(line_number, Some(2));
    }
  }

  #[cfg(target_os = "windows")]
  run_error! {
    name: run_args,
    src: r#"
      set windows-powershell
      a return code:
        @function x() { {{return}} {{code + "0"}}; }; x
    "#,
    args: ["a", "exit", "15"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "a");
      assert_eq!(code, 150);
      assert_eq!(line_number, Some(3));
    }
  }

  run_error! {
    name: missing_some_arguments,
    src: "a b c d:",
    args: ["a", "b", "c"],
    error: ArgumentCountMismatch {

Review comment (suggestion):
This change doesn't seem related to this PR.

I think this PR should get a new test which just tests the feature being added.

This could be as simple as:

```rust
#[test]
fn windows_poweshell_setting_uses_powershell() {
  Test::new()
    .justfile(
     "
      set windows-powershell

      foo:
        Write-Output bar
    "#,
    )
    .stdout("bar")
    .stderr("Write-Output bar")
    .run();
}
```

This uses the new, struct-based tests instead of macros, which are preferred at this point, although both kinds of tests still exist.

This test can go in a new module `tests/windows_powershell.rs`

Code after:
      assert_eq!(line_number, Some(2));
    }
  }

  run_error! {
    name: run_args,
    src: r#"
      a return code:
        @x() { {{return}} {{code + "0"}}; }; x
    "#,
    args: ["a", "return", "15"],
    error: Code {
      recipe,
      line_number,
      code,
    },
    check: {
      assert_eq!(recipe, "a");
      assert_eq!(code, 150);
      assert_eq!(line_number, Some(2));
    }
  }

  run_error! {
    name: missing_some_arguments,
    src: "a b c d:",
    args: ["a", "b", "c"],
    error: ArgumentCountMismatch {
      recipe,
      parameters,
      found,
      min,
      max,
    },
    check: {
      let param_names = parameters
        .iter()
        .map(|p| p.name.lexeme())
        .collect::<Vec<&str>>();
      assert_eq!(recipe, "a");
      assert_eq!(param_names, ["b", "c", "d"]);
      assert_eq!(found, 2);
      assert_eq!(min, 3);
      assert_eq!(max, 3);
    }
  }

  run_error! {
    name: missing_some_arguments_variadic,
    src: "a b c +d:",
    args: ["a", "B", "C"],
Repository: casey/just
File: src/settings.rs (Rust)

Code before:
use crate::common::*;

pub(crate) const DEFAULT_SHELL: &str = "sh";
pub(crate) const DEFAULT_SHELL_ARG: &[&str] = &["-cu"];
pub(crate) const WINDOWS_DEFAULT_SHELL: &str = "powershell.exe";
pub(crate) const WINDOWS_DEFAULT_SHELL_ARG: &[&str] = &["-NoLogo", "-Command"];

#[derive(Debug, PartialEq, Serialize)]
pub(crate) struct Settings<'src> {
  pub(crate) dotenv_load: Option<bool>,
  pub(crate) export: bool,
  pub(crate) positional_arguments: bool,
  pub(crate) shell: Option<setting::Shell<'src>>,
  pub(crate) windows_powershell: bool,
}

impl<'src> Settings<'src> {
  pub(crate) fn new() -> Settings<'src> {
    Settings {
      dotenv_load: None,
      export: false,
      positional_arguments: false,
      shell: None,
      windows_powershell: false,
    }
  }

  pub(crate) fn shell_command(&self, config: &Config) -> Command {
    let mut cmd = Command::new(self.shell_binary(config));

Review comment (suggestion):
```suggestion
pub(crate) const DEFAULT_SHELL_ARGS: &[&str] = &["-cu"];
```

Code after:
use crate::common::*;

pub(crate) const DEFAULT_SHELL: &str = "sh";
pub(crate) const DEFAULT_SHELL_ARGS: &[&str] = &["-cu"];
pub(crate) const WINDOWS_POWERSHELL_SHELL: &str = "powershell.exe";
pub(crate) const WINDOWS_POWERSHELL_ARGS: &[&str] = &["-NoLogo", "-Command"];

#[derive(Debug, PartialEq, Serialize)]
pub(crate) struct Settings<'src> {
  pub(crate) dotenv_load: Option<bool>,
  pub(crate) export: bool,
  pub(crate) positional_arguments: bool,
  pub(crate) shell: Option<setting::Shell<'src>>,
  pub(crate) windows_powershell: bool,
}

impl<'src> Settings<'src> {
  pub(crate) fn new() -> Settings<'src> {
    Settings {
      dotenv_load: None,
      export: false,
      positional_arguments: false,
      shell: None,
      windows_powershell: false,
    }
  }

  pub(crate) fn shell_command(&self, config: &Config) -> Command {
    let mut cmd = Command::new(self.shell_binary(config));