diff --git a/.vscode/settings.json b/.vscode/settings.json index 514eb56..eb32b6a 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,5 +7,8 @@ }, "rust-analyzer.rustfmt.extraArgs": ["+nightly"], "rust-analyzer.diagnostics.disabled": ["macro-error"], - "rust-analyzer.lens.enable": true + "rust-analyzer.lens.enable": true, + "[markdown]": { + "editor.wordWrapColumn": 100 + } } diff --git a/Cargo.lock b/Cargo.lock index 9f7e454..a8a9ebd 100755 --- a/Cargo.lock +++ b/Cargo.lock @@ -80,34 +80,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "arx" -version = "0.1.0" -dependencies = [ - "base32", - "chrono", - "clap", - "crossterm 0.27.0", - "flate2", - "git2", - "glob-match", - "home", - "indicatif", - "inquire", - "itertools", - "kdl", - "miette", - "reqwest", - "run_script", - "serde", - "tar", - "thiserror", - "tokio", - "toml", - "unindent", - "walkdir", -] - [[package]] name = "autocfg" version = "1.1.0" @@ -335,6 +307,34 @@ dependencies = [ "winapi", ] +[[package]] +name = "decaff" +version = "0.1.0" +dependencies = [ + "base32", + "chrono", + "clap", + "crossterm 0.27.0", + "flate2", + "git2", + "glob-match", + "home", + "indicatif", + "inquire", + "itertools", + "kdl", + "miette", + "reqwest", + "run_script", + "serde", + "tar", + "thiserror", + "tokio", + "toml", + "unindent", + "walkdir", +] + [[package]] name = "dunce" version = "1.0.2" diff --git a/Cargo.toml b/Cargo.toml index 7825896..3ff67e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,10 +1,10 @@ [package] -name = "arx" +name = "decaff" version = "0.1.0" edition = "2021" authors = ["Vladislav Mamon "] -description = "Simple and user-friendly command-line tool for declarative scaffolding." -repository = "https://github.com/norskeld/arx" +description = "Opinionated, simple, user-friendly command-line tool for declarative scaffolding." +repository = "https://github.com/norskeld/decaff" publish = false [dependencies] diff --git a/README.md b/README.md index 9bc9f07..3b5c6de 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,174 @@ -# arx +# decaff -[![Checks](https://img.shields.io/github/actions/workflow/status/norskeld/arx/checks.yml?style=flat-square&colorA=22272d&colorB=22272d&label=checks)](https://github.com/norskeld/arx/actions) +[![Checks](https://img.shields.io/github/actions/workflow/status/norskeld/decaff/checks.yml?style=flat-square&colorA=22272d&colorB=22272d&label=checks)](https://github.com/norskeld/decaff/actions) -Simple and user-friendly command-line tool for declarative scaffolding. +Opinionated, simple, user-friendly command-line tool for declarative scaffolding. ## Status > [!NOTE] > -> This is an MVP. -> -> - [Spec] was fleshed out and (mostly) implemented. -> - [Spec] is thoroughly commented and temporarily serves as a reference/documentation. -> - Bugs and uncovered edge cases are to be expected. -> - Test coverage is lacking. +> Mostly working, but bugs and uncovered edge cases to be expected. ## Installation -Right now **arx** can only be installed from source via **Cargo**. +Right now **decaff** can only be installed from source via **Cargo**. ### From source (Cargo) -Make sure to [install Rust toolchain][rust-toolchain] first. After that you can install arx using **Cargo**: +Make sure to [install Rust toolchain][rust-toolchain] first. After that you can install decaff using **Cargo**: ```shell -cargo install --locked --git https://github.com/norskeld/arx +cargo install --locked --git https://github.com/norskeld/decaff +``` + +## Example + +Below is a sample configuration file that demonstrates features of **decaff** and can be used as a reference. + +```scala +// Options defined here can be overridden from CLI. +options { + // Delete decaff config file after we're done. Defaults to `true`. + delete false +} + +// Actions to run after the repository was successfully downloaded and unpacked. All actions or +// suites of actions run sequentially, there is no concurrency or out-of-order execution for +// predictable outcomes. +// +// You can define either suites of actions — named groups of actions — or a flat list of actions, +// but not both. +// +// Notes: +// +// - Unpacking into an existing destination is forbidden. +// - Invalid or unknown actions, nodes or replacements will be skipped. Warnings will be issued. +// - Action failure terminates the main process. +// - No cleanup on failures by default. +actions { + suite "hello" { + // This action simply echoes the argument to stdout. Raw strings are trimmed by default and + // aligned to the leftmost non-whitespace character. Trimming can be disabled with `trim=false`. + echo r#" + Sup! Let's set everything up. We will: + + - Print this message. + - Ask some questions via prompts. + - Initialize git repository (not for real). + - Run some commands that will use input from prompts. + - Commit everything (again, not for real). + "# + } + + // In this suite we run a series of prompts asking different questions. + // + // Answers will be stored globally and available from any _subsequent_ action or suite of actions. + suite "prompts" { + // Text prompt. + input "repo_name" { + hint "Repository name" + default "norskeld/serpent" + } + + // Editor prompt. This runs the default $EDITOR. + editor "repo_desc" { + hint "Repository description" + default "Scaffolded with decaff" + } + + // Select prompt. + select "repo_pm" { + hint "Package manager of choice" + options "npm" "pnpm" "yarn" "bun" + } + + // Number prompt. Accepts both integers and floats. + number "magic_number" { + hint "Magic number" + default 42 + } + + // If no default value provided, prompt will become required. + input "repo_pm_args" { + hint "Additional arguments for package manager" + } + + // Simple confirm prompt. + confirm "should_commit" { + hint "Whether to stage and commit changes after scaffolding" + default false + } + } + + suite "git" { + // This action runs a given shell command and prints its output to stdout. + run "echo git init" + } + + // Here we demonstrate using replacements. + suite "replacements" { + // Replace all occurences of given replacements in files that match the glob pattern. + replace in=".template/**" { + "repo_name" + "repo_desc" + } + + // Replace all occurences of given replacements in _all_ files. This is equivalent to using + // "**/*" as the glob pattern. + replace { + "repo_pm" + } + + // Trying to run a non-existent replacement will do nothing (a warning will be issued though). + replace { + "NONEXISTENTREPLACEMENT" + } + } + + // In this suite we demonstrate actions for operating on files. All these actions support glob + // patterns, except the `to` field, that should be a relative path. + // + // Note: + // + // - Paths don't expand, i.e. ~ won't expand to the home directory and env vars won't work either. + suite "files" { + cp from=".template/*.toml" to="." + rm ".template/*.toml" + mv from=".template/**/*" to="." + rm ".template" + } + + // Here we demonstrate how to inject prompts' values. + suite "install" { + // To disambiguate whether {repo_pm} is part of a command or is a replacement that should be + // replaced with something, we pass `inject` node that explicitly tells decaff what to inject + // into the command. + // + // All replacements are processed _before_ running a command. + run "{repo_pm} install {repo_pm_args}" { + inject "repo_pm" "repo_pm_args" + } + } + + // Here we demonstrate multiline commands using `run`. + suite "commit" { + // Similarly to the `echo` action you can use raw strings to define multiline commands. Plus, + // you don't have to escape anything. + // + // The action below will be executed as if it were two separate `run` actions: + // + // run "git add ." + // run "git commit -m 'chore: init repository'" + // + // You can name `run` actions for clarity, otherwise decaff will use either the command itself + // or the first line of a multiline command as the hint. + run name="stage and commit" r#" + echo git add . + echo git commit -m 'chore: init repository' + "# + } +} ``` ## Acknowledgements @@ -37,7 +181,6 @@ Thanks to [Rich Harris][rich-harris] and his [degit] for inspiration. `:^)` -[spec]: spec.kdl [degit]: https://github.com/Rich-Harris/degit [rich-harris]: https://github.com/Rich-Harris [rust-toolchain]: https://rust-lang.org/tools/install diff --git a/rust-toolchain b/rust-toolchain deleted file mode 100644 index 2bf5ad0..0000000 --- a/rust-toolchain +++ /dev/null @@ -1 +0,0 @@ -stable diff --git a/rust-toolchain.toml b/rust-toolchain.toml new file mode 100644 index 0000000..73cb934 --- /dev/null +++ b/rust-toolchain.toml @@ -0,0 +1,3 @@ +[toolchain] +channel = "stable" +components = ["rustfmt", "clippy"] diff --git a/spec.kdl b/spec.kdl deleted file mode 100644 index 6389145..0000000 --- a/spec.kdl +++ /dev/null @@ -1,142 +0,0 @@ -// Options defined here can be overridden from CLI. -options { - // Delete arx config file after we're done. Defaults to `true`. - delete false -} - -// Actions to run after the repository was successfully downloaded and unpacked. All actions or -// suites of actions run sequentially, there is no concurrency or out-of-order execution for -// predictable outcomes. -// -// You can define either suites of actions — named groups of actions — or a flat list of actions, -// but not both. -// -// Notes: -// -// - Unpacking into an existing destination is forbidden. -// - Invalid or unknown actions, nodes or replacements will be skipped. Warnings will be issued. -// - Action failure terminates the main process. -// - No cleanup on failures by default. -actions { - suite "hello" { - // This action simply echoes the argument to stdout. Raw strings are trimmed by default and - // aligned to the leftmost non-whitespace character. Trimming can be disabled with `trim=false`. - echo r#" - Sup! Let's set everything up. We will: - - - Print this message. - - Ask some questions via prompts. - - Initialize git repository (not for real). - - Run some commands that will use input from prompts. - - Commit everything (again, not for real). - "# - } - - // In this suite we run a series of prompts asking different questions. - // - // Answers will be stored globally and available from any _subsequent_ action or suite of actions. - suite "prompts" { - // Text prompt. - input "repo_name" { - hint "Repository name" - default "norskeld/serpent" - } - - // Editor prompt. This runs the default $EDITOR. - editor "repo_desc" { - hint "Repository description" - default "Scaffolded with arx" - } - - // Select prompt. - select "repo_pm" { - hint "Package manager of choice" - options "npm" "pnpm" "yarn" "bun" - } - - // Number prompt. Accepts both integers and floats. - number "magic_number" { - hint "Magic number" - default 42 - } - - // If no default value provided, prompt will become required. - input "repo_pm_args" { - hint "Additional arguments for package manager" - } - - // Simple confirm prompt. - confirm "should_commit" { - hint "Whether to stage and commit changes after scaffolding" - default false - } - } - - suite "git" { - // This action runs a given shell command and prints its output to stdout. - run "echo git init" - } - - // Here we demonstrate using replacements. - suite "replacements" { - // Replace all occurences of given replacements in files that match the glob pattern. - replace in=".template/**" { - "repo_name" - "repo_desc" - } - - // Replace all occurences of given replacements in _all_ files. This is equivalent to "**/*" as - // the glob pattern. - replace { - "repo_pm" - } - - // Trying to run a non-existent replacement will do nothing (a warning will be issued though). - replace { - "NONEXISTENTREPLACEMENT" - } - } - - // In this suite we demonstrate actions for operating on files. All these actions support glob - // patterns, except the `to` field, that should be a relative path. - // - // Note: - // - // - Paths don't expand, i.e. ~ won't expand to the home directory and env vars won't work either. - suite "files" { - cp from=".template/*.toml" to="." - rm ".template/*.toml" - mv from=".template/**/*" to="." - rm ".template" - } - - // Here we demonstrate how to inject prompts' values. - suite "install" { - // To disambiguate whether {repo_pm} is part of a command or is a replacement that should be - // replaced with something, we pass `inject` node that explicitly tells arx what to inject - // into the command. - // - // All replacements are processed _before_ running a command. - run "{repo_pm} install {repo_pm_args}" { - inject "repo_pm" "repo_pm_args" - } - } - - // Here we demonstrate multiline commands using `run`. - suite "commit" { - // Similarly to the `echo` action you can use raw strings to define multiline commands. Plus, - // you don't have to escape anything. - // - // The action below will be executed as if it were two separate `run` actions: - // - // run "git add ." - // run "git commit -m 'chore: init repository'" - // - // You can name `run` actions for clarity, otherwise it will use either the command itself or - // the first line of a multiline command as the hint. - run name="stage and commit" r#" - echo git add . - echo git commit -m 'chore: init repository' - "# - } -} diff --git a/src/actions/actions.rs b/src/actions/actions.rs index 820f968..7bde14c 100644 --- a/src/actions/actions.rs +++ b/src/actions/actions.rs @@ -18,7 +18,7 @@ use crate::spinner::Spinner; #[derive(Debug, Diagnostic, Error)] pub enum ActionError { #[error("{message}")] - #[diagnostic(code(arx::actions::io))] + #[diagnostic(code(decaff::actions::io))] Io { message: String, #[source] diff --git a/src/actions/executor.rs b/src/actions/executor.rs index ad9081f..5c344b0 100644 --- a/src/actions/executor.rs +++ b/src/actions/executor.rs @@ -11,7 +11,7 @@ use crate::config::{ActionSingle, ActionSuite, Actions, Config, Value}; #[derive(Debug, Diagnostic, Error)] pub enum ExecutorError { #[error("{message}")] - #[diagnostic(code(arx::actions::executor::io))] + #[diagnostic(code(decaff::actions::executor::io))] Io { message: String, #[source] @@ -84,7 +84,7 @@ impl Executor { Ok(()) } - /// Execute a suite of actions. + /// Execute suites of actions. async fn suite(&self, suites: &[ActionSuite]) -> miette::Result<()> { let mut state = State::new(); @@ -94,7 +94,6 @@ impl Executor { println!("[{hint}: {name}]\n"); - // Man, I hate how peekable iterators work in Rust. let mut it = actions.iter().peekable(); while let Some(action) = it.next() { diff --git a/src/actions/prompts.rs b/src/actions/prompts.rs index eb76b94..9fd1c7c 100644 --- a/src/actions/prompts.rs +++ b/src/actions/prompts.rs @@ -6,7 +6,6 @@ use crate::config::{Number, Value}; use crate::utils::prompts as helpers; impl ConfirmPrompt { - /// Execute the prompt and populate the state. pub async fn execute(&self, state: &mut State) -> miette::Result<()> { let (name, hint, help) = helpers::messages(&self.name, &self.hint); @@ -28,7 +27,6 @@ impl ConfirmPrompt { } impl InputPrompt { - /// Execute the prompt and populate the state. pub async fn execute(&self, state: &mut State) -> miette::Result<()> { let (name, hint, help) = helpers::messages(&self.name, &self.hint); @@ -53,7 +51,6 @@ impl InputPrompt { } impl NumberPrompt { - /// Execute the prompt and populate the state. pub async fn execute(&self, state: &mut State) -> miette::Result<()> { let (name, hint, help) = helpers::messages(&self.name, &self.hint); @@ -80,7 +77,6 @@ impl NumberPrompt { } impl SelectPrompt { - /// Execute the prompt and populate the state. pub async fn execute(&self, state: &mut State) -> miette::Result<()> { let (name, hint, help) = helpers::messages(&self.name, &self.hint); @@ -100,7 +96,6 @@ impl SelectPrompt { } impl EditorPrompt { - /// Execute the prompt and populate the state. pub async fn execute(&self, state: &mut State) -> miette::Result<()> { let (name, hint, help) = helpers::messages(&self.name, &self.hint); diff --git a/src/cache.rs b/src/cache.rs index 74e6a99..998df0e 100644 --- a/src/cache.rs +++ b/src/cache.rs @@ -18,13 +18,13 @@ use crate::repository::RemoteRepository; /// Unpadded Base 32 alphabet. const BASE32_ALPHABET: Alphabet = Alphabet::RFC4648 { padding: false }; -/// `%userprofile%/AppData/Local/arx/.cache` +/// `%userprofile%/AppData/Local/decaff/.cache` #[cfg(target_os = "windows")] -const CACHE_ROOT: &str = "AppData/Local/arx/.cache"; +const CACHE_ROOT: &str = "AppData/Local/decaff/.cache"; -/// `$HOME/.cache/arx` +/// `$HOME/.cache/decaff` #[cfg(not(target_os = "windows"))] -const CACHE_ROOT: &str = ".cache/arx"; +const CACHE_ROOT: &str = ".cache/decaff"; /// `/tarballs/.tar.gz` const CACHE_TARBALLS_DIR: &str = "tarballs"; @@ -35,17 +35,17 @@ const CACHE_MANIFEST: &str = "manifest.toml"; #[derive(Debug, Diagnostic, Error)] pub enum CacheError { #[error("{message}")] - #[diagnostic(code(arx::cache::io))] + #[diagnostic(code(decaff::cache::io))] Io { message: String, #[source] source: io::Error, }, #[error(transparent)] - #[diagnostic(code(arx::cache::manifest::serialize))] + #[diagnostic(code(decaff::cache::manifest::serialize))] TomlSerialize(toml::ser::Error), #[error(transparent)] - #[diagnostic(code(arx::cache::manifest::deserialize))] + #[diagnostic(code(decaff::cache::manifest::deserialize))] TomlDeserialize(toml::de::Error), #[error("{0}")] #[diagnostic(transparent)] @@ -211,7 +211,7 @@ impl Cache { fn parse_repository(input: &str) -> Result { RemoteRepository::from_str(input).map_err(|_| { CacheError::Diagnostic(miette::miette!( - code = "arx::cache::malformed_entry", + code = "decaff::cache::malformed_entry", help = "Manifest may be malformed, clear the cache and try again.", "Couldn't parse entry: `{input}`." )) @@ -318,7 +318,7 @@ impl Cache { if let Some(bytes) = base32::decode(BASE32_ALPHABET, key) { let entry = String::from_utf8(bytes).map_err(|_| { CacheError::Diagnostic(miette::miette!( - code = "arx::cache::invalid_utf8", + code = "decaff::cache::invalid_utf8", help = "Manifest may be malformed, clear the cache and try again.", "Couldn't decode entry due to invalid UTF-8 in the string: `{key}`." )) @@ -341,7 +341,7 @@ impl Cache { } } else { return Err(CacheError::Diagnostic(miette::miette!( - code = "arx::cache::malformed_entry", + code = "decaff::cache::malformed_entry", help = "Manifest may be malformed, clear the cache and try again.", "Couldn't decode entry: `{key}`." ))); diff --git a/src/config/config.rs b/src/config/config.rs index 9d93871..17bd730 100644 --- a/src/config/config.rs +++ b/src/config/config.rs @@ -13,7 +13,7 @@ use crate::config::prompts::*; use crate::config::value::*; use crate::config::KdlUtils; -const CONFIG_NAME: &str = "arx.kdl"; +const CONFIG_NAME: &str = "decaff.kdl"; /// Helper macro to create a [ConfigError::Diagnostic] in a slightly less verbose way. macro_rules! diagnostic { @@ -29,7 +29,7 @@ macro_rules! diagnostic { #[derive(Debug, Diagnostic, Error)] pub enum ConfigError { #[error("{message}")] - #[diagnostic(code(arx::config::io))] + #[diagnostic(code(decaff::config::io))] Io { message: String, #[source] @@ -125,7 +125,7 @@ pub enum ActionSingle { Unknown(Unknown), } -/// Arx config. +/// decaff config. #[derive(Debug)] pub struct Config { /// Config directory. @@ -224,7 +224,7 @@ impl Config { defaults.delete = node.get_bool(0).ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::options", + code = "decaff::config::options", labels = vec![LabeledSpan::at( node.span().to_owned(), "this node requires a boolean argument" @@ -292,7 +292,7 @@ impl Config { // Otherwise we have invalid actions block. else { Err(ConfigError::Diagnostic(miette::miette!( - code = "arx::config::actions", + code = "decaff::config::actions", "You can use either suites of actions or a flat list of single actions. \ Right now you have a mix of both." ))) @@ -433,7 +433,7 @@ impl Config { node.get_string(0).ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![ LabeledSpan::at(start..end, "this node requires a string argument"), LabeledSpan::at_offset(end, "argument should be here") @@ -447,7 +447,7 @@ impl Config { node.get_string(key).ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![LabeledSpan::at( node.span().to_owned(), format!("this node requires the `{key}` attribute") @@ -474,7 +474,7 @@ impl Config { node.children().ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![LabeledSpan::at( node.span().to_owned(), format!("this node requires the following child nodes: {nodes}") @@ -488,7 +488,7 @@ impl Config { let hint = nodes.get("hint").ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![LabeledSpan::at( parent.span().to_owned(), "prompts require a `hint` child node" @@ -514,7 +514,7 @@ impl Config { let options = nodes.get("options").ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![LabeledSpan::at( parent.span().to_owned(), "select prompts require the `options` child node" @@ -538,7 +538,7 @@ impl Config { } else { return Err(diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![LabeledSpan::at( span, "option values can be either strings or numbers" @@ -550,7 +550,7 @@ impl Config { let option = value.ok_or_else(|| { diagnostic!( source = &self.source, - code = "arx::config::actions", + code = "decaff::config::actions", labels = vec![LabeledSpan::at( span, "failed to converted this value to a string" diff --git a/src/config/value.rs b/src/config/value.rs index 10c0f1f..4a54810 100644 --- a/src/config/value.rs +++ b/src/config/value.rs @@ -6,7 +6,7 @@ use thiserror::Error; #[derive(Debug, Diagnostic, Error)] #[error("`{0}` is not a valid number.")] -#[diagnostic(code(arx::config::prompts::parse))] +#[diagnostic(code(decaff::config::prompts::parse))] pub struct NumberParseError(pub String); /// Value of a number prompt. diff --git a/src/main.rs b/src/main.rs index 0ec0b7c..2cb5d16 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use arx::app::App; +use decaff::app::App; #[tokio::main] async fn main() { diff --git a/src/repository.rs b/src/repository.rs index 1976fe2..67fe42c 100644 --- a/src/repository.rs +++ b/src/repository.rs @@ -26,7 +26,7 @@ macro_rules! parse_error { #[derive(Debug, Diagnostic, Error)] pub enum RepositoryError { #[error("{message}")] - #[diagnostic(code(arx::repository::io))] + #[diagnostic(code(decaff::repository::io))] Io { message: String, #[source] @@ -40,7 +40,7 @@ pub enum RepositoryError { pub struct ParseError(Report); #[derive(Debug, Diagnostic, Error)] -#[diagnostic(code(arx::repository::fetch))] +#[diagnostic(code(decaff::repository::fetch))] pub enum FetchError { #[error("Request failed.")] RequestFailed, @@ -51,7 +51,7 @@ pub enum FetchError { } #[derive(Debug, Diagnostic, Error)] -#[diagnostic(code(arx::repository::remote))] +#[diagnostic(code(decaff::repository::remote))] pub enum RemoteError { #[error("Failed to create a detached in-memory remote.\n\n{url}")] CreateDetachedRemoteFailed { url: Report }, @@ -60,14 +60,14 @@ pub enum RemoteError { } #[derive(Debug, Diagnostic, Error)] -#[diagnostic(code(arx::repository::reference))] +#[diagnostic(code(decaff::repository::reference))] pub enum ReferenceError { #[error("Invalid reference: `{0}`.")] InvalidSelector(String), } #[derive(Debug, Diagnostic, Error)] -#[diagnostic(code(arx::repository::checkout))] +#[diagnostic(code(decaff::repository::checkout))] pub enum CheckoutError { #[error("Failed to open the git repository.")] OpenFailed(git2::Error), @@ -309,7 +309,7 @@ impl FromStr for RemoteRepository { | _ => { return Err(parse_error!( source = source.to_string(), - code = "arx::repository::parse", + code = "decaff::repository::parse", labels = vec![LabeledSpan::at( (0, host.len()), "must be one of: github/gh, gitlab/gl, or bitbucket/bb" @@ -331,7 +331,7 @@ impl FromStr for RemoteRepository { } else { return Err(parse_error!( source = source.to_string(), - code = "arx::repository::parse", + code = "decaff::repository::parse", labels = vec![LabeledSpan::at( (offset, user.len()), "only ASCII alphanumeric characters, _ and - allowed" @@ -350,7 +350,7 @@ impl FromStr for RemoteRepository { if matches!(input.find('#'), Some(hash_idx) if slash_idx < hash_idx) { return Err(parse_error!( source = source.to_string(), - code = "arx::repository::parse", + code = "decaff::repository::parse", labels = vec![LabeledSpan::at((offset + slash_idx, 1), "remove this")], "Multiple slashes in the input." )); @@ -366,7 +366,7 @@ impl FromStr for RemoteRepository { if !repo.chars().all(is_valid_repo) { return Err(parse_error!( source = source.to_string(), - code = "arx::repository::parse", + code = "decaff::repository::parse", labels = vec![LabeledSpan::at( (offset, repo.len()), "only ASCII alphanumeric characters, _, - and . allowed" @@ -564,7 +564,7 @@ mod tests { Err( parse_error!( source = "srht:foo/bar", - code = "arx::repository::parse", + code = "decaff::repository::parse", labels = vec![LabeledSpan::at( (0, 5), "must be one of: github/gh, gitlab/gl, or bitbucket/bb" diff --git a/src/unpacker.rs b/src/unpacker.rs index c20d470..bae4b2e 100644 --- a/src/unpacker.rs +++ b/src/unpacker.rs @@ -22,7 +22,7 @@ const USE_PERMISSIONS: bool = true; #[derive(Debug, Diagnostic, Error)] pub enum UnpackError { #[error("{message}")] - #[diagnostic(code(arx::unpack::io))] + #[diagnostic(code(decaff::unpack::io))] Io { message: String, #[source]