mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-08-19 22:48:26 +08:00
Compare commits
7 Commits
master
...
copilot/do
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78c871176f | ||
|
|
1595e00f7c | ||
|
|
eb62826522 | ||
|
|
c15b32baa4 | ||
|
|
ffd4c95a4f | ||
|
|
4cdd45338c | ||
|
|
8e5be2cb3a |
46
.github/workflows/main.yml
vendored
46
.github/workflows/main.yml
vendored
@@ -41,3 +41,49 @@ jobs:
|
|||||||
./themes/*.zsh-theme; do
|
./themes/*.zsh-theme; do
|
||||||
zsh -n "$file" || return 1
|
zsh -n "$file" || return 1
|
||||||
done
|
done
|
||||||
|
|
||||||
|
- name: Focused syntax check for bootstrap-adjacent touched files
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
run: |
|
||||||
|
mapfile -t touched < <(
|
||||||
|
git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}" \
|
||||||
|
| grep -E '^(lib/bootstrap\.zsh|lib/tests/bootstrap.*\.zsh|oh-my-zsh\.sh|lib/(completion|compfix|functions|theme-and-appearance)\.zsh|plugins/.+/.+\.plugin\.zsh|themes/.+\.zsh-theme)$' \
|
||||||
|
|| true
|
||||||
|
)
|
||||||
|
|
||||||
|
if [ "${#touched[@]}" -eq 0 ]; then
|
||||||
|
echo "No bootstrap-adjacent files touched"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
for file in "${touched[@]}"; do
|
||||||
|
echo "Syntax checking $file"
|
||||||
|
zsh -n "$file"
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: Run bootstrap unit test
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
run: zsh ./lib/tests/bootstrap.test.zsh
|
||||||
|
|
||||||
|
- name: Run inline bootstrap invariants smoke test
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
run: zsh ./lib/tests/bootstrap-inline-ci.test.zsh
|
||||||
|
|
||||||
|
plugin-manager-smoke:
|
||||||
|
name: Plugin manager smoke (${{ matrix.manager }}:${{ matrix.scenario }})
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'ohmyzsh/ohmyzsh' && github.event_name == 'pull_request'
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
manager: [antigen, zinit]
|
||||||
|
scenario: [positive, negative]
|
||||||
|
steps:
|
||||||
|
- name: Set up git repository
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
|
- name: Install zsh
|
||||||
|
run: sudo apt-get update; sudo apt-get install zsh
|
||||||
|
|
||||||
|
- name: Run plugin-manager bootstrap integration
|
||||||
|
run: zsh ./lib/tests/plugin-manager-bootstrap-integration.test.zsh "${{ matrix.manager }}" "${{ matrix.scenario }}"
|
||||||
|
|||||||
37
.github/workflows/plugin-manager-nightly.yml
vendored
Normal file
37
.github/workflows/plugin-manager-nightly.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
name: Plugin manager integration (advisory)
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 6 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
plugin-manager-matrix:
|
||||||
|
name: ${{ matrix.manager }}:${{ matrix.scenario }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
|
continue-on-error: true
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
manager: [antigen, zinit, zgen, zplug, antibody, zulu]
|
||||||
|
scenario: [positive, negative]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Set up git repository
|
||||||
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
|
|
||||||
|
- name: Install zsh and go
|
||||||
|
run: sudo apt-get update; sudo apt-get install zsh golang
|
||||||
|
|
||||||
|
- name: Run plugin-manager bootstrap integration
|
||||||
|
run: zsh ./lib/tests/plugin-manager-bootstrap-integration.test.zsh "${{ matrix.manager }}" "${{ matrix.scenario }}"
|
||||||
|
|
||||||
|
- name: Rollout note
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
echo "Phase 2 active: full manager matrix is advisory/nightly."
|
||||||
|
echo "Phase 3 target: promote full matrix to required after stability window."
|
||||||
@@ -23,6 +23,7 @@ you would make is not already covered.
|
|||||||
- [A note on AI-assisted contributions](#a-note-on-ai-assisted-contributions)
|
- [A note on AI-assisted contributions](#a-note-on-ai-assisted-contributions)
|
||||||
- [Use the Search, Luke](#use-the-search-luke)
|
- [Use the Search, Luke](#use-the-search-luke)
|
||||||
- [Commit Guidelines](#commit-guidelines)
|
- [Commit Guidelines](#commit-guidelines)
|
||||||
|
- [Plugin And Theme Bootstrap Compatibility](#plugin-and-theme-bootstrap-compatibility)
|
||||||
- [Format](#format)
|
- [Format](#format)
|
||||||
- [Style](#style)
|
- [Style](#style)
|
||||||
- [Volunteer](#volunteer)
|
- [Volunteer](#volunteer)
|
||||||
@@ -176,6 +177,24 @@ specification. The automatic changelog tool uses these to automatically generate
|
|||||||
a changelog based on the commit messages. Here's a guide to writing a commit message
|
a changelog based on the commit messages. Here's a guide to writing a commit message
|
||||||
to allow this:
|
to allow this:
|
||||||
|
|
||||||
|
### Plugin And Theme Bootstrap Compatibility
|
||||||
|
|
||||||
|
Oh My Zsh now provides a shared bootstrap entrypoint at `lib/bootstrap.zsh` for plugin-manager setups that don't
|
||||||
|
source `oh-my-zsh.sh`.
|
||||||
|
|
||||||
|
When working on plugins/themes:
|
||||||
|
|
||||||
|
- assume bootstrap has already run in manager-driven setups
|
||||||
|
- rely on bootstrap guarantees (`ZSH*` defaults, cache/completions setup, required `fpath` entries)
|
||||||
|
- avoid adding per-plugin/per-theme copies of common setup unless truly plugin-specific
|
||||||
|
|
||||||
|
Common patterns we should migrate away from over time:
|
||||||
|
|
||||||
|
- repeated cache setup logic (`mkdir -p "$ZSH_CACHE_DIR/completions"`)
|
||||||
|
- repeated base `fpath` bootstrapping for OMZ core/custom directories
|
||||||
|
|
||||||
|
If your plugin/theme still needs custom initialization, keep it scoped to that plugin/theme behavior only.
|
||||||
|
|
||||||
### Format
|
### Format
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
115
README.md
115
README.md
@@ -46,6 +46,7 @@ Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
|
|||||||
- [Manual Installation](#manual-installation)
|
- [Manual Installation](#manual-installation)
|
||||||
- [Installation Problems](#installation-problems)
|
- [Installation Problems](#installation-problems)
|
||||||
- [Custom Plugins And Themes](#custom-plugins-and-themes)
|
- [Custom Plugins And Themes](#custom-plugins-and-themes)
|
||||||
|
- [Using Plugin Managers Without `oh-my-zsh.sh`](#using-plugin-managers-without-oh-my-zshsh)
|
||||||
- [Enable GNU ls In macOS And FreeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
|
- [Enable GNU ls In macOS And FreeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
|
||||||
- [Skip Aliases](#skip-aliases)
|
- [Skip Aliases](#skip-aliases)
|
||||||
- [Async git prompt](#async-git-prompt)
|
- [Async git prompt](#async-git-prompt)
|
||||||
@@ -349,6 +350,120 @@ If you have many functions that go well together, you can put them as a `XYZ.plu
|
|||||||
If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the
|
If you would like to override the functionality of a plugin distributed with Oh My Zsh, create a plugin of the
|
||||||
same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
|
same name in the `custom/plugins/` directory and it will be loaded instead of the one in `plugins/`.
|
||||||
|
|
||||||
|
### Using Plugin Managers Without `oh-my-zsh.sh`
|
||||||
|
|
||||||
|
Some plugin managers load individual OMZ plugins/themes directly and do not source `oh-my-zsh.sh`.
|
||||||
|
For those setups, source this bootstrap entrypoint before loading any OMZ plugin or theme:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
source "$ZSH/lib/bootstrap.zsh"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Bootstrap compatibility contract
|
||||||
|
|
||||||
|
`lib/bootstrap.zsh` is idempotent and is the only required pre-load step for plugin-manager setups.
|
||||||
|
It guarantees:
|
||||||
|
|
||||||
|
- `ZSH`, `ZSH_CUSTOM`, and `ZSH_CACHE_DIR` defaults
|
||||||
|
- writable cache fallback to `${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh`
|
||||||
|
- `$ZSH_CACHE_DIR/completions` directory creation
|
||||||
|
- required OMZ `fpath` entries for plugins/themes:
|
||||||
|
- `$ZSH/functions`
|
||||||
|
- `$ZSH/completions`
|
||||||
|
- `$ZSH_CUSTOM/functions`
|
||||||
|
- `$ZSH_CUSTOM/completions`
|
||||||
|
- `$ZSH_CACHE_DIR/completions`
|
||||||
|
- public signal: `OMZ_IS_BOOTSTRAPPED=true` (for one-time hook guards)
|
||||||
|
|
||||||
|
What still requires `oh-my-zsh.sh`:
|
||||||
|
|
||||||
|
- update checks
|
||||||
|
- plugin auto-discovery from the `plugins=(...)` list
|
||||||
|
- `compinit`/`compfix` orchestration and zcompdump metadata refresh
|
||||||
|
- alias filtering via `:omz:*` zstyles during file sourcing
|
||||||
|
- final full-init signal: `OMZ_IS_LOADED=true`
|
||||||
|
|
||||||
|
#### Plugin manager hook guidance
|
||||||
|
|
||||||
|
Run bootstrap once, before any OMZ plugin/theme load:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
[[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Antigen** (pre-bundle hook pattern):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
omz_preload() { [[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"; }
|
||||||
|
omz_preload
|
||||||
|
antigen bundle OMZ::plugins/git
|
||||||
|
antigen apply
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Zinit** (`atinit` pre-load hook):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zinit ice atinit'[[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"'
|
||||||
|
zinit snippet OMZ::plugins/git/git.plugin.zsh
|
||||||
|
```
|
||||||
|
|
||||||
|
- **zgen** (pre-load hook function called before OMZ loads):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
omz_preload() { [[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"; }
|
||||||
|
omz_preload
|
||||||
|
zgen load ohmyzsh/ohmyzsh plugins/git
|
||||||
|
```
|
||||||
|
|
||||||
|
- **zplug** (run pre-load hook immediately before OMZ entries):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
omz_preload() { [[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"; }
|
||||||
|
omz_preload
|
||||||
|
zplug "plugins/git", from:oh-my-zsh
|
||||||
|
zplug load
|
||||||
|
```
|
||||||
|
|
||||||
|
- **antibody** (run pre-load hook before `antibody bundle`/`source` output):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
omz_preload() { [[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"; }
|
||||||
|
omz_preload
|
||||||
|
source <(antibody bundle <<'EOF'
|
||||||
|
ohmyzsh/ohmyzsh path:plugins/git
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
- **zulu** (run pre-load hook before OMZ module loads):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
omz_preload() { [[ -n "${OMZ_IS_BOOTSTRAPPED:-}" ]] || source "$ZSH/lib/bootstrap.zsh"; }
|
||||||
|
omz_preload
|
||||||
|
zulu install oh-my-zsh
|
||||||
|
```
|
||||||
|
|
||||||
|
Compatibility matrix:
|
||||||
|
|
||||||
|
| Load mode | `OMZ_IS_BOOTSTRAPPED` | `OMZ_IS_LOADED` | Suitable for |
|
||||||
|
| :-- | :--: | :--: | :-- |
|
||||||
|
| `source $ZSH/oh-my-zsh.sh` | ✅ | ✅ | Full OMZ framework features |
|
||||||
|
| `source $ZSH/lib/bootstrap.zsh` + manager-loaded OMZ plugins/themes | ✅ | ❌ | Plugin/theme prerequisites only |
|
||||||
|
|
||||||
|
#### Manager entrypoints and OMZ-side auto-injection limits
|
||||||
|
|
||||||
|
Most plugin managers load OMZ by directly sourcing selected plugin/theme/lib entrypoints, not by sourcing
|
||||||
|
`oh-my-zsh.sh`, so OMZ cannot universally inject bootstrap on its own.
|
||||||
|
|
||||||
|
| Manager | Typical OMZ entrypoint(s) it loads | Can OMZ auto-inject bootstrap without user hook? |
|
||||||
|
| :-- | :-- | :--: |
|
||||||
|
| Antigen | `antigen bundle ...` targets after `antigen use oh-my-zsh` | ❌ |
|
||||||
|
| Zinit | `OMZ::`, `OMZL::`, `OMZP::`, `OMZT::` snippets | ❌ |
|
||||||
|
| zgen | `zgen oh-my-zsh ...` selected OMZ paths | ❌ |
|
||||||
|
| zplug | `from:oh-my-zsh` selected OMZ entries | ❌ |
|
||||||
|
| antibody | `ohmyzsh/ohmyzsh path:...` selected OMZ paths | ❌ |
|
||||||
|
| zulu | OMZ package/module entries selected by zulu | ❌ |
|
||||||
|
|
||||||
### Enable GNU ls In macOS And FreeBSD Systems
|
### Enable GNU ls In macOS And FreeBSD Systems
|
||||||
|
|
||||||
<a name="enable-gnu-ls"></a>
|
<a name="enable-gnu-ls"></a>
|
||||||
|
|||||||
44
lib/bootstrap.zsh
Normal file
44
lib/bootstrap.zsh
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# Shared Oh My Zsh bootstrap entrypoint.
|
||||||
|
#
|
||||||
|
# This file can be sourced by plugin managers that don't source `oh-my-zsh.sh`.
|
||||||
|
# It is safe to source multiple times.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Keep source path for callers that invoke omz_bootstrap again later.
|
||||||
|
typeset -g _OMZ_BOOTSTRAP_SOURCE="${${(%):-%x}:a}"
|
||||||
|
|
||||||
|
omz_bootstrap() {
|
||||||
|
# If ZSH is not defined, infer from this file location.
|
||||||
|
[[ -n "${ZSH:-}" ]] || export ZSH="${_OMZ_BOOTSTRAP_SOURCE:h:h}"
|
||||||
|
|
||||||
|
# Set ZSH_CUSTOM to the path where custom config files and plugins exist.
|
||||||
|
[[ -n "${ZSH_CUSTOM:-}" ]] || ZSH_CUSTOM="$ZSH/custom"
|
||||||
|
|
||||||
|
# Set cache directory.
|
||||||
|
[[ -n "${ZSH_CACHE_DIR:-}" ]] || ZSH_CACHE_DIR="$ZSH/cache"
|
||||||
|
|
||||||
|
# Ensure cache dir is writable, otherwise fallback to a HOME-based cache.
|
||||||
|
if [[ ! -w "$ZSH_CACHE_DIR" ]]; then
|
||||||
|
ZSH_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create cache and completions dir.
|
||||||
|
command mkdir -p "$ZSH_CACHE_DIR/completions"
|
||||||
|
|
||||||
|
# Add required OMZ search paths.
|
||||||
|
local dir
|
||||||
|
for dir in \
|
||||||
|
"$ZSH/functions" \
|
||||||
|
"$ZSH/completions" \
|
||||||
|
"$ZSH_CUSTOM/functions" \
|
||||||
|
"$ZSH_CUSTOM/completions" \
|
||||||
|
"$ZSH_CACHE_DIR/completions"; do
|
||||||
|
(( ${fpath[(Ie)$dir]} )) || fpath=("$dir" $fpath)
|
||||||
|
done
|
||||||
|
|
||||||
|
# Public signal: OMZ bootstrap has completed.
|
||||||
|
typeset -g OMZ_IS_BOOTSTRAPPED=true
|
||||||
|
}
|
||||||
|
|
||||||
|
omz_bootstrap "$@"
|
||||||
35
lib/tests/bootstrap-inline-ci.test.zsh
Executable file
35
lib/tests/bootstrap-inline-ci.test.zsh
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/zsh -df
|
||||||
|
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
bootstrap_file="${0:A:h:h}/bootstrap.zsh"
|
||||||
|
|
||||||
|
assert() {
|
||||||
|
local condition="$1" message="$2"
|
||||||
|
if ! eval "$condition"; then
|
||||||
|
print -u2 "\e[31mError\e[0m: $message"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp==(:)
|
||||||
|
mkdir -p "$tmp/ohmyzsh"/{functions,completions,cache} "$tmp/ohmyzsh/custom"/{functions,completions}
|
||||||
|
|
||||||
|
export ZSH="$tmp/ohmyzsh"
|
||||||
|
unset ZSH_CUSTOM ZSH_CACHE_DIR OMZ_IS_BOOTSTRAPPED
|
||||||
|
fpath=()
|
||||||
|
|
||||||
|
source "$bootstrap_file"
|
||||||
|
|
||||||
|
assert '[[ "$OMZ_IS_BOOTSTRAPPED" == true ]]' "OMZ bootstrap signal should be true"
|
||||||
|
assert '[[ -d "$ZSH_CACHE_DIR/completions" ]]' "cache completions directory should exist"
|
||||||
|
assert '[[ "${fpath[(Ie)$ZSH/functions]}" -gt 0 ]]' "fpath should include OMZ functions"
|
||||||
|
assert '[[ "${fpath[(Ie)$ZSH/completions]}" -gt 0 ]]' "fpath should include OMZ completions"
|
||||||
|
assert '[[ "${fpath[(Ie)$ZSH_CUSTOM/functions]}" -gt 0 ]]' "fpath should include custom functions"
|
||||||
|
assert '[[ "${fpath[(Ie)$ZSH_CUSTOM/completions]}" -gt 0 ]]' "fpath should include custom completions"
|
||||||
|
assert '[[ "${fpath[(Ie)$ZSH_CACHE_DIR/completions]}" -gt 0 ]]' "fpath should include cache completions"
|
||||||
|
|
||||||
|
touch "$ZSH_CACHE_DIR/completions/_bootstrap_ci_smoke"
|
||||||
|
assert '[[ -f "$ZSH_CACHE_DIR/completions/_bootstrap_ci_smoke" ]]' "completion cache write should succeed"
|
||||||
|
|
||||||
|
print -u2 "\e[32mSuccess\e[0m bootstrap inline invariants"
|
||||||
88
lib/tests/bootstrap.test.zsh
Normal file
88
lib/tests/bootstrap.test.zsh
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
#!/usr/bin/zsh -df
|
||||||
|
|
||||||
|
set -u
|
||||||
|
|
||||||
|
bootstrap_file="${0:A:h:h}/bootstrap.zsh"
|
||||||
|
|
||||||
|
_assert() {
|
||||||
|
local condition="$1" message="$2"
|
||||||
|
if ! eval "$condition"; then
|
||||||
|
print -u2 "\e[31mError\e[0m: $message"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_bootstrap_sets_defaults_and_paths() {
|
||||||
|
local tmp==(:)
|
||||||
|
mkdir -p "$tmp/ohmyzsh"/{functions,completions,cache} "$tmp/ohmyzsh/custom"/{functions,completions}
|
||||||
|
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
export ZSH="$tmp/ohmyzsh"
|
||||||
|
unset ZSH_CUSTOM ZSH_CACHE_DIR OMZ_IS_BOOTSTRAPPED
|
||||||
|
fpath=()
|
||||||
|
source "$bootstrap_file"
|
||||||
|
|
||||||
|
_assert '[[ "$ZSH_CUSTOM" == "'"$tmp/ohmyzsh/custom"'" ]]' "ZSH_CUSTOM default should be set"
|
||||||
|
_assert '[[ "$ZSH_CACHE_DIR" == "'"$tmp/ohmyzsh/cache"'" ]]' "ZSH_CACHE_DIR default should be set"
|
||||||
|
_assert '[[ -d "'"$tmp/ohmyzsh/cache/completions"'" ]]' "completions dir should be created"
|
||||||
|
_assert '[[ "${fpath[(Ie)'"$tmp/ohmyzsh/functions"']}" -gt 0 ]]' "fpath should include OMZ functions dir"
|
||||||
|
_assert '[[ "${fpath[(Ie)'"$tmp/ohmyzsh/completions"']}" -gt 0 ]]' "fpath should include OMZ completions dir"
|
||||||
|
_assert '[[ "${fpath[(Ie)'"$tmp/ohmyzsh/custom/functions"']}" -gt 0 ]]' "fpath should include custom functions dir"
|
||||||
|
_assert '[[ "${fpath[(Ie)'"$tmp/ohmyzsh/custom/completions"']}" -gt 0 ]]' "fpath should include custom completions dir"
|
||||||
|
_assert '[[ "${fpath[(Ie)'"$tmp/ohmyzsh/cache/completions"']}" -gt 0 ]]' "fpath should include cache completions dir"
|
||||||
|
_assert '[[ "$OMZ_IS_BOOTSTRAPPED" == true ]]' "bootstrap signal should be set"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_bootstrap_is_idempotent() {
|
||||||
|
local tmp==(:)
|
||||||
|
mkdir -p "$tmp/ohmyzsh"/{functions,completions,cache} "$tmp/ohmyzsh/custom"/{functions,completions}
|
||||||
|
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
export ZSH="$tmp/ohmyzsh"
|
||||||
|
unset ZSH_CUSTOM ZSH_CACHE_DIR OMZ_IS_BOOTSTRAPPED
|
||||||
|
fpath=()
|
||||||
|
source "$bootstrap_file"
|
||||||
|
source "$bootstrap_file"
|
||||||
|
omz_bootstrap
|
||||||
|
|
||||||
|
_assert '[[ ${#fpath} -eq ${#${(u)fpath}} ]]' "fpath entries should not duplicate after repeated bootstrap"
|
||||||
|
_assert '[[ "$OMZ_IS_BOOTSTRAPPED" == true ]]' "bootstrap signal should remain true"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
test_bootstrap_uses_writable_cache_fallback() {
|
||||||
|
local tmp==(:)
|
||||||
|
mkdir -p "$tmp/ohmyzsh"/{functions,completions} "$tmp/ohmyzsh/custom"/{functions,completions}
|
||||||
|
mkdir -p "$tmp/no-write" "$tmp/xdg-cache"
|
||||||
|
chmod 0555 "$tmp/no-write"
|
||||||
|
|
||||||
|
(
|
||||||
|
set -e
|
||||||
|
export ZSH="$tmp/ohmyzsh"
|
||||||
|
export XDG_CACHE_HOME="$tmp/xdg-cache"
|
||||||
|
export ZSH_CACHE_DIR="$tmp/no-write"
|
||||||
|
unset ZSH_CUSTOM OMZ_IS_BOOTSTRAPPED
|
||||||
|
fpath=()
|
||||||
|
source "$bootstrap_file"
|
||||||
|
|
||||||
|
_assert '[[ "$ZSH_CACHE_DIR" == "'"$tmp/xdg-cache/oh-my-zsh"'" ]]' "cache dir should fallback when not writable"
|
||||||
|
_assert '[[ -d "'"$tmp/xdg-cache/oh-my-zsh/completions"'" ]]' "fallback completions dir should be created"
|
||||||
|
_assert '[[ "${fpath[(Ie)'"$tmp/xdg-cache/oh-my-zsh/completions"']}" -gt 0 ]]' "fpath should include fallback completions dir"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
tests=(
|
||||||
|
test_bootstrap_sets_defaults_and_paths
|
||||||
|
test_bootstrap_is_idempotent
|
||||||
|
test_bootstrap_uses_writable_cache_fallback
|
||||||
|
)
|
||||||
|
|
||||||
|
for test_name in $tests; do
|
||||||
|
print -u2 "Test: $test_name"
|
||||||
|
"$test_name" || exit 1
|
||||||
|
print -u2 "\e[32mSuccess\e[0m"
|
||||||
|
print -u2 ""
|
||||||
|
done
|
||||||
104
lib/tests/plugin-manager-bootstrap-integration.test.zsh
Executable file
104
lib/tests/plugin-manager-bootstrap-integration.test.zsh
Executable file
@@ -0,0 +1,104 @@
|
|||||||
|
#!/usr/bin/zsh -df
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if (( $# != 2 )); then
|
||||||
|
print -u2 "Usage: $0 <manager> <positive|negative>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
manager="$1"
|
||||||
|
scenario="$2"
|
||||||
|
|
||||||
|
if [[ "$scenario" != "positive" && "$scenario" != "negative" ]]; then
|
||||||
|
print -u2 "scenario must be 'positive' or 'negative'"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
repo_root="${0:A:h:h:h}"
|
||||||
|
tmp==(:)
|
||||||
|
workspace="$tmp/workspace"
|
||||||
|
home_dir="$tmp/home"
|
||||||
|
cache_dir="$tmp/cache"
|
||||||
|
zshrc="$tmp/.zshrc"
|
||||||
|
|
||||||
|
mkdir -p "$workspace" "$home_dir" "$cache_dir"
|
||||||
|
|
||||||
|
manager_install=''
|
||||||
|
manager_source=''
|
||||||
|
|
||||||
|
case "$manager" in
|
||||||
|
antigen)
|
||||||
|
manager_install='git clone https://github.com/zsh-users/antigen.git "$MANAGER_HOME/antigen" >/dev/null 2>&1'
|
||||||
|
manager_source='source "$MANAGER_HOME/antigen/antigen.zsh"'
|
||||||
|
;;
|
||||||
|
zinit)
|
||||||
|
manager_install='git clone https://github.com/zdharma-continuum/zinit.git "$MANAGER_HOME/zinit" >/dev/null 2>&1'
|
||||||
|
manager_source='source "$MANAGER_HOME/zinit/zinit.zsh"'
|
||||||
|
;;
|
||||||
|
zgen)
|
||||||
|
manager_install='git clone https://github.com/tarjoilija/zgen.git "$MANAGER_HOME/zgen" >/dev/null 2>&1'
|
||||||
|
manager_source='source "$MANAGER_HOME/zgen/zgen.zsh"'
|
||||||
|
;;
|
||||||
|
zplug)
|
||||||
|
manager_install='git clone https://github.com/zplug/zplug "$MANAGER_HOME/zplug" >/dev/null 2>&1'
|
||||||
|
manager_source='export ZPLUG_HOME="$MANAGER_HOME/zplug"; source "$ZPLUG_HOME/init.zsh"'
|
||||||
|
;;
|
||||||
|
antibody)
|
||||||
|
manager_install='command -v go >/dev/null 2>&1; export GOBIN="$MANAGER_HOME/bin"; mkdir -p "$GOBIN"; go install github.com/getantibody/antibody@latest >/dev/null 2>&1'
|
||||||
|
manager_source='"$MANAGER_HOME/bin/antibody" --version >/dev/null 2>&1'
|
||||||
|
;;
|
||||||
|
zulu)
|
||||||
|
manager_install='git clone https://github.com/zulu-zsh/zulu.git "$MANAGER_HOME/zulu" >/dev/null 2>&1'
|
||||||
|
manager_source='source "$MANAGER_HOME/zulu/zulu.zsh"'
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print -u2 "Unsupported manager: $manager"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
cat > "$zshrc" <<RC
|
||||||
|
set -eo pipefail
|
||||||
|
|
||||||
|
export HOME="$home_dir"
|
||||||
|
export XDG_CACHE_HOME="$cache_dir"
|
||||||
|
export OMZ_ROOT="$repo_root"
|
||||||
|
export ZSH="\$OMZ_ROOT"
|
||||||
|
export MANAGER_HOME="$workspace/$manager"
|
||||||
|
mkdir -p "\$MANAGER_HOME"
|
||||||
|
|
||||||
|
$manager_install
|
||||||
|
$manager_source
|
||||||
|
RC
|
||||||
|
|
||||||
|
if [[ "$scenario" == "positive" ]]; then
|
||||||
|
cat >> "$zshrc" <<'RC'
|
||||||
|
source "$OMZ_ROOT/lib/bootstrap.zsh"
|
||||||
|
[[ "${OMZ_IS_BOOTSTRAPPED:-}" == true ]] || { print -u2 "bootstrap signal missing before OMZ load"; return 1; }
|
||||||
|
RC
|
||||||
|
else
|
||||||
|
cat >> "$zshrc" <<'RC'
|
||||||
|
[[ -z "${OMZ_IS_BOOTSTRAPPED:-}" ]] || { print -u2 "bootstrap signal unexpectedly set without hook"; return 1; }
|
||||||
|
source "$OMZ_ROOT/lib/bootstrap.zsh"
|
||||||
|
RC
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >> "$zshrc" <<RC
|
||||||
|
[[ "\${OMZ_IS_BOOTSTRAPPED:-}" == true ]] || { print -u2 "bootstrap signal not set before OMZ entrypoint sourcing"; return 1; }
|
||||||
|
|
||||||
|
source "\$OMZ_ROOT/lib/functions.zsh"
|
||||||
|
source "\$OMZ_ROOT/plugins/git/git.plugin.zsh"
|
||||||
|
autoload -Uz compinit
|
||||||
|
compinit -i -d "\$ZSH_CACHE_DIR/.zcompdump"
|
||||||
|
|
||||||
|
source "\$OMZ_ROOT/themes/robbyrussell.zsh-theme"
|
||||||
|
|
||||||
|
[[ -d "\$ZSH_CACHE_DIR/completions" ]] || { print -u2 "completions cache directory missing"; return 1; }
|
||||||
|
|
||||||
|
touch "\$ZSH_CACHE_DIR/completions/_ci_${manager}_${scenario}" || { print -u2 "completion cache write failed"; return 1; }
|
||||||
|
[[ -f "\$ZSH_CACHE_DIR/completions/_ci_${manager}_${scenario}" ]] || { print -u2 "completion cache file missing"; return 1; }
|
||||||
|
RC
|
||||||
|
|
||||||
|
zsh -df "$zshrc"
|
||||||
|
print -u2 "\e[32mSuccess\e[0m $manager $scenario"
|
||||||
24
oh-my-zsh.sh
24
oh-my-zsh.sh
@@ -50,31 +50,14 @@ unset -f omz_f
|
|||||||
# If ZSH is not defined, use the current script's directory.
|
# If ZSH is not defined, use the current script's directory.
|
||||||
[[ -n "$ZSH" ]] || export ZSH="${${(%):-%x}:a:h}"
|
[[ -n "$ZSH" ]] || export ZSH="${${(%):-%x}:a:h}"
|
||||||
|
|
||||||
# Set ZSH_CUSTOM to the path where your custom config files
|
# Shared, manager-agnostic bootstrap.
|
||||||
# and plugins exists, or else we will use the default custom/
|
source "$ZSH/lib/bootstrap.zsh"
|
||||||
[[ -n "$ZSH_CUSTOM" ]] || ZSH_CUSTOM="$ZSH/custom"
|
|
||||||
|
|
||||||
# Set ZSH_CACHE_DIR to the path where cache files should be created
|
|
||||||
# or else we will use the default cache/
|
|
||||||
[[ -n "$ZSH_CACHE_DIR" ]] || ZSH_CACHE_DIR="$ZSH/cache"
|
|
||||||
|
|
||||||
# Make sure $ZSH_CACHE_DIR is writable, otherwise use a directory in $HOME
|
|
||||||
if [[ ! -w "$ZSH_CACHE_DIR" ]]; then
|
|
||||||
ZSH_CACHE_DIR="${XDG_CACHE_HOME:-$HOME/.cache}/oh-my-zsh"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create cache and completions dir and add to $fpath
|
|
||||||
mkdir -p "$ZSH_CACHE_DIR/completions"
|
|
||||||
(( ${fpath[(Ie)$ZSH_CACHE_DIR/completions]} )) || fpath=("$ZSH_CACHE_DIR/completions" $fpath)
|
|
||||||
|
|
||||||
# Check for updates on initial load...
|
# Check for updates on initial load...
|
||||||
source "$ZSH/tools/check_for_upgrade.sh"
|
source "$ZSH/tools/check_for_upgrade.sh"
|
||||||
|
|
||||||
# Initializes Oh My Zsh
|
# Initializes Oh My Zsh
|
||||||
|
|
||||||
# add a function path
|
|
||||||
fpath=($ZSH/{functions,completions} $ZSH_CUSTOM/{functions,completions} $fpath)
|
|
||||||
|
|
||||||
# Load all stock functions (from $fpath files) called below.
|
# Load all stock functions (from $fpath files) called below.
|
||||||
autoload -U compaudit compinit zrecompile
|
autoload -U compaudit compinit zrecompile
|
||||||
|
|
||||||
@@ -234,3 +217,6 @@ fi
|
|||||||
|
|
||||||
# set completion colors to be the same as `ls`, after theme has been loaded
|
# set completion colors to be the same as `ls`, after theme has been loaded
|
||||||
[[ -z "$LS_COLORS" ]] || zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
|
[[ -z "$LS_COLORS" ]] || zstyle ':completion:*' list-colors "${(s.:.)LS_COLORS}"
|
||||||
|
|
||||||
|
# Public signal: full Oh My Zsh init script has completed.
|
||||||
|
typeset -g OMZ_IS_LOADED=true
|
||||||
|
|||||||
Reference in New Issue
Block a user