Repository navigation
feat(config): default writes to user scope; import a config file (0.23.0) - #184
Merged
Merged
Conversation
…3.0) `dt config set` wrote project scope, which surprised people twice over: a setting made in one repo did not apply in the next one, and `.dt/config.yaml` is tracked by git, so a personal preference arrived in every collaborator's checkout on the next pull. Most settings -- a GitHub owner, an SSH username, a cache root, a staging dir -- describe the person and the machine rather than the repository, so user scope is the one that does what was meant. Project scope is the sharper instrument and now has to be asked for by name. Flipping the default creates two new ways to be quietly wrong, so both now speak up. A user-scope write under a project or local value succeeds while changing nothing observable, which reads as the tool ignoring the command: it now says which file outranks it, what value is still in force, and which scope to target. And `unset`, which misses by default whenever the key is project-scoped, now lists the scopes that do hold the key with their paths instead of a bare "not found". Also adds `dt config import <file>`, for the case the default change does not cover: an offsite collaborator on a different filesystem, who needs the team's registry and secret-manager settings but owns their own paths. The file is an ordinary config.yaml -- the same one `dt config path --user` points at -- so it can be handed over and imported without knowing where config lives on that machine, and copying it into place by hand still works. Over `cp` it merges rather than replaces (keys the file omits are left alone, so lab defaults do not wipe local paths), diffs and confirms replacements, refuses a list under a key that takes a scalar before it can break a released version, and flags imported paths that do not exist here -- the usual symptom of a file from another filesystem. `set_value` now delegates to a new bulk `set_values`, unchanged from outside. The large-files hook hint gains `--project`: under the new default it would otherwise raise the limit in every repo, not the one with the big files. The config integration tests ran `dt` in a subprocess inheriting os.environ, so with the new default they would have rewritten the developer's own ~/.config/dt/config.yaml; they now pin XDG_CONFIG_HOME to tmp_path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
dt config setwrote project scope, which surprised people twice over: a setting made in one repo did not apply in the next one, and.dt/config.yamlis tracked by git, so a personal preference arrived in every collaborator's checkout on the next pull.Most settings — a GitHub owner, an SSH username, a cache root, a staging dir — describe the person and the machine rather than the repository. User scope is the one that does what was meant; project scope is the sharper instrument and now has to be asked for with
--project.What changed
The default.
set,add,remove, andunsetall write user scope unless a scope flag says otherwise. A baredt config settherefore no longer writes a git-tracked file.Two new diagnostics, because flipping the default creates two new ways to be quietly wrong — cases where the command succeeds and the effective value isn't what you asked for:
unsetmisses by default whenever the key is project-scoped. Instead of a bare "not found":Both are backed by a new
cfg.scopes_defining(key).setalso now prints the path it wrote, since the default location is off in~and no longer visible from where you're standing.dt config import <file>, for the case the default change doesn't cover: an offsite collaborator on a different filesystem, who needs the team's registry and secret-manager settings but owns their own paths.The file is an ordinary
config.yaml— the same onedt config path --userpoints at — so it can be emailed and imported without knowing where config lives on that machine, and copying it into place by hand still works. Overcpit:--yes,--dry-run);LIST_VALUED_KEYS);Re-importing is a no-op, so an updated copy is safe to send. Scope flags work as on
set.Incidental:
set_valuenow delegates to a new bulkset_values(unchanged from outside). The large-files hook hint gains--project— under the new default it would otherwise raise the limit in every repo, not the one with the big files.Deliberately not included
URL fetching and placeholder substitution. The narrowed case is handing over a file; with paths simply omitted from the shared file there is nothing to template, and URL support brings network/TLS trust surface for no gain here. For a team on one filesystem, a shared system-scope file via
XDG_CONFIG_DIRSis still the better answer than handing out copies — the docs say so, soimportdoesn't become the default answer to the wrong question.Test notes
The config integration tests ran
dtin a subprocess inheritingos.environ, so under the new default they would have rewritten the developer's own~/.config/dt/config.yaml. They now pinXDG_CONFIG_HOME/XDG_CONFIG_DIRStotmp_path, and the three bareconfig setcalls intest_clone_cmd.pypass--project.Default-scope behaviour was previously untested — every test passed an explicit flag — so it's now covered at both levels, along with
scopes_defining, the shadow warning, the unset-miss message, andimport.2331 passed, 2 skipped (
tests/unit+tests/integration/test_config_cmd.py), run on a compute node viaqxub.Breaking change
Anyone with muscle memory for
dt config set <key> <value>writing.dt/config.yamlneeds--projectnow. Existing config files are untouched and precedence is unchanged, so nothing already committed changes behaviour. Minor version bump to 0.23.0.🤖 Generated with Claude Code