Skip to content

Commit 31e1b10

Browse files
committed
Merge main into fix/ci-release-patterns: resolve test_release_patterns conflicts (lowercase duf/lazygit + keychain cases)
2 parents e0ee124 + 05e2443 commit 31e1b10

28 files changed

+1781
-531
lines changed

.github/workflows/pytest.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
steps:
1515
- uses: actions/checkout@v4
1616
- uses: actions/setup-python@v5
17-
- uses: astral-sh/setup-uv@v5
17+
- uses: astral-sh/setup-uv@v6
1818
- name: Cache release downloads
1919
id: cache-release-downloads
2020
uses: actions/cache@v4
@@ -45,7 +45,7 @@ jobs:
4545
with:
4646
python-version: ${{ matrix.python-version }}
4747
- name: Install uv
48-
uses: astral-sh/setup-uv@v5
48+
uses: astral-sh/setup-uv@v6
4949
- name: Install dependencies
5050
run: |
5151
uv sync --all-extras

.github/workflows/real-test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
with:
2323
python-version: 3.13
2424
- name: Install uv
25-
uses: astral-sh/setup-uv@v5
25+
uses: astral-sh/setup-uv@v6
2626
- name: dotbins sync
2727
run: |
2828
cd .github

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
steps:
1616
- uses: actions/checkout@v4
1717
- name: Install uv
18-
uses: astral-sh/setup-uv@v5
18+
uses: astral-sh/setup-uv@v6
1919
- name: Build
2020
run: uv build
2121
- name: Publish package distributions to PyPI

.github/workflows/update-readme.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jobs:
2020
uses: actions/setup-python@v5
2121

2222
- name: Install uv
23-
uses: astral-sh/setup-uv@v5
23+
uses: astral-sh/setup-uv@v6
2424

2525
- name: Run markdown-code-runner
2626
run: uvx --with . markdown-code-runner README.md

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ venv/
127127
ENV/
128128
env.bak/
129129
venv.bak/
130+
.envrc
130131

131132
# Spyder project settings
132133
.spyderproject

README.md

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ Here's what happens during `dotbins sync`:
204204

205205
1. **Version Detection**:
206206

207-
- Checks each tool's current version in `versions.json`
207+
- Checks each tool's current version in `manifest.json`
208208
- Queries GitHub API for the latest release of each tool
209209

210210
2. **Smart Updates**:
@@ -220,10 +220,15 @@ Here's what happens during `dotbins sync`:
220220
- Can be limited to current system only: `dotbins sync -c`
221221

222222
4. **File Generation**:
223-
- Updates `versions.json` with new version information
223+
- Updates `manifest.json` with new version information
224224
- Regenerates shell integration scripts with PATH and tool configurations
225225
- Creates a README in the tools directory with installation status
226226

227+
5. **Pinning to Manifest**:
228+
229+
- Use the `dotbins sync --pin-to-manifest` CLI flag to force `sync` to use the tags already recorded in `manifest.json`.
230+
- This ignores the latest release information from GitHub and ensures that the installed versions match exactly what's in your manifest, which is useful for reproducibility or if your manifest file is version-controlled.
231+
227232
Example update workflow:
228233

229234
```bash
@@ -239,7 +244,10 @@ dotbins sync --current
239244
# Force reinstall everything, even if up to date
240245
dotbins sync --force
241246

242-
# See what would be updated without making changes
247+
# Update tools using only the versions recorded in manifest.json
248+
dotbins sync --pin-to-manifest
249+
250+
# See what is installed
243251
dotbins status
244252
```
245253

@@ -432,7 +440,7 @@ Here's what gets created:
432440
│ ├── nushell.nu
433441
│ ├── powershell.ps1
434442
│ └── zsh.sh
435-
└── versions.json # Version tracking information
443+
└── manifest.json # Version tracking information
436444
```
437445

438446
### Tool Configuration
@@ -756,7 +764,7 @@ tools:
756764
repo: eza-community/eza
757765
shell_code:
758766
bash,zsh: |
759-
alias l="eza -lah --git --icons"
767+
alias l="eza --long --all --git --icons=auto"
760768
fzf:
761769
repo: junegunn/fzf
762770
shell_code:
@@ -790,6 +798,10 @@ tools:
790798
bash,zsh: |
791799
eval "$(atuin init __DOTBINS_SHELL__ --disable-up-arrow)"
792800
801+
keychain:
802+
repo: funtoo/keychain
803+
asset_patterns: keychain
804+
793805
uv:
794806
repo: astral-sh/uv
795807
binary_name: [uv, uvx]
@@ -943,7 +955,7 @@ source "$HOME/.dotbins/shell/bash.sh"
943955
source "$HOME/.dotbins/shell/fish.fish"
944956
945957
# For Nushell
946-
source $env.HOME/.dotbins/shell/nushell.nu
958+
source ~/.dotbins/shell/nushell.nu
947959
```
948960

949961
---
@@ -1024,6 +1036,7 @@ tools:
10241036
yq: mikefarah/yq # YAML/XML/TOML processor similar to jq
10251037
zellij: zellij-org/zellij # Terminal multiplexer
10261038
zoxide: ajeetdsouza/zoxide # Smarter cd command with learning
1039+
keychain: funtoo/keychain # ssh-agent manager
10271040
10281041
platforms:
10291042
linux:

dotbins.yaml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ tools:
3232
repo: eza-community/eza
3333
shell_code:
3434
bash,zsh: |
35-
alias l="eza -lah --git --icons"
35+
alias l="eza --long --all --git --icons=auto"
3636
fzf:
3737
repo: junegunn/fzf
3838
shell_code:
@@ -66,6 +66,10 @@ tools:
6666
bash,zsh: |
6767
eval "$(atuin init __DOTBINS_SHELL__ --disable-up-arrow)"
6868
69+
keychain:
70+
repo: funtoo/keychain
71+
asset_patterns: keychain
72+
6973
uv:
7074
repo: astral-sh/uv
7175
binary_name: [uv, uvx]

dotbins/cli.py

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,12 @@ def _initialize(config: Config) -> None:
9191
config.generate_readme()
9292

9393

94-
def _get_tool(source: str, dest_dir: str | Path, name: str | None = None) -> None:
94+
def _get_tool(
95+
source: str,
96+
dest_dir: str | Path,
97+
name: str | None = None,
98+
tag: str | None = None,
99+
) -> int:
95100
"""Get a specific tool and install it directly to a location.
96101
97102
This command bypasses the standard configuration and tools directory,
@@ -102,6 +107,7 @@ def _get_tool(source: str, dest_dir: str | Path, name: str | None = None) -> Non
102107
source: GitHub repository in the format 'owner/repo' or URL/path to a YAML configuration file.
103108
dest_dir: Directory to install the binary to (e.g., ~/.local/bin)
104109
name: Optional name to use for the binary (defaults to repo name)
110+
tag: Optional tag to use for the binary (if None, the latest release will be used)
105111
106112
"""
107113
platform, arch = current_platform()
@@ -116,10 +122,12 @@ def _get_tool(source: str, dest_dir: str | Path, name: str | None = None) -> Non
116122
config = Config(
117123
tools_dir=dest_dir_path,
118124
platforms={platform: [arch]},
119-
tools={tool_name: build_tool_config(tool_name, {"repo": source})},
125+
tools={tool_name: build_tool_config(tool_name, {"repo": source, "tag": tag})},
120126
)
121127
config._bin_dir = dest_dir_path
122128
config.sync_tools(current=True, force=True, generate_readme=False, copy_config_file=False)
129+
exit_code = 1 if config._update_summary.failed else 0
130+
return exit_code # noqa: RET504
123131

124132

125133
def create_parser() -> argparse.ArgumentParser:
@@ -167,6 +175,10 @@ def create_parser() -> argparse.ArgumentParser:
167175
"--name",
168176
help="Name to use for the binary (defaults to repository name if not specified) and is ignored if source is a URL",
169177
)
178+
get_parser.add_argument(
179+
"--tag",
180+
help="Tag to use for the binary (if None, the latest release will be used)",
181+
)
170182

171183
# sync command
172184
sync_parser = subparsers.add_parser(
@@ -201,7 +213,15 @@ def create_parser() -> argparse.ArgumentParser:
201213
"-c",
202214
"--current",
203215
action="store_true",
204-
help="Only install or update for the current platform and architecture (convenient shorthand)",
216+
help="Install/update only for the current platform and architecture."
217+
" This allows syncing for the current system even if it's not explicitly"
218+
" listed in the `platforms` configuration.",
219+
)
220+
sync_parser.add_argument(
221+
"--pin-to-manifest",
222+
action="store_true",
223+
help="Use the tags from the `manifest.json` file instead of the latest release"
224+
" or the tag specified in the config file",
205225
)
206226
sync_parser.add_argument(
207227
"--no-shell-scripts",
@@ -305,8 +325,8 @@ def main() -> None: # pragma: no cover
305325

306326
try:
307327
if args.command == "get":
308-
_get_tool(args.source, args.dest, args.name)
309-
return
328+
exit_code = _get_tool(args.source, args.dest, args.name, args.tag)
329+
sys.exit(exit_code)
310330
if args.command is None:
311331
parser.print_help()
312332
return
@@ -334,12 +354,12 @@ def main() -> None: # pragma: no cover
334354
github_token=args.github_token,
335355
verbose=args.verbose,
336356
generate_shell_scripts=not args.no_shell_scripts,
357+
pin_to_manifest=args.pin_to_manifest,
337358
)
359+
if config._update_summary.failed:
360+
sys.exit(1)
338361
elif args.command == "readme":
339-
config.generate_readme(
340-
not args.no_file,
341-
args.verbose,
342-
)
362+
config.generate_readme(not args.no_file, args.verbose)
343363
elif args.command == "status":
344364
platform = args.platform
345365
arch = args.architecture
@@ -348,7 +368,7 @@ def main() -> None: # pragma: no cover
348368
platform, arch = current_platform()
349369

350370
# If both --compact and --full are specified, --compact takes precedence
351-
config.version_store.print(
371+
config.manifest.print(
352372
config,
353373
compact=not args.full,
354374
platform=platform,

0 commit comments

Comments
 (0)