8961 Commits

Author SHA1 Message Date
Jonas Greitemann
33a5d21e3a merge-tools builtin: fix update of executable flag of empty files
The property-based test exposed another bug; this can be reproduced in
the following way:

$ touch empty-file
$ jj commit -m "add non-executable file"
$ jj split

...then select the file mode change interactively and give the split-off
change a name. Since all the changes have been selected, one would
expect the first part to contain the file mode change and the second
part to be empty, but in fact:

    First part: nrkmknyr 785bfe6e (empty) bla
    Second part: qmwwknqx b5a92967 (no description set)

Doing the equivalent thing non-interactively has the expected result:

$ jj undo
$ jj split empty-file
Warning: All changes have been selected, so the second commit will be empty
First part: nrkmknyr 3f156f9e first
Second part: zlurmpxm 06e24b2d (empty) (no description set)

This problem only occurs when the file is empty.

When the file mode of an empty text file changes, scm-record produces
`SelectedContents::Unchanged`, even though there is a change that
needs to be addressed. AFAICT, empty files are the only situation
where `Unchanged` is produced. If the file mode of a non-empty file
is changed, `SelectedContent::Text` is produced, even though the file
itself has not changed and does not have to be written to the store.
With the current semantics, IMHO `Unchanged` is a little misleading and
acts more like an `Empty`.

Knowing this, it is possible to fix the bug by just writing an empty
file. However, this is a little wasteful to have to write the file blob
anew when it hasn't changed (both when the file is empty or not). It
would be nicer to have scm-record report an actual `Unchanged` (also
when a non-empty file hasn't changed) and to have some way to update the
executable flag in `MergedTreeBuilder` rather then having to provide a
new value from scratch.
2025-05-04 18:04:32 +02:00
Jonas Greitemann
21c63fbdf8 tree_builder: ignore tombstone overrides on nested trees
scm-record yields a selected change with `FileMode::Absent` in one of
two cases:
- when an existing file is deleted and this change is selected,
- when a new file is created and this change is not selected.

From the information provided by `File::get_selected_contents`, it is
not possible to distinguish these two cases. In the first case, the
tree definitely needs to change to reflect the deletion, so a "tombstone"
override is set on the tree builder. In the second case, that tombstone
is usually ignored when `TreeBuilder::write_tree()` processes the
overrides because the associated file does not exist.

However, when the tombstone happens to coindice with a deleted directory
and a new file has been created in its place, but neither change is
selected, then the tombstone had the effect of deleting the directory
from the tree.

This is fixed now by ignoring tombstones on trees. When a directory is
actually intentionally deleted, this will result in a bunch of tombstones
on the files therein; after processing the file overrides, `write_tree()`
will remove any now-empty directory trees anyway.

Perhaps, a better solution would see scm-record provide information to
distinguish a selected deletion from an unselected creation to avoid
placing the tombstone altogether. For now, this fixes the test case
`test_edit_diff_builtin_replace_directory_with_file` and one failure
source of the property-based tests.
2025-05-04 17:30:32 +02:00
Jonas Greitemann
e000275ba5 merge-tools builtin: add property-based testing
This adds the proptest crate for property-based testing as well as the
proptest-state-machine crate as direct dev dependencies of jj-cli and as
dependencies of the internal testutils crate. 

Within testutils, a `proptest` module provides a reference state machine
which models a repository workspace as a tree-like data structure whose
leaves represent `File`s. The possible transitions of this state machine
are for now limited to the creation of new files (including replacements
of existing files or directories) and deletions of files (pruning the
tree of empty directory nodes). Additional transitions (moving files,
modifying file contents incrementally, ...) and states (symlinks,
submodules, conflicts, ...) may be added in the future.

The `ReferenceStateMachine` trait implementation provides proptest
with strategies for the generation and shrinking of both the initial
state and the transitions that are replayed on it; by shrinking the
transitions rather than another independent reference state, proptest
can search of a failing test input with a minimal diff. This makes this
approach quite suited to VCS problems.

This reference state machine is then applied to the builtin merge-tool's
test suite:
- The initial state is used to build a corresponding `MergedTree`. Its
  ID is used for the fixed "left" tree and serves as the starting point
  for the right tree.
- As transitions are applied, the right tree is updated accordingly.
- Each step of the way, the same test logic as in the manual
  `test_edit_diff_builtin*` tests is run to check that splitting off
  none or all of the changes results in the left or right tree,
  respectively.

Aside from the bug already captured by `*_replace_directory_with_file`,
the property-based test found an independent problem related to file
mode changes of empty files. Regression test seeds for both of these
issues are also checked in. This ensures that others / CI will reproduce
known edge cases deterministically before randomly exploring additional
onwards.
2025-05-04 16:56:14 +02:00
Jonas Greitemann
9b3433e507 repo_path: impl Extend for RepoPathBuf 2025-05-04 16:14:41 +02:00
Jonas Greitemann
7ff6741e14 merge-tools builtin: add regression test for directory replaced by file
This is a manual regression test for issue #5189. When this change is
replaced onto `v0.28.2`, the test produces a panic, as described in the
issue.

As of #6411, the panic no longer happens. However, the test still fails
and rightfully so: When following the reproduction and not selecting any
change in `jj split`, the split-off (first) commit will still record the
deletion of `folder/.keep` but not the creation of the file `folder`.
2025-05-04 16:14:41 +02:00
Nicole Patricia Mazzuca
05fa4bc0a3 docs: add some more info on signing
I was asked about this in Discord, so I wanted to make sure to have the
information available in the docs and not just the code.
2025-05-03 11:27:36 +00:00
Ilya Grigoriev
4f3d890bee docs cli reference: update and pin clap-markdown, include aliases in reference
clap-markdown doesn't follow semver, so I pinned the version exactly.
2025-05-03 00:35:12 +00:00
Nicole Patricia Mazzuca
b568bb67f0 config: deprecate macOS legacy platform configs 2025-05-02 20:05:24 +00:00
Nicole Patricia Mazzuca
6f6496ba83 config: default to XDG config files on macOS
Support existing users with the "legacy" config directory, as well.
This will be deprecated in a latter commit.
2025-05-02 20:05:24 +00:00
Nicole Patricia Mazzuca
f9966a644b config: switch to etcetera from dirs 2025-05-02 20:05:24 +00:00
Nicole Patricia Mazzuca
19f997a466 config: change how config paths are represented
This change, from an enum to a struct, is a more accurate representation
of the actual way that a ConfigPath works; additionally, it lets us add
different information without modifying every single enumeration field.
2025-05-02 20:05:24 +00:00
Steve Fink
0eceed9832 restore, diffedit: do not output "Created ..." message, which dates back to before we couldn't lookup by change id. 2025-05-01 21:11:31 +00:00
Yuya Nishihara
1b300fefa2 templater: add type alias for Box<dyn TemplateProperty<..>>
It's verbose to type.
2025-05-01 00:33:59 +00:00
Yuya Nishihara
b96924d17f templater: convert property to trait object by caller
I'm trying to refactor property wrapping functions, and noticed that it's odd
that .wrap_<property>() does boxing internally whereas .wrap_template() doesn't.

Also, it sometimes makes sense to turn property into trait object earlier. For
example, we can deduplicate L::wrap_boolean() in build_binary_operation().
2025-05-01 00:33:59 +00:00
Yuya Nishihara
96b633a091 templater: add property.into_dyn() helper
I'm going to move Box<dyn _> conversion to callers, so there will be more places
to use this helper.
2025-05-01 00:33:59 +00:00
Yuya Nishihara
533fb5e4bb generic_templater: remove unneeded lifetime bounds
Perhaps, these bounds were needed because the context type were compiled into
the template object before.
2025-05-01 00:33:59 +00:00
Théo Daron
3ab9e098d7 cli config edit: Rollback to previous config when invalid TOML is saved 2025-04-29 16:26:11 +00:00
Jonas Greitemann
928984019f completion: fix completion of arguments for aliases/default-command in bash and zsh
This also adds a test case for the completion of arguments following
multi-argument aliases, to cover the bug reported in issue #5377.

The default command is like a special kind of alias, one which is
expanded from zero tokens. Consequently, it also triggers the bug
#5377 on bash/zsh, even if the `default-command` is just a single token.

The fix is along the lines sketched out by the "TODO" comment. Bash and
Zsh don't behave identical, so the padding ([""]) still needs to be
applied (and removed) conditionally in a disciplined manner.
2025-04-29 14:38:25 +00:00
Jonas Greitemann
eaaaf058a8 completion tests: parameterize test case over different shells
The completion mechanism works differently in different shells:

For example, when the command line `jj aaa bb ccc` is completed at the
end of the `bb` token, bash and zsh pass the completer the whole line
`-- jj aaa bb ccc` and an index of 2 which refers to the `bb` token;
they are then expected to complete `bb`. Meanwhile, fish and Powershell
only pass the command up to the completion point, so `-- jj aaa bb`;
the completer is always expected to complete the last token. In all
cases, the shell ultimately decides what to do with the completions,
e.g. to complete up to a common prefix (bash), to show an interactive
picker (zsh, fish), or to insert the completion if it is the only one
(all shells). Remaining tokens (`ccc`) are also always appended by the
shell and not part of the completion.

While this is mostly handled by the clap_complete crate, we do expand
aliases and present clap_complete with a fake view of the real command
line, thereby reaching into its internals by wrapping the interface
between the completion shell script that is provided by clap_complete
and its Rust code in `CommandEnv::try_complete()`. If we get this wrong,
completion might yield unexpected results, so it is worth testing
completion for both flavors of shells whenever aliases are potentially
in the mix.

To avoid redundancy, the shell-specific invocation of `jj` is factored
into a `complete_at()` function of the test fixture. The `test-case`
crate is then used to instantiate each test case for different values of
clap_complete's `Shell` enum.

filter

bash/zsh specific behavior

move impl
2025-04-29 14:38:25 +00:00
Gaëtan Lehmann
2c4a0328f9 templates: add self.trailers().contains_key(key)
as a simpler and more readable alternative to

    self.trailers().filter(|t| t.key() == "Change-Id")
2025-04-29 06:36:12 +00:00
Martin von Zweigbergk
b7489aac81 CliRunner: don't require hook functions to have static lifetime
I want to pass in a closure that captures some variables in the local
scope of my `main()` function.
2025-04-29 04:22:47 +00:00
Martin von Zweigbergk
4435fae3be CliRunner: replace start hook by dispatch hook
The `CliRunner` lets a custom binary add processing that should happen
before running a command. This patch replaces that by a hook that can
do processing before and/or after. I thought I would want to use this
for adding telemetry (such as timings) to our custom binary at
Google. I ended up adding that logging outside of `CliRunner::run()`
instead, so it gives a more accurate timing of the whole invocation. I
think this patch is still an improvement, as it's more generic than
the start hook.
2025-04-29 02:49:12 +00:00
dependabot[bot]
517292fd46 cargo: bump the cargo-dependencies group with 3 updates
Bumps the cargo-dependencies group with 3 updates: [insta](https://github.com/mitsuhiko/insta), [syn](https://github.com/dtolnay/syn) and [toml_edit](https://github.com/toml-rs/toml).


Updates `insta` from 1.42.2 to 1.43.0
- [Release notes](https://github.com/mitsuhiko/insta/releases)
- [Changelog](https://github.com/mitsuhiko/insta/blob/master/CHANGELOG.md)
- [Commits](https://github.com/mitsuhiko/insta/compare/1.42.2...1.43.0)

Updates `syn` from 2.0.100 to 2.0.101
- [Release notes](https://github.com/dtolnay/syn/releases)
- [Commits](https://github.com/dtolnay/syn/compare/2.0.100...2.0.101)

Updates `toml_edit` from 0.22.24 to 0.22.25
- [Commits](https://github.com/toml-rs/toml/compare/v0.22.24...v0.22.25)

---
updated-dependencies:
- dependency-name: insta
  dependency-version: 1.43.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: cargo-dependencies
- dependency-name: syn
  dependency-version: 2.0.101
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
- dependency-name: toml_edit
  dependency-version: 0.22.25
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 19:24:18 +00:00
dependabot[bot]
b2636dd9fa github: bump the github-dependencies group with 5 updates
Bumps the github-dependencies group with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [taiki-e/install-action](https://github.com/taiki-e/install-action) | `2.49.50` | `2.50.3` |
| [DeterminateSystems/nix-installer-action](https://github.com/determinatesystems/nix-installer-action) | `16` | `17` |
| [actions/setup-python](https://github.com/actions/setup-python) | `5.5.0` | `5.6.0` |
| [astral-sh/setup-uv](https://github.com/astral-sh/setup-uv) | `5.4.2` | `6.0.0` |
| [github/codeql-action](https://github.com/github/codeql-action) | `3.28.15` | `3.28.16` |


Updates `taiki-e/install-action` from 2.49.50 to 2.50.3
- [Release notes](https://github.com/taiki-e/install-action/releases)
- [Changelog](https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md)
- [Commits](09dc018eee...ab3728c7ba)

Updates `DeterminateSystems/nix-installer-action` from 16 to 17
- [Release notes](https://github.com/determinatesystems/nix-installer-action/releases)
- [Commits](e50d5f73bf...21a544727d)

Updates `actions/setup-python` from 5.5.0 to 5.6.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](8d9ed9ac5c...a26af69be9)

Updates `astral-sh/setup-uv` from 5.4.2 to 6.0.0
- [Release notes](https://github.com/astral-sh/setup-uv/releases)
- [Commits](d4b2f3b6ec...c7f87aa956)

Updates `github/codeql-action` from 3.28.15 to 3.28.16
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](45775bd823...28deaeda66)

---
updated-dependencies:
- dependency-name: taiki-e/install-action
  dependency-version: 2.50.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-dependencies
- dependency-name: DeterminateSystems/nix-installer-action
  dependency-version: '17'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-dependencies
- dependency-name: actions/setup-python
  dependency-version: 5.6.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: github-dependencies
- dependency-name: astral-sh/setup-uv
  dependency-version: 6.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: github-dependencies
- dependency-name: github/codeql-action
  dependency-version: 3.28.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-dependencies
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-28 19:24:08 +00:00
Yuya Nishihara
4f3e7e972d templater: don't attribute method table functions as pub
It's unlikely that these functions are used by external callers.
2025-04-28 01:37:49 +00:00
Yuya Nishihara
27a35a79b1 merge-tools: builtin: refactor mapping of binary files
We no longer need this, but I think this is easier to follow than destructuring
FileContents in larger match block.
2025-04-28 01:37:45 +00:00
Mateus Auler
968806bc64 templates: implement Commit.trailers() 2025-04-27 18:29:25 +00:00
Yuya Nishihara
6e67d79c10 merge-tools: builtin: parse conflict hunks back to merge value
Closes #4963
2025-04-27 01:33:48 +00:00
Yuya Nishihara
acb4e27bd9 merge-tools: builtin: split apply_diff_builtin() function
In builtin diff editor, we materializes conflicts, so we need to parse them
back to reproduce the original (or partially-resolved) contents. OTOH, the
merge editor should write the merged contents transparently.

This change also revealed that binary hunks wouldn't be processed correctly in
the merge editor.
2025-04-27 01:33:48 +00:00
Yuya Nishihara
105c892ce4 tests: do not shell out taplo to gather forgotten test files
It would be annoying if forgotten tests wouldn't be reported locally.
2025-04-27 01:33:23 +00:00
Ilya Grigoriev
5a735182ac docs conflicts.md: clarify the revert example a bit
Yuya's suggestion from
<https://github.com/jj-vcs/jj/pull/6415#discussion_r2061122640>.

Co-authored-by:  Yuya Nishihara <yuya@tcha.org>
2025-04-27 00:40:27 +00:00
Ilya Grigoriev
1f14f7a0ff docs conflicts.md: fix confusing typo
Fix #6414.
2025-04-27 00:40:27 +00:00
Martin von Zweigbergk
13477940af local_working_copy: avoid a block_on() in already async function 2025-04-26 02:22:23 +00:00
Yuya Nishihara
a3dcd8b659 merge-tools: builtin: leverage materialized_diff_stream() 2025-04-26 02:05:40 +00:00
Yuya Nishihara
be37209423 merge-tools: builtin: do not include unchanged entry in test diffs, sort paths
This matches the edit_diff_builtin() behavior. "unused" path is removed since
it's the same as "unchanged".
2025-04-26 02:05:40 +00:00
Yuya Nishihara
9c723a1c76 merge-tools: builtin: extract wrapper functions in tests
make_diff_files() will be async function that uses materialized_diff_stream()
internally. apply_diff_builtin() will take callbacks to handle binary/conflict
files.
2025-04-26 02:05:40 +00:00
Jacob Hayes
1cdd79071e git: tolerate unknown git.fetch remotes if others are available
If `git.fetch` contains remotes that are not available, we currently error even
if other remotes are available. For common fork workflows with separate
`upstream` and `origin` remotes (for example), this requires a user to either
set both remotes in their user config and override single-remote repos or set
only one in their user config and override all multi-remote repos to fetch from
`upstream` (or both).

This change updates fetching to only *warn* about unknown remotes **if** other
remotes are available. If none of the configured remotes are available, an error
is still raised as before.
2025-04-25 14:06:53 +00:00
Martin von Zweigbergk
92629ded4c docs: make technical conflicts doc better match our recent thinking
These days, we usually think of conflicts as one base state and series
of diffs between other states. The base state is normally the parent
when rebasing.

Also, we're deprecated `jj backout` in favor of `jj revert`, so let's
use that terminology.
2025-04-25 13:53:28 +00:00
Martin von Zweigbergk
146900a071 cli: put editor-*.jjdescription file in /tmp instead of .jj/repo/
When we ask the user to prodive a commit description, we currently
write a file to `.jj/repo/` with the draft description and then pass
that to the editor. If the editor exits with an error status, we leave
the file in place and tell the user about the path so they can recover
the description. I'm not sure I've ever used one of these files. I
have certainly never used a file that's not from the most recent
edit. I have, however, cleaned up old such files. This patch changes
the code so we write them to /tmp instead, so we get the cleanup for
free.
2025-04-25 02:08:30 +00:00
Martin von Zweigbergk
d41c83e96a merged_tree: make merge_trees() async
`merge_tree_values()` was already marked async, but it was calling the
blocking `merge_trees()`, so it could still block.
2025-04-24 16:29:24 +00:00
Jonas Greitemann
7bb8e17e88 tests: factor out utility function is_external_tool_installed
A pattern has emerged where a integration tests check for the
availability of an external tool (`git`, `taplo`, `gpg`, ...) and skip
the test (by simply passing it) when it is not available. To check this,
the program is run with the `--version` flag.

Some tests require that the program be available at least when running
in CI, by calling `ensure_running_outside_ci` conditionally on the
outcome. The decision is up to each test, though, the utility merely
returns a `bool`.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
bf2c01e74b config-schema: allow "command-env"-style for editors and fix tools
The `CommandNameAndArgs` struct is used in multiple places to specify
external tools. Previously, the schema only allowed for this in
`ui.pager`.

This commit adds a few sample configs which define variables editors and
fix tools as commands with env vars.

The schema has also been updated to make these valid.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
d35dd31c87 config-schema: require both "command" and "env" keys in structured tool config
Not sure if that is intentional or should rather be considered a bug,
but currently the "structured" option for specifying an external tool
requires that both the command "command" and the "env" keys are
specified. The "command" key makes sense; for the "env" key it came as
a surprise, but it can be argued that this form should only be used when
environment variables need to be specified and the plain string or array
form should be used otherwise.

Either way, the schema did not accurately reflect the current behavior;
now it does. Two sample configs have been added as schema test cases.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
4a1754bc46 config-schema: deny empty arrays for command-like config options
Anytime an external tool is referenced in the config, the command can be
provided as a string or as a token array. In the latter case, the array
must not be empty; at least the command name must be provided.

The schema didn't previously object to an empty array, though; this has
now been rectified. I've added more sample configs to cover this case.
Those same configs can also be used to illustrate that this is indeed
jj's current behavior:

$ jj --config-file cli/tests/sample-configs/invalid/ui.pager_empty_array.toml show
Config error: Invalid type or value for ui.pager
Caused by: data did not match any variant of untagged enum CommandNameAndArgs
                                                                                                                                                                                  
$ jj --config-file cli/tests/sample-configs/invalid/ui.pager.command_empty_array.toml show
Config error: Invalid type or value for ui.pager
Caused by: data did not match any variant of untagged enum CommandNameAndArgs
                                                                                                                                                                                  
$ jj --config-file cli/tests/sample-configs/invalid/ui.editor_empty_array.toml config edit --user
Config error: Invalid type or value for ui.editor
Caused by: data did not match any variant of untagged enum CommandNameAndArgs
                                                                                                                                                                                  
$ jj --config-file cli/tests/sample-configs/invalid/ui.diff-editor_empty_array.toml split
Error: Failed to load tool configuration
Caused by:
1: Invalid type or value for ui.diff-editor
2: data did not match any variant of untagged enum CommandNameAndArgs
                                                                                                                                                                                  
$ jj --config-file cli/tests/sample-configs/invalid/ui.merge-editor_empty_array.toml resolve
Error: Failed to load tool configuration
Caused by:
1: Invalid type or value for ui.merge-editor
2: data did not match any variant of untagged enum CommandNameAndArgs
                                                                                                                                                                                  
$ jj --config-file cli/tests/sample-configs/invalid/ui.diff.tool_empty_array.toml diff
Config error: Invalid type or value for ui.diff.tool
Caused by: data did not match any variant of untagged enum CommandNameAndArgs
                                                                                                                                                                                  
$ jj --config-file cli/tests/sample-configs/invalid/fix.tools.command_empty_array.toml fix
Config error: Invalid type or value for fix.tools.black
Caused by: data did not match any variant of untagged enum CommandNameAndArgs
in `command`

As a notable exception, `ui.default-command` *is* allowed to be an empty
array. In that case, `jj` will print a usage message. This is also
covered by a valid sample config.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
5444067c37 config-schema: schema wrongly allowed ui.pager.command to be a string
While `ui.pager` can be a string which will be tokenized on whitespace,
and argument token array, or a command/env table, the `command` key
within that table currently must be an array. The schema previously
explicitly also allowed it to be a string but that does not actually
work, as exemplified by running:
```sh
$ jj --config-file cli/tests/sample-configs/invalid/ui.pager_command-env_string.toml config list
Config error: Invalid type or value for ui.pager
Caused by: data did not match any variant of untagged enum CommandNameAndArgs
```

`CommandNameAndArgs` should potentially be changed to allow strings.
For now, the schema has been updated to reflect the status quo. A new
sample toml has been added to the `invalid` directory to cover this;
prior to updating the schema, this new test case failed. Once the
behavior is changed to allow string, the file merely needs to be moved
to `valid`.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
d4024e0d92 config-schema: fix 2 default values which weren't booleans, but strings
These are two more instances where the default values were wrong and in
fact not even consistent with the schema itself.

I've found these by running
```sh
jq -r 'paths(type == "object" and has("default")) as $p | getpath($p).default | tojson as $v | $p | map("\"\(select(. != "properties"))\"") | join(".") as $k | "\($k) = \($v)"' cli/src/config-schema.json | taplo check --schema=file://$PWD/cli/src/config-schema.json -
```
which uses `jq` to filter the default values from the schema definition
to create a rudimentary TOML file containing all the defaults according
to the schema and then uses `taplo` the validate this TOML against the
schema.

This approach could be developed further to also parse the intermediate
TOML file and compare the result with the default config (from parsing
an empty config). That would not only test for self-consistency of the
schema's proclaimed defaults but also for consistency with the actual
defaults as assumed by jj.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
8c4586ab09 config-schema: add sample config files to exercise schema tests
Adds a bunch of additional sample config toml files. Via the
`datatest_runner`, these each correspond to a test case to check that
the toml is correctly (in-)validated according to the schema.

The `valid/*.toml` files typically define multiple related config
options at once. Where there's some overlap with the default configs in
`cli/src/config`, the aim was to choose different allowed values, e.g.
hex colors, file size in bytes (numeric), etc.

The `invalid/*.toml` files typically only define a single offending
property such as to not obscure individual false negatives. All of the
"invalid" files are still valid toml as the aim is not to test the
`toml_edit` crate or Taplo.

The sample files all contain a Taplo schema directive. This allows them
to be validated against the schema on the fly by Taplo's LSP and derived
IDE plugins to speed up editing and immediately highlight offending
options.

Closes #5695.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
d286b406e7 config-schema: use datatest-stable crate to instantiate tests
The `datatest-stable` crate allows to dynamically instantiate test cases
based on available files. This is applied to `test_config_schema` to
create one test case per config file. As case in point, the test case
for `hints.toml` was missing previously, hence the total number of tests
is up one.

This will become useful when adding more config examples to somewhat
exhaust the schema.

`datatest-stable` uses a custom test harness and thus cannot be used in
the same integration test binary that all of the other test modules run
in. However, if data-driven tests are to be used for other applications,
they can share in the same binary, so the module structure is already
set up to mirror the central "runner" approach.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
8882f0016d tests: allow multiple integration tests in check for forgotton test files
The previous implementation of `assert_no_forgotten_test_files`
hard-coded the name of the `runner` integration test and required all
other source files to appear in matching `mod` declarations. Thus, this
approach cannot handle multiple integration tests.

However, additional integration tests may be desirable
- to support tests using a custom test harness (see upcoming commits)
- to balance the trade-off between test run time and compile time as
  the test suite grows in the future.

The new implementation first uses `taplo` to parse the `[[test]]`
sections of the manifest to identify integration test main modules,
and then searches in those for `mod` declarations. This is then compared
to the list of source files in the tests directory. Like the previous
implementation, the new one does not attempt to recurse into submodules
or to handle directory-style modules; just like before it only treats
source files without a module declaration as an error and relies on the
compiler to complain about the other way around.

When `taplo` is not installed, the check is skipped unless it is running
in CI where we require `taplo` to be available.
2025-04-24 15:48:08 +00:00
Jonas Greitemann
69cf7b38fc config-schema: add missing default for core.fsmonitor 2025-04-24 15:48:08 +00:00