diff --git a/CHANGELOG.md b/CHANGELOG.md index 80c6fd79f1..e684f7dea9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * `jj config list` command prints values from config (with other subcommands coming soon). +* `jj debug config-schema` command prints out JSON (and TOML) schema + for jj config files. + ### Fixed bugs * When sharing the working copy with a Git repo, we used to forget to export diff --git a/Cargo.lock b/Cargo.lock index e73ede0199..fa8b8a026e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -708,6 +708,7 @@ dependencies = [ "console", "lazy_static", "linked-hash-map", + "regex", "similar", "yaml-rust", ] diff --git a/Cargo.toml b/Cargo.toml index 0be3957628..8a4db6b9b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,7 @@ libc = { version = "0.2.139" } assert_cmd = "2.0.7" criterion = "0.4.0" criterion_bencher_compat = "0.4.0" -insta = "1.23.0" +insta = { version = "1.23.0", features = ["filters"] } predicates = "2.1.5" regex = "1.7.0" test-case = "2.2.2" diff --git a/src/commands.rs b/src/commands.rs index 0df07ec8a1..6a2101d6e2 100644 --- a/src/commands.rs +++ b/src/commands.rs @@ -999,6 +999,7 @@ struct GitExportArgs {} enum DebugCommands { Completion(DebugCompletionArgs), Mangen(DebugMangenArgs), + ConfigSchema(DebugConfigSchemaArgs), #[command(name = "resolverev")] ResolveRev(DebugResolveRevArgs), #[command(name = "workingcopy")] @@ -1043,6 +1044,10 @@ struct DebugCompletionArgs { #[derive(clap::Args, Clone, Debug)] struct DebugMangenArgs {} +/// Print the JSON schema for jj's TOML config format. +#[derive(clap::Args, Clone, Debug)] +struct DebugConfigSchemaArgs {} + /// Resolve a revision identifier to its full ID #[derive(clap::Args, Clone, Debug)] struct DebugResolveRevArgs { @@ -3174,6 +3179,11 @@ fn cmd_debug( man.render(&mut buf)?; ui.stdout_formatter().write_all(&buf)?; } + DebugCommands::ConfigSchema(_config_schema_matches) => { + // TODO(#879): Consider generating entire schema dynamically vs. using static file. + let buf = include_bytes!("config-schema.json"); + ui.stdout_formatter().write_all(buf)?; + } DebugCommands::ResolveRev(resolve_matches) => { let workspace_command = command.workspace_helper(ui)?; let commit = workspace_command.resolve_single_rev(&resolve_matches.revision)?; diff --git a/tests/test_debug_command.rs b/tests/test_debug_command.rs new file mode 100644 index 0000000000..2a0aede6dc --- /dev/null +++ b/tests/test_debug_command.rs @@ -0,0 +1,56 @@ +// Copyright 2022 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use insta::assert_snapshot; +use regex::Regex; + +use crate::common::TestEnvironment; + +pub mod common; + +#[test] +fn test_debug_config_schema() { + let test_env = TestEnvironment::default(); + let stdout = test_env.jj_cmd_success(test_env.env_root(), &["debug", "config-schema"]); + let expected_schema_re = Regex::new(r"(?s)^\{\n.*\n\}\n").unwrap(); + assert!( + expected_schema_re.is_match(&stdout), + "output didn't match format {expected_schema_re:?}:\n{stdout}" + ); +} + +#[test] +fn test_debug_index() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let workspace_path = test_env.env_root().join("repo"); + let stdout = test_env.jj_cmd_success(&workspace_path, &["debug", "index"]); + insta::with_settings!( + {filters => vec![ + (r" Name: [0-9a-z]+", " Name: [hash]"), + ]}, + { + assert_snapshot!(stdout, @r###" + Number of commits: 2 + Number of merges: 0 + Max generation number: 1 + Number of heads: 1 + Number of changes: 2 + Stats per level: + Level 0: + Number of commits: 2 + Name: [hash] + "###) + }); +}