From 14fe425a2e5d40daf8bca24ca77c303cd1fff273 Mon Sep 17 00:00:00 2001 From: Christopher Harrison Date: Thu, 16 Mar 2023 11:08:39 +0000 Subject: [PATCH 1/4] Differentiate exit code by error type --- README.md | 16 ++++++++++++++++ src/bin/topiary/error.rs | 35 ++++++++++++++++++++++++++++++++++- src/bin/topiary/main.rs | 7 +++++-- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a018a54f..2d296cc9 100644 --- a/README.md +++ b/README.md @@ -181,6 +181,22 @@ Language selection is based on precedence, in the following order: * Detected from the input file's extension * A specified query file +#### Exit Codes + +The Topiary process will exit with a zero exit code upon successful +formatting. Otherwise, the following exit codes are defined: + +| Reason | Code | +| :--------------------------- | ---- | +| Unspecified error | 1 | +| CLI argument parsing error | 2 | +| I/O error | 3 | +| Topiary query error | 4 | +| Source parsing error | 5 | +| Language detection error | 6 | +| Idempotency error | 7 | +| Unspecified formatting error | 8 | + #### Example Once built, the program can be run like this: diff --git a/src/bin/topiary/error.rs b/src/bin/topiary/error.rs index 1720520d..5207ae12 100644 --- a/src/bin/topiary/error.rs +++ b/src/bin/topiary/error.rs @@ -1,4 +1,4 @@ -use std::{error, fmt, io, result}; +use std::{error, fmt, io, process::ExitCode, result}; use topiary::FormatterError; /// A convenience wrapper around `std::result::Result`. @@ -40,6 +40,39 @@ impl error::Error for TopiaryError { } } +impl From for ExitCode { + fn from(e: TopiaryError) -> Self { + let exit_code = match e { + // Formatting errors: Exit 8 + TopiaryError::Lib(FormatterError::Formatting(_)) => 8, + + // Idempotency errors: Exit 7 + TopiaryError::Lib(FormatterError::Idempotence) => 7, + + // Language detection errors: Exit 6 + TopiaryError::Lib(FormatterError::LanguageDetection(_, _)) => 6, + + // Parsing errors: Exit 5 + TopiaryError::Lib(FormatterError::Parsing { .. }) => 5, + + // Query errors: Exit 4 + TopiaryError::Lib(FormatterError::Query(_, _)) => 4, + + // I/O errors: Exit 3 + TopiaryError::Lib(FormatterError::Io(_)) => 3, + TopiaryError::Bin(_, Some(CLIError::IOError(_))) => 3, + + // Bad arguments: Exit 2 + // (Handled by clap) + + // Anything else: Exit 1 + _ => 1, + }; + + ExitCode::from(exit_code) + } +} + impl From for TopiaryError { fn from(e: FormatterError) -> Self { Self::Lib(e) diff --git a/src/bin/topiary/main.rs b/src/bin/topiary/main.rs index 84ee2d56..fa08bef6 100644 --- a/src/bin/topiary/main.rs +++ b/src/bin/topiary/main.rs @@ -8,6 +8,7 @@ use std::{ fs::File, io::{stdin, BufReader, BufWriter, Read}, path::PathBuf, + process::ExitCode }; use clap::{ArgGroup, Parser}; @@ -68,11 +69,13 @@ struct Args { } #[tokio::main] -async fn main() { +async fn main() -> ExitCode { if let Err(e) = run().await { print_error(&e); - std::process::exit(1); + return e.into(); } + + ExitCode::SUCCESS } async fn run() -> CLIResult<()> { From 11874fd657e9af90c5b5fd4863404050c81ab8c6 Mon Sep 17 00:00:00 2001 From: Christopher Harrison Date: Thu, 16 Mar 2023 11:26:32 +0000 Subject: [PATCH 2/4] Update precommit hook script Skip over language detection errors --- flake.nix | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/flake.nix b/flake.nix index 8bfa71a8..dc6a45ab 100644 --- a/flake.nix +++ b/flake.nix @@ -9,7 +9,7 @@ "tweag-topiary.cachix.org-1:8TKqya43LAfj4qNHnljLpuBnxAY/YwEBfzo3kzXxNY0=" ]; }; - + inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; @@ -34,7 +34,8 @@ let pkgs = nixpkgs.legacyPackages.${system}; code = pkgs.callPackage ./. { inherit nixpkgs system advisory-db crane rust-overlay nix-filter; }; - in { + in + { packages = with code; { inherit web-playground; default = app; @@ -48,17 +49,28 @@ enable = true; name = "topiary"; description = "A general code formatter based on tree-sitter."; - entry = let - topiary-inplace = pkgs.writeShellApplication { - name = "topiary-inplace"; - text = '' - for file; do - ${code.app}/bin/topiary --in-place --input-file "$file" - done - ''; - }; - in "${topiary-inplace}/bin/topiary-inplace"; - files = "(\\.json$)|(\\.toml$)|(\\.mli?$)"; + entry = + let + topiary-inplace = pkgs.writeShellApplication { + name = "topiary-inplace"; + text = '' + for FILE; do + if ${code.app}/bin/topiary --in-place --input-file "$FILE"; then + continue + else + EXIT=$? + if (( EXIT == 6 )); then + continue + else + exit $EXIT + fi + fi + done + ''; + }; + in + "${topiary-inplace}/bin/topiary-inplace"; + types = [ "text" ]; }; } ); From fdd08ea1527653fbe252f3718ac6094f4b158f45 Mon Sep 17 00:00:00 2001 From: Christopher Harrison Date: Thu, 16 Mar 2023 11:34:42 +0000 Subject: [PATCH 3/4] Fix formatting rustfmt is being weird and failing to run automatically on my machine, all of a sudden... --- src/bin/topiary/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/topiary/main.rs b/src/bin/topiary/main.rs index fa08bef6..17fe7ef1 100644 --- a/src/bin/topiary/main.rs +++ b/src/bin/topiary/main.rs @@ -8,7 +8,7 @@ use std::{ fs::File, io::{stdin, BufReader, BufWriter, Read}, path::PathBuf, - process::ExitCode + process::ExitCode, }; use clap::{ArgGroup, Parser}; From 745582290bdc758da993dac9feb406eb60a789ff Mon Sep 17 00:00:00 2001 From: Christopher Harrison Date: Thu, 16 Mar 2023 13:22:20 +0000 Subject: [PATCH 4/4] Explanatory comments --- flake.nix | 1 + src/bin/topiary/error.rs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index dc6a45ab..132a8a78 100644 --- a/flake.nix +++ b/flake.nix @@ -60,6 +60,7 @@ else EXIT=$? if (( EXIT == 6 )); then + # Skip over language detection errors continue else exit $EXIT diff --git a/src/bin/topiary/error.rs b/src/bin/topiary/error.rs index 5207ae12..acaf81aa 100644 --- a/src/bin/topiary/error.rs +++ b/src/bin/topiary/error.rs @@ -63,7 +63,7 @@ impl From for ExitCode { TopiaryError::Bin(_, Some(CLIError::IOError(_))) => 3, // Bad arguments: Exit 2 - // (Handled by clap) + // (Handled by clap: https://github.com/clap-rs/clap/issues/3426) // Anything else: Exit 1 _ => 1,