├── .asdfrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .genaiscript
├── .gitattributes
└── .gitignore
├── .gitconfig
├── .gitconfig-no_push
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.yml
│ ├── config.yml
│ └── feature_request.yml
├── PULL_REQUEST_TEMPLATE.md
├── config
│ ├── labeller.yml
│ └── labels.yml
├── release-drafter.yml
├── renovate.json
└── workflows
│ ├── auto-approve.yml
│ ├── codeball.yml
│ ├── codeql.yml
│ ├── delete-disabled-workflows.yml
│ ├── detect-secrets-generate-baseline.yml
│ ├── detect-secrets.yml
│ ├── label-sync.yml
│ ├── lint-codeowners.yml
│ ├── lint-docker.yml
│ ├── lint-pr-actions-skip.yml
│ ├── lint-pr-actions.yml
│ ├── lint-pr-markdown.yml
│ ├── lint-shell.yml
│ ├── lint-tf.yml
│ ├── mirror.yml
│ ├── pr-labeller.yml
│ └── pre-commit.yml
├── .gitignore
├── .gitignoreglobal
├── .pre-commit-config.yaml
├── .prettierignore
├── .prettierrc.js
├── .secrets.baseline
├── .vimrc
├── .whitesource
├── 0-paths.rc
├── 1-zgen.rc
├── 10-prompt.rc
├── 14-source-files.rc
├── 15-events.rc
├── 16-fabric.rc
├── 3-location_specifics.rc
├── 4-aliases.rc
├── 5-exports.rc
├── 6-zsh_options.rc
├── 7-history.rc
├── 9-functions.rc
├── CODEOWNERS
├── LICENSE
├── NOTES.md
├── README.md
├── bat-config
├── bootstrap_shell.sh
├── commitlint.config.js
├── dircolors
├── githooks
└── pre-push
├── htoprc
├── renovate.json
├── rsyncd.conf
├── run_tests.sh
├── tmux.conf
└── zshrc
/.asdfrc:
--------------------------------------------------------------------------------
1 | legacy_version_file = yes
2 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | # EditorConfig https://EditorConfig.org
4 |
5 | # top-most EditorConfig file
6 | root = true
7 |
8 | # Unix-style newlines with a newline ending every file
9 | [*]
10 | end_of_line = lf
11 | insert_final_newline = true
12 | trim_trailing_whitespace = true
13 | charset = utf-8
14 |
15 | # Ensure we're standardising on 2 space soft-tabs for most files
16 | [*.md, *.markdown, *.yml, *.yaml, *.json, *.js, *.ts, *.tsx, *.sh]
17 | indent_style = space
18 | indent_size = 2
19 |
20 | # Makefile specific
21 | [Makefile]
22 | indent_style = tab
23 | indent_size = 4
24 |
25 | # Python specific
26 | [*.py, *.pyi]
27 | indent_style = space
28 | indent_size = 4
29 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | .ide
4 | .idea
5 | .vscode
6 | **/__pycache__
7 | **/__pypackages__
8 | **/.bin
9 | **/.DS_Store
10 | **/.env.*
11 | **/.git
12 | **/.out
13 | **/.venv
14 | **/*.log
15 | **/*.tmp
16 | **/build
17 | **/cdk.out
18 | **/coverage
19 | **/dist
20 | **/global.setup.ts
21 | **/htmlcov
22 | **/logs
23 | **/node_modules
24 | **/public
25 | **/temp
26 | **/tmp
27 | **/venv
28 |
29 | # Obsidian
30 | .obsidian
31 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW
2 |
3 | // Required packages:
4 | // 'eslint-config-prettier'
5 | // 'eslint-plugin-deprecation'
6 | // 'eslint-plugin-import'
7 | // 'eslint-plugin-jest'
8 | // 'eslint-plugin-unused-imports'
9 | // 'eslint'
10 | // 'prettier-plugin-packagejson'
11 | // 'prettier'
12 |
13 | module.exports = {
14 | env: {
15 | browser: true,
16 | commonjs: true,
17 | es2021: true,
18 | jest: true,
19 | },
20 | parserOptions: {
21 | ecmaVersion: 'latest',
22 | sourceType: 'module',
23 | },
24 | plugins: ['import', 'prettier'],
25 | extends: ['plugin:prettier/recommended', 'eslint:recommended'],
26 | root: true,
27 | rules: {
28 | quotes: ['error', 'single', { avoidEscape: true }],
29 | 'comma-dangle': ['error', 'always-multiline'],
30 | 'comma-spacing': ['error', { before: false, after: true }],
31 | 'no-multi-spaces': ['error', { ignoreEOLComments: false }],
32 | 'array-bracket-newline': ['error', 'consistent'],
33 | 'object-curly-spacing': ['error', 'always'],
34 | 'array-bracket-spacing': ['error', 'never'],
35 | 'object-curly-newline': ['error', { multiline: true, consistent: true }],
36 | 'object-property-newline': ['error', { allowAllPropertiesOnSameLine: true }],
37 | 'keyword-spacing': ['error'],
38 | 'brace-style': ['error', '1tbs', { allowSingleLine: true }],
39 | 'space-before-blocks': 'error',
40 | curly: ['error', 'multi-line', 'consistent'],
41 | 'no-bitwise': ['error'],
42 | 'no-console': 0,
43 | 'no-trailing-spaces': ['error'],
44 | 'no-duplicate-imports': ['error'],
45 | 'no-shadow': 'off',
46 | 'no-use-before-define': 'off',
47 | 'import/order': 'error',
48 | 'prettier/prettier': 'error',
49 | 'max-classes-per-file': ['error', 3],
50 | 'no-underscore-dangle': 'off',
51 | 'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: true }],
52 | },
53 | ignorePatterns: [
54 | '!**/*.eslintrc.js*',
55 | '!**/*.prettierrc.js*',
56 | '**/node_modules/**',
57 | '**/dist/**',
58 | '**/build/**',
59 | '**/coverage/**',
60 | '**/cdk.out/**',
61 | 'jest.setup.ts',
62 | ],
63 | };
64 |
--------------------------------------------------------------------------------
/.genaiscript/.gitattributes:
--------------------------------------------------------------------------------
1 | # avoid merge issues and ignore files in diffs
2 | *.json -diff merge=ours linguist-generated
3 | *.jsonl -diff merge=ours linguist-generated
4 | *.js -diff merge=ours linguist-generated
5 |
--------------------------------------------------------------------------------
/.genaiscript/.gitignore:
--------------------------------------------------------------------------------
1 | runs/
2 | cache/
3 | retrieval/
4 | containers/
5 | temp/
6 | tests/
7 | stats/
8 | *.csv
9 |
--------------------------------------------------------------------------------
/.gitconfig:
--------------------------------------------------------------------------------
1 | [core]
2 | excludesfile = ~/.gitignoreglobal
3 | ignorecase = true
4 |
5 | [credential]
6 | helper = store
7 |
8 | [include]
9 | path = ~/.gitconfig.private
10 |
11 | #[url "git@github.com:"]
12 | # insteadOf = https://github.com/
13 |
14 | ## Behaviour
15 | [init]
16 | defaultBranch = main
17 | [push]
18 | default = current
19 | autoSetupRemote = true
20 | followtags = true
21 | [pull]
22 | rebase = true
23 | [rebase]
24 | autosquash = true
25 | [branch]
26 | autoSetupMerge = true
27 | sort = -committerdate
28 | [mergetool]
29 | prompt = false
30 | [filter "lfs"]
31 | required = true
32 | clean = git-lfs clean -- %f
33 | smudge = git-lfs smudge -- %f
34 | process = git-lfs filter-process
35 | [tar "tar.xz"]
36 | command = xz -c
37 |
38 | ### DIFF TOOLING ###
39 | [core]
40 | pager = delta #--features=interactive #,diff-so-fancy,decorations
41 | #page = diff-so-fancy | less --tabs=2 -RFX
42 | [merge]
43 | conflictstyle = zdiff3
44 | tool = delta
45 |
46 | [diff]
47 | colorMoved = default
48 | submodule = log
49 | algorithm = histogram
50 | tool = delta
51 | # external = delta
52 | prompt = false
53 |
54 | [delta]
55 | side-by-side = true
56 | navigate = true
57 | features = decorations unobtrusive-line-numbers diff-so-fancy dark
58 | syntax-theme = Dracula
59 | tabs = 4
60 | true-color = always
61 | hyperlinks = true
62 | hyperlinks-file-link-format = "vscode://file/{path}:{line}"
63 | # or: hyperlinks-file-link-format = "idea://open?file={path}&line={line}"
64 | # or: hyperlinks-file-link-format = "pycharm://open?file={path}&line={line}"
65 | [delta "interactive"]
66 | diffFilter = delta --color-only --dark --features=interactive,unobtrusive-line-numbers,diff-so-fancy
67 | keep-plus-minus-markers = false
68 | [delta "decorations"]
69 | commit-decoration-style = bold yellow box ul
70 | file-style = bold yellow ul
71 | file-decoration-style = none
72 | hunk-header-decoration-style = yellow box
73 | commit-decoration-style = blue ol
74 | # commit-style = raw
75 | # file-style = omit
76 | # hunk-header-decoration-style = blue box
77 | hunk-header-file-style = red
78 | # hunk-header-line-number-style = "#067a00"
79 | hunk-header-style = file line-number syntax
80 | [delta "unobtrusive-line-numbers"]
81 | line-numbers = true
82 | line-numbers-minus-style = "#444444"
83 | line-numbers-zero-style = "#444444"
84 | line-numbers-plus-style = "#444444"
85 | line-numbers-left-format = "{nm:>4}┊"
86 | line-numbers-right-format = "{np:>4}│"
87 | line-numbers-left-style = blue
88 | line-numbers-right-style = blue
89 |
90 |
91 | # Diff-so-fancy diff-tool
92 | [interactive]
93 | diffFilter = delta --diff-so-fancy # diff-so-fancy --patch
94 | [diff-so-fancy]
95 | changeHunkIndicators = true
96 | ### END DIFF ###
97 |
98 | [safe]
99 | directory = /github/workspace
100 | [status]
101 | submodulesummary = 1
102 | [rerere] # Reuse Recorded Resolution
103 | enable = true
104 | enabled = true
105 | autoUpdate = true
106 | [help]
107 | autocorrect = 1
108 | [fetch]
109 | prunetags = true
110 | [log]
111 | date = iso
112 |
113 | # Alases
114 | [alias]
115 | init-safe-commit = !~/.safe-commit-hook/install-for-project.sh
116 | quick-stats = ! /usr/local/bin/git-quick-stats
117 | prune = fetch --prune
118 | undo = reset --soft HEAD^
119 | glog = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset'
120 | logline = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit
121 | tree = log --graph --decorate --pretty=oneline --abbrev-commit
122 | squash-all = "!f(){ git reset $(git commit-tree HEAD^{tree} -m \"${1:-A new start}\");};f"
123 | #squash-all = "!f(){ git reset $(git commit-tree HEAD^{tree} -m \"${1:-Make Actions Great Again}\");};f"
124 | scrub = reset --hard @{upstream}
125 | recentb = "!r() { refbranch=$1 count=$2; git for-each-ref --sort=-committerdate refs/heads --format='%(refname:short)|%(HEAD)%(color:yellow)%(refname:short)|%(color:bold green)%(committerdate:relative)|%(color:blue)%(subject)|%(color:magenta)%(authorname)%(color:reset)' --color=always --count=${count:-20} | while read line; do branch=$(echo \"$line\" | awk 'BEGIN { FS = \"|\" }; { print $1 }' | tr -d '*'); ahead=$(git rev-list --count \"${refbranch:-origin/master}..${branch}\"); behind=$(git rev-list --count \"${branch}..${refbranch:-origin/master}\"); colorline=$(echo \"$line\" | sed 's/^[^|]*|//'); echo \"$ahead|$behind|$colorline\" | awk -F'|' -vOFS='|' '{$5=substr($5,1,70)}1' ; done | ( echo \"ahead|behind||branch|lastcommit|message|author\\n\" && cat) | column -ts'|';}; r"
126 | runs = "!f() { \
127 | watch_gha_runs \
128 | \"$(git remote get-url origin)\" \
129 | \"$(git rev-parse --abbrev-ref HEAD)\"; \
130 | }; f"
131 |
132 | # *********************
133 | # Rebase workflow
134 | mainbranch = "!git remote show origin | sed -n '/HEAD branch/s/.*: //p'"
135 | synced = "!git pull origin $(git mainbranch) --rebase"
136 | update = "!git pull origin $(git rev-parse --abbrev-ref HEAD) --rebase"
137 | squash = "!git rebase -v -i $(git mainbranch)"
138 | publish = push origin HEAD --force-with-lease
139 | pub = publish
140 | ammend = commit --amend
141 | amend = commit --amend
142 | fpush = push
143 | # *********************
144 |
145 |
146 | # [maintenance]
147 | # repo = /path/to/example/repo
148 |
--------------------------------------------------------------------------------
/.gitconfig-no_push:
--------------------------------------------------------------------------------
1 | # Prevents accidental pushing to branches
2 |
3 | [branch "master"]
4 | pushRemote = no_push
5 | [branch "main"]
6 | # pushRemote = no_push
7 |
8 | # this can be undone for a specific directory by running:
9 | # git config --worktree branch.main.pushRemote origin
10 | # git config --worktree branch.master.pushRemote origin
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: 🐛 Bug report
4 | description: Create a bug report to help us improve
5 | labels: ["bug"]
6 | body:
7 | - type: textarea
8 | id: description
9 | attributes:
10 | label: 🐞 Describe the bug
11 | description: |
12 | A brief description of the bug.
13 | validations:
14 | required: true
15 |
16 | - type: textarea
17 | id: reproduce
18 | attributes:
19 | label: 📚 To reproduce
20 | description: |
21 | Steps to reproduce the behaviour.
22 | validations:
23 | required: false
24 |
25 | - type: textarea
26 | id: expected
27 | attributes:
28 | label: 💡 Expected behaviour
29 | description: |
30 | A description of what you expected to happen.
31 | validations:
32 | required: false
33 |
34 | - type: textarea
35 | id: suggestion
36 | attributes:
37 | label: 🤔 Suggestion
38 | description: |
39 | Any suggestions on how to fix the bug?
40 | validations:
41 | required: false
42 |
43 |
44 | - type: textarea
45 | id: screenshots
46 | attributes:
47 | label: 🖼️ Screenshots
48 | description: |
49 | If applicable, add screenshots to help explain your problem.
50 | validations:
51 | required: false
52 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | blank_issues_enabled: false
4 | # contact_links:
5 | # - name: 📚 Docs
6 | # url: https://github.com/sammcj/${{ github.repository }}#-usage
7 | # about: Checkout ${{ github.repository }}'s documentation.
8 | # - name: 🚀 Feature Request
9 | # url: https://github.com/sammcj/${{ github.repository }}/discussions/new?category=ideas
10 | # about: Share ideas for new features
11 | # - name: ❓ Ask a Question
12 | # url: https://github.com/sammcj/${{ github.repository }}/discussions/new?category=q-a
13 | # about: Ask the community for help
14 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "💡 Feature Request"
4 | description: Create a new ticket for a new feature request
5 | title: "💡 [REQUEST] -
"
6 | labels: ["question"]
7 |
8 | body:
9 | - type: textarea
10 | id: related_issues
11 | attributes:
12 | label: "Related Issues"
13 | description: Are there any related issues?
14 | validations:
15 | required: false
16 |
17 | - type: textarea
18 | id: summary
19 | attributes:
20 | label: "Summary"
21 | description: Provide a brief explanation of the feature
22 | placeholder: Describe in a few lines your feature request
23 | validations:
24 | required: true
25 |
26 | - type: textarea
27 | id: example
28 | attributes:
29 | label: "Example"
30 | description: Indicate here some basic examples of your feature.
31 | validations:
32 | required: false
33 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/.github/config/labeller.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | # .github/config/labeller.yml
4 |
5 | version: v1
6 |
7 | labels:
8 | - label: "Feat"
9 | sync: true
10 | matcher:
11 | title: ".*(feat:|(IF-[0-9]+ -- (feat))).*/i"
12 | body: "(feat:.*|feature:.*)/i"
13 | branch: "(^feat\/.*)/i"
14 | baseBranch: "(^feat\/.*)/i"
15 | commits: "(^feat:.*|(IF-[0-9]+ -- (feat))).*/i"
16 |
17 | - label: "Fix"
18 | sync: true
19 | matcher:
20 | title: "(^hotfix:.*|^fix:.*|(IF-[0-9]+ -- (fix|hotfix).*))/i"
21 | body: "(hotfix:.*|fix:.*|bug:.*)/i"
22 | branch: "(^hotfix\/.*|^fix\/.*)/i"
23 | baseBranch: "(^hotfix\/.*|^fix\/.*)/i"
24 | commits: "(^hotfix:.*|^fix:.*|(IF-[0-9]+ -- (fix|hotfix).*))/i"
25 |
26 | - label: "Chore"
27 | sync: true
28 | matcher:
29 | title: "(^chore:.*|(IF-[0-9]+ -- chore.*))/i"
30 | body: "(hotfix:.*|fix:.*|bug:.*)/i"
31 | branch: "(^chore\/.*)/i"
32 | baseBranch: "(^chore\/.*)/i"
33 | commits: "(^chore:.*|(IF-[0-9]+ -- chore.*))/i"
34 | author:
35 | - "renovatebot"
36 | - "renovatebot[bot]"
37 |
38 | - label: "Docs"
39 | sync: true
40 | matcher:
41 | title: "(^docs:.*|(IF-[0-9]+ -- docs.*))/i"
42 | body: "(docs:.*|documentation:)/i"
43 | branch: "(^docs\/.*)/i"
44 | baseBranch: "(^docs\/.*)/i"
45 | commits: "(^docs:.*|(IF-[0-9]+ -- docs.*))/i"
46 | files:
47 | any: ["**/docs/**", "**/doc/**", "**/*.md", "**/*.markdown", "**/*.rst", "**/*.txt"]
48 | count:
49 | gte: 1
50 | lte: 1000
51 |
52 | - label: "CDK"
53 | sync: true
54 | matcher:
55 | title: "(.*cdk|(IF-[0-9]+ -- cdk).*)/i"
56 | body: ".*(cdk:|cloudformation:).*/i"
57 | branch: "(.*cdk\/.*)/i"
58 | baseBranch: "(.*cdk\/.*)/i"
59 | commits: "(.*cdk:|(IF-[0-9]+ -- cdk)).*/i"
60 | files:
61 | any: ["**/cdk/**", "**/cloudformation/**", "**/*.cdk.*", "**/*.stack.*"]
62 | count:
63 | gte: 1
64 | lte: 1000
65 |
66 | - label: "Github"
67 | sync: true
68 | matcher:
69 | title: "(^actions:.*|(IF-[0-9]+ -- actions.*)|^workflow:.*|(IF-[0-9]+ -- workflow.*)|.*github:.*|(IF-[0-9]+ -- github.*))/i"
70 | body: ".*(actions:.*|github-actions:|github:|workflow:).*/i"
71 | branch: "(^actions\/.*|^github\/.*^workflow\/.*)/i"
72 | baseBranch: "(^actions\/.*|^github\/.*^workflow\/.*)/i"
73 | commits: "(^actions:.*|(IF-[0-9]+ -- actions.*)|^workflow:.*|(IF-[0-9]+ -- workflow.*)|^github:.*|(IF-[0-9]+ -- github.*))/i"
74 | files:
75 | any: [".github\/*", "CODEOWNERS"]
76 | count:
77 | gte: 1
78 | lte: 1000
79 |
80 | - label: "Test"
81 | sync: true
82 | matcher:
83 | title: "(^test|(IF-[0-9]+ -- test)|jest).*/i"
84 | body: ".*(tests:|test:|testing:|jest:).*/i"
85 | branch: "(^test\/.*)/i"
86 | baseBranch: "(^test\/.*)/i"
87 | commits: "(^tests:.*|^test:.*|(IF-[0-9]+ -- test.*))/i"
88 | files:
89 | any: ["**/.*(test|.spec).*", "**/.*jest.*"]
90 | count:
91 | gte: 1
92 | lte: 1000
93 |
94 | - label: "Performance"
95 | sync: true
96 | matcher:
97 | title: "(^perf:|(IF-[0-9]+ -- perf)).*/i"
98 | body: "(perf:|performance:).*/i"
99 | branch: "(^perf\/.*)/i"
100 | baseBranch: "(^perf\/.*)/i"
101 | commits: "(^perf:|(IF-[0-9]+ -- perf)).*/i"
102 |
103 | - label: "Style"
104 | sync: true
105 | matcher:
106 | title: ".*(style:|(IF-[0-9]+ -- (style|lint)|lint)).*/i"
107 | body: ".*(style:|styling:|lint:|linting|format:|formatting).*/i"
108 | branch: "(^style\/.*)/i"
109 | baseBranch: "(^style\/.*)/i"
110 | commits: ".*(style:|(IF-[0-9]+ -- style)|lint|formatting.*)/i"
111 | files:
112 | any:
113 | [
114 | "**/.*prettier.*",
115 | "**/.*eslint.*",
116 | "**/.*stylelint.*",
117 | "**/.*style.*",
118 | "**/.*lint.*",
119 | "**/.*editorconfig.*",
120 | ]
121 | count:
122 | gte: 1
123 | lte: 1000
124 |
125 | - label: "Database"
126 | sync: true
127 | matcher:
128 | title: "(^db:.*|.*sql.*|(IF-[0-9]+ -- db.*))/i"
129 | body: ".*(db:|database:).*/i"
130 | branch: "(^db\/.*)/i"
131 | baseBranch: "(^db\/.*)/i"
132 | commits: "(^db:.*|.*sql|(IF-[0-9]+ -- db.*))/i"
133 | files:
134 | # regex glob to match a file with extension .sql in any directory recursively
135 | any: ["**/*.sql", "**/*.db", "**/db/**", "**/flyway.*", "**/migrations/**", "**/*.sqlite.*"]
136 | count:
137 | gte: 1
138 | lte: 1000
139 |
140 | - label: "Security"
141 | sync: true
142 | matcher:
143 | title: ".*(CVE|sec:|security).*/i"
144 | body: ".*(CVE|sec:|security).*/i/i"
145 | branch: ".*(CVE|sec:|security).*/i"
146 | baseBranch: ".*(CVE|sec:|security).*/i"
147 | commits: ".*(CVE|sec:|security).*/i"
148 | files:
149 | any:
150 | [
151 | "CODEOWNERS",
152 | "SECURITY.*",
153 | ".github/settings.yml",
154 | "**/*.pem",
155 | "**/*.crt",
156 | "**/.*password.*",
157 | "**/.*secret.*",
158 | "**/.*token.*",
159 | "**/.*key.*",
160 | ]
161 | count:
162 | gte: 1
163 | lte: 1000
164 |
165 | - label: "Git"
166 | sync: true
167 | matcher:
168 | title: ".*git.*/i"
169 | files:
170 | any: ["**/.git.*", "**/.husky/*", "**/.pre-commit-config.*"]
171 | count:
172 | gte: 1
173 | lte: 1000
174 |
175 | - label: "Sync-Files"
176 | sync: true
177 | matcher:
178 | title: ".*Sync-Files.*/i"
179 |
180 | - label: "DO NOT MERGE"
181 | sync: true
182 | matcher:
183 | title: ".*(DO NOT MERGE|DONT MERGE|DON'T MERGE).*"
184 | body: ".*(DO NOT MERGE|DONT MERGE|DON'T MERGE).*"
185 | commits: ".*(DO NOT MERGE|DONT MERGE|DON'T MERGE).*"
186 |
187 | checks:
188 | - context: "Merge check"
189 | description: "Disable merging when 'DO NOT MERGE' label is set"
190 | labels:
191 | none: ["DO NOT MERGE"]
192 |
--------------------------------------------------------------------------------
/.github/config/labels.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | # .github/config/labels.yml
4 |
5 | - name: "Feat"
6 | color: "c52bff"
7 | aliases: ["Feature", "Features"]
8 |
9 | - name: "Fix"
10 | color: "125a29"
11 | aliases: ["bug", "bugfix", "patched", "Hotfix"]
12 |
13 | - name: "Chore"
14 | color: "293535"
15 | aliases: ["maintenance", "maint"]
16 |
17 | - name: "Bug"
18 | color: "b45f06"
19 | aliases: ["problem"]
20 |
21 | - name: "High"
22 | color: "ff0000"
23 | aliases: ["high", "urgent", "critical"]
24 |
25 | - name: "Medium"
26 | color: "6fa8dc"
27 | aliases: ["medium"]
28 |
29 | - name: "Low"
30 | color: "ade0d6"
31 | aliases: ["low"]
32 |
33 | - name: "Docs"
34 | color: "7c9e9d"
35 | aliases: ["doco", "Documentation"]
36 |
37 | - name: "CDK"
38 | color: "ce7e00"
39 | aliases: ["AWS", "cloudformation", "CFn"]
40 |
41 | - name: "Github"
42 | color: "ff1089"
43 | aliases: ["Actions", "Workflow"]
44 |
45 | - name: "Git"
46 | color: "3e6890"
47 |
48 | - name: "Test"
49 | color: "981f5c"
50 | aliases: ["testing", "tests", "Jest"]
51 |
52 | - name: "Style"
53 | color: "0018a8"
54 | aliases: ["lint", "formatting", "styling", "prettier", "eslint"]
55 |
56 | - name: "Database"
57 | color: "43e8d8"
58 | aliases: ["DB", "SQL", "Flyway", "Migrations"]
59 |
60 | - name: "Security"
61 | color: "f51100"
62 | aliases: ["sec", "vulnerability", "CVE", "vuln", "CODEOWNERS"]
63 |
64 | - name: "Performance"
65 | color: "ff825a"
66 | aliases: ["perf", "optimisation"]
67 |
68 | - name: "DO NOT MERGE"
69 | color: "d54360"
70 | aliases: ["DONT MERGE", "WIP", "Work In Progress"]
71 |
72 | - name: "renovatebot"
73 | color: "123000"
74 | aliases: ["Renovate"]
75 |
76 | - name: "minor"
77 | color: "123000"
78 | aliases: ["minor-update"]
79 |
80 | - name: "major"
81 | color: "123000"
82 | aliases: ["major-update"]
83 |
84 | - name: "patch"
85 | color: "123000"
86 | aliases: ["patch-update"]
87 |
88 | - name: "comments"
89 | color: "4360d5"
90 | aliases: ["comment", "blog-comments"]
91 |
92 | - name: "sync-files"
93 | color: "130000"
94 |
95 | - name: "codeball:needs-careful-review"
96 | color: "fde68a"
97 | description: "This PR needs careful review"
98 | aliases: ["codeball:needs-review"]
99 |
100 | - name: "codeball:approved"
101 | color: "86efac"
102 | description: "This PR has been approved by Codeball AI"
103 |
--------------------------------------------------------------------------------
/.github/release-drafter.yml:
--------------------------------------------------------------------------------
1 | template: |
2 | ## What's Changed
3 |
4 | $CHANGES
5 |
--------------------------------------------------------------------------------
/.github/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["github>sammcj/renovate-config"],
3 | "description": "This file is managed in template-repo",
4 | "ignorePaths": [
5 | ".github/workflows/codeball.yml",
6 | ".github/workflows/label-sync.yml",
7 | ".github/workflows/lint-pr-actions.yml",
8 | ".github/workflows/lint-pr-actions-skip.yml",
9 | ".github/workflows/lint-pr-markdown.yml",
10 | ".github/workflows/pr-labeller.yml",
11 | ".github/workflows/todo.yml",
12 | ".github/workflows/mirror.yml"
13 | ]
14 | }
15 |
--------------------------------------------------------------------------------
/.github/workflows/auto-approve.yml:
--------------------------------------------------------------------------------
1 | name: Auto approve gha-template-repo-token-generator PRs # and renovate
2 |
3 | on:
4 | pull_request_target: #Disabling on PRs for now
5 | workflow_dispatch:
6 |
7 | # One build per branch, cancel out of date builds
8 | concurrency:
9 | group: ${{ github.workflow }}-${{ github.ref }}
10 | cancel-in-progress: true
11 |
12 | jobs:
13 | auto-approve:
14 | runs-on: ubuntu-latest
15 | timeout-minutes: 5
16 | permissions:
17 | pull-requests: write
18 | if: github.actor == 'gha-template-repo-token-generator' # || github.actor == 'renovate[bot]' || github.actor == 'apps/renovate'
19 | steps:
20 | - uses: hmarr/auto-approve-action@v3
21 |
--------------------------------------------------------------------------------
/.github/workflows/codeball.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: Codeball
4 |
5 | on:
6 | pull_request:
7 | branches:
8 | - main
9 | - master
10 | - "!repo-sync/**"
11 | - "!renovate/**"
12 | - "!update/pre-commit-hooks/**"
13 | workflow_dispatch:
14 |
15 | permissions:
16 | contents: read
17 | issues: write
18 | pull-requests: write
19 | checks: write
20 | statuses: write
21 | actions: read
22 |
23 | # One build per branch, cancel out of date builds
24 | concurrency:
25 | group: ${{ github.workflow }}-${{ github.ref }}
26 | cancel-in-progress: true
27 |
28 | jobs:
29 | codeball-review:
30 | runs-on: ubuntu-latest
31 | timeout-minutes: 10
32 | if: ${{ !github.event.pull_request.draft }}
33 | name: Run Codeball Code Review
34 | steps:
35 | - name: Codeball AI Actions
36 | uses: sturdy-dev/codeball-action@v2
37 | with:
38 | approvePullRequests: "false"
39 | labelPullRequestsWhenApproved: "true"
40 | labelPullRequestsWhenReviewNeeded: "true"
41 | failJobsWhenReviewNeeded: "false"
42 |
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "CodeQL"
4 |
5 | on:
6 | schedule:
7 | - cron: "25 17 * * 3"
8 |
9 | jobs:
10 | analyze:
11 | name: Analyze
12 | runs-on: ubuntu-24.04
13 | permissions:
14 | actions: read
15 | contents: read
16 | security-events: write
17 | pull-requests: write
18 | checks: write
19 |
20 | steps:
21 | - name: Checkout repository
22 | uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
23 |
24 | - name: Initialize CodeQL
25 | uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v3
26 |
27 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
28 | # If this step fails, then you should remove it and run the build manually (see below)
29 | - name: Autobuild
30 | uses: github/codeql-action/autobuild@d39d31e687223d841ef683f52467bd88e9b21c14 # v3
31 |
32 | - name: Perform CodeQL Analysis
33 | uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14 # v3
34 |
--------------------------------------------------------------------------------
/.github/workflows/delete-disabled-workflows.yml:
--------------------------------------------------------------------------------
1 | name: Delete Disabled and Deprecated Workflows
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | github-token:
7 | description: 'Custom GitHub Token, to not be rate limited to 1,000 requests, defaults to GITHUB_TOKEN'
8 | required: false
9 | purge-deprecated:
10 | description: 'Delete deprecated workflows, defaults to true'
11 | required: false
12 | default: "true"
13 | delete-disabled:
14 | description: 'Delete disabled workflows, defaults to true'
15 | required: false
16 | default: "true"
17 | wait-days:
18 | description: 'Number of days to wait before deleting disabled workflows, defaults to 7'
19 | required: false
20 | default: 7
21 | type: number
22 | schedule:
23 | - cron: '0 0 * * 4' # At 00:00, only on Thursday
24 |
25 | permissions:
26 | actions: write
27 | contents: read
28 |
29 | jobs:
30 | delete-deprecated-workflows:
31 | runs-on: ubuntu-latest
32 | timeout-minutes: 15
33 | if: inputs.purge-deprecated == true
34 | steps:
35 | - uses: otto-de/purge-deprecated-workflow-runs@v1
36 | with:
37 | token: ${{ inputs.github-token || secrets.GITHUB_TOKEN }}
38 |
39 | delete-disabled-workflows:
40 | runs-on: ubuntu-latest
41 | timeout-minutes: 15
42 | if: inputs.delete-disabled == true
43 | steps:
44 | - uses: actions/github-script@v6
45 | with:
46 | github-token: ${{ inputs.github-token || secrets.GITHUB_TOKEN }}
47 | script: |
48 | const githubContext = {
49 | owner: context.repo.owner,
50 | repo: context.repo.repo,
51 | }
52 |
53 | // filter out workflows that are not disabled
54 | const allDisabledWorkflows = await github.paginate(
55 | github.rest.actions.listRepoWorkflows,
56 | githubContext
57 | ).then(workflows => workflows.filter(workflow => workflow.state == 'disabled_manually'))
58 |
59 | // filter out workflows that have only been disabled for less than wait-days
60 | const disabledWorkflows = allDisabledWorkflows.filter(workflow => {
61 | const now = new Date()
62 | const disabledAt = new Date(workflow.updated_at)
63 | const diff = now - disabledAt
64 | const days = diff / (1000 * 60 * 60 * 24)
65 | return days > ${{ inputs.wait-days }}
66 | })
67 |
68 | console.log(`::group::List of disabled workflows older than ${{ inputs.wait-days }}`)
69 | console.log(disabledWorkflows)
70 | console.log('::endgroup::')
71 |
72 | // get the runs for each workflow
73 | for (const workflow of disabledWorkflows) {
74 | const runs = await github.paginate(
75 | github.rest.actions.listWorkflowRuns,
76 | {
77 | ...githubContext,
78 | workflow_id: workflow.id,
79 | }
80 | )
81 |
82 | console.log(`::group::Workflow ${workflow.id} >> Title`)
83 | console.log(`::group::Workflow ${workflow.id} >> Runs`)
84 |
85 | // log the title of each run
86 | for (const run of runs) {
87 | console.log(`::group::Workflow ${workflow.id} >> Run ${run.id} >> Title`)
88 | console.log(run.head_commit.message)
89 | console.log('::endgroup::')
90 | }
91 | console.log('::endgroup::')
92 |
93 | // delete each run
94 | for (const run of runs) {
95 | const response = await github.rest.actions.deleteWorkflowRun({
96 | ...githubContext,
97 | run_id: run.id,
98 | })
99 |
100 | console.log(`::group::Workflow ${workflow.id} >> Run ${run.id} >> Delete`)
101 | console.log(response)
102 | console.log('::endgroup::')
103 |
104 | }
105 |
106 | }
107 |
--------------------------------------------------------------------------------
/.github/workflows/detect-secrets-generate-baseline.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: detect-secrets update baseline
4 |
5 | on:
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: write
10 | pull-requests: write
11 | checks: write
12 |
13 | env:
14 | EXCLUDE_LINES: |
15 | --exclude-lines='CHECKSUM'
16 | --exclude-lines='MOCKING'
17 | --exclude-lines='GOOGLE_API_KEY'
18 | --exclude-lines='google-api-key'
19 | --exclude-lines='NODE_OPTIONS'
20 | --exclude-lines='http://localhost'
21 | --exclude-lines='#*tag=v'
22 | --exclude-lines='secrets*inherit'
23 | EXCLUDE_FILES: |
24 | --exclude-files='node_modules'
25 | --exclude-files='dist'
26 | --exclude-files='*secrets*baseline'
27 |
28 | jobs:
29 | detect-secrets-baseline-update:
30 | runs-on: ubuntu-latest
31 | steps:
32 | - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
33 | - name: "Set output variable to update or create baseline"
34 | id: baseline
35 | run: |
36 | if [ -f .secrets.baseline ]; then
37 | echo "::set-output name=baseline::--baseline .secrets.baseline"
38 | else
39 | echo "::set-output name=baseline::> .secrets.baseline"
40 | fi
41 |
42 | - name: run detect-secrets update baseline
43 | uses: reviewdog/action-detect-secrets@master
44 | with:
45 | github_token: ${{ secrets.github_token }}
46 | reporter: github-pr-review
47 | fail_on_error: "true"
48 | level: warning
49 | detect_secrets_flags: "${{ env.EXCLUDE_FILES }} ${{ env.EXCLUDE_LINES }} ${{ steps.baseline.outputs.baseline }}"
50 |
51 | # Create a PR with the new baseline
52 | - uses: peter-evans/create-pull-request@5e914681df9dc83aa4e4905692ca88beb2f9e91f # v7
53 | with:
54 | token: ${{ secrets.GITHUB_TOKEN }}
55 | branch: update/security-baseline
56 | title: "update detect-secrets baseline"
57 | commit-message: "chore: update detect-secrets baseline"
58 | body: Update versions of detect-secrets baseline, remember to check the file for unexpected additions.
59 | add-paths: |
60 | .secrets.baseline
61 |
--------------------------------------------------------------------------------
/.github/workflows/detect-secrets.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Detect Secrets"
4 |
5 | # https://github.com/Yelp/detect-secrets
6 | # https://github.com/reviewdog/action-detect-secrets
7 |
8 | on:
9 | # Disabled automated running as I'm not convinced in it's value.
10 | # pull_request:
11 | # branches:
12 | # - main
13 | # - master
14 | # - "!repo-sync/**"
15 | # - "!renovate/**"
16 | # - "!update/pre-commit-hooks/**"
17 | workflow_dispatch:
18 |
19 | permissions:
20 | contents: read
21 | issues: write
22 | pull-requests: write
23 | checks: write
24 |
25 | env:
26 | EXCLUDE_LINES: |
27 | --exclude-lines='CHECKSUM'
28 | --exclude-lines='MOCKING'
29 | --exclude-lines='GOOGLE_API_KEY'
30 | --exclude-lines='google-api-key'
31 | --exclude-lines='NODE_OPTIONS'
32 | --exclude-lines='http://localhost'
33 | --exclude-lines='#*tag=v'
34 | --exclude-lines='secrets*inherit'
35 | EXCLUDE_FILES: |
36 | --exclude-files='node_modules'
37 | --exclude-files='dist/*'
38 | --exclude-files='*secrets*baseline'
39 |
40 | jobs:
41 | detect-secrets:
42 | name: "Detect Secrets in Code"
43 | runs-on: ubuntu-22.04
44 | steps:
45 | - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
46 | # Detect if .secrets.baseline exists and if so set the variable BASELINE to '--baseline .secrets.baseline'
47 | - name: "Set BASELINE variable if baseline exists"
48 | id: baseline
49 | run: |
50 | if [ -f .secrets.baseline ]; then
51 | echo "::set-output name=baseline::--baseline .secrets.baseline"
52 | fi
53 |
54 | - name: run detect-secrets
55 | uses: reviewdog/action-detect-secrets@master
56 | with:
57 | github_token: ${{ secrets.github_token }}
58 | reporter: github-pr-review
59 | fail_on_error: "true"
60 | level: warning
61 | detect_secrets_flags: "${{ env.EXCLUDE_FILES }} ${{ env.EXCLUDE_LINES }} ${{ steps.baseline.outputs.baseline }}"
62 | #
63 | #
64 | # Allowlisting Secrets
65 | #
66 | # You can add exclude-lines as above that will apply to all repositories this runs against.
67 | #
68 | # It is also possible to disable detection for individual lines of code in case of false positives.
69 | # To do this, add a comment at the end of the line with text `pragma: allowlist secret`
70 | #
71 | # public_key: | # pragma: allowlist secret
72 | # gX69YO4CvBsVjzAwYxdG
73 | # yDd30t5+9ez31gKATtj4
74 | #
75 | # Or add a comment with the text `pragma: allowlist nextline secret` before the line.
76 | # pragma: allowlist nextline secret
77 | # public_key = gX69YO4CvBsVjzAwYxdG
78 | #
79 | # Baselines
80 | # - To create a baseline file allowlisting the current secrets, run the following command:
81 | # detect-secrets scan > .secrets.baseline
82 | # e.g. detect-secrets scan --exclude-lines 'CHECKSUM' --exclude-lines 'MOCKING' > .secrets.baseline
83 | #
84 | # - To update an existing baseline file, run the following command:
85 | # detect-secrets scan --baseline .secrets.baseline
86 | #
87 | # - To audit an existing baseline file, run the following command:
88 | # detect-secrets audit .secrets.baseline
89 | #
90 | # For more information see https://github.com/Yelp/detect-secrets#quickstart
91 |
--------------------------------------------------------------------------------
/.github/workflows/label-sync.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Sync Available Github Labels"
4 |
5 | on:
6 | workflow_dispatch:
7 | schedule:
8 | - cron: "30 4 * * 0"
9 | push:
10 | paths:
11 | - .github/config/labels.yml
12 | - .github/config/labeller.yml
13 | - .github/workflows/label-sync.yml
14 |
15 | permissions:
16 | pull-requests: write
17 | contents: read
18 | issues: write
19 |
20 | # One build per branch, cancel out of date builds
21 | concurrency:
22 | group: ${{ github.workflow }}-${{ github.ref }}
23 | cancel-in-progress: true
24 |
25 | jobs:
26 | sync-labels:
27 | name: Sync Github Labels
28 | runs-on: ubuntu-latest
29 | timeout-minutes: 10
30 | steps:
31 | - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
32 | - uses: EndBug/label-sync@da00f2c11fdb78e4fae44adac2fdd713778ea3e8 # v2
33 | with:
34 | delete-other-labels: true
35 | dry-run: false
36 | token: ${{ secrets.GITHUB_TOKEN }}
37 | config-file: .github/config/labels.yml
38 |
--------------------------------------------------------------------------------
/.github/workflows/lint-codeowners.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Lint CODEOWNERS"
4 | on:
5 | pull_request:
6 | paths:
7 | - "**/CODEOWNERS"
8 | - "!**/node_modules/**"
9 | branches:
10 | - main
11 | - master
12 |
13 | # One build per branch, cancel out of date builds
14 | concurrency:
15 | group: ${{ github.workflow }}-${{ github.ref }}
16 | cancel-in-progress: true
17 |
18 | permissions:
19 | issues: write
20 | pull-requests: write
21 | statuses: write
22 | checks: write
23 | contents: read
24 | security-events: read
25 |
26 | jobs:
27 | lint-codeowners:
28 | name: "Lint CODEOWNERS file"
29 | runs-on: ubuntu-24.04
30 | timeout-minutes: 10
31 | steps:
32 | - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
33 | - uses: mszostok/codeowners-validator@7f3f5e28c6d7b8dfae5731e54ce2272ca384592f # tag=v0.7.4
34 | with:
35 | checks: "files,duppatterns,syntax"
36 | experimental_checks: "avoid-shadowing"
37 | github_access_token: "${{ secrets.GITHUB_TOKEN }}"
38 |
--------------------------------------------------------------------------------
/.github/workflows/lint-docker.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Lint Docker"
4 |
5 | on:
6 | pull_request:
7 | paths:
8 | - "**/Dockerfile.*"
9 | - "**/docker-compose.*"
10 | - "!**/node_modules/**"
11 | branches:
12 | - main
13 | - master
14 | - "!repo-sync/**"
15 | - "!renovate/**"
16 | - "!update/pre-commit-hooks/**"
17 | workflow_dispatch:
18 |
19 | jobs:
20 | hadolint:
21 | name: "Lint Docker with hadolint"
22 | runs-on: ubuntu-22.04
23 | steps:
24 | - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
25 | - name: run tflint
26 | uses: reviewdog/action-hadolint@master
27 | with:
28 | github_token: ${{ secrets.github_token }}
29 | reporter: github-pr-review
30 | fail_on_error: "false"
31 | level: warning
32 | filter_mode: "nofilter" # Optional. Check all files, not just the diff
33 | # tflint_version: "v0.24.0" # Optional. Custom version, instead of latest
34 | # tflint_rulesets: "azurerm google" # Optional. Extra official rulesets to install
35 | # flags: "--module" # Optional. Add custom tflint flags
36 |
--------------------------------------------------------------------------------
/.github/workflows/lint-pr-actions-skip.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Lint Github Actions Workflows"
4 |
5 | # This is a gross hack to allow PRs that don't require a specific workflow to run (e.g. don't lint files not touched) by providing a positive status check in their place.
6 | # This workflow runs on an inverse match using the paths-ignore filter, so it will only run if the PR doesn't touch any of the paths that the other linting workflow does
7 | # The "name:" must match the name of the workflow it's skipping.
8 | # As recommended by Github - https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
9 |
10 | on:
11 | pull_request:
12 | types:
13 | - opened
14 | - edited
15 | - reopened
16 | - synchronize
17 | branches:
18 | - main
19 | - master
20 | - "!repo-sync/**"
21 | - "!renovate/**"
22 | - "!update/pre-commit-hooks/**"
23 | paths-ignore:
24 | - ".github/**"
25 | - "!**/node_modules/**"
26 |
27 | # One build per branch, cancel out of date builds
28 | concurrency:
29 | group: ${{ github.workflow }}-${{ github.ref }}-skipped
30 | cancel-in-progress: true
31 |
32 | jobs:
33 | lint-actions-workflows:
34 | name: Lint Actions Workflows
35 | runs-on: ubuntu-latest
36 | timeout-minutes: 5
37 | if: ${{ !github.event.pull_request.draft }}
38 | steps:
39 | - run: echo "This workflow is a placeholder for PRs that don't require linting of Github Actions workflows"
40 |
--------------------------------------------------------------------------------
/.github/workflows/lint-pr-actions.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Lint Github Actions Workflows"
4 | on:
5 | pull_request:
6 | types:
7 | - opened
8 | - edited
9 | - reopened
10 | - synchronize
11 | branches:
12 | - main
13 | - master
14 | - "!repo-sync/**"
15 | - "!renovate/**"
16 | - "!update/pre-commit-hooks/**"
17 | paths:
18 | - ".github/**"
19 | - "!**/node_modules/**"
20 |
21 | permissions:
22 | contents: read
23 | checks: write
24 | pull-requests: write
25 | issues: write
26 | statuses: write
27 | actions: read
28 |
29 | # One build per branch, cancel out of date builds
30 | concurrency:
31 | group: ${{ github.workflow }}-${{ github.ref }}
32 | cancel-in-progress: true
33 |
34 | jobs:
35 | lint-actions-workflows:
36 | name: Lint Actions Workflows
37 | runs-on: ubuntu-latest
38 | timeout-minutes: 10
39 | steps:
40 | - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab # v3
41 | - uses: reviewdog/action-actionlint@42de1e3a0f52d5f8b8390894de87bc603844e530 # v1
42 | with:
43 | fail_on_error: false
44 | level: error
45 | reporter: github-pr-review
46 | filter_mode: file
47 | env:
48 | REVIEWDOG_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
50 | SHELLCHECK_OPTS: "-e SC2086 -e SC2129 -e SC1091 -e SC2050 -e SC2194 -e SC2154 -e SC2157"
51 |
--------------------------------------------------------------------------------
/.github/workflows/lint-pr-markdown.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: Lint Markdown Files
4 |
5 | # https://github.com/reviewdog/action-markdownlint
6 |
7 | on:
8 | pull_request:
9 | paths:
10 | - "*.md"
11 | - "pages/**/*.md"
12 | - "posts/**/*.md"
13 | - "_pages/**/*.md"
14 | - "_posts/**/*.md"
15 | - "docs/**/*.md"
16 | - "documentation/**/*.md"
17 | - "!**/node_modules/**"
18 | branches:
19 | - main
20 | - master
21 | - "!repo-sync/**"
22 | - "!renovate/**"
23 | - "!update/pre-commit-hooks/**"
24 | workflow_dispatch:
25 |
26 | permissions:
27 | contents: read
28 | checks: write
29 | pull-requests: write
30 |
31 | # One build per branch, cancel out of date builds
32 | concurrency:
33 | group: ${{ github.workflow }}-${{ github.ref }}
34 | cancel-in-progress: true
35 |
36 | jobs:
37 | lint-markdown:
38 | name: Lint Markdown
39 | runs-on: ubuntu-22.04
40 | timeout-minutes: 10
41 | steps:
42 | - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
43 | - name: markdownlint
44 | uses: reviewdog/action-markdownlint@97e3df02fe1573d505a7b268046a44fa5409cbc3 # tag=v0
45 | with:
46 | github_token: ${{ secrets.GITHUB_TOKEN }}
47 | reporter: github-pr-review
48 | level: error
49 | filter_mode: added
50 | fail_on_error: false
51 | markdownlint_flags: "'**/*.md' --ignore node_modules --disable MD013"
52 |
--------------------------------------------------------------------------------
/.github/workflows/lint-shell.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Lint Shell Files"
4 |
5 | on:
6 | pull_request:
7 | paths:
8 | - "**/*.sh"
9 | - "**/*.rc"
10 | - "!**/node_modules/**"
11 | branches:
12 | - main
13 | - master
14 | - "!repo-sync/**"
15 | - "!renovate/**"
16 | - "!update/pre-commit-hooks/**"
17 | workflow_dispatch:
18 |
19 | jobs:
20 | shellcheck:
21 | name: lint-shell
22 | runs-on: ubuntu-24.04
23 | timeout-minutes: 10
24 | steps:
25 | - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
26 | - name: shellcheck
27 | uses: reviewdog/action-shellcheck@72365a51bf6476fe952a117c3ff703eb7775e40a # v1
28 | with:
29 | github_token: ${{ secrets.GITHUB_TOKEN }}
30 | reporter: github-pr-review
31 | path: "."
32 | pattern: |
33 | *.sh
34 | *.rc
35 | exclude: |
36 | ./.git/*
37 | ./**/node_modules/*
38 | check_all_files_with_shebangs: false
39 | fail_on_error: false
40 | level: warning
41 | shellcheck_flags: "--external-sources"
42 |
--------------------------------------------------------------------------------
/.github/workflows/lint-tf.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "tflint and tfsec"
4 |
5 | on:
6 | pull_request:
7 | paths:
8 | - "**/*.tf"
9 | - "**/*.tf.*"
10 | - "**/*.tfvars.*"
11 | - "**/*.terraform.*"
12 | - "!**/node_modules/**"
13 | branches:
14 | - main
15 | - master
16 | - "!repo-sync/**"
17 | - "!renovate/**"
18 | - "!update/pre-commit-hooks/**"
19 | workflow_dispatch:
20 |
21 | jobs:
22 | tflint:
23 | name: "Lint Terraform"
24 | runs-on: ubuntu-22.04
25 | steps:
26 | - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
27 | # Install latest Terraform manually as
28 | # Docker-based GitHub Actions are slow due to lack of caching
29 | # Note: Terraform is not needed for tflint
30 | - name: Install Terraform
31 | run: |
32 | curl -sSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -
33 | sudo apt-add-repository "deb [arch=amd64] https://apt.releases.hashicorp.com $(lsb_release -cs) main"
34 | sudo apt-get update && sudo apt-get install terraform -y
35 | # Run init to get module code to be able to use `--module`
36 | - name: Terraform init
37 | run: |
38 | terraform init
39 | - name: run tflint
40 | uses: reviewdog/action-tflint@master
41 | with:
42 | github_token: ${{ secrets.github_token }}
43 | reporter: github-pr-review
44 | fail_on_error: "false"
45 | level: warning
46 | filter_mode: "nofilter" # Optional. Check all files, not just the diff
47 | # tflint_version: "v0.24.0" # Optional. Custom version, instead of latest
48 | # tflint_rulesets: "azurerm google" # Optional. Extra official rulesets to install
49 | # flags: "--module" # Optional. Add custom tflint flags
50 |
51 | tfsec:
52 | name: "tfsec"
53 | runs-on: ubuntu-22.04
54 | steps:
55 | - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # tag=v3
56 | - name: Run tfsec
57 | uses: reviewdog/action-tfsec@master
58 | with:
59 | github_token: ${{ secrets.github_token }}
60 | level: warning
61 | reporter: github-pr-review
62 | filter_mode: nofilter # Check all files, not just the diff
63 | fail_on_error: false # Fail action if errors are found
64 | # flags: -tee # Add debug flag to reviewdog
65 | # tfsec_flags: "" # Optional
66 |
--------------------------------------------------------------------------------
/.github/workflows/mirror.yml:
--------------------------------------------------------------------------------
1 | name: Mirror repo to GitLab
2 |
3 | on: [push, delete, workflow_dispatch]
4 |
5 | jobs:
6 | to_gitlab:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - uses: actions/checkout@v3
10 | with:
11 | fetch-depth: 0
12 | - uses: pixta-dev/repository-mirroring-action@v1
13 | with:
14 | target_repo_url:
15 | git@gitlab.com:sammcj/zsh_bootstrap_mirror.git
16 | ssh_private_key:
17 | ${{ secrets.GITLAB_SSH_PRIVATE_KEY }}
18 |
--------------------------------------------------------------------------------
/.github/workflows/pr-labeller.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: "Pull Request Labeller"
4 | on:
5 | pull_request:
6 | types:
7 | - opened
8 | - edited
9 | - reopened
10 | - synchronize
11 | - ready_for_review
12 | branches:
13 | - main
14 | - master
15 |
16 | # One build per branch, cancel out of date builds
17 | concurrency:
18 | group: ${{ github.workflow }}-${{ github.ref }}
19 | cancel-in-progress: true
20 |
21 | permissions:
22 | issues: write
23 | pull-requests: write
24 | statuses: write
25 | checks: write
26 | contents: read
27 | security-events: read
28 |
29 | jobs:
30 | pr-labeller:
31 | name: "Pull Request Labeller"
32 | runs-on: ubuntu-latest
33 | timeout-minutes: 5
34 | if: ${{ !github.event.pull_request.draft }}
35 | steps:
36 | - uses: fuxingloh/multi-labeler@v2 # tag=v2
37 | id: pr-labeller
38 | with:
39 | github-token: ${{ secrets.GITHUB_TOKEN }}
40 | config-path: .github/config/labeller.yml
41 |
--------------------------------------------------------------------------------
/.github/workflows/pre-commit.yml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | name: pre-commit
4 |
5 | on:
6 | workflow_dispatch:
7 |
8 | permissions:
9 | contents: read
10 | pull-requests: write
11 | checks: write
12 |
13 | jobs:
14 | pre-commit:
15 | runs-on: ubuntu-latest
16 | steps:
17 | - uses: actions/checkout@0ad4b8fadaa221de15dcec353f45205ec38ea70b # v4
18 | - uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4
19 | with:
20 | node-version: 16
21 | - run: |
22 | npm install -g npm
23 | npm ci
24 | - uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5
25 | - uses: pre-commit/action@2c7b3805fd2a0fd8c1884dcaebf91fc102a13ecd # v3.0.1
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | # This is a generic .gitignore for JS/TS/Java/Python projects
4 |
5 | # Inverse matchs to ensure these aren't ignored
6 | !*.env.template
7 | !*.template.env
8 | !*.eslintrc.js
9 | !*.prettierrc.js
10 | !*.config.js
11 |
12 | # Typescipt and CDK
13 | **/*.cdk.staging
14 | **/*.d.ts
15 | **/*.tabl.json
16 | **/*.tsbuildinfo
17 | **/cdk.context.json
18 | **/cdk.out
19 |
20 | # NodeJS
21 | **/node_modules
22 | node_modules/**
23 |
24 | # Test and coverage output
25 | **/coverage/
26 | **/test-report.xml
27 | .coverage.*
28 | htmlcov/
29 | megalinter-reports/
30 |
31 | # Editors
32 | .project
33 | .settings
34 | .springBeans
35 | **/.favorites.json
36 | **/.idea
37 | **/.vscode
38 | **/*.Session.vim
39 | **/*.sw[a-z]
40 | **/*.vim
41 | **/*.zwc
42 | **/*~
43 |
44 | # OS generated files
45 | **/._*
46 | **/.AppleDouble
47 | **/.dccache
48 | **/.dropbox
49 | **/.dropbox.attr
50 | **/.dropbox.cache
51 | **/.DS_Store
52 | **/.DS_STORE
53 | **/.lnk
54 | **/.LSOverride
55 | **/$RECYCLE.BIN/
56 | **/Desktop.ini
57 | **/ehthumbs.db
58 | **/Thumbs.db
59 |
60 | # Files that might appear in the root of a volume
61 | **/.com.apple.timemachine.donotpresent
62 | **/.DocumentRevisions-V100
63 | **/.fseventsd
64 | **/.Spotlight-V100
65 | **/.TemporaryItems
66 | **/.Trashes
67 | **/.VolumeIcon.icns
68 |
69 | # Directories potentially created on remote AFP share
70 | **/.apdisk
71 | **/.AppleDB
72 | **/.AppleDesktop
73 | **/Network Trash Folder
74 | **/Temporary Items
75 |
76 | # Temp files
77 | **/.temp
78 | **/.tmp
79 | tmp/
80 |
81 | # Files that commonly contain secrets
82 | **/*.key
83 | **/*.pem
84 | **/*.pfx
85 | **/*.p12
86 | **/*.jks
87 | **/*.keystore
88 | **/*.pkcs12
89 | **/*.pkcs8
90 | **/*.pkpass
91 | **/*.secrets
92 |
93 | # git mu-repo
94 | **/.mu_repo
95 |
96 | # Local state files / misc
97 | .dynamodb/
98 | .eslintcache
99 | .env
100 | .fusebox/
101 | .grunt
102 | .local
103 | .lock-wscript
104 | .next
105 | .node_repl_history
106 | .npm
107 | .nuxt
108 | .nyc_output
109 | .serverless/
110 | .vuepress/dist
111 | .yarn-integrity
112 | *.seed
113 | *.tgz
114 | **/.BUILD_COMPLETED
115 | **/.cache
116 | **/.filesystem
117 | **/.LAST_BUILD
118 | **/.local-npm
119 | **/.nyc_output
120 | **/.nycrc
121 | **/.tools
122 | **/.webassets-cache
123 | **/*.lock
124 | **/*.lock.hcl
125 | **/*.pid
126 | **/db.sqlite3
127 | **/db.sqlite3-journal
128 | bower_components
129 | jspm_packages/
130 | lib-cov
131 |
132 | # Logs
133 | **/*.log
134 |
135 | # Build directories
136 | **/_build/
137 | **/dist
138 | build/
139 | out/
140 | target/
141 |
142 | # Python
143 | __pycache__/
144 | __pypackages__/
145 | .ipynb_checkpoints
146 | *$py.class
147 | celerybeat-schedule
148 | develop-eggs/
149 | dmypy.json
150 | eggs/
151 | ipython_config.py
152 | local_settings.py
153 | pip-delete-this-directory.txt
154 | pip-log.txt
155 | pip-wheel-metadata/
156 | venv
157 |
158 | # Jekyll
159 | _site
160 | .jekyll-cache
161 | .jekyll-metadata
162 | .sass-cache
163 | Gemfile.lock
164 |
165 | # Windows Installer files
166 | *.cab
167 | *.msi
168 | *.msm
169 | *.msp
170 |
171 | # Bootstrap files
172 | *private*.rc
173 | .gitconfig.private
174 | redo_aliases
175 |
176 | # Local .terraform directories
177 | **/.terraform/*
178 | *.tfstate
179 | *.tfstate.*
180 | override.tf
181 | override.tf.json
182 | *_override.tf
183 | *_override.tf.json
184 |
185 | # Docker
186 | **/docker-compose.override.y*ml
187 |
188 | # Hugo
189 | /public/
190 | /resources/_gen/
191 | /assets/jsconfig.json
192 | hugo_stats.json
193 | hugo.linux
194 | hugo.darwin
195 | /.hugo_build.lock
196 |
197 | # aws thing I'm trying
198 | update-aws-creds.sh
199 |
--------------------------------------------------------------------------------
/.gitignoreglobal:
--------------------------------------------------------------------------------
1 | # Editors
2 | **/.dccache
3 |
4 | **/.vscode/extensions.json
5 | **/.vscode/*
6 | **/.vscode
7 | .vscode/settings.json
8 | **/.vscode/settings.json
9 | .idea
10 | *.swp
11 | *.swo
12 | Session.vim
13 |
14 | # Apple
15 | .DS_STORE
16 |
17 | # misc
18 | .tmp
19 |
20 | # git mu-repo
21 | .mu_repo
22 |
23 | # node
24 | #node_modules
25 |
26 | # Trunk linter for vscode (can be included per repo)
27 | .trunk
28 |
29 | #AI
30 | .aider*
31 |
32 | #vscode
33 | **/.vscode
34 |
35 | #cmake
36 | CMakeFiles/*
37 | CMakeCache.txt
38 |
39 | **/*.log
40 | **/*.pem
41 | **/*.key
42 | **/*.crt
43 | **/*.csr
44 | **/*.cer
45 | **/*.pfx
46 | **/*.p12
47 |
48 | **/*.pdf
49 |
50 | DEV_TASKS.md
51 | DEVELOPMENT_TASKS.md
52 | DEV_PLAN.md
53 | DEVELOPMENT_PLAN.md
54 |
55 | **/.repomix
56 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | # See https://pre-commit.com for more information
4 | # See https://pre-commit.com/hooks.html for more hooks
5 |
6 | exclude: '(^themes.*|^static/files/.*)'
7 | repos:
8 | - repo: https://github.com/pre-commit/pre-commit-hooks
9 | rev: v4.4.0
10 | hooks:
11 | - id: trailing-whitespace
12 | - id: check-yaml
13 | files: \.yaml$, \.yml$
14 | types: [file]
15 | - id: check-case-conflict
16 | - id: check-json
17 | files: \.json$
18 | types: [file]
19 | - id: check-symlinks
20 | - id: check-toml
21 | files: \.toml$
22 | types: [file]
23 | - id: check-xml
24 | files: \.xml$
25 | types: [file]
26 | - id: check-merge-conflict
27 | - id: mixed-line-ending
28 | args: [ --fix=no ]
29 | - id: pretty-format-json
30 | files: '!htmltest_output/refcache.json$'
31 |
32 | - repo: https://github.com/pre-commit/mirrors-eslint
33 | rev: v8.29.0
34 | hooks:
35 | - id: eslint
36 | files: \.[jt]sx?$ # *.js, *.jsx, *.ts and *.tsx
37 | types: [file]
38 | additional_dependencies:
39 | - eslint-config-prettier@8.5.0
40 | - eslint-plugin-deprecation@1.3.2
41 | - eslint-plugin-import@2.26.0
42 | - eslint-plugin-unused-imports@2.0.0
43 |
44 | - repo: https://github.com/syntaqx/git-hooks
45 | rev: v0.0.17
46 | hooks:
47 | - id: shellcheck
48 | files: \.sh$
49 | types: [file]
50 | - id: shfmt
51 | files: \.sh$
52 | types: [file]
53 | args: ["-i", "2", "-d", "-l"]
54 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | #### THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW ####
2 |
3 | .ide
4 | .idea
5 | .vscode
6 | **/__pycache__
7 | **/__pypackages__
8 | **/.bin
9 | **/.DS_Store
10 | **/.env.*
11 | **/.git
12 | **/.out
13 | **/.venv
14 | **/*.log
15 | **/*.tmp
16 | **/build
17 | **/cdk.out
18 | **/coverage
19 | **/dist
20 | **/global.setup.ts
21 | **/htmlcov
22 | **/logs
23 | **/node_modules
24 | **/public
25 | **/temp
26 | **/tmp
27 | **/venv
28 |
29 | # Obsidian
30 | .obsidian
31 |
--------------------------------------------------------------------------------
/.prettierrc.js:
--------------------------------------------------------------------------------
1 | // THIS FILE IS MANAGED BY AN AUTOMATED WORKFLOW
2 |
3 | module.exports = {
4 | overrides: [
5 | {
6 | files: ['*.yml', '*.yaml'],
7 | options: { singleQuote: false },
8 | },
9 | {
10 | files: ['Makefile'],
11 | options: { useTabs: true },
12 | },
13 | ],
14 | tabWidth: 2,
15 | useTabs: false,
16 | singleQuote: true,
17 | trailingComma: 'all',
18 | semi: true,
19 | printWidth: 100,
20 | htmlWhitespaceSensitivity: 'ignore',
21 | };
22 |
--------------------------------------------------------------------------------
/.secrets.baseline:
--------------------------------------------------------------------------------
1 | {
2 | "version": "1.4.0",
3 | "plugins_used": [
4 | {
5 | "name": "ArtifactoryDetector"
6 | },
7 | {
8 | "name": "AWSKeyDetector"
9 | },
10 | {
11 | "name": "AzureStorageKeyDetector"
12 | },
13 | {
14 | "name": "Base64HighEntropyString",
15 | "limit": 4.5
16 | },
17 | {
18 | "name": "BasicAuthDetector"
19 | },
20 | {
21 | "name": "CloudantDetector"
22 | },
23 | {
24 | "name": "DiscordBotTokenDetector"
25 | },
26 | {
27 | "name": "GitHubTokenDetector"
28 | },
29 | {
30 | "name": "HexHighEntropyString",
31 | "limit": 3.0
32 | },
33 | {
34 | "name": "IbmCloudIamDetector"
35 | },
36 | {
37 | "name": "IbmCosHmacDetector"
38 | },
39 | {
40 | "name": "JwtTokenDetector"
41 | },
42 | {
43 | "name": "KeywordDetector",
44 | "keyword_exclude": ""
45 | },
46 | {
47 | "name": "MailchimpDetector"
48 | },
49 | {
50 | "name": "NpmDetector"
51 | },
52 | {
53 | "name": "PrivateKeyDetector"
54 | },
55 | {
56 | "name": "SendGridDetector"
57 | },
58 | {
59 | "name": "SlackDetector"
60 | },
61 | {
62 | "name": "SoftlayerDetector"
63 | },
64 | {
65 | "name": "SquareOAuthDetector"
66 | },
67 | {
68 | "name": "StripeDetector"
69 | },
70 | {
71 | "name": "TwilioKeyDetector"
72 | }
73 | ],
74 | "filters_used": [
75 | {
76 | "path": "detect_secrets.filters.allowlist.is_line_allowlisted"
77 | },
78 | {
79 | "path": "detect_secrets.filters.common.is_baseline_file",
80 | "filename": ".secrets.baseline"
81 | },
82 | {
83 | "path": "detect_secrets.filters.common.is_ignored_due_to_verification_policies",
84 | "min_level": 2
85 | },
86 | {
87 | "path": "detect_secrets.filters.heuristic.is_indirect_reference"
88 | },
89 | {
90 | "path": "detect_secrets.filters.heuristic.is_likely_id_string"
91 | },
92 | {
93 | "path": "detect_secrets.filters.heuristic.is_lock_file"
94 | },
95 | {
96 | "path": "detect_secrets.filters.heuristic.is_not_alphanumeric_string"
97 | },
98 | {
99 | "path": "detect_secrets.filters.heuristic.is_potential_uuid"
100 | },
101 | {
102 | "path": "detect_secrets.filters.heuristic.is_prefixed_with_dollar_sign"
103 | },
104 | {
105 | "path": "detect_secrets.filters.heuristic.is_sequential_string"
106 | },
107 | {
108 | "path": "detect_secrets.filters.heuristic.is_swagger_file"
109 | },
110 | {
111 | "path": "detect_secrets.filters.heuristic.is_templated_secret"
112 | }
113 | ],
114 | "results": {},
115 | "generated_at": "2022-10-17T02:06:04Z"
116 | }
117 |
--------------------------------------------------------------------------------
/.vimrc:
--------------------------------------------------------------------------------
1 | " vi: ft=vimrc
2 |
3 | "" Vundle begin
4 | " :PluginList - lists configured plugins
5 | " :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate
6 | " :PluginSearch foo - searches for foo; append `!` to refresh local cache
7 | " :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal
8 |
9 | " Install Vundle if it's not already
10 | let vundleInstalled=1
11 | let vundle_readme=expand('~/.vim/bundle/Vundle.vim/README.md')
12 | if !filereadable(vundle_readme)
13 | echo "Installing Vundle.."
14 | echo ""
15 | silent !mkdir -p ~/.vim/bundle
16 | silent !git clone https://github.com/VundleVim/Vundle.vim.git ~/.vim/bundle/Vundle.vim
17 | let vundleInstalled=0
18 | endif
19 | set rtp+=~/.vim/bundle/Vundle.vim/
20 | call vundle#rc()
21 |
22 | " let Vundle manage Vundle, required
23 | Plugin 'VundleVim/Vundle.vim'
24 | if vundleInstalled == 0
25 | echo "Installing Bundles, please ignore key map error messages"
26 | echo ""
27 | :PluginInstall
28 | endif
29 |
30 | set nocompatible
31 | filetype off
32 | set rtp+=~/.vim/bundle/Vundle.vim
33 |
34 | " Plugins begin
35 | call vundle#begin()
36 | Plugin 'VundleVim/Vundle.vim'
37 | Plugin 'tpope/vim-fugitive'
38 | Plugin 'airblade/vim-gitgutter'
39 | Plugin 'jonhiggs/tabline.vim'
40 | Plugin 'scrooloose/syntastic'
41 | Plugin 'dracula/vim', { 'name': 'dracula' }
42 | Plugin 'github/copilot.vim'
43 | "Plugin 'preservim/nerdtree'
44 | "Plugin 'tiagofumo/vim-nerdtree-syntax-highlight'
45 | Plugin 'ryanoasis/vim-devicons'
46 | Plugin 'robertbasic/vim-hugo-helper'
47 | Plugin 'junegunn/fzf', { 'do': { -> fzf#install() } }
48 | Plugin 'nanotee/zoxide.vim'
49 | call vundle#end()
50 | " Plugins END
51 | filetype plugin on " required
52 | "" Vundle END
53 |
54 |
55 | "" SETTINGS BEGIN
56 |
57 | set autochdir " change to directory of current file.
58 | set backspace=indent,eol,start " allow backspace to delete before insert point.
59 | set listchars=tab:▸\ ,eol:$ " configure the invisible characters.
60 | set modeline " make sure the modeline is used if it exists.
61 | set mouse=a
62 | set nocursorline " disabled because it makes keyboard repeat too slow.
63 | set ruler
64 | set visualbell
65 | set scrolloff=8 " start scrolling before reaching the bottom.
66 | set rtp+=/opt/homebrew/bin/fzf
67 | set encoding=UTF-8
68 | set laststatus=2 " always show status line.
69 | set magic " For regular expressions turn magic on
70 | set showmatch " Show matching brackets when text indicator is over them
71 | set ignorecase " Ignore case when searching
72 | set hlsearch " Highlight search results
73 | set incsearch " Makes search act like search in modern browsers
74 | set autoread " Set to auto read when a file is changed from the outside
75 | set wildmenu " Turn on wildmenu
76 | au FocusGained,BufEnter * checktime
77 |
78 | "set nofoldenable
79 | "set nowrap
80 |
81 | "" Spellchecking
82 | set spelllang=en_uk
83 |
84 |
85 | "" Filetypes
86 | au BufRead,BufNewFile *.md set filetype=markdown
87 | set ffs=unix " Use Unix as the standard file type
88 |
89 | "" Theme begin
90 | set background=dark
91 | if (has("termguicolors"))
92 | set termguicolors
93 | endif
94 | set t_Co=256 " enable 256 colours.
95 | syntax on
96 | syntax enable
97 | colorscheme dracula
98 | "" Theme end
99 |
100 | "" nerdtree begin
101 | "nnoremap n :NERDTreeFocus
102 | "nnoremap :NERDTree
103 | "nnoremap :NERDTreeToggle
104 | "nnoremap :NERDTreeFind
105 | "let NERDTreeShowHidden=1
106 | "let NERDTreeIgnore = ['\.pyc$', '__pycache__', 'node_modules']
107 | " Start NERDTree. If a file is specified, move the cursor to its window.
108 | "autocmd StdinReadPre * let s:std_in=1
109 | "autocmd VimEnter * NERDTree | if argc() > 0 || exists("s:std_in") | wincmd p | endif
110 | " If another buffer tries to replace NERDTree, put it in the other window, and bring back NERDTree.
111 | "autocmd BufEnter * if bufname('#') =~ 'NERD_tree_\d\+' && bufname('%') !~ 'NERD_tree_\d\+' && winnr('$') > 1 |
112 | " \ let buf=bufnr() | buffer# | execute "normal! \w" | execute 'buffer'.buf | endif
113 | " Exit Vim if NERDTree is the only window remaining in the only tab.
114 | "autocmd BufEnter * if tabpagenr('$') == 1 && winnr('$') == 1 && exists('b:NERDTree') && b:NERDTree.isTabTree() | quit | endif
115 | "" nerdtree END
116 |
117 | " airline settings
118 | let g:airline_theme='dark'
119 | let g:airline#extensions#tabline#enabled = 1
120 | let g:airline_powerline_fonts = 1
121 |
122 | "" Tabs / Spacing
123 | " Default to soft tabs, 2 spaces
124 | set shiftwidth=2
125 | set showtabline=2
126 | set tabstop=2
127 | set expandtab
128 | set sw=2
129 | set sts=2
130 | " Except for Makefiles
131 | autocmd FileType make set noexpandtab shiftwidth=8 softtabstop=0
132 | " Except for Python
133 | autocmd FileType python set noexpandtab shiftwidth=4 softtabstop=0
134 | " Dont add comments
135 | autocmd FileType * setlocal formatoptions-=c formatoptions-=r formatoptions-=o
136 |
137 |
138 | "" Syntastic
139 | set statusline+=%#warningmsg#
140 | set statusline+=%{SyntasticStatuslineFlag()}
141 | set statusline+=%*
142 | let g:syntastic_always_populate_loc_list = 1
143 | let g:syntastic_auto_loc_list = 1
144 | let g:syntastic_check_on_open = 1
145 | let g:syntastic_aggregate_errors = 1
146 | let g:syntastic_check_on_wq = 0
147 | let g:syntastic_exit_checks = 0
148 |
149 | "" GitGutter
150 | let g:gitgutter_eager = 1
151 | let g:gitgutter_realtime = 1
152 | let g:gitgutter_sign_column_always = 0
153 | let g:gitgutter_sign_added = '█'
154 | let g:gitgutter_sign_modified = '█'
155 | let g:gitgutter_sign_modified_removed = '▁'
156 | let g:gitgutter_sign_removed = '▁'
157 | let g:gitgutter_sign_removed_first_line = '▔'
158 | autocmd BufEnter * GitGutterAll
159 | autocmd ShellCmdPost * GitGutterAll
160 |
161 | "" KEY MAPPINGS
162 |
163 | " Map leader key
164 | let mapleader = ","
165 |
166 | " Move between panes with ctrl+arrow
167 | map
168 | map
169 | map
170 | map
171 |
172 | " Fix Delete (backspace) on Mac OS X
173 | set backspace=2
174 |
175 | " Do not attempt to fix style on paste
176 | nnoremap p "+p
177 |
178 | " When you press r you can search and replace the selected text
179 | vnoremap r :call VisualSelection('replace', '')
180 |
181 | " Pressing ,ss will toggle and untoggle spell checking
182 | map ss :setlocal spell!
183 | map :setlocal spell! spell?
184 |
185 | " Shortcuts using
186 | map sn ]s
187 | map sp [s
188 | map sa zg
189 | map s? z=
190 |
191 | " Fast reload of vimrc
192 | map e :e! ~/.vimrc
193 | autocmd! bufwritepost ~/.vimrc source ~/.vimrc
194 |
195 | " Bash like keys for the command line
196 | cnoremap
197 | cnoremap
198 | cnoremap
199 | cnoremap
200 | cnoremap
201 |
202 | " Tab Shortcuts
203 | map :tabnext
204 | map :tabprevious
205 |
206 | " Setup the F Key maps.
207 | set pastetoggle=
208 | map :set hlsearch!
209 |
210 | " Redraw Screen
211 | map :GitGutterAll:redraw!
212 |
213 | " Fix current word with first spelling suggestion.
214 | map Z 1z=
215 |
216 | " Enable incremental search
217 | set is hls
218 |
219 |
220 | "" FUNCTIONS
221 | " RemoveFancyCharacters COMMAND
222 | function! RemoveFancyCharacters()
223 | let typo = {}
224 | let typo["“"] = '"'
225 | let typo["”"] = '"'
226 | let typo["‘"] = "'"
227 | let typo["’"] = "'"
228 | let typo["–"] = '--'
229 | let typo["—"] = '---'
230 | let typo["…"] = '...'
231 | :exe ":%s/".join(keys(typo), '\|').'/\=typo[submatch(0)]/ge'
232 | endfunction
233 | command! RemoveFancyCharacters :call RemoveFancyCharacters()
234 |
--------------------------------------------------------------------------------
/.whitesource:
--------------------------------------------------------------------------------
1 | {
2 | "scanSettings": {
3 | "baseBranches": []
4 | },
5 | "checkRunSettings": {
6 | "vulnerableCheckRunConclusionLevel": "failure",
7 | "displayMode": "diff",
8 | "useMendCheckNames": true
9 | },
10 | "issueSettings": {
11 | "minSeverityLevel": "MEDIUM",
12 | "issueType": "DEPENDENCY"
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/0-paths.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | # homebrew
4 | export PATH="/opt/homebrew/bin:/usr/local/bin:/opt/homebrew/sbin:/opt/homebrew/opt/gnu-getopt/bin:${PATH}"
5 |
6 | # my scripts
7 | export PATH="${PATH}:${HOME}/Library/Mobile\ Documents/com\~apple\~CloudDocs/Dropbox\ Import/bin:${HOME}/git/scripts:${HOME}/.local/bin:${HOME}/bin"
8 |
9 | # Golang
10 | export PATH="${PATH}:${HOME}/go/bin"
11 |
12 | # macOS Sonoma fix
13 | export PATH="/sbin:${PATH}"
14 |
15 | # added by Miniconda3 installer
16 | export PATH="/Users/samm/miniconda3/bin:${PATH}"
17 |
18 | # cargo
19 | export PATH="${HOME}/.cargo/bin:${PATH}"
20 |
21 | ### Kubernetes / k8s related exports ###
22 |
23 | # Krew Kubernetes plugin manager
24 | # export PATH="${KREW_ROOT:-$HOME/.krew}/bin:${PATH}"
25 |
26 | #source $HOME/.helm/helmenv.sh
27 |
28 | function conda_init() {
29 |
30 | # >>> conda initialize >>>
31 | # !! Contents within this block are managed by 'conda init' !!
32 | __conda_setup="$('/opt/homebrew/Caskroom/mambaforge/base/bin/conda' 'shell.zsh' 'hook' 2>/dev/null)"
33 | if [ $? -eq 0 ]; then
34 | eval "$__conda_setup"
35 | # else
36 | # if [ -f "/opt/homebrew/Caskroom/mambaforge/base/etc/profile.d/conda.sh" ]; then
37 | # # . "/opt/homebrew/Caskroom/mambaforge/base/etc/profile.d/conda.sh" # commented out by conda initialize
38 | # else
39 | # # export PATH="/opt/homebrew/Caskroom/mambaforge/base/bin:$PATH" # commented out by conda initialize
40 | # fi
41 | fi
42 | unset __conda_setup
43 | # <<< conda initialize <<<
44 |
45 | }
46 |
47 | # pnpm
48 | export PNPM_HOME="/Users/samm/Library/pnpm"
49 | case ":$PATH:" in
50 | *":$PNPM_HOME:"*) ;;
51 | *) export PATH="$PNPM_HOME:$PATH" ;;
52 | esac
53 | # pnpm end
54 |
55 | # [ -f ~/.inshellisense/key-bindings.zsh ] && source ~/.inshellisense/key-bindings.zsh
56 | export PATH="/opt/homebrew/opt/llvm/bin:$PATH"
57 | export PATH="/opt/homebrew/opt/qt@5/bin:$PATH"
58 | export PATH="/opt/homebrew/opt/openjdk/bin:$PATH"
59 |
60 | # to fix Library not loaded: @rpath/libllama.dylib
61 | export PATH="${HOME}/git/llama.cpp/bin:$PATH"
62 |
--------------------------------------------------------------------------------
/1-zgen.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | autoload -Uz compinit -C
4 | compinit -C
5 | autoload -U +X bashcompinit
6 | bashcompinit
7 |
8 | # load zgen
9 | source "${HOME}/.zgen/zgen.zsh"
10 |
11 | export ZGEN_RESET_ON_CHANGE="${HOME}/.zshrc"
12 | export ZSH_DISABLE_AUTO_UPDATE=7 # Only check for oh-my-zsh updates every 7 days
13 |
14 | # start compdef
15 | # compinit -u
16 |
17 | if ! zgen saved; then
18 | # echo "Creating a zgen save"
19 |
20 | ## load omz plugins ##
21 | # zgen oh-my-zsh
22 | zgen oh-my-zsh plugins/gitfast
23 | zgen oh-my-zsh plugins/command-not-found
24 | zgen oh-my-zsh plugins/fzf # https://github.com/ohmyzsh/ohmyzsh/issues/12412
25 | # zgen oh-my-zsh plugins/fnm
26 | # zgen oh-my-zsh plugins/docker
27 | zgen oh-my-zsh plugins/docker-compose
28 | zgen oh-my-zsh plugins/aws
29 | zgen oh-my-zsh plugins/colored-man-pages
30 | # plugins/macos - throwing compdef errors
31 | # zgen oh-my-zsh plugins/nmap
32 | # zgen oh-my-zsh plugins/gh
33 |
34 | ## load normal plugins ##
35 | zgen loadall </dev/null)" != "1" ]]; then
10 | # # ref=$(command git symbolic-ref HEAD 2>/dev/null) || - ref=$(command git rev-parse --short HEAD 2>/dev/null) || return 0
11 | # # echo "$ZSH_THEME_GIT_PROMPT_PREFIX${ref#refs/heads/}$(parse_git_dirty)$ZSH_THEME_GIT_PROMPT_SUFFIX"
12 | # echo "${ZSH_THEME_GIT_PROMPT_PREFIX}${ref#refs/heads/}${ZSH_THEME_GIT_PROMPT_SUFFIX}"
13 | # # fi
14 | # }
15 |
16 | # show git changes on the command line
17 | autoload -Uz vcs_info add-zsh-hook
18 | setopt prompt_subst
19 | add-zsh-hook precmd vcs_info
20 |
21 | zstyle ':vcs_info:*' enable git
22 | precmd() {
23 | vcs_info
24 | }
25 |
26 | # Enable checking for (un)staged changes, enabling use of %u and %c
27 | zstyle ':vcs_info:*' check-for-changes true
28 | zstyle ':vcs_info:git:*' formats '[%b%u%c]'
29 | zstyle ':vcs_info:git:*' actionformats '[%b|%a%u%c]'
30 | # add the number of unstaged/staged changes to the prompt
31 | zstyle ':vcs_info:git:*' enable git
32 |
33 | # %s - The current version control system, like git or svn.
34 | # %r - The name of the root directory of the repository
35 | # %S - The current path relative to the repository root directory
36 | # %b - Branch information, like master
37 | # %m - In case of Git, show information about stashes
38 | # %u - Show unstaged changes in the repository
39 | # %c - Show staged changes in the repository
40 |
41 | # %{$(tput setaf 60)%}%m # this is the machine IP/hostname
42 |
43 | # Right hand side of the prompt line
44 | # RPROMPT="%{$(tput setaf 177)%}\$vcs_info_msg_0_"
45 |
46 | # PROMPT="%{$(tput setaf 60)%}%m %{$(tput setaf 105)%}%~${vcs_info_msg_0_}%{$(tput sgr0)%} %(?..[%?] )$ "
47 |
48 | # %{$(tput setaf 177)%}\$vcs_info_msg_0_ # means pink git information
49 |
50 | PROMPT="%{$(tput setaf 177)%}\$vcs_info_msg_0_ %{$(tput setaf 105)%}%~${vcs_info_msg_0_}%{$(tput sgr0)%} %(?..[%?] )$ "
51 |
--------------------------------------------------------------------------------
/14-source-files.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | # Node / Javascript
4 | # Note: If this doesn't work, make sure you've cleaned up nvm directories and related PATHs
5 | eval "$(/opt/homebrew/bin/fnm env --use-on-cd --corepack-enabled)"
6 |
7 | #saml2aws
8 | eval "$(saml2aws --completion-script-zsh)"
9 |
10 | #asdf
11 | # . /opt/homebrew/opt/asdf/libexec/asdf.sh
12 |
13 | #pyenv
14 | export PYENV_ROOT="$HOME/.pyenv"
15 | command -v pyenv >/dev/null || export PATH="$PYENV_ROOT/bin:$PATH"
16 | eval "$(pyenv init -)"
17 |
18 | . ~/.venv/bin/activate
19 |
20 | # # pnpm
21 | # export PNPM_HOME="/Users/samm/Library/pnpm"
22 | # case ":$PATH:" in
23 | # *":$PNPM_HOME:"*) ;;
24 | # *) export PATH="$PNPM_HOME:$PATH" ;;
25 | # esac
26 | # pnpm end
27 |
28 | #nav
29 | # source "${HOME}/.nav/nav.zsh"
30 | # nav bindkeys
31 |
32 | #cargo
33 | if [ -f "$HOME/.cargo/env" ]; then
34 | . "$HOME/.cargo/env"
35 | fi
36 |
--------------------------------------------------------------------------------
/15-events.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | # Events - things that are triggered by other things
4 |
5 | # ### remindme ###
6 | # REMINDME_PATH="${HOME}/git/scripts/remindme.sh"
7 | # COMMAND_NAME="remind"
8 | # #
9 | # # Configure directories to check for reminders
10 | # # shellcheck disable=SC2088
11 | # CHECK_REMINDER_DIRECTORIES=("${HOME}/git" "~/git" "${HOME}/Documents" "~/Downloads" "~/Documents")
12 | # #
13 | # # Function to check if the current directory is in the list of directories to check
14 | # should_check_reminders() {
15 | # local dir
16 | # for dir in "${CHECK_REMINDER_DIRECTORIES[@]}"; do
17 | # if [[ "${PWD/#$HOME/~}" == "$dir" ]]; then
18 | # return 0
19 | # fi
20 | # done
21 | # return 1
22 | # }
23 |
24 | # # Function to check for reminders related to the current directory
25 | # check_reminders_on_chdir() {
26 | # if should_check_reminders; then
27 | # local reminders
28 | # reminders=$(source "$REMINDME_PATH" -l | while IFS= read -r line; do
29 | # if [[ "$line" == *"$PWD"* ]]; then
30 | # echo "${line#*= }"
31 | # fi
32 | # done)
33 | # if [ -n "$reminders" ]; then
34 | # echo "Reminders for this directory:"
35 | # echo "$reminders"
36 | # echo "Use \"${COMMAND_NAME} -d \" to mark a reminder as completed."
37 | # fi
38 | # fi
39 | # }
40 |
41 | # # Call the check_reminders_on_chdir function whenever you change directories
42 | # autoload -U add-zsh-hook
43 | # add-zsh-hook chpwd check_reminders_on_chdir
44 |
45 | # # Define the reminder_me function for convenience
46 | # remind() {
47 | # source "$REMINDME_PATH" "$@"
48 | # }
49 |
50 | ### END remindme ###
51 |
--------------------------------------------------------------------------------
/16-fabric.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 | #
3 | # Reminder: you can save with fabric by piping text to save, e.g. pbpaste|save
4 | #
5 |
--------------------------------------------------------------------------------
/3-location_specifics.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148
2 |
3 | case $HOST in
4 | samm-digio*)
5 | # placeholder
6 | ;;
7 | Sams-Air*)
8 | # placeholder
9 | ;;
10 | *)
11 | # placeholder for all
12 | ;;
13 | esac
14 |
--------------------------------------------------------------------------------
/4-aliases.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | #TODO: cleanup this, move stuff out of Dropbox\ Import
4 | THIS_DIRECTORY="/Users/samm/Library/Mobile Documents/com~apple~CloudDocs/Dropbox Import/dotfiles/shell_config"
5 |
6 | ### Aliases ###
7 |
8 | # Directory Jumps
9 | alias d="cd ~/Downloads && ls -ltarh"
10 | alias icloud_drive="cd ~/Library/Mobile\ Documents/com\~apple\~CloudDocs/"
11 |
12 | # IDE Projects
13 | #shellcheck disable=SC2139
14 | alias zshconfig="code '${THIS_DIRECTORY}'"
15 | alias zzshconfig="zed '${THIS_DIRECTORY}'"
16 | # shellcheck disable=SC2139
17 | alias wezedit="code '${HOME}'/.config/wezterm/wezterm.lua"
18 | #shellcheck disable=SC2139
19 | alias zshconfigd="cd '${THIS_DIRECTORY}'"
20 |
21 | alias app_store_upgrade_mmas="mas upgrade"
22 | alias go_update_all="gup update"
23 | alias pa="pip freeze --local | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U"
24 |
25 | # Second homebrew install with x86 arch
26 | alias brew86="arch -x86_64 /usr/local/homebrew/bin/brew"
27 |
28 | # Git
29 | # alias gbd="git branch -d" Moved to functions
30 | #alias gitrb='for branch in $(git branch -r --merged | grep -v HEAD); do echo -e $(git show --format="%ci %cr %an" "$branch" | head -n 1) \\t$branch; done | sort -r'
31 | alias amend="git commit --amend --no-edit"
32 | alias bfg="java -jar ~/bin/bfg.jar"
33 | alias ch="commit-hotfix"
34 | alias cj="commit-jira"
35 | alias commit="git commit -m"
36 | alias git-cleanup-repack="bfg"
37 | alias git-delete-local-branches="git fetch --all --prune"
38 | alias git-delete-remote-branch="git push origin --delete"
39 | alias git-my-recent-branches="git reflog show --pretty=format:'%gs ~ %gd' --date=relative | grep 'checkout:' | grep -oE '[^ ]+ ~ .*' | awk -F~ '!seen[$1]++' | head -n 10 | awk -F' ~ HEAD@{' '{printf(" %12s:\t%s\n", substr($2, 1, length($2) - 1), $1)}'"
40 | alias git-remove-untracked-branches="git fetch -p; git branch --merged main | egrep -v '^\s*\*?\s*main$' | xargs -r git branch -d" #and re-run with -D if required
41 | alias gitamendrebase="GIT_SEQUENCE_EDITOR=\"sed -i -re 's/^pick /e /'\"; git rebase -i"
42 | alias gitclean="git fetch -p; git remote prune origin; git repack -a -d -f --max-pack-size=10g --depth=500 --window=250; git gc --aggressive"
43 | alias gitday="git diff HEAD 'HEAD@{1 day ago}'"
44 | alias gitdiff="git diff --color-words --color=always"
45 | alias githist="git log --graph --pretty=oneline --abbrev-commit"
46 | alias github-runs="github_actions_watcher"
47 | alias gitlast="git add .;git commit --amend -C HEAD ; git push"
48 | alias gitmonth="git diff HEAD 'HEAD@{1 month ago}'"
49 | alias gitupdateallrepos="find . -name .git -type d | xargs -n1 -P4 -I% git --git-dir=% --work-tree=%/.. fetch --all --recurse-submodules"
50 | alias gitweek="git diff HEAD 'HEAD@{1 week ago}'"
51 | alias gitwip="git add .; git commit -n -m 'minor updates'; git push"
52 | alias hotfix-checkout="checkout-hotfix"
53 | alias hotfix-commit="commit-hotfix"
54 | alias hotfix="checkout-hotfix"
55 | alias L="ls -ltarh"
56 | alias j="checkout-jira"
57 | alias jira-checkout="checkout-jira"
58 | alias jira-commit="commit-jira"
59 | alias jira="checkout-jira"
60 | alias main="git checkout main && git pull"
61 | alias minor="git commit -m 'chore: minor tweaks [skip ci]"
62 | ### Short git aliases
63 | alias add="git add ."
64 | alias c="git commit -m"
65 | alias h="hugo serve --disableFastRender --buildDrafts"
66 | alias m="git checkout main"
67 | alias p="git pull"
68 | alias P="git push"
69 |
70 | # GNU tools
71 | alias sed="gsed"
72 |
73 | # Find commands I type often so I can alias them
74 | alias typeless='history n 20000 | sed "s/.* //" | sort | uniq -c | sort -g | tail -n 100'
75 |
76 | # alias jpgcompress='echo convert INPUTFILE -sampling-factor 4:2:0 -strip -interlace JPEG -colorspace sRGB OUTPUTFILE'
77 |
78 | # NPM / Yarn
79 | # Check for unused packages
80 | alias npm-check-unused="npx npm-check"
81 |
82 | # Misc
83 | alias farsync='rsync -xrhm --numeric-ids -e "ssh -T -c aes128-gcm@openssh.com -o Compression=no" -x --partial --progress' #TODO: fix bug where this overwrites file name
84 | alias arcfarsync="rsync -rhm --numeric-ids -e 'ssh -T -c arcfour -o Compression=no -x' --partial --progress"
85 | alias tree="tree -ChF"
86 | alias mtr="sudo mtr"
87 | alias iftop="sudo iftop -i en0"
88 | alias ls='gls --color=auto -AHhF --group-directories-first'
89 | alias updatedb='sudo /usr/libexec/locate.updatedb'
90 | alias netwatch='lsof -i'
91 | alias flushdns='sudo discoveryutil udnsflushcaches'
92 | alias httpserver='sudo python3 -m http.server 80'
93 | alias cc='colorize.py'
94 | alias rmid="ssh-keygen -R"
95 | # alias aria="aria2c -s 5 -j 5 -x 5 -c --enable-http-pipelining=true --http-accept-gzip=true --max-connection-per-server=10 --content-disposition-default-utf8=true"
96 | # alias a=aria
97 | alias dmesg="dmesg -LT"
98 | alias cpuinfo="sysctl -n machdep.cpu.brand_string"
99 | # alias psql="/Applications/Postgres.app/Contents/Versions/latest/bin/psql"
100 | alias fastmail_you_there_bro="openssl s_client -connect imap.fastmail.com:993 -crlf"
101 | alias zmv='noglob zmv -W'
102 | alias mc='yazi'
103 |
104 | # MacOS shortcuts
105 | # alias delete-all-local-snapshots='for d in $(tmutil listlocalsnapshotdates | grep -v "Snapshot dates for all disks"); do sudo tmutil deletelocalsnapshots $d; done'
106 | alias clear-download-history="sqlite3 ~/Library/Preferences/com.apple.LaunchServices.QuarantineEventsV* 'delete from LSQuarantineEvent'"
107 | alias screenshots-jpg='defaults write com.apple.screencapture type JPG'
108 | alias screenshots-png='defaults write com.apple.screencapture type PNG'
109 |
110 | # Kubes
111 | alias kubes-busybox='kubectl run -i --tty loader --image=busybox /bin/sh'
112 | alias k='kubectl'
113 |
114 | # VSC
115 | alias code='/Applications/Visual\ Studio\ Code.app/Contents/Resources/app/bin/code'
116 |
117 | # Merge two files with diff
118 | alias merge='diff --line-format %L'
119 |
120 | # Terraform
121 | alias t='terraform'
122 | alias tf='terraform'
123 | alias tfn='terraform'
124 |
125 | # DNS benchmarking using https://github.com/redsift/dnstrace
126 | alias dnsbenchmark='dnstrace -n 10 -c 10 --server 192.168.0.1 --recurse microsoft.com'
127 |
128 | # Docker
129 | # podman machine init --cpus=3 --disk-size=30 --memory=3192 podman-machine-default
130 | # colima start --cpu 3 --memory 3 --disk 30 --mount $HOME/.vault-tokens:w
131 | # ln -s /usr/local/bin/colima /usr/local/bin/docker
132 | # alias docker='colima'
133 |
134 | alias youtube-dl='yt-dlp'
135 |
136 | alias nvm='echo I think you meant FNM'
137 |
138 | # node / typescript
139 | # update all packages in package.json except @types/node
140 | alias ncu='ncu -u \!@types/node --deep'
141 |
142 | # nice JSON graphing / visualisation tool
143 | alias json-graph='colima start && docker run -p 8888:8080 jsonvisio && open http://localhost:8888/editor'
144 |
145 | # Backblaze
146 | alias backblaze_edit='code /Library/Backblaze.bzpkg/bzdata/bzexcluderules_editable.xml'
147 |
148 | alias scripts='cd ~/git/scripts'
149 | alias nzb="cd ~/git/sammcj/nzb-docker"
150 | alias nzbdocker="open vscode://vscode-remote/ssh-remote+nas/root/git/nzb-docker/.vscode/nas-docker.code-workspace"
151 |
152 | ### Suffix Aliases ###
153 |
154 | # VSCode
155 | alias -s {ts,json,yaml,css,yml}=code
156 |
157 | # Firefox
158 | alias -s html=/Applications/Firefox.app
159 |
160 | # VLC
161 | alias -s {mkv,mp4,m4v,avi,mpg,mpeg}=vlc
162 |
163 | # Preview
164 | alias -s {jpg,jpeg,png,gif,bmp,ico,svg,webp}=open
165 |
166 | # Glow for Markdown
167 | alias -s md=glow
168 |
169 | # Networking
170 | alias ip6="curl -s 6.ipquail.com/ip"
171 | alias ip4="curl -s 4.ipquail.com/ip"
172 | alias ptr6="curl -s 6.ipquail.com/ptr"
173 | alias ptr4="curl -s 4.ipquail.com/ptr"
174 |
175 | # Find files modified today
176 | alias modified-today="mdfind 'kMDItemFSContentChangeDate>\$time.today'"
177 |
178 | # If running on macOS replace lsusb with ioreg -p IOUSB -l -w 0
179 | if [[ "$OSTYPE" == "darwin"* ]]; then
180 | alias lsusb='ioreg -p IOUSB -l -w 0'
181 | fi
182 |
183 | # 3D Printing
184 | alias rockpi='ssh root@rockpi'
185 | alias cura='open -a /Applications/UltiMaker Cura.app'
186 | alias cura-backup='cp -r ~/Library/Application\ Support/cura/*.zip ~/Library/Mobile\ Documents/com~apple~CloudDocs/Backups/3dprinting/cura/'
187 |
188 | alias backup-models="rsync -avr --partial '/Users/samm/Library/Mobile Documents/com~apple~CloudDocs/3D Printing/Models' root@nas:/mnt/raid/3dprinting/"
189 | alias backup-models-delete="rsync -avr --partial '/Users/samm/Library/Mobile Documents/com~apple~CloudDocs/3D Printing/Models' root@nas:/mnt/raid/3dprinting/ --delete"
190 |
191 | alias creality='/Users/samm/git/sammcj/ender-configs/creality-sonic-pad/login.exp'
192 | alias ender='cd ~/git/sammcj/ender-configs/ && code .'
193 |
194 | # pip install git+https://github.com/ChristophSchranz/Tweaker-3.git
195 | alias rotate='tweaker3 -vb -x -i'
196 | alias rotate_min_supports='tweaker3 -vb -x -min sur -i'
197 |
198 | alias obsidian='cd /Users/samm/Library/Mobile\ Documents/iCloud~md~obsidian/Documents/Main && ls -ltarh'
199 |
200 | # ML / AI
201 | # shellcheck disable=SC2139
202 | alias clinerules="code /Users/samm/Library/Mobile\ Documents/com\~apple\~CloudDocs/Documents/Cline"
203 | alias clinerulesd="cd /Users/samm/Library/Mobile\ Documents/com\~apple\~CloudDocs/Documents/Cline"
204 | alias sync_ollama_models="${HOME}/git/sammcj/scripts/ollama/export_ollama_model.py"
205 | alias copilot="gh copilot suggest -t shell"
206 | alias copilot-explain="gh copilot explain"
207 | alias '??'='copilot'
208 | alias wtf='copilot'
209 | alias l="OLLAMA_HOST=http://localhost:11434 gollama -l"
210 | alias i="ingest"
211 | alias code2prompt="ingest"
212 | alias ln="gollama -l"
213 | alias gl="gollama"
214 | alias ol="mods"
215 | alias idf='. $HOME/git/esp-idf/export.sh'
216 | alias o='tlm explain'
217 | alias hf="hfdownloader -c 10 -t \$HUGGINGFACE_TOKEN -j"
218 | alias imagesearch="sisi search"
219 |
220 | # uv
221 | alias venv='uv venv ; source .venv/bin/activate'
222 |
223 | ### AWS ###
224 | alias aws-rds-list-instances="aws rds describe-db-instances --region ap-southeast-2 --query \"DBInstances[].{Instance: DBInstanceIdentifier, Class: DBInstanceClass, Endpoint: Endpoint.Address, Status: DBInstanceStatus}\" --output text | sed -r 's/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[m|K]//g'"
225 |
--------------------------------------------------------------------------------
/5-exports.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | ### Exports ###
4 | export SAM_CLI_TELEMETRY=0 TELEMETRY=0 ENABLE_TELEMETRY=0 SEND_TELEMETRY=0 DO_NOT_TRACK=1 ANALYTICS=0 DISABLE_ANALYTICS=1 NO_ANALYTICS=1 DOTNET_CLI_TELEMETRY_OPTOUT=1 # General catch-all
5 | export GREP_OPTIONS="--color"
6 | # export LSCOLORS="ExFxCxDxBxegedabagacad"
7 | export LS_COLORS="$(vivid generate dracula)"
8 | export CLICOLOR=1
9 | export GOPATH="${HOME}/go"
10 | export XZ_OPT="--threads=8"
11 | export MU_REPO_SERIAL=false
12 | export EDITOR=vim
13 |
14 | # colima / docker
15 | # export DOCKER_HOST="unix://$HOME/.colima/docker.sock"
16 | # export DOCKER_HOST="unix:///Users/samm/.colima/default/docker.sock"
17 |
18 | # Tells 'less' not to paginate if less than a page
19 | export LESS="-F -X $LESS"
20 |
21 | # Options to fzf command
22 | export FZF_COMPLETION_OPTS='--border --info=inline'
23 |
24 | # Export a variable that contains the directory this script is sourced from (e.g. /Users/username/icloud docs/somedir/).
25 | # we can't use BASH_SOURCE[0] because it's not available in zsh
26 | # DOTFILES_DIR="$(cd "$(dirname "$0")" && pwd)"
27 | # export DOTFILES_DIR
28 |
29 | # # Global package manager caches to save on disk space
30 | # export PIP_DOWNLOAD_CACHE="${HOME}/Library/Caches/pip"
31 | # export NPM_CONFIG_CACHE="${HOME}/.npm"
32 |
33 | ## Text formatting shortcuts ##
34 | export _FMT_ITL="\e[3m"
35 | export _FMT_BLD="\e[1m"
36 | export _FMT_RED="\e[31m"
37 | export _FMT_GRN="\e[32m"
38 | export _FMT_YLW="\e[33m"
39 | export _FMT_BLU="\e[34m"
40 | export _FMT_MAG="\e[35m"
41 | export _FMT_CYN="\e[36m"
42 | export _FMT_WHT="\e[37m"
43 | export _FMT_BRED="\e[1;31m"
44 | export _FMT_BGRN="\e[1;32m"
45 | export _FMT_BYLW="\e[1;33m"
46 | export _FMT_BBLU="\e[1;34m"
47 | export _FMT_BMAG="\e[1;35m"
48 | export _FMT_BCYN="\e[1;36m"
49 | export _FMT_BWHT="\e[1;37m"
50 | export _FMT_END="\e[0m" # end of line stop formatting
51 | ##
52 |
53 | ## AI/ML ##
54 |
55 | # automatic1111
56 | # export COMMANDLINE_ARGS="${COMMANDLINE_ARGS:-$COMMANDLINE_ARGS --skip-torch-cuda-test --upcast-sampling --opt-sub-quad-attention}" # --use-cpu interrogate
57 | export HF_HUB_ENABLE_HF_TRANSFER=1
58 | export CONDA_SUBDIR=osx-arm64
59 |
60 | # SEE ALSO private exports for Ollama things
61 |
62 | # if running on macos
63 | # if [[ "$OSTYPE" == "darwin"* ]]; then
64 | # BLAS_INCLUDE_DIRS=/opt/homebrew/Cellar/clblast/1.6.2/
65 | # export CMAKE_ARGS="${CMAKE_ARGS} -DLLAMA_CUDA=off -DLLAMA_METAL=on -DLLAMA_CLBLAST=1"
66 | # fi
67 |
68 | export ENABLE_ANALYTICS=0
69 |
--------------------------------------------------------------------------------
/6-zsh_options.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | ### Options ###
4 |
5 | #unalias run-help
6 | # autoload run-help
7 | # HELPDIR=/usr/local/share/zsh/help
8 |
9 | # Useful for moving / renaming files with glob patterns
10 | # e.g. zmv -W '**/*.js' '**/*.ts' # recursively move anything matching the first pattern to the second pattern
11 | autoload -Uz zmv
12 |
13 | zmodload zsh/complist
14 | zmodload zsh/mapfile # bring mapfile to zsh
15 | # zmodload zsh/attr # attrs info
16 |
17 | # Keep echo "station" > station from clobbering station
18 | setopt NO_CLOBBER
19 |
20 | # Case insensitive globbing
21 | setopt NO_CASE_GLOB
22 |
23 | # Be Reasonable!
24 | setopt NUMERIC_GLOB_SORT
25 |
26 | # I don't know why I never set this before.
27 | setopt EXTENDED_GLOB
28 |
29 | ### Completion Stuff ###
30 |
31 | ## zsh-completion-generator ##
32 | # Requires zgen load RobSis/zsh-completion-generator - see 1-zgen.rc
33 | # Can also be run on the cli using: gencomp
34 | zstyle :plugin:zsh-completion-generator programs ggrep tr cat xattr
35 | ##
36 |
37 | # If we have a glob this will expand it
38 | setopt GLOB_COMPLETE
39 | setopt PUSHD_MINUS
40 |
41 | bindkey -M viins '\C-i' complete-word
42 |
43 | zstyle ':zle:*-word-shell' word-style shell
44 |
45 | zle -N forward-word-shell forward-word-match
46 | zle -N backward-word-shell backward-word-match
47 |
48 | # Faster! (?)
49 | zstyle ':completion::complete:*' use-cache 1
50 |
51 | # case insensitive completion
52 | # NOTE THIS MAY CAUSE PERFORMANCE ISSUES
53 | zstyle ':completion:*' matcher-list '' 'm:{a-zA-Z}={A-Za-z}' 'r:|[._-]=* r:|=*' 'l:|=* r:|=*'
54 |
55 | # tab completion for the middle of words
56 | autoload compinstall
57 | zstyle ':completion:*' matcher-list '' '' '' 'l:|=* r:|=*'
58 |
59 | zstyle ':completion:*' verbose yes
60 | zstyle ':completion:*:descriptions' format '%B%d%b'
61 | zstyle ':completion:*:messages' format '%d'
62 | zstyle ':completion:*:warnings' format 'No matches for: %d'
63 | zstyle ':completion:*' group-name ''
64 |
65 | # AWS specific
66 | zstyle ':completion:*:*:aws' fzf-search-display true
67 |
68 | # Note these need functions to be defined, see functions.rc
69 | zstyle ':completion:*' completer _oldlist _expand _force_rehash _complete
70 | zstyle ':completion:*' completer _expand _force_rehash _complete _ignored
71 |
72 | zstyle ':completion:*:*:docker:*' option-stacking yes
73 | zstyle ':completion:*:*:docker-*:*' option-stacking yes
74 |
75 | # Group completions by type (file, external command, etc)
76 | zstyle ':completion:*:matches' group 'yes'
77 |
78 | # don't mess up url passing as arguments
79 | zstyle ':urlglobber' url-other-schema
80 |
81 | # generate descriptions with magic.
82 | zstyle ':completion:*' auto-description 'specify: %d'
83 |
84 | # Don't prompt for a huge list, page it!
85 | zstyle ':completion:*:default' list-prompt '%S%M matches%s'
86 |
87 | # Don't prompt for a huge list, menu it!
88 | zstyle ':completion:*:default' menu 'select=0'
89 |
90 | # Have the newer files last so I see them first
91 | zstyle ':completion:*' file-sort modification reverse
92 |
93 | # color code completion!!!! Wohoo!
94 | zstyle ':completion:*' list-colors "=(#b) #([0-9]#)*=36=31"
95 |
96 | # don't tab complete hosts (slow and if you have ad-blocking in your hosts file annoying)
97 | #zstyle ':completion:*' hosts off
98 |
99 | unsetopt LIST_AMBIGUOUS
100 | setopt COMPLETE_IN_WORD
101 |
102 | # Separate man page sections. Neat.
103 | zstyle ':completion:*:manuals' separate-sections true
104 |
105 | zstyle ':completion:*' list-separator '»»'
106 |
107 | # complete with a menu for xwindow ids
108 | zstyle ':completion:*:windows' menu on=0
109 | zstyle ':completion:*:expand:*' tag-order all-expansions
110 |
111 | # more errors allowed for large words and fewer for small words
112 | zstyle ':completion:*:approximate:*' max-errors "reply=( $((($#PREFIX + $#SUFFIX) / 3)) )"
113 |
114 | # Errors format
115 | zstyle ':completion:*:corrections' format '%B%d (errors %e)%b'
116 | zstyle ':completion:*:correct:*' insert-unambiguous true
117 | zstyle ':completion:*:correct:*' original true
118 |
119 | # Don't complete stuff already on the line
120 | zstyle ':completion::*:(rm|vi):*' ignore-line true
121 |
122 | # Don't complete directory we are already in (../here)
123 | zstyle ':completion:*' ignore-parents parent pwd
124 |
125 | zstyle ':completion::approximate*:*' prefix-needed false
126 |
127 | # make kill way awesome
128 | zstyle ':completion:*:processes' command 'ps -au$USER -o pid,time,cmd|grep -v "ps -au$USER -o pid,time,cmd"'
129 | zstyle ':completion:*:*:kill:*:processes' list-colors '=(#b) #([0-9]#)[ 0-9:]#([^ ]#)*=01;30=01;31=01;38'
130 |
131 | ### Auto Suggest Settings ###
132 | # Autosuggest highlight colour
133 | export ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=#7c4fef,bold,underline"
134 |
135 | # Autosuggestions from history, if none use the completion engine.
136 | export ZSH_AUTOSUGGEST_STRATEGY=(history completion)
137 |
138 | # Accept autosuggestion with shift+tab - I use this EVERY day
139 | bindkey '^I' complete-word # tab | complete
140 | bindkey '^[[Z' autosuggest-accept # shift + tab | autosuggest
141 |
142 | # Autocomplete kubectl for k alias
143 | # complete -F __start_kubectl k
144 | # compdef __start_kubectl k
145 |
146 | ### END Autocompletion ###
147 |
148 | ### Key bindings ###
149 |
150 | # Who doesn't want home and end to work?
151 | bindkey '\e[1~' beginning-of-line
152 | bindkey '\e[4~' end-of-line
153 |
154 | # Incremental search is elite!
155 | bindkey -M vicmd "/" history-incremental-search-backward
156 | bindkey -M vicmd "?" history-incremental-search-forward
157 |
158 | # Search based on what you typed in already
159 | bindkey -M vicmd "//" history-beginning-search-backward
160 | bindkey -M vicmd "??" history-beginning-search-forward
161 |
162 | # oh wow! This is killer... try it!
163 | bindkey -M vicmd "q" push-line
164 |
165 | # Ensure that arrow keys work as they should
166 | bindkey '\e[A' up-line-or-history
167 | bindkey '\e[B' down-line-or-history
168 |
169 | bindkey '\eOA' up-line-or-history
170 | bindkey '\eOB' down-line-or-history
171 |
172 | bindkey '\e[C' forward-char
173 | bindkey '\e[D' backward-char
174 |
175 | bindkey '\eOC' forward-char
176 | bindkey '\eOD' backward-char
177 |
178 | # bindkey "5C" emacs-forward-word
179 | # bindkey "5D" backward-word
180 | bindkey "5C" forward-word #control left
181 | bindkey "5D" backward-word #control right
182 | bindkey "^[[1;5C" forward-word #control left in xterm/tmux
183 | bindkey "^[[1;5D" backward-word #control right in xterm/tmux
184 |
185 | bindkey "^[[A" history-search-backward # Search history with up arrow
186 | bindkey "^[[B" history-search-forward # Search history with up arrow
187 |
188 | # gross. Makes Meta-' write '\'' for you
189 | bindkey -s \\e\' \'\\\\\'\'
190 |
191 | # bindkey "^[[3~" delete-char # delete keys
192 | # bindkey "^[3;5~" delete-char # delete keys
193 |
194 | bindkey -M emacs '^H' backward-kill-word # backwards delete word
195 |
196 | # it's like, space AND completion. Gnarlbot.
197 | bindkey -M viins ' ' magic-space
198 |
199 | # Push your line to the stack and run another command then pop it back
200 | bindkey -M vicmd "^q" push-line
201 |
202 | # cd into a directory when you type its name
203 | setopt autocd
204 |
205 | ### Fix slowness of pastes with zsh-syntax-highlighting.zsh ###
206 | # Still needed as of 2023-06-24!
207 | pasteinit() {
208 | # shellcheck disable=SC2296,SC2298
209 | OLD_SELF_INSERT=${${(s.:.)widgets[self-insert]}[2,3]}
210 | zle -N self-insert url-quote-magic
211 | }
212 |
213 | pastefinish() {
214 | zle -N self-insert "$OLD_SELF_INSERT"
215 | }
216 | zstyle :bracketed-paste-magic paste-init pasteinit
217 | zstyle :bracketed-paste-magic paste-finish pastefinish
218 | ### End fix slowness of pastes ###
219 |
220 | # Suggest corrections for commands
221 | setopt correct
222 |
223 | # ### Expand aliases
224 | # globalias() {
225 | # zle _expand_alias
226 | # zle expand-word
227 | # zle self-insert
228 | # }
229 | # zle -N globalias
230 | # # space expands all aliases, including global
231 | # bindkey -M emacs " " globalias
232 | # bindkey -M viins " " globalias
233 |
234 | # # control-space to make a normal space
235 | # bindkey -M emacs "^ " magic-space
236 | # bindkey -M viins "^ " magic-space
237 |
238 | # # normal space during searches
239 | # bindkey -M isearch " " magic-space
240 |
241 | #nav bindkeys
242 | # bindkey '^[[1;5A' nav-up # cmd + up
243 | # bindkey '^[[1;5B' nav-down # cmd + down
244 | # bindkey '^[[1;5C' nav-forward # cmd + right
245 | # bindkey '^[[1;5D' nav-back # cmd + left
246 | # #
247 |
248 | # Bind ctrl+g to run the command 'git status'
249 | _git_status() {
250 | git status
251 | zle redisplay
252 | }
253 | zle -N _git_status
254 | bindkey '^g' '_git_status' # ctrl + g
255 |
256 | # Bind ctrl+l to run sgpt with all text on the command line as a single quoted argument
257 | _sgptline() {
258 | LINE=$LBUFFER
259 | echo -e "\n"
260 | sgpt "'$LINE'"
261 | LBUFFER=""
262 | zle redisplay
263 | }
264 | zle -N _sgptline
265 | bindkey '^l' '_sgptline' # ctrl + l
266 |
267 |
268 | # https://github.com/ohmyzsh/ohmyzsh/wiki/Settings
269 |
270 | # Oh My Zsh will print a red ellipsis to indicate that Zsh is still processing a completion request
271 | export COMPLETION_WAITING_DOTS=true
272 |
--------------------------------------------------------------------------------
/7-history.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | ### History Stuff ###
4 |
5 | # Don't share tab history on iTerm2
6 | #unsetopt inc_append_history
7 |
8 | # Where it gets saved
9 | HISTFILE=~/.history
10 |
11 | # Remember a lot of history (AWESOME)
12 | export SAVEHIST=2000000
13 | export HISTSIZE=2000000
14 |
15 | # Don't overwrite, append!
16 | setopt APPEND_HISTORY
17 |
18 | # Write after each command
19 | # setopt INC_APPEND_HISTORY
20 |
21 | # Killer: share history between multiple shells
22 | setopt SHARE_HISTORY
23 |
24 | # If I type cd and then cd again, only save the last one
25 | setopt HIST_IGNORE_DUPS
26 |
27 | # Even if there are commands in between commands that are the same, still only save the last one
28 | setopt HIST_IGNORE_ALL_DUPS
29 |
30 | # Pretty Obvious. Right?
31 | setopt HIST_REDUCE_BLANKS
32 |
33 | # If a line starts with a space, don't save it.
34 | setopt HIST_IGNORE_SPACE
35 | setopt HIST_NO_STORE
36 |
37 | # When using a hist thing, make a newline show the change before executing it.
38 | setopt HIST_VERIFY
39 |
40 | # Save the time and how long a command ran
41 | setopt EXTENDED_HISTORY
42 |
43 | setopt HIST_SAVE_NO_DUPS
44 | setopt HIST_EXPIRE_DUPS_FIRST
45 | setopt HIST_FIND_NO_DUPS
46 |
47 | # When outputting history, print it out with timestamps and command only
48 | alias history="history -i"
49 |
--------------------------------------------------------------------------------
/9-functions.rc:
--------------------------------------------------------------------------------
1 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
2 |
3 | function mkcd {
4 | dir="$*"
5 | mkdir -p "$dir" && cd "$dir" || exit
6 | }
7 |
8 | # change /dev/null to youtube-dl-"$(date +%Y%m%d-%H%M%S)".log if you want logging
9 |
10 | function git_sparse_clone() (
11 | rurl="$1" localdir="$2" && shift 2
12 |
13 | mkdir -p "$localdir"
14 | cd "$localdir"
15 |
16 | git init
17 | git remote add -f origin "$rurl"
18 |
19 | git sparse-checkout init
20 |
21 | # Loops over remaining args
22 | for i; do
23 | echo "$i" >>.git/info/sparse-checkout
24 | done
25 |
26 | git pull origin main
27 |
28 | git sparse-checkout list
29 | )
30 |
31 | # A function that checks a git repo for any incorrect casing / cashing clashes and force over-rides local changes if so
32 | git-fix-casing() {
33 | local original_dir
34 | original_dir=$(pwd)
35 | cd "$1" || return 1
36 | sh -c 'git ls-files -ci --exclude-standard -z | xargs -0 git rm --cached'
37 | git status
38 | if [[ $(git ls-files -ci --exclude-standard) ]]; then
39 | echo "There are files with incorrect casing in the git repo"
40 | git reset --hard
41 | git status
42 | fi
43 | cd "$original_dir" || return 1
44 | }
45 |
46 | # wrapper for adding advanced git cli customisation
47 | alias git='git_wrapper'
48 | git_wrapper() {
49 | set +m # Make jobs quiet by default
50 | # If invoked by another function, alias or xargs, interpret it as normal
51 | if [[ -n ${FUNCNAME[*]} ]] || [[ -n $ALIASES ]] || [[ -n $XARGS ]]; then
52 | command git "$@"
53 | return
54 | fi
55 |
56 | # clone with depth=1 if no depth is not specified
57 | if [[ $1 == "clone" ]] && [[ $* != *"--depth"* ]]; then
58 | shift
59 | command git clone --depth=1 "$@"
60 |
61 | # Move into the cloned directory (taking into account the destination directory might be provided)
62 | if [[ $* == *" "* ]]; then
63 | local dest_dir
64 | dest_dir=$(echo "$*" | awk '{print $NF}')
65 | cd "$dest_dir"
66 | else
67 | cd "$(basename "$1" .git)"
68 | fi
69 |
70 | # Update the fetch configuration to track all upstream branches
71 | git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
72 |
73 | # Fetch all branches in the background, silently
74 | git fetch --all --quiet #&>/dev/null &
75 |
76 | # Move back to the original directory
77 | cd -
78 | else
79 | command git "$@"
80 | fi
81 | set -m # Make jobs verbose again
82 | }
83 |
84 | function gco() {
85 | if [[ -n $1 ]]; then
86 | if [[ $1 == "-b" ]]; then
87 | # shift to remove -b from args
88 | shift 1
89 | fi
90 | local branchname remote_branch_exist
91 | branchname="$1"
92 |
93 | # If the branch name is "main" or "master" just check it out
94 | if [[ "$branchname" == "main" ]] || [[ "$branchname" == "master" ]]; then
95 | command git switch "$branchname"
96 | return
97 | fi
98 |
99 | # check to see if the branch exists locally, if it doesn't offer to create it and check it out otherwise just check it out
100 | if command git show-ref --verify --quiet refs/heads/"$branchname"; then
101 | echo "Branch exists locally, switching branch..."
102 | command git switch "$branchname"
103 | else
104 | echo "Checking if branch exists remotely..."
105 | remote_branch_exist=$(command git ls-remote --heads origin "$branchname")
106 | if [ -n "$remote_branch_exist" ]; then
107 | echo "Branch exists remotely, checking out and pulling..."
108 | command git fetch # origin "$branchname"
109 | # command git checkout "$branchname" "origin/${branchname}" || echo "Error - available branches: $(git branch -v -a)"
110 | command git switch -c "$branchname" "origin/${branchname}" || echo "Error - available branches: $(git branch -v -a)"
111 | command git pull
112 | else
113 | # If the branch doesn't exist either locally or remotely
114 | echo "Branch doesn't exist locally or remotely, creating and switching..."
115 | command git switch -c "$branchname"
116 | fi
117 | fi
118 | else
119 | # shellcheck disable=SC2033
120 | command git branch --sort=-committerdate | fzf --header 'Checkout Recent Branch' --preview 'git diff --color=always {1}' --pointer='>' | xargs command git switch
121 | echo -e "${_FMT_ITL}Hint: You can check remote branches with 'gcor'${_FMT_END}"
122 | fi
123 | }
124 |
125 | function gcor() {
126 | # list all remote branches and select one with fzf git branch -v -a
127 | command git branch -v -a | fzf --header 'Checkout Remote Branch' --preview 'git diff --color=always {1}' --pointer='>' | awk '{print $1}' | xargs command git checkout
128 | }
129 |
130 | function gbd() {
131 | if [[ -n $* ]]; then
132 | command git branch -d "$@"
133 | else
134 | # shellcheck disable=SC2033
135 | command git branch --sort=-committerdate | fzf --header 'Delete Git Branch' --preview 'git diff --color=always {1}' --pointer='>' | xargs command git branch -d
136 | fi
137 | }
138 |
139 | # generate_commit_msg() {
140 | # # This function generates a commit message using the ollama API
141 | # # Map the function to a keybinding (e.g., gcm) in your .zshrc file:
142 | # # bindkey '^Xg' generate_commit_msg
143 | # local -r model="tinydolphin:1.1b- v2.8-q5_ K_ M"
144 | # local -r prompt=$(git diff --cached --name-only | xargs -I{} echo "Why did you change {}?")
145 | # local -r api_url="http://localhost:11434/api/generate"
146 | # }
147 |
148 | # A function that provides an untracked_files check for other functions
149 | function __staged_changes() {
150 | # Display all changes including untracked files
151 | local STAGED_FILES
152 | STAGED_FILES=$(git diff --cached --name-only)
153 | if [[ -n "$STAGED_FILES" ]]; then
154 | echo "Staged files:"
155 | echo "$STAGED_FILES"
156 | else
157 | echo "No staged changes to add."
158 | # Ask the user if they want to stage all changes
159 | echo "Do you want to add all changes to the commit? (y/n)"
160 | read -r yn
161 | if [[ "$yn" =~ ^[Yy]$ ]]; then
162 | # Stage all changes
163 | git add .
164 | else
165 | echo "Staging cancelled by the user."
166 | return 1 # Return failure to indicate staging was not done
167 | fi
168 | fi
169 | }
170 |
171 | function checkout-hotfix() {
172 | local PREFIX="hotfix-${USER}"
173 | local DATESTAMP
174 | DATESTAMP=$(date +%Y-%m-%d)
175 | # If the hotfix branch already exists, append a number to the branch name, if the number already exists increment it
176 | if command git branch -a | grep -q "$PREFIX-$DATESTAMP"; then
177 | local COUNT=1
178 | while git branch -a | grep -q "$PREFIX-$DATESTAMP-$COUNT"; do
179 | COUNT=$((COUNT + 1))
180 | done
181 | command git checkout -b "${PREFIX}-${DATESTAMP}-${COUNT}"
182 | else
183 | command git checkout -b "${PREFIX}-${DATESTAMP}"
184 | fi
185 | }
186 |
187 | function commit-hotfix() {
188 | local DATESTAMP
189 | DATESTAMP=$(date +%Y/%m/%d)
190 | local GIT_ARGS=()
191 | local MESSAGE=""
192 |
193 | # Check for the '-n' flag and prepare commit options accordingly
194 | if [[ "$1" == "-n" ]]; then
195 | GIT_ARGS+=("-n") # Add '-n' to the git commit command options
196 | shift # Remove '-n' from the argument list so it's not included in the commit message
197 | fi
198 |
199 | # After shifting '-n', all remaining arguments form the commit message
200 | MESSAGE="$*"
201 |
202 | # Attempt to stage changes; if the user cancels, abort the commit
203 | if ! __staged_changes; then
204 | echo "Commit aborted due to no changes being staged."
205 | return 1
206 | fi
207 |
208 | # Proceed with commit
209 | local CURRENT_BRANCH
210 | CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
211 | git commit "${GIT_ARGS[@]}" -m "Hotfix-${DATESTAMP} -- ${MESSAGE}"
212 |
213 | # Check if the commit was successful before attempting to push
214 | if git rev-parse --verify "$CURRENT_BRANCH" >/dev/null 2>&1; then
215 | git push --set-upstream origin "$CURRENT_BRANCH"
216 | echo "Changes committed and pushed to $CURRENT_BRANCH."
217 | else
218 | echo "Failed to push changes. Branch $CURRENT_BRANCH does not exist."
219 | fi
220 | }
221 |
222 | function checkout-jira() {
223 | JIRA_BRANCH="IF-${1}-${USER}-$(date +%Y-%m-%d)"
224 | # If the JIRA branch already exists, append the current time to the branch name
225 | if command git branch -a | grep -q "remotes/origin/${JIRA_BRANCH}" || command git branch -a | grep -q "${JIRA_BRANCH}"; then
226 | JIRA_BRANCH="${JIRA_BRANCH}-$(date +%H-%M-%S)"
227 | fi
228 | command git checkout -b "${JIRA_BRANCH}"
229 | }
230 |
231 | function commit-jira() {
232 | local GIT_ARGS=()
233 | local MESSAGE=""
234 | local BRANCH_PREFIX CURRENT_BRANCH
235 |
236 | # Check for the '-n' flag and prepare commit options accordingly
237 | if [[ "$1" == "-n" ]]; then
238 | GIT_ARGS+=("-n") # Add '-n' to the git commit command options
239 | shift # Remove '-n' from the argument list so it's not included in the commit message
240 | fi
241 |
242 | # After shifting '-n', all remaining arguments form the commit message
243 | MESSAGE="$*"
244 |
245 | # Call the updated function to check and stage all changes
246 | if ! __staged_changes; then
247 | echo "Commit aborted due to no changes being staged."
248 | return 1
249 | fi
250 |
251 | # add the branch prefix to the message (e.g. IF-1234 -- message)
252 | CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
253 | BRANCH_PREFIX=$(echo "$CURRENT_BRANCH" | cut -d'-' -f1 -f2)
254 | MESSAGE="${BRANCH_PREFIX} -- ${MESSAGE}"
255 |
256 | # Proceed with commit
257 | if ! git diff --cached --quiet; then
258 | echo "No changes to commit."
259 | # Check if the branch exists on the remote
260 | if ! git ls-remote --heads origin "$CURRENT_BRANCH" | grep -q "$CURRENT_BRANCH"; then
261 | # Offer to push and track the branch if it doesn't exist on the remote
262 | echo "Current branch '$CURRENT_BRANCH' does not exist on the remote. Would you like to push it? (y/n)"
263 | read -r yn
264 | if [[ "$yn" =~ ^[Yy]$ ]]; then
265 | git push --set-upstream origin "$CURRENT_BRANCH"
266 | echo "Branch pushed and tracked on remote."
267 | else
268 | echo "Push cancelled by the user."
269 | fi
270 | fi
271 | else
272 | # Execute the commit with any options and the message
273 | git commit "${GIT_ARGS[@]}" -m "$MESSAGE"
274 | git push --set-upstream origin "$CURRENT_BRANCH"
275 | echo "Changes committed and pushed to '$CURRENT_BRANCH'."
276 | fi
277 | }
278 |
279 | # Outputs the name of the current branch
280 | # Usage example: git pull origin "$(git_current_branch)"
281 | # Using '--quiet' with 'symbolic-ref' will not cause a fatal error (128) if
282 | # it's not a symbolic ref, but in a Git repo.
283 | function git_current_branch() {
284 | local ref
285 | ref=$(command git symbolic-ref --quiet HEAD 2>/dev/null)
286 | local ret=$?
287 | if [[ $ret != 0 ]]; then
288 | [[ $ret == 128 ]] && return # no git repo.
289 | ref=$(command git rev-parse --short HEAD 2>/dev/null) || return
290 | fi
291 | echo "${ref#refs/heads/}"
292 | }
293 |
294 | function pr-checkout() {
295 | local jq_template pr_number
296 |
297 | jq_template='"''#\(.number) - \(.title)''\t''Author: \(.user.login)\n''Created: \(.created_at)\n''Updated: \(.updated_at)\n\n''\(.body)''"'
298 |
299 | pr_number=$(
300 | gh api 'repos/:owner/:repo/pulls' |
301 | jq ".[] | $jq_template" |
302 | sed -e 's/"\(.*\)"/\1/' -e 's/\\t/\t/' |
303 | fzf \
304 | --with-nth=1 \
305 | --delimiter='\t' \
306 | --preview='echo -e {2}' \
307 | --preview-window=top:wrap |
308 | sed 's/^#\([0-9]\+\).*/\1/'
309 | )
310 |
311 | if [ -n "$pr_number" ]; then
312 | gh pr checkout "$pr_number"
313 | fi
314 | }
315 |
316 | function git_add_global_prepush_hook() {
317 | local repo_path=$1
318 | local branch_name=$2
319 | local hooks_path="$repo_path/.git/hooks"
320 |
321 | # Check if the repo_path is a Git repository
322 | if [ ! -d "$repo_path/.git" ]; then
323 | echo "$repo_path is not a Git repository"
324 | return 1
325 | fi
326 |
327 | # Create the pre-push hook if it doesn't exist
328 | if [ ! -f "$hooks_path/pre-push" ]; then
329 | touch "$hooks_path/pre-push"
330 | chmod +x "$hooks_path/pre-push"
331 | fi
332 |
333 | # Add the code to the pre-push hook
334 | cat <>"$hooks_path/pre-push"
335 | #!/usr/bin/env bash
336 |
337 | # This script can be run as a pre-push hook locally on repositories to add messages / ensure we're not pushing to the wrong branch etc...
338 |
339 | branch_name=$(git symbolic-ref --short HEAD)
340 | if [ "$branch_name" == "main" ] || [ "$branch_name" == "master" ]; then
341 | echo "WARNING: You are pushing to the $branch_name branch!"
342 | read -r -p "Are you sure you want to push to $branch_name? [y/N] " response
343 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
344 | echo "$response - Pushing to $branch_name"
345 | else
346 | echo "Aborting push"
347 | exit 1
348 | fi
349 | fi
350 | EOF
351 |
352 | echo "Global pre-push hook added to $repo_path"
353 | }
354 |
355 | # Gets the number of commits ahead from remote
356 | function git_commits_ahead() {
357 | if command git rev-parse --git-dir &>/dev/null; then
358 | local commits
359 | commits="$(git rev-list --count @{upstream}..HEAD)"
360 | if [[ "$commits" != 0 ]]; then
361 | echo "$ZSH_THEME_GIT_COMMITS_AHEAD_PREFIX$commits$ZSH_THEME_GIT_COMMITS_AHEAD_SUFFIX"
362 | fi
363 | fi
364 | }
365 |
366 | # Gets the number of commits behind remote
367 | function git_commits_behind() {
368 | if command git rev-parse --git-dir &>/dev/null; then
369 | local commits
370 | commits="$(git rev-list --count HEAD..@{upstream})"
371 | if [[ "$commits" != 0 ]]; then
372 | echo "$ZSH_THEME_GIT_COMMITS_BEHIND_PREFIX$commits$ZSH_THEME_GIT_COMMITS_BEHIND_SUFFIX"
373 | fi
374 | fi
375 | }
376 |
377 | # Outputs if current branch is ahead of remote
378 | function git_prompt_ahead() {
379 | if [[ -n "$(command git rev-list origin/"$(git_current_branch)"..HEAD 2>/dev/null)" ]]; then
380 | echo "$ZSH_THEME_GIT_PROMPT_AHEAD"
381 | fi
382 | }
383 |
384 | # Outputs if current branch is behind remote
385 | function git_prompt_behind() {
386 | if [[ -n "$(command git rev-list HEAD..origin/"$(git_current_branch)" 2>/dev/null)" ]]; then
387 | echo "$ZSH_THEME_GIT_PROMPT_BEHIND"
388 | fi
389 | }
390 |
391 | # Outputs if current branch exists on remote or not
392 | function git_prompt_remote() {
393 | if [[ -n "$(command git show-ref origin/"$(git_current_branch)" 2>/dev/null)" ]]; then
394 | echo "$ZSH_THEME_GIT_PROMPT_REMOTE_EXISTS"
395 | else
396 | echo "$ZSH_THEME_GIT_PROMPT_REMOTE_MISSING"
397 | fi
398 | }
399 |
400 | # Formats prompt string for current git commit short SHA
401 | function git_prompt_short_sha() {
402 | local SHA
403 | SHA=$(command git rev-parse --short HEAD 2>/dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
404 | }
405 |
406 | # Formats prompt string for current git commit long SHA
407 | function git_prompt_long_sha() {
408 | local SHA
409 | SHA=$(command git rev-parse HEAD 2>/dev/null) && echo "$ZSH_THEME_GIT_PROMPT_SHA_BEFORE$SHA$ZSH_THEME_GIT_PROMPT_SHA_AFTER"
410 | }
411 |
412 | # # Get the status of the working tree
413 | # function git_prompt_status() {
414 | # local INDEX STATUS
415 | # INDEX=$(command git status --porcelain -b 2>/dev/null)
416 | # STATUS=""
417 | # if eval "$(echo "$INDEX" | command grep -E '^\?\? ' &>/dev/null)"; then
418 | # STATUS="$ZSH_THEME_GIT_PROMPT_UNTRACKED$STATUS"
419 | # fi
420 | # if eval "$(echo "$INDEX" | grep '^A ' &>/dev/null)"; then
421 | # STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
422 | # elif eval "$(echo "$INDEX" | grep '^M ' &>/dev/null)"; then
423 | # STATUS="$ZSH_THEME_GIT_PROMPT_ADDED$STATUS"
424 | # fi
425 | # if eval "$(echo "$INDEX" | grep '^ M ' &>/dev/null)"; then
426 | # STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
427 | # elif eval "$(echo "$INDEX" | grep '^AM ' &>/dev/null)"; then
428 | # STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
429 | # elif eval "$(echo "$INDEX" | grep '^ T ' &>/dev/null)"; then
430 | # STATUS="$ZSH_THEME_GIT_PROMPT_MODIFIED$STATUS"
431 | # fi
432 | # if eval "$(echo "$INDEX" | grep '^R ' &>/dev/null)"; then
433 | # STATUS="$ZSH_THEME_GIT_PROMPT_RENAMED$STATUS"
434 | # fi
435 | # if eval "$(echo "$INDEX" | grep '^ D ' &>/dev/null)"; then
436 | # STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
437 | # elif eval "$(echo "$INDEX" | grep '^D ' &>/dev/null)"; then
438 | # STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
439 | # elif eval "$(echo "$INDEX" | grep '^AD ' &>/dev/null)"; then
440 | # STATUS="$ZSH_THEME_GIT_PROMPT_DELETED$STATUS"
441 | # fi
442 | # if eval "$(command git rev-parse --verify refs/stash >/dev/null 2>&1)"; then
443 | # STATUS="$ZSH_THEME_GIT_PROMPT_STASHED$STATUS"
444 | # fi
445 | # if eval "$(echo "$INDEX" | grep '^UU ' &>/dev/null)"; then
446 | # STATUS="$ZSH_THEME_GIT_PROMPT_UNMERGED$STATUS"
447 | # fi
448 | # if eval "$(echo "$INDEX" | grep '^## [^ ]\+ .*ahead' &>/dev/null)"; then
449 | # STATUS="$ZSH_THEME_GIT_PROMPT_AHEAD$STATUS"
450 | # fi
451 | # if eval "$(echo "$INDEX" | grep '^## [^ ]\+ .*behind' &>/dev/null)"; then
452 | # STATUS="$ZSH_THEME_GIT_PROMPT_BEHIND$STATUS"
453 | # fi
454 | # if eval "$(echo "$INDEX" | grep '^## [^ ]\+ .*diverged' &>/dev/null)"; then
455 | # STATUS="$ZSH_THEME_GIT_PROMPT_DIVERGED$STATUS"
456 | # fi
457 | # echo "$STATUS"
458 | # }
459 |
460 | # # TODO: replace this with something more standard, this was a temporary workaround for poor performance of the stock oh-my-zsh git plugin
461 | # # Compares the provided version of git to the version installed and on path
462 | # # Outputs -1, 0, or 1 if the installed version is less than, equal to, or
463 | # # greater than the input version, respectively.
464 | # function git_compare_version() {
465 | # local INPUT_GIT_VERSION INSTALLED_GIT_VERSION
466 | # # shellcheck disable=SC2206,SC2207,SC2296
467 | # INPUT_GIT_VERSION=(${(s/./)1})
468 | # # shellcheck disable=SC2206,SC2207,SC2296
469 | # INSTALLED_GIT_VERSION=($(command git --version 2>/dev/null))
470 | # # shellcheck disable=SC2206,SC2207,SC2296
471 | # INSTALLED_GIT_VERSION=(${(s/./)INSTALLED_GIT_VERSION[3]})
472 |
473 | # for i in {1..3}; do
474 | # if [[ ${INSTALLED_GIT_VERSION[$i]} -gt ${INPUT_GIT_VERSION[$i]} ]]; then
475 | # echo 1
476 | # return 0
477 | # fi
478 | # if [[ ${INSTALLED_GIT_VERSION[$i]} -lt ${INPUT_GIT_VERSION[$i]} ]]; then
479 | # echo -1
480 | # return 0
481 | # fi
482 | # done
483 | # echo 0
484 | # }
485 |
486 | # Outputs the name of the current user
487 | # Usage example: $(git_current_user_name)
488 | function git_current_user_name() {
489 | command git config user.name 2>/dev/null
490 | }
491 |
492 | # Outputs the email of the current user
493 | # Usage example: $(git_current_user_email)
494 | function git_current_user_email() {
495 | command git config user.email 2>/dev/null
496 | }
497 |
498 | # Clean up the namespace slightly by removing the checker function
499 | # unfunction git_compare_version
500 |
501 | #source /usr/local/etc/profile.d/autojump.sh
502 |
503 | pdfcompress() {
504 | gs -q -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pdfwrite -dCompatibilityLevel=1.3 -dPDFSETTINGS=/screen -dEmbedAllFonts=true -dSubsetFonts=true -dColorImageDownsampleType=/Bicubic -dColorImageResolution=144 -dGrayImageDownsampleType=/Bicubic -dGrayImageResolution=144 -dMonoImageDownsampleType=/Bicubic -dMonoImageResolution=144 -sOutputFile="$1".compressed.pdf "$1"
505 | }
506 |
507 | # Usage: mv oldfilename
508 | # If you call mv without the second parameter it will prompt you to edit the filename on command line.
509 | # Original mv is called when it's called with more than one argument.
510 | # It's useful when you want to change just a few letters in a long name.
511 |
512 | function mv() {
513 | if [ "$#" -ne 1 ]; then
514 | command mv "$@"
515 | return
516 | fi
517 | if [ ! -f "$1" ]; then
518 | command file "$@"
519 | return
520 | fi
521 |
522 | read -ei "$1" newfilename
523 | mv -v "$1" "$newfilename"
524 | }
525 |
526 | _force_rehash() {
527 | ((CURRENT == 1)) && rehash
528 | return 1 # Because we didn't really complete anything
529 | }
530 |
531 | # This was causing tab complete errors such as zle-line-init:1: command not found
532 | # edit-command-output() {
533 | # BUFFER=$(eval "$BUFFER")
534 | # CURSOR=0
535 | # }
536 | # zle -N edit-command-output
537 |
538 | __mkdir() { if [[ ! -d $1 ]]; then mkdir -p "$1"; fi; }
539 |
540 | tch() {
541 | for x in "$@"; do
542 | __mkdir "${x:h}"
543 | done
544 | touch "$@"
545 | }
546 |
547 | # Interactive git diff
548 | function git-diff() {
549 | git log --graph --color=always \
550 | --format="%C(auto)%h%d %s %C(black)%C(bold)%cr" "$@" |
551 | fzf --ansi --preview "echo {} \
552 | | grep -o '[a-f0-9]\{7\}' \
553 | | head -1 \
554 | | xargs -I % sh -c 'git show --color=always %'" \
555 | --bind "enter:execute:
556 | (grep -o '[a-f0-9]\{7\}' \
557 | | head -1 \
558 | | xargs -I % sh -c 'git show --color=always % \
559 | | less -R') << 'FZF-EOF'
560 | {}
561 | FZF-EOF"
562 | }
563 |
564 | # Github
565 | # Deletes workflow logs from a given repo older than 1 month
566 | # e.g. USER=myuser REPO=myrepo ghac
567 | function ghac() {
568 | DATE=$(date -v "-1m" +"%Y-%m-%d") gh api "repos/${USER}/${REPO}/actions/runs" --paginate -q '.workflow_runs[] | select (.run_started_at <= "env.DATE") | (.id)' |
569 | xargs -n1 -I % gh api "repos/${USER}/${REPO}/actions/runs"/% -X DELETE
570 | }
571 |
572 | function github_actions_watcher() {
573 | # https://github.com/nedbat/watchgha
574 | TOKEN_BACKUP=$GITHUB_TOKEN
575 | unset GITHUB_TOKEN
576 | watch_gha_runs "$@" \
577 | "$(git remote get-url origin)" \
578 | "$(git rev-parse --abbrev-ref HEAD)"
579 | GITHUB_TOKEN=$TOKEN_BACKUP
580 | }
581 |
582 | # Git checkout new branch, git add, git commit, git push in all subdirectories matching a pattern
583 | function git_add_commit_push() {
584 | if [[ -z $1 ]] || [[ -z "$2" ]] || [[ -z "$3" ]]; then
585 | echo 'You must pass three paramters, branchname, commit message, dir match - e.g. "my-branch" "commit message" ABC*'
586 | fi
587 | BRANCHNAME="$1"
588 | COMMITNAME="$2"
589 | MATCHDIRS="$3"
590 | for dir in $MATCHDIRS; do
591 | (
592 | cd "$dir" &&
593 | git checkout -b "$BRANCHNAME" &&
594 | git add . &&
595 | git commit -n -m "$COMMITNAME" &&
596 | git push
597 | )
598 | done
599 | }
600 |
601 | # Interactive cd using fzf
602 | function fcd() {
603 | local dir
604 |
605 | while true; do
606 | # exit with ^D
607 | dir="$(ls -a1p | grep '/$' | grep -v '^./$' | fzf --height 40% --reverse --no-multi --preview 'pwd' --preview-window=up,1,border-none --no-info)"
608 | if [[ -z "${dir}" ]]; then
609 | break
610 | else
611 | cd "${dir}" || exit
612 | fi
613 | done
614 | }
615 |
616 | # list env variables with fzf
617 | list_env() {
618 | var=$(printenv | cut -d= -f1 | fzf) &&
619 | echo "$var=$(printenv "$var")" &&
620 | unset var
621 | }
622 |
623 | # Encryption (using age)
624 |
625 | # File with generated password
626 | encrypt_file_pw() {
627 | # Suggest installing age if not installed
628 | if ! command -v age &>/dev/null; then
629 | echo "age could not be found. Install it with 'brew install age'"
630 | return
631 | else
632 | age -p "$1" -o "${1}.age"
633 | fi
634 | }
635 |
636 | conda_setup() {
637 | # CONDA - is managed via a function when needed
638 | # >>> conda initialize >>>
639 | # !! Contents within this block are managed by 'conda init' !!
640 | __conda_setup="$('/Users/samm/miniconda3/bin/conda' 'shell.zsh' 'hook' 2>/dev/null)"
641 | if [ $? -eq 0 ]; then
642 | eval "$__conda_setup"
643 | else
644 | if [ -f "/Users/samm/miniconda3/etc/profile.d/conda.sh" ]; then
645 | . "/Users/samm/miniconda3/etc/profile.d/conda.sh"
646 | else
647 | export PATH="/Users/samm/miniconda3/bin:$PATH"
648 | fi
649 | fi
650 | unset __conda_setup
651 | # <<< conda initialize <<<
652 | }
653 |
654 | function update_asdf() {
655 | asdf update
656 | asdf plugin-update --all
657 | }
658 |
659 | # Prompts for a name and a password and stores it in keychain
660 | keychain_password_prompt() {
661 | echo "Enter a name for the password:"
662 | read -r name
663 | echo "Enter the password:"
664 | stty -echo # disable echoing the password
665 | read -r password
666 | security add-generic-password -s "$name" -a "$(whoami)" -w "$password"
667 | stty echo # re-enable echoing
668 | }
669 |
670 | # Reads a password from keychain and outputs it
671 | # usage: keychain_password
672 | keychain_password() {
673 | stty -echo # disable echoing the password
674 | security find-generic-password -s "$1" -a "$(whoami)" -w
675 | stty echo # re-enable echoing
676 | }
677 |
678 | ### AWS Auth ###
679 | # aws-profile uses s2a-keychain to login to AWS using saml2aws and then exports the AWS_PROFILE variable
680 | # Requires saml2aws, fzf, and keychain_password
681 | alias aad=aws-profile
682 | alias awslogin=aws-profile
683 | alias aws-azure-login=aws-profile
684 |
685 | # shellcheck disable=SC2068 disable=SC2046 disable=SC2145
686 | function s2a() {
687 | eval $($(command saml2aws) script --shell=bash --profile=$@)
688 | }
689 |
690 | # Logs into AWS using saml2aws and a password stored in keychain
691 | function s2a-keychain() {
692 | local IDPPW INPUT_PROFILE KEYCHAIN_ITEM
693 | KEYCHAIN_ITEM=${KEYCHAIN_ITEM:-"saml2awspw"}
694 | INPUT_PROFILE=${1:-"default"}
695 | CHECK_SCREENRECORDER=${CHECK_SCREENRECORDER:-"false"}
696 |
697 | IDPPW=$(keychain_password "$KEYCHAIN_ITEM") # requires mfa and keychain authentication
698 |
699 | aws configure list --profile "${INPUT_PROFILE}"
700 |
701 | # Login to AWS
702 | # /Users/samm/git/saml2aws-fork/dist/saml2aws_darwin_arm64/saml2aws
703 | saml2aws login -a "$INPUT_PROFILE" \
704 | --skip-prompt \
705 | --password="$IDPPW" \
706 | --profile="$INPUT_PROFILE"
707 | # --skip-verify
708 | export AWS_PROFILE="$INPUT_PROFILE"
709 | export AWSCLIPARAMS="--profile=${INPUT_PROFILE}"
710 | export AWS_DEFAULT_REGION=ap-southeast-2
711 | unset IDPPW
712 | }
713 |
714 | # Interactively export AWS_PROFILE
715 | function aws-profile() {
716 | # if provided an argument, use that as the profile
717 | if [[ -n $1 ]]; then
718 | export AWS_PROFILE=$1
719 | export AWSCLIPARAMS="--profile=$1"
720 | else
721 | # otherwise, use fzf to select a profile
722 | AWS_PROFILE=$(grep profile "${HOME}"/.aws/config |
723 | awk '{print $2}' | sed 's,],,g' |
724 | fzf --layout reverse --height=30% --border)
725 | export AWS_PROFILE
726 | export AWSCLIPARAMS="--profile=${AWS_PROFILE}"
727 | fi
728 | s2a-keychain "$AWS_PROFILE"
729 |
730 | echo "[You are now using the ${AWS_PROFILE} profile]"
731 | }
732 |
733 | ### END AWS Auth ###
734 |
735 | # A function that checks ssh-add and adds my keys if they're not already added
736 | function ssh-add-keys() {
737 | if ! ssh-add -l | grep -qe 'ED25519\|RSA'; then
738 | ssh-add --apple-use-keychain ~/.ssh/id_*.key
739 | fi
740 | }
741 |
742 | function tmux_create() {
743 | SESSION="$1"
744 | echo "Creating tmux session ${SESSION}"
745 | tmux new-session -d -s "$SESSION"
746 | tmux switch-client -t "$SESSION"
747 | }
748 |
749 | function tmux_attach() {
750 | # If not provided an argument, use fzf to select a session
751 | if [[ -n $1 ]]; then
752 | SESSION="$1"
753 |
754 | # check if there are any sessions
755 | if [[ -z $(tmux ls) ]]; then
756 | echo "No tmux sessions found"
757 | return 1
758 | fi
759 | else
760 | SESSION=$(tmux ls | grep -Eo '^[0-9]+.*' | fzf --layout reverse --height=40% --border | awk '{print $1}')
761 | fi
762 | echo "Attaching to tmux session ${SESSION}"
763 | tmux switch-client -t "$SESSION"
764 | }
765 |
766 | clean_string() {
767 | # Escape special characters in a string such as $, ", ', `, \, and newline.
768 | # Usage: escape_string "string to escape"
769 | local string="${1}"
770 | local escaped_string
771 | escaped_string=$(printf '%q' "${string}")
772 | echo "${escaped_string}"
773 | }
774 |
775 | docker_login_ghcr() {
776 | # Dependencies: gh
777 | set -e
778 |
779 | if [ ! -f ~/.docker/config.json ]; then
780 | echo '{"credsStore": "desktop","credHelpers": {"docker.pkg.github.com": "gh","ghcr.io": "gh"}}' >~/.docker/config.json
781 | fi
782 |
783 | cmd="${1}"
784 | if [ "erase" = "${cmd}" ]; then
785 | cat - >/dev/null
786 | exit 0
787 | fi
788 | if [ "store" = "${cmd}" ]; then
789 | cat - >/dev/null
790 | exit 0
791 | fi
792 | if [ "get" != "${cmd}" ]; then
793 | exit 1
794 | fi
795 |
796 | host="$(cat -)"
797 | host="${host#https://}"
798 | host="${host%/}"
799 | if [ "${host}" != "ghcr.io" ] && [ "${host}" != "docker.pkg.github.com" ]; then
800 | exit 1
801 | fi
802 |
803 | token="$(gh config get -h github.com oauth_token)"
804 | if [ -z "${token}" ]; then
805 | exit 1
806 | fi
807 |
808 | printf '{"Username":"%s", "Secret":"%s"}\n' "$(gh config get -h github.com user)" "${token}"
809 | }
810 |
811 | docker_inspect_all() {
812 | # Get the IDs of all running containers
813 | local container_ids=("$(docker ps -q)")
814 |
815 | # Iterate over each container ID
816 | for container_id in "${container_ids[@]}"; do
817 | # Run docker inspect command and store the output in a variable
818 | local inspect_output=$(docker inspect --format='{{json .}}' "$container_id")
819 |
820 | # Extract container name and remove leading '/'
821 | local container_name=$(jq -r '.Name[1:]' <<<"$inspect_output")
822 |
823 | # Extract container status, creation timestamp, and IP addresses
824 | local container_status=$(jq -r '.State.Status' <<<"$inspect_output")
825 | local created_timestamp=$(jq -r '.Created' <<<"$inspect_output")
826 | local ip_address=$(jq -r '.NetworkSettings.Networks[].IPAddress' <<<"$inspect_output")
827 | local ipv6_address=$(jq -r '.NetworkSettings.Networks[].GlobalIPv6Address' <<<"$inspect_output")
828 |
829 | # Extract forwarded ports
830 | local ports=$(jq -r '.NetworkSettings.Ports | to_entries[] | .key + " -> " + .value[0].HostPort' <<<"$inspect_output")
831 |
832 | # Display the extracted information
833 | echo "Container ID: $container_id"
834 | echo "Container Name: $container_name"
835 | echo "Container Status: $container_status"
836 | echo "Created Timestamp: $created_timestamp"
837 | echo "IP Address: $ip_address"
838 | echo "IPv6 Address: $ipv6_address"
839 | echo "Forwarded Ports: $ports"
840 | echo "-----------------------"
841 | done
842 | }
843 |
844 | ps-docker() {
845 | # ps -aux but with the container name and nice formatting
846 | echo -e "Processing docker containers, this may take a moment...\n"
847 | {
848 | echo -e "CONTAINER NAME\tUSER\tPID\t%CPU\t%MEM\tRUN TIME\tCOMMAND"
849 | ps -aux | awk '{print $2}' | while read pid; do
850 | container_id=$(grep -Eo "docker-([a-f0-9]{64})\.scope" /proc/"$pid"/cgroup 2>/dev/null | head -n1 | grep -Eo "([a-f0-9]{64})")
851 | if [ ! -z "$container_id" ]; then
852 | container_name=$(docker ps --no-trunc | grep "$container_id" | awk '{print $NF}')
853 | if [ ! -z "$container_name" ]; then
854 | ps -p "$pid" -o user,pid,%cpu,%mem,etime,cmd --no-headers | awk -v cn="$container_name" '{printf "%-20s\t%-8s\t%-8s\t%-5s\t%-5s\t%-10s\t%-40s\n", cn, $1, $2, $3, $4, $5, substr($0, index($0,$6))}'
855 | fi
856 | fi
857 | done
858 | } | awk 'BEGIN {OFS="\t"; prev="none"} NR==1 {print} NR>1 {split($0,a,"\t"); if (a[1]!=prev && NR>2) print "--------------------\t\t\t\t\t\t\t"; print; prev=a[1]}'
859 | }
860 |
861 | # 3D Printing
862 | function cura-backup() {
863 | # Zip up the latest cura config from the newest number cura config directory (~/Library/Application\ Support/cura/(number.number) (e.g. 4.8)
864 | # and copy it to the cloud backup folder
865 | local cura_base_dir="${HOME}/Library/Application Support/cura"
866 | local destination="${HOME}/Library/Mobile Documents/com~apple~CloudDocs/Backups/3dprinting/cura"
867 | local latest_version_dir="$(ls -d "${cura_base_dir}"/*/ | tail -n1)"
868 |
869 | # zip it up with the date
870 | local date="$(date +%Y-%m-%d)"
871 | local zip_file="${destination}/cura-${date}.zip"
872 | zip -r "${zip_file}" "${latest_version_dir}"
873 | echo "Created ${zip_file}"
874 | }
875 |
876 | function ripSearch() {
877 | # 1. Search for text in files using Ripgrep
878 | # 2. Interactively narrow down the list using fzf
879 | # 3. Open the file in vscode
880 |
881 | while getopts n OPTION; do
882 | case "${OPTION}" in
883 | n) NEW_WINDOW="--new-window" ;;
884 | *) echo "ERROR: we only support -n" && exit 1 ;;
885 | esac
886 | done
887 | shift $((OPTIND - 1))
888 |
889 | : "${NEW_WINDOW:=""}"
890 |
891 | # Allow the function to be cancelled with Ctrl-C, but don't exit the shell
892 | trap 'return 1' INT
893 |
894 | ARGLIST=""
895 | while IFS=: read -rA SELECTED; do
896 | if [ "${#SELECTED[@]}" -gt 0 ]; then
897 | ARGLIST+="--goto ${SELECTED[0]}:${SELECTED[1]} "
898 | fi
899 | done < <(
900 | rg --color=always --line-number --no-heading --smart-case "${*:-}" |
901 | fzf --ansi \
902 | --color "hl:-1:underline,hl+:-1:underline:reverse" \
903 | --delimiter : \
904 | --multi \
905 | --preview 'bat --color=always {1} --highlight-line {2} --style=header,grid {}' \
906 | --preview-window 'right,60%,border-bottom,+{2}+3/3,~3'
907 | )
908 | if [ -n "${ARGLIST}" ]; then
909 | code "${NEW_WINDOW}" "${ARGLIST}"
910 | fi
911 | }
912 |
913 | ### CAPTURE AND RETURN OUTPUT OF A COMMAND ###
914 | # Usage:
915 | # $ find . -name 'filename' | cap
916 | # /path/to/filename
917 | # $ ret
918 | # /path/to/filename
919 |
920 | # capture the output of a command so it can be retrieved with ret
921 | cap() { tee /tmp/capture.out; }
922 |
923 | # return the output of the most recent command that was captured by cap
924 | ret() { cat /tmp/capture.out; }
925 | ### END CAPTURE AND RETURN OUTPUT OF A COMMAND ###
926 |
927 | # Backup VSCode extensions settings
928 | function backup-vscode() {
929 | local date
930 | date="$(date +%Y-%m-%d)"
931 | local destination="${HOME}/Library/Mobile Documents/com~apple~CloudDocs/Backups/vscode/${date}"
932 | local extensions_file="${destination}/extensions.txt"
933 | local settings_file="${destination}/settings.json"
934 | local keybindings_file="${destination}/keybindings.json"
935 |
936 | mkdir -p "${destination}"
937 |
938 | # List extensions
939 | code --list-extensions >"${extensions_file}"
940 | echo "Created ${extensions_file}"
941 |
942 | # Backup settings
943 | cp "${HOME}/Library/Application Support/Code/User/settings.json" "${settings_file}"
944 | echo "Created:"
945 | echo "$settings_file"
946 |
947 | # Backup keybindings
948 | cp "${HOME}/Library/Application Support/Code/User/keybindings.json" "${keybindings_file}"
949 | echo "$keybindings_file"
950 | }
951 |
952 | ### Github Functions ###
953 | function gh() {
954 | # unset GITHUB_TOKEN for gh cli
955 | GITHUB_TOKEN="" command gh "$@"
956 | }
957 |
958 | function gh_pr_list_open() {
959 | local search_param=""
960 | local other_params=()
961 |
962 | while [[ $# -gt 0 ]]; do
963 | case "$1" in
964 | --match)
965 | search_param="$2"
966 | shift 2
967 | ;;
968 | *)
969 | other_params+=("$1")
970 | shift
971 | ;;
972 | esac
973 | done
974 |
975 | if [[ -n "$search_param" ]]; then
976 | other_params+=("--search=\"$search_param\"")
977 | fi
978 |
979 | gh pr list --state open "${other_params[@]}"
980 | }
981 |
982 | function gh_pr_list_open_dir_repos() {
983 | local search_param=""
984 | local other_params=()
985 |
986 | while [[ $# -gt 0 ]]; do
987 | case "$1" in
988 | --match)
989 | search_param="$2"
990 | shift 2
991 | ;;
992 | *)
993 | other_params+=("$1")
994 | shift
995 | ;;
996 | esac
997 | done
998 |
999 | for repo in */; do
1000 | if [[ -d "$repo" ]]; then
1001 | # Get the repo name from the git config
1002 | repo_name=$(git -C "$repo" config --get remote.origin.url | sed -E 's/.*github.com[:/].*\/(.*)\.git/\1/')
1003 | # Get the repo owner from the git config
1004 | repo_owner=$(git -C "$repo" config --get remote.origin.url | sed -E 's/.*github.com[:/](.*)\/.*/\1/')
1005 |
1006 | echo "Repository: $repo_owner/$repo_name"
1007 |
1008 | gh_pr_list_open --repo "$repo_owner/$repo_name" --match "$search_param" "${other_params[@]}"
1009 |
1010 | echo ""
1011 | fi
1012 | done
1013 | }
1014 |
1015 | function gh_pr_merge_matching() {
1016 | local search_param="$1"
1017 | local other_params=()
1018 |
1019 | while [[ $# -gt 0 ]]; do
1020 | case "$1" in
1021 | --match)
1022 | search_param="$2"
1023 | shift 2
1024 | ;;
1025 | *)
1026 | other_params+=("$1")
1027 | shift
1028 | ;;
1029 | esac
1030 | done
1031 |
1032 | local pr_numbers=()
1033 | gh_pr_list_open --match "$search_param" "${other_params[@]}" | while IFS= read -r pr_info; do
1034 | pr_number=$(echo "$pr_info" | jq -r '.number')
1035 | pr_numbers+=("$pr_number")
1036 | echo "PR #$pr_number: $(echo "$pr_info" | jq -r '.title')"
1037 | done
1038 |
1039 | if [[ ${#pr_numbers[@]} -eq 0 ]]; then
1040 | echo "No matching PRs found."
1041 | return 1
1042 | fi
1043 |
1044 | read -p "Merge and resolve these PRs? (y/n): " choice
1045 | if [[ $choice == [yY] ]]; then
1046 | for pr_number in "${pr_numbers[@]}"; do
1047 | gh pr merge "$pr_number" --auto "${other_params[@]}"
1048 | done
1049 | fi
1050 | }
1051 |
1052 | ### END Github Functions ###
1053 |
1054 | ### Get output from last command ###
1055 | # CTRL+Q,CTRL+L
1056 | zmodload -i zsh/parameter
1057 |
1058 | insert-last-command-output() {
1059 | # shellcheck disable=SC2154
1060 | LBUFFER+="$(eval "$history"[$((HISTCMD - 1))])"
1061 | }
1062 | zle -N insert-last-command-output
1063 |
1064 | bindkey "^Q^L" insert-last-command-output
1065 | ### End get output from last command ###
1066 |
1067 | # if ifup or ifdown is run - remind the user of the correct
1068 | ifup() {
1069 | echo "Did you mean 'ip link set $1 up'?"
1070 | }
1071 |
1072 | ifdown() {
1073 | echo "Did you mean 'ip link set $1 down'?"
1074 | }
1075 |
1076 | # A small function that updates chromium (don't worry - my main browser is Firefox) and removes the extended attributes that cause it to be quarantined by macOS
1077 | __update_chromium() {
1078 | # check if there is an update available from homebrew
1079 | local chromium_update
1080 | chromium_update=$(brew outdated --cask --greedy | grep -i chromium)
1081 |
1082 | if [[ -n $chromium_update ]]; then
1083 | brew upgrade --cask --greedy --no-quarantine chromium
1084 | xattr -d com.apple.quarantine /Applications/Chromium.app
1085 | echo "Updated Chromium to $chromium_update, and removed quarantine attributes."
1086 | fi
1087 | }
1088 |
1089 | # a function that checks for macOS OS updates and downloads them (without installing) then pops up a notification in the background
1090 | function __update_macos() {
1091 | # check for updates
1092 | softwareupdate -l
1093 | if [[ $? -eq 0 ]]; then
1094 | # notify the user there are updates to download and that they may have to enter their password in the terminal
1095 | osascript -e 'display notification "macOS updates are available. You may need to enter your password in the terminal to download them." with title "macOS Update" action button "Show iTerm"'
1096 | # download updates
1097 | softwareupdate -d -a --no-scan --agree-to-license --background
1098 | fi
1099 | }
1100 |
1101 | function ba() {
1102 | # trap ctrl-c
1103 | trap '' SIGINT
1104 |
1105 | # create a log file, if it already exists move it to .1 and create a new one
1106 | local log_file="${HOME}/.ba.log"
1107 | local error_log="${HOME}/.ba.errors.log"
1108 |
1109 | # link all ollama models to lm-studio
1110 | llamalink >>"${log_file}" 2>&1 &
1111 |
1112 | # update vscode packages
1113 | code --update-extensions >>"${log_file}" 2>&1 &
1114 |
1115 | # update homebrew and all apps
1116 | brew update >>"${error_log}" 2>&1
1117 |
1118 | mv "${log_file}" "${log_file}.1"
1119 |
1120 | echo "Upgrading shell and packages in the background, tail -f ${log_file} for details."
1121 |
1122 | touch "${log_file}" "${error_log}"
1123 | echo "Starting update at $(date +%Y-%m-%d) ..." >>"${log_file}"
1124 |
1125 | __upgrade_shell >>"${log_file}" 2>&1 &
1126 | __upgrade_packages >>"${log_file}" 2>&1 &
1127 |
1128 | echo "Upgrading apps in the foreground..."
1129 | __upgrade_apps # >>"${log_file}"
1130 |
1131 | echo "Checking and downloading macOS updates in the background..."
1132 | __update_macos >>"${log_file}" 2>&1 &
1133 |
1134 | # ~/bin/build_ollama.sh >>"${log_file}" 2>&1 &
1135 |
1136 | echo "Upgrading rust in the background..."
1137 | rustup update >>"${log_file}" 2>&1 &
1138 |
1139 | echo "Updating Github Copilot CLI in the background..."
1140 | gh extension upgrade gh-copilot >>"${log_file}" 2>&1 &
1141 |
1142 | # list all background jobs
1143 | jobs
1144 |
1145 | # every 5 seconds, check if any background jobs are paused, if so, foreground them
1146 | while true; do
1147 | sleep 5
1148 | if [[ -n $(jobs -p -s) ]]; then
1149 | sleep 1
1150 | echo -e ""
1151 | fg
1152 | else
1153 | break
1154 | fi
1155 | done
1156 |
1157 | # wait for all background jobs to finish
1158 | wait
1159 | fg # bring the last background job to the foreground
1160 |
1161 | compdump # recompile zsh completion files
1162 |
1163 | echo "Updates complete, see ${log_file} for details."
1164 |
1165 | # unset trap
1166 | trap - SIGINT
1167 | }
1168 |
1169 | function __upgrade_apps() {
1170 | trap 'fg' SIGINT
1171 |
1172 | brew update
1173 | NONINTERACTIVE=1 __update_chromium
1174 | NONINTERACTIVE=1 brew upgrade --greedy --greedy-latest
1175 | NONINTERACTIVE=1 brew upgrade --cask --greedy
1176 | NONINTERACTIVE=1 mas upgrade
1177 | brew cleanup
1178 | brew autoremove
1179 | gup update
1180 |
1181 | # unset trap
1182 | trap - SIGINT
1183 |
1184 | # check for any suspended jobs and foreground them
1185 | if [[ -n $(jobs -p -s) ]]; then
1186 | fg
1187 | fi
1188 | }
1189 |
1190 | function __upgrade_packages() {
1191 | trap 'fg' SIGINT
1192 |
1193 | pip3 install -U pip
1194 | npm i -g npm-check-updates
1195 | \ncu --global
1196 | echo | vim +PluginInstall +qall &>/dev/null
1197 |
1198 | # unset trap
1199 | trap - SIGINT
1200 | }
1201 |
1202 | function __upgrade_shell() {
1203 | zgen selfupdate
1204 | zgen update
1205 | omz update
1206 | }
1207 |
1208 | function __upgrade_docker_compose() {
1209 | VERSION=$(curl --silent https://api.github.com/repos/docker/compose/releases/latest | jq .name -r)
1210 | DESTINATION=/usr/local/bin/docker-compose
1211 | COMPOSE_LOCATION=$(which docker-compose 2>/dev/null)
1212 |
1213 | # Check if we've got docker-compose already installed and if we're using the homebrew version
1214 | if [[ $COMPOSE_LOCATION == "/opt/homebrew/bin/docker-compose" ]]; then
1215 | echo "You're using the homebrew version of docker-compose, skipping update."
1216 | return
1217 | fi
1218 |
1219 | if [[ -f $DESTINATION ]] && [[ $(docker-compose version --short) == "$VERSION" ]]; then
1220 | echo "docker-compose is already up to date."
1221 | return
1222 | else
1223 | curl -L "https://github.com/docker/compose/releases/download/${VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o "$DESTINATION"
1224 | chmod 755 "$DESTINATION"
1225 | ln -fs "$(which docker-compose)" /usr/libexec/docker/cli-plugins/docker-compose
1226 | echo "Updated docker-compose to ${VERSION}"
1227 | fi
1228 | }
1229 |
1230 | # Now in 1-zgen.rc
1231 | # bg_silent() {
1232 | # # background a task quietly and disown
1233 | # { "$@" 2>&3 & } 3>&2 2>/dev/null
1234 | # disown &>/dev/null
1235 | # }
1236 |
1237 | ### OLD
1238 | # # AWS Azure AD login
1239 | # function aws-azure-login() {
1240 | # command aws-azure-login --no-prompt --profile "$@"
1241 | # export AWS_PROFILE=$*
1242 | # export AWSCLIPARAMS="--profile=$*"
1243 | # }
1244 |
1245 | # # saml2aws
1246 | # aad() {
1247 | # local IDPPW INPUT_PROFILE
1248 |
1249 | # # Check for input
1250 | # if [ -z "${1}" ]; then
1251 | # echo "ERROR: account name required, e.g. $(basename "$0") data-dev"
1252 | # return 1
1253 | # else
1254 | # # Cleanup the input
1255 | # INPUT_PROFILE=$(echo "$1" | sed -e 's/dosa/kis/g;s/cust/klue/g')
1256 | # fi
1257 |
1258 | # # Fetch the password from keychain
1259 | # IDPPW=$(keychain_password awsazurepw) # requires mfa and keychain authentication
1260 |
1261 | # aws configure list --profile "${1}"
1262 | # # Login to AWS
1263 | # saml2aws login -a "$INPUT_PROFILE" \
1264 | # --skip-prompt \
1265 | # --password="$IDPPW" \
1266 | # --profile="$INPUT_PROFILE" \
1267 | # --cache-saml &&
1268 | # export AWS_PROFILE="$INPUT_PROFILE" &&
1269 | # export AWSCLIPARAMS="--profile=${INPUT_PROFILE}" &&
1270 | # export AWS_DEFAULT_REGION=ap-southeast-2
1271 | # unset IDPPW
1272 |
1273 | # # Check the login was successful
1274 | # aws --profile "$AWS_PROFILE" sts get-caller-identity
1275 | # }
1276 |
1277 | # function awslogin() {
1278 | # if [ -z "${1}" ]; then
1279 | # echo "ERROR: account name required, e.g. awslogin data-dev"
1280 | # else
1281 | # # Check credentials are current, refresh if needed and export into shell
1282 | # aws configure list --profile "${1}" && eval "$(saml2aws script --profile "${1}")"
1283 | # fi
1284 | # }
1285 |
1286 | # Function to recursively replace the registry in package-lock.json files
1287 | npm_replace_registry() {
1288 | # Define the string to search for and the string to replace it with
1289 | local search_string="${LOCAL_NPM_REGISTRY}"
1290 | local replace_string="registry.npmjs.org"
1291 |
1292 | # skip if search string is empty
1293 | if [ -z "$search_string" ]; then
1294 | return 0
1295 | fi
1296 |
1297 | # Use find to locate all package-lock.json files and loop through them
1298 | find . -type f -name 'package-lock.json' | while read -r file; do
1299 | echo "Processing $file"
1300 |
1301 | # Use sed to perform the string replacement
1302 | sed -i.bak "s|$search_string|$replace_string|g" "$file"
1303 |
1304 | # Remove the backup file created by sed
1305 | rm -f "${file}.bak"
1306 |
1307 | echo "Replaced $search_string with $replace_string in $file"
1308 | done
1309 | }
1310 |
1311 | ### Docker Compose ###
1312 | # Functions to help when working with docker-compose especially with multiple docker-compose files and profiles
1313 |
1314 | # ddc() {
1315 | # local command="$1"
1316 | # shift
1317 | # local service_name="$1"
1318 | # shift
1319 | # local profile=""
1320 |
1321 | # # Iterate through all docker-compose*.yaml files to find the profile
1322 | # for file in docker-compose*.yaml; do
1323 | # # Check if the specified service exists in the file
1324 | # if grep -q "^ $service_name:" "$file"; then
1325 | # # Extract profile name
1326 | # profile_name=$(awk -v service="$service_name" '$1 == service":" { getline; getline; print $3 }' "$file")
1327 | # profile_name="${profile_name#- }"
1328 | # profile_name="${profile_name%\"}"
1329 | # profile_name="${profile_name#\"}"
1330 | # if [[ ! -z "$profile_name" ]]; then
1331 | # profile="--profile $profile_name"
1332 | # fi
1333 | # break
1334 | # fi
1335 | # done
1336 |
1337 | # # Run the docker-compose command
1338 | # docker-compose $profile $command "$service_name" "$@"
1339 | # }
1340 |
1341 | function docker-network() {
1342 | docker ps -q | xargs -n 1 docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}} {{ .Name }}' | sed 's/ \// /' | sort
1343 | }
1344 |
1345 | dpup() {
1346 | pushd "$DOCKER_COMPOSE_DIR" || return
1347 | docker-compose --profile "$1" up -d "$1"
1348 | echo "----"
1349 | docker logs -f "$1"
1350 | popd
1351 | }
1352 |
1353 | # Run docker-compose profiles on a remote (ssh) server
1354 | nas_dcup() {
1355 | local server="$1"
1356 | local profile="$2"
1357 | local service="$3"
1358 | local command="$4"
1359 |
1360 | ssh "$server" "cd ${DOCKER_COMPOSE_DIR} && docker-compose --profile ${profile} ${command} ${service}"
1361 | }
1362 |
1363 | # Yazi https://github.com/sxyazi/yazi
1364 | # https://github.com/sxyazi/yazi/tree/main/config/docs
1365 | function y() {
1366 | tmp="$(mktemp -t "yazi-cwd.XXXXX")"
1367 | yazi --cwd-file="$tmp"
1368 | if cwd="$(cat -- "$tmp")" && [ -n "$cwd" ] && [ "$cwd" != "$PWD" ]; then
1369 | cd -- "$cwd"
1370 | fi
1371 | rm -f -- "$tmp"
1372 | }
1373 |
1374 | function brewbackup() {
1375 | # shellcheck disable=SC2139,SC2153
1376 | brew bundle dump --force --file="/Users/${USER}/Library/Mobile Documents/com~apple~CloudDocs/Backups/homebrew/Brewfile-${HOST}"
1377 | }
1378 |
1379 | # Function to reload updated Zsh functions
1380 | zsh_reload_updated_functions() {
1381 | # Create a unique temporary file to store currently loaded functions
1382 | local temp_file
1383 | temp_file="/tmp/zsh_functions_$(date +%s%N)"
1384 |
1385 | # Extract currently loaded functions into the temporary file
1386 | typeset -f >"$temp_file"
1387 |
1388 | # File containing the function definitions (e.g., ~/.zshrc)
1389 | local source_file="$HOME/.zshrc"
1390 |
1391 | # Find updated functions
1392 | local updated_functions
1393 | updated_functions=$(comm -13 <(awk '/^function / {print $2}' "$temp_file" | sort) <(awk '/^function / {print $2}' "$source_file" | sort))
1394 |
1395 | # Reload updated functions
1396 | for fn in $updated_functions; do
1397 | unfunction "$fn" 2>/dev/null
1398 | source "$source_file"
1399 | echo "Reloaded function: $fn"
1400 | done
1401 |
1402 | # Remove temporary file
1403 | rm -f "$temp_file"
1404 | }
1405 |
1406 | # Update pam to enable touchID for sudo
1407 | function touchid_sudo() {
1408 | # Check if pam is already configured
1409 | if grep -q "pam_tid.so" /etc/pam.d/sudo; then
1410 | echo "pam_tid.so is already configured in /etc/pam.d/sudo"
1411 | return 0
1412 | fi
1413 |
1414 | cat /etc/pam.d/sudo
1415 |
1416 | # Add pam_tid.so to /etc/pam.d/sudo
1417 | echo "Adding pam_tid.so to /etc/pam.d/sudo"
1418 | sudo sed -i '' '1s/^/auth sufficient pam_tid.so\n/' /etc/pam.d/sudo
1419 | }
1420 |
1421 | a() {
1422 | # Extract filename from the URL (the part after the last slash)
1423 | local filename
1424 | filename=$(basename "$1")
1425 |
1426 | # Base aria2c options
1427 | local aria_opts=(
1428 | --split=12
1429 | --always-resume=true
1430 | --max-tries=15
1431 | --retry-wait=3
1432 | --enable-http-pipelining=true
1433 | --http-accept-gzip=true
1434 | --max-connection-per-server=14
1435 | --max-concurrent-downloads=5
1436 | --min-split-size=10M
1437 | --auto-file-renaming=false
1438 | --content-disposition-default-utf8=true
1439 | --disk-cache=64M
1440 | --file-allocation=prealloc
1441 | --out="$filename"
1442 | )
1443 |
1444 | # Check if URL is from Huggingface
1445 | if [[ "$1" == *"huggingface.co"* ]] || [[ "$1" == *"hf.co"* ]]; then
1446 | # Check if HUGGINGFACE_TOKEN is set
1447 | if [ -z "${HUGGINGFACE_TOKEN}" ]; then
1448 | echo "Warning: HUGGINGFACE_TOKEN is not set. You may experience rate limiting."
1449 | else
1450 | # Verify token is valid by making a test request to the newer endpoint
1451 | echo "Verifying Huggingface token..."
1452 | local token_check
1453 | token_check=$(curl -s -I -H "Authorization: Bearer ${HUGGINGFACE_TOKEN}" "https://huggingface.co/api/whoami-v2" | grep -c "HTTP/2 200")
1454 |
1455 | if [ "$token_check" -eq 1 ]; then
1456 | echo "✅ Huggingface token is valid."
1457 | aria_opts+=(--header="Authorization: Bearer ${HUGGINGFACE_TOKEN}")
1458 | else
1459 | echo "⚠️ Huggingface token appears to be invalid. Downloads may be rate limited."
1460 | echo "Note: If your token starts with 'hf_', this is expected format for newer tokens."
1461 | # shellcheck disable=SC2162
1462 | read -p "Continue anyway? (y/n): " confirm
1463 | if [[ "$confirm" != "y" ]]; then
1464 | echo "Download cancelled."
1465 | return 1
1466 | fi
1467 | # Add the token anyway as it might still work for downloads even if validation fails
1468 | aria_opts+=(--header="Authorization: Bearer ${HUGGINGFACE_TOKEN}")
1469 | fi
1470 | fi
1471 | fi
1472 |
1473 | # Run aria2c with the assembled options
1474 | aria2c "${aria_opts[@]}" "$1"
1475 |
1476 | echo "downloaded ${1} as ${filename}"
1477 | }
1478 |
1479 | rename_files() {
1480 | # see also, one liner - find . -name "*sdc-maps*" -exec bash -c 'mv "$0" "${0/sdc/spl}"' {} \;
1481 | local find_word="$1"
1482 | local replace_word="$2"
1483 | local files_to_rename=()
1484 | local new_names=()
1485 |
1486 | if [ -z "$find_word" ] || [ -z "$replace_word" ]; then
1487 | echo "Usage: rename_files "
1488 | return 1
1489 | fi
1490 |
1491 | # Collect the list of files to be renamed
1492 | for f in *"$find_word"*; do
1493 | if [ -e "$f" ]; then # Check if file exists
1494 | files_to_rename+=("$f")
1495 | new_names+=("${f//$find_word/$replace_word}")
1496 | fi
1497 | done
1498 |
1499 | # Display the list of files to be renamed
1500 | echo "Files to be renamed:"
1501 | for i in "${!files_to_rename[@]}"; do
1502 | echo "'${files_to_rename[$i]}' -> '${new_names[$i]}'"
1503 | done
1504 |
1505 | # Ask for confirmation
1506 | echo "Proceed with renaming? (y/n)"
1507 | read -r confirm
1508 | if [ "$confirm" = "y" ] || [ "$confirm" = "Y" ]; then
1509 | for i in "${!files_to_rename[@]}"; do
1510 | mv "${files_to_rename[$i]}" "${new_names[$i]}"
1511 | done
1512 | else
1513 | echo "Renaming cancelled."
1514 | fi
1515 | }
1516 |
1517 | hfdl() {
1518 | local cliargs=()
1519 | # Huggingface download wrapper
1520 | if [[ $# -eq 0 ]]; then
1521 | echo "Usage: hfdl "
1522 | return 1
1523 | fi
1524 |
1525 | local url=$1
1526 |
1527 | # if a third argument is provided, treat it as a file to download (include)
1528 | if [[ $# -eq 2 ]]; then
1529 | local file_to_download="$2"
1530 | cliargs+=("--include" "$file_to_download")
1531 | fi
1532 |
1533 | local stripped_url=$(echo "$url" | sed 's|https://huggingface.co/||')
1534 | local owner=$(echo "$stripped_url" | cut -d'/' -f1)
1535 | local repo=$(echo "$stripped_url" | cut -d'/' -f2)
1536 |
1537 | HF_HUB_ENABLE_HF_TRANSFER=1 huggingface-cli download "$owner/$repo" --local-dir-use-symlinks False --local-dir "$repo" "${cliargs[@]}"
1538 | }
1539 |
1540 | # hide overlayfs in df
1541 | df() {
1542 | # if macOS use /bin/df
1543 | if [[ $(uname) == "Darwin" ]]; then
1544 | /bin/df "$@"
1545 | return
1546 | fi
1547 | /usr/bin/df -x overlay "$@"
1548 | }
1549 |
1550 | gpumem() {
1551 | # Increase the GPU memory limit for my 96GB MBP
1552 | sudo /usr/sbin/sysctl iogpu.wired_limit_mb=86000
1553 | }
1554 |
1555 | # loops through all subdirectories one level deep that are git repos and runs the specified command
1556 | function git-loop() {
1557 | local command="$1"
1558 | shift
1559 | local args=("$@")
1560 |
1561 | for dir in */; do
1562 | if [ -d "$dir/.git" ]; then
1563 | echo "Running $command in $dir"
1564 | git -C "$dir" "$command" "${args[@]}"
1565 | fi
1566 | done
1567 | }
1568 | # Register each git repo in directory with maintenance
1569 | alias git-maintenance-register="git-loop maintenance register"
1570 |
1571 | # If the user runs the conda activate command before running conda init - offer to run conda init, otherwise run conda activate
1572 | function conda() {
1573 | if [[ $1 == "activate" ]]; then
1574 | if [[ -z $CONDA_EXE ]]; then
1575 | echo "Conda is not initialized, would you like to initialize it? (y/n)"
1576 | read -r response
1577 | if [[ $response == "y" ]]; then
1578 | conda_init
1579 | fi
1580 | else
1581 | command conda "$@"
1582 | fi
1583 | else
1584 | command conda "$@"
1585 | fi
1586 | }
1587 |
1588 | # a function that overrides pip commands with uv pip
1589 | function pip() {
1590 | # if the first argument is -n, use the normal pip command
1591 | if [[ $1 == "-n" ]]; then
1592 | command pip "${@:2}"
1593 | return
1594 | fi
1595 | echo "using uv for pip..."
1596 | if [[ $1 == "install" ]]; then
1597 | uv pip install "${@:2}"
1598 | elif [[ $1 == "uninstall" ]]; then
1599 | uv pip uninstall "${@:2}"
1600 | else
1601 | command pip "$@"
1602 | fi
1603 | }
1604 |
1605 | # A function that does an ollama cp of any models that start with sammcj to instead start with registry.domain/ollama/
1606 | # function ollama-cp() {
1607 | # local models
1608 | # local registry
1609 | # registry=$(echo "$OLLAMA_REGISTRY" | sed 's/\//\\\//g')
1610 | # # shellcheck disable=SC2207 # array assignment is intentional
1611 | # models=($(ollama list | grep sammcj | grep -v grep | awk '{print $1}'))
1612 | # # sort by smallest to largest (human readable MB/GB)
1613 | # # calulate the total size of the models
1614 | # total_size=$(ollama list | grep sammcj | grep -v grep | awk '{print $3}' | paste -sd+ - | bc)
1615 | # echo "Total size of models to be considered: ${total_size}GB"
1616 | # # shellcheck disable=SC2207
1617 | # models=($(echo "${models[@]}" | tr ' ' '\n' | sort -h))
1618 | # for model in "${models[@]}"; do
1619 | # echo "Model: $model"
1620 | # new_model=$(echo "$model" | gsed -e s/sammcj/"$registry"/ | tr '[:upper:]' '[:lower:]')
1621 | # # if ollama list | grep -q "$new_model"; then
1622 | # # echo "Model $new_model already exists, skipping"
1623 | # # continue
1624 | # # fi
1625 | # echo "Copying $model to $new_model"
1626 | # ollama cp "$model" "$new_model" && ollama rm "$model"
1627 | # echo "Pushing $new_model"
1628 | # ollama push "$new_model"
1629 | # done
1630 | # }
1631 |
1632 | function ollama-pull-all() {
1633 | local BATCH_SIZE
1634 | local PULL_LOCAL_REGISTRY_MODELS
1635 | PULL_LOCAL_REGISTRY_MODELS=true
1636 | BATCH_SIZE=3
1637 |
1638 | if $PULL_LOCAL_REGISTRY_MODELS; then
1639 | echo "pulling all models in batches of ${BATCH_SIZE}..."
1640 | ollama list | awk '$1 {print $1}' | while read -r model; do
1641 | # pull the modules in parallel batches
1642 | batch_count=$(jobs -p | wc -l)
1643 | if [ "$batch_count" -ge "$BATCH_SIZE" ]; then
1644 | sleep 1
1645 | wait -n
1646 | fi
1647 | echo "Pulling $model"
1648 | ollama pull "$model" &
1649 | done
1650 | else
1651 | echo "pulling all models not in the local registry in batches of ${BATCH_SIZE}..."
1652 | ollama list | awk '$1 !~ /^${OLLAMA_REGISTRY}/ {print $1}' | while read -r model; do
1653 | # pull the modules in parallel batches
1654 | batch_count=$(jobs -p | wc -l)
1655 | if [ "$batch_count" -ge "$BATCH_SIZE" ]; then
1656 | sleep 1
1657 | wait -n
1658 | fi
1659 | echo "Pulling $model"
1660 | ollama pull "$model" &
1661 | done
1662 | fi
1663 |
1664 | # wait for all background jobs to finish
1665 | wait
1666 |
1667 | echo "All models pulled"
1668 |
1669 | }
1670 |
1671 | function aws-sso() {
1672 | if [[ -z $1 ]]; then
1673 | echo "Usage: aws-sso "
1674 | return 1
1675 | fi
1676 | aws sso login --profile "$1"
1677 | eval "$(aws configure export-credentials --format env --profile "$1")"
1678 | export AWS_PROFILE="$1"
1679 | export AWS_REGION=ap-southeast-2
1680 | }
1681 | alias aws-ai="aws-sso aisandpit"
1682 |
1683 | function aws-nas() {
1684 | /Users/samm/Library/Mobile\ Documents/com~apple~CloudDocs/Dropbox\ Import/dotfiles/shell_config/update-aws-creds.sh aisandpit
1685 | }
1686 |
1687 | ollama_extend_models() {
1688 | local ctx_size=${1:-32768}
1689 |
1690 | # Prompt the user if they want to proceed
1691 | read -r -p "This will create longer context (${ctx_size}) models for all ollama models. Do you want to proceed? (y/n): " choice
1692 | if [[ $choice != [yY] ]]; then
1693 | echo "Aborting..."
1694 | return 1
1695 | fi
1696 |
1697 | # Run ollama ls and process each line
1698 | ollama ls | tail -n +2 | while read -r line; do
1699 | # Extract model name
1700 | model_name=$(echo "$line" | awk '{print $1}')
1701 |
1702 | # Split model name into base name and variant
1703 | base_name=$(echo "$model_name" | cut -d':' -f1)
1704 | variant=$(echo "$model_name" | cut -d':' -f2)
1705 |
1706 | # Create Modelfile
1707 | cat >"Modelfile-$model_name" <= 551 and want to
17 | # enable mouse scrolling support in `bat` when running inside tmux. This might
18 | # disable text selection, unless you press shift.
19 | #--pager="less --RAW-CONTROL-CHARS --quit-if-one-screen --mouse"
20 |
21 | # Syntax mappings: map a certain filename pattern to a language.
22 | # Example 1: use the C++ syntax for Arduino .ino files
23 | # Example 2: Use ".gitignore"-style highlighting for ".ignore" files
24 | #--map-syntax "*.ino:C++"
25 | #--map-syntax ".ignore:Git Ignore"
26 |
--------------------------------------------------------------------------------
/bootstrap_shell.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Sets up my:
4 | # - zsh shell
5 | # - dotfiles
6 | # - packages
7 | #
8 | # Requirements:
9 | # - macOS
10 | # - iCloud synced, internet access
11 | # - Homebrew, git installed
12 | # - Probably some other things I've forgotten
13 |
14 | THIS_REPO="${HOME}/Library/Mobile\ Documents/com\~apple\~CloudDocs/Dropbox\ Import/dotfiles/shell_config/"
15 |
16 | # If ssh keys are not already added, add them
17 | if ! ssh-add -l | grep -e 'ED25519\|RSA'; then
18 | ssh-add --apple-use-keychain ~/.ssh/id_*.key
19 | fi
20 |
21 | function installHomebrew() {
22 | if ! command -v brew &>/dev/null; then
23 | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
24 | fi
25 |
26 | # Brew installs moved to Brewfile (brew bundle dump to generate)
27 | brew bundle
28 | }
29 |
30 | function installPythonPackages() {
31 | curl -LsSf https://astral.sh/uv/install.sh | sh # Install uv via astral
32 |
33 | pushd "$HOME"
34 | uv venv
35 | . venv/bin/activate
36 | popd
37 | uv pip3 install -U mu-repo oterm
38 |
39 | oterm --install-completion zsh
40 | }
41 |
42 | # Ensure we don't have those pesky ^ in our package.json files
43 | npm config set save-exact=true
44 |
45 | function installNpmPackages() {
46 | npm install -g npm-check-updates eslint prettier editorconfig \
47 | @typescript-eslint/parser typescript ts-node bash-language-server
48 | }
49 |
50 | function clone_repo() {
51 | if [[ -d "$1" ]]; then
52 | echo "Directory $1 already exists"
53 | read -r -p "Do you want to replace it with a clone of the repo $2? [y/N] " response
54 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
55 | rm -rf "$1"
56 | git clone "$2" "$1" --depth=1
57 | fi
58 | else
59 | echo "No changes made to $1"
60 | fi
61 | }
62 |
63 | function installGoPackages() {
64 | go install github.com/rhysd/actionlint/cmd/actionlint@latest
65 | go install github.com/nao1215/gup@latest # gup - updates go packages
66 | go install github.com/jesseduffield/lazydocker@latest
67 | go install github.com/rs/dnstrace@latest
68 |
69 | }
70 |
71 | function installCargoPackages() {
72 | if ! command -v cargo &>/dev/null; then
73 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Install rust via rustup
74 | fi
75 |
76 | # Install cargo packages
77 | cargo install cai code2prompt gitu lazycli
78 | }
79 |
80 | function installAsdf() {
81 | ### asdf ###
82 |
83 | ## install plugins
84 | # languages
85 | asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs.git
86 | asdf plugin-add yarn https://github.com/twuni/asdf-yarn.git
87 | asdf plugin-add golang https://github.com/kennyp/asdf-golang.git
88 | asdf plugin-add rust https://github.com/code-lever/asdf-rust.git
89 |
90 | # asdf plugin-add python https://github.com/danhper/asdf-python.git
91 |
92 | # Tools that are only available via asdf
93 | asdf plugin-add action-validator https://github.com/mpalmer/action-validator.git
94 | asdf plugin-add semver https://github.com/mathew-fleisch/asdf-semver.git
95 |
96 | # # Terraform
97 | # asdf plugin-add tfenv https://github.com/carlduevel/asdf-tfenv.git
98 | # asdf plugin-add tfsec https://github.com/woneill/asdf-tfsec.git
99 | # asdf plugin-add terraform https://github.com/asdf-community/asdf-hashicorp.git
100 | # asdf plugin-add terraform-ls https://github.com/asdf-community/asdf-hashicorp.git
101 | # asdf plugin-add terraform-validator https://github.com/asdf-community/asdf-hashicorp.git
102 | # asdf plugin-add tfupdate https://github.com/yuokada/asdf-tfupdate.git
103 | # asdf plugin-add tfstate-lookup https://github.com/carnei-ro/asdf-tfstate-lookup.git
104 |
105 | # Install all asdf plugins
106 | asdf plugin-update --all
107 | }
108 |
109 | function installDockerCompose() {
110 | # Docker compose v2
111 | mkdir -p ~/.docker/cli-plugins/
112 | chmod +x ~/.docker/cli-plugins/docker-compose
113 | ln -sfn /opt/homebrew/opt/docker-compose/bin/docker-compose "${HOME}/.docker/cli-plugins/docker-compose"
114 | }
115 |
116 | function installZshZgen() {
117 | mkdir -p "${HOME}/.zsh.d"
118 | grep -q -F '/opt/homebrew/bin/zsh' /etc/shells || echo '/opt/homebrew/bin/zsh' | sudo tee -a /etc/shells
119 | clone_repo "${HOME}/.zgen" "https://github.com/tarjoilija/zgen.git"
120 | }
121 |
122 | function installTmuxTpm() {
123 | clone_repo "${HOME}/.tmux/plugins/tpm"
124 | }
125 |
126 | ## Local functions ##
127 | function link_dotfile() {
128 | # Error if there are more than two arguments
129 | if [[ $# -gt 2 ]]; then
130 | echo "Too many arguments"
131 | return 1
132 | fi
133 | # Check if there is a second argument, if so, use it as the destination file name otherwise use the source file name
134 | if [ -z "$2" ]; then
135 | local DEST="${HOME}/${1}"
136 | else
137 | local DEST="${HOME}/${2}"
138 | # Check if the directories up to the destination file exist, if not, create them
139 | if [ ! -d "$(dirname "${DEST}")" ]; then
140 | mkdir -p "$(dirname "${DEST}")"
141 | fi
142 | fi
143 | if [[ -f "$DEST" ]]; then
144 | echo "File $DEST already exists"
145 | read -r -p "Do you want to replace it with a symlink to the file in this repo? [y/N] " response
146 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
147 | rm -f "$DEST"
148 | ln -s "${THIS_REPO}/$1" "${HOME}/${DEST}"
149 | else
150 | exit 1
151 | #shellcheck disable=SC2317
152 | echo "No changes made to ${DEST}"
153 | fi
154 |
155 | fi
156 | }
157 |
158 | function gitConfig() {
159 | clone_repo "${HOME}/.git/fuzzy" "https://github.com/bigH/git-fuzzy.git" && ln -s "${HOME}/.git/fuzzy/bin/git-fuzzy" "${HOME}/bin/git-fuzzy"
160 |
161 | # git
162 | git config --global branch.autoSetupMerge true
163 | git config --global --add --bool push.autoSetupRemote true
164 | git config --global rerere.enabled true
165 | git config --global rerere.autoUpdate true
166 | git config --global branch.sort -committerdate
167 | git config --global alias.fpush push --force-with-lease
168 | git config --global help.autocorrect 1
169 | git config --global diff.algorithm histogram
170 | git config --global rebase.autosquash true
171 | git config --global merge.conflictstyle zdiff3
172 | git config --global fetch.prunetags true
173 | git config --global log.date iso
174 | git config --global diff.tool difftastic # brew install difftastic / cargo install --locked difftastic
175 | git config --global push.followtags true
176 | git maintenance start
177 | git maintenance register
178 | }
179 |
180 | function macOSConfig() {
181 | # Completion plugins
182 | gh completion -s zsh >/usr/local/share/zsh/site-functions/_gh
183 |
184 | # Increase the density of status bar icons
185 | defaults -currentHost write -globalDomain NSStatusItemSelectionPadding -int 3
186 |
187 | echo "Do you want to enable touchID for sudo? [y/N]"
188 | read -r response
189 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
190 | source '9-functions.rc'
191 | touchid_sudo
192 | fi
193 | }
194 |
195 | function configureDotfiles() {
196 | # Link dotfiles
197 | dotfiles=(".gitignoreglobal" ".gitconfig" ".vimrc" ".gitconfig_nopush" ".gitconfig.private" ".dircolors" ".tmux.conf" ".zshrc" ".asdfrc")
198 | for dotfile in "${dotfiles[@]}"; do
199 | link_dotfile "$dotfile"
200 | done
201 |
202 | link_dotfile "bat-config" "/Users/samm/.config/bat/config"
203 | link_dotfile "rsyncd.conf" "/Users/samm/.rsyncd.conf"
204 |
205 | # TODO: clean this up
206 | ln -s /Users/samm/Library/Mobile\ Documents/com~apple~CloudDocs/Dropbox\ Import/dotfiles/aider/.aider.conf.yml $HOME/.aider.conf.yml
207 | ln -s /Users/samm/Library/Mobile\ Documents/com~apple~CloudDocs/Dropbox\ Import/dotfiles/aider/.aider.models.json $HOME/.aider.models.json
208 | }
209 |
210 | function main() {
211 | installHomebrew
212 | installPythonPackages
213 | installGoPackages
214 | installCargoPackages
215 | installNpmPackages
216 |
217 | installDockerCompose
218 |
219 | installZshZgen
220 | installTmuxTpm
221 |
222 | macOSConfig
223 | gitConfig
224 | configureDotfiles
225 | }
226 |
227 | # Run the main functions to install and configure
228 | main
229 |
230 | echo "Done"
231 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | parserPreset: 'conventional-changelog-conventionalcommits',
3 | rules: {
4 | 'body-leading-blank': [1, 'always'],
5 | 'body-max-line-length': [2, 'always', 100],
6 | 'footer-leading-blank': [1, 'always'],
7 | 'footer-max-line-length': [2, 'always', 100],
8 | 'header-max-length': [2, 'always', 100],
9 | 'subject-case': [2, 'never', ['sentence-case', 'start-case', 'pascal-case', 'upper-case']],
10 | 'subject-empty': [2, 'never'],
11 | 'subject-full-stop': [2, 'never', '.'],
12 | 'type-case': [2, 'always', 'lower-case'],
13 | 'type-empty': [2, 'never'],
14 | 'type-enum': [
15 | 2,
16 | 'always',
17 | [
18 | 'build',
19 | 'chore',
20 | 'ci',
21 | 'docs',
22 | 'feat',
23 | 'fix',
24 | 'perf',
25 | 'refactor',
26 | 'revert',
27 | 'style',
28 | 'test',
29 | ],
30 | ],
31 | },
32 | prompt: {
33 | questions: {
34 | type: {
35 | description: "Select the type of change that you're committing",
36 | enum: {
37 | feat: {
38 | description: 'A new feature',
39 | title: 'Features',
40 | emoji: '✨',
41 | },
42 | fix: {
43 | description: 'A bug fix',
44 | title: 'Bug Fixes',
45 | emoji: '🐛',
46 | },
47 | docs: {
48 | description: 'Documentation only changes',
49 | title: 'Documentation',
50 | emoji: '📚',
51 | },
52 | style: {
53 | description:
54 | 'Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)',
55 | title: 'Styles',
56 | emoji: '💎',
57 | },
58 | refactor: {
59 | description: 'A code change that neither fixes a bug nor adds a feature',
60 | title: 'Code Refactoring',
61 | emoji: '📦',
62 | },
63 | perf: {
64 | description: 'A code change that improves performance',
65 | title: 'Performance Improvements',
66 | emoji: '🚀',
67 | },
68 | test: {
69 | description: 'Adding missing tests or correcting existing tests',
70 | title: 'Tests',
71 | emoji: '🚨',
72 | },
73 | build: {
74 | description:
75 | 'Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)',
76 | title: 'Builds',
77 | emoji: '🛠',
78 | },
79 | ci: {
80 | description:
81 | 'Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)',
82 | title: 'Continuous Integrations',
83 | emoji: '⚙️',
84 | },
85 | chore: {
86 | description: "Other changes that don't modify src or test files",
87 | title: 'Chores',
88 | emoji: '♻️',
89 | },
90 | revert: {
91 | description: 'Reverts a previous commit',
92 | title: 'Reverts',
93 | emoji: '🗑',
94 | },
95 | },
96 | },
97 | scope: {
98 | description: 'What is the scope of this change (e.g. component or file name)',
99 | },
100 | subject: {
101 | description: 'Write a short, imperative tense description of the change',
102 | },
103 | body: {
104 | description: 'Provide a longer description of the change',
105 | },
106 | isBreaking: {
107 | description: 'Are there any breaking changes?',
108 | },
109 | breakingBody: {
110 | description:
111 | 'A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself',
112 | },
113 | breaking: {
114 | description: 'Describe the breaking changes',
115 | },
116 | isIssueAffected: {
117 | description: 'Does this change affect any open issues?',
118 | },
119 | issuesBody: {
120 | description:
121 | 'If issues are closed, the commit requires a body. Please enter a longer description of the commit itself',
122 | },
123 | issues: {
124 | description: 'Add issue references (e.g. "fix #123", "re #123".)',
125 | },
126 | },
127 | },
128 | };
129 |
--------------------------------------------------------------------------------
/dircolors:
--------------------------------------------------------------------------------
1 | # Configuration file for dircolors, a utility to help you set the
2 | # LS_COLORS environment variable used by GNU ls with the --color option.
3 |
4 | # Copyright (C) 1996-2022 Free Software Foundation, Inc.
5 | # Copying and distribution of this file, with or without modification,
6 | # are permitted provided the copyright notice and this notice are preserved.
7 |
8 | # The keywords COLOR, OPTIONS, and EIGHTBIT (honored by the
9 | # slackware version of dircolors) are recognized but ignored.
10 |
11 | # Global config options can be specified before TERM or COLORTERM entries
12 |
13 | # Below are TERM or COLORTERM entries, which can be glob patterns, which
14 | # restrict following config to systems with matching environment variables.
15 | COLORTERM ?*
16 | TERM Eterm
17 | TERM ansi
18 | TERM *color*
19 | TERM con[0-9]*x[0-9]*
20 | TERM cons25
21 | TERM console
22 | TERM *direct*
23 | TERM dtterm
24 | TERM gnome
25 | TERM hurd
26 | TERM jfbterm
27 | TERM konsole
28 | TERM kterm
29 | TERM linux
30 | TERM linux-c
31 | TERM mlterm
32 | TERM putty
33 | TERM rxvt*
34 | TERM screen*
35 | TERM st
36 | TERM terminator
37 | TERM tmux*
38 | TERM vt48;2;98;114;164
39 | TERM xterm*
40 |
41 | # Below are the color init strings for the basic file types.
42 | # One can use codes for 256 or more colors supported by modern terminals.
43 | # The default color codes use the capabilities of an 8 color terminal
44 | # with some additional attributes as per the following codes:
45 | # Attribute codes:
46 | # 00=none 01=bold 04=underscore 05=blink 07=reverse 08=concealed
47 | # Text color codes:
48 | # 38;2;33;34;44=black 38;2;255;85;85=red 38;2;80;250;123=green 38;2;241;250;140=yellow 38;2;189;147;249=blue 38;2;255;121;198=magenta 38;2;139;233;253=cyan 38;2;248;248;242=white
49 | # Background color codes:
50 | # 48;2;33;34;44=black 48;2;255;85;85=red 48;2;80;250;123=green 48;2;241;250;140=yellow 48;2;189;147;249=blue 48;2;255;121;198=magenta 48;2;139;233;253=cyan 48;2;248;248;242=white
51 | #NORMAL 00 # no color code at all
52 | #FILE 00 # regular file: use no color at all
53 | RESET 0 # reset to "normal" color
54 | DIR 01;38;2;189;147;249 # directory
55 | LINK 01;38;2;139;233;253 # symbolic link. (If you set this to 'target' instead of a
56 | # numerical value, the color is as for the file pointed to.)
57 | MULTIHARDLINK 00 # regular file with more than one link
58 | FIFO 48;2;33;34;44;38;2;241;250;140 # pipe
59 | SOCK 01;38;2;255;121;198 # socket
60 | DOOR 01;38;2;255;121;198 # door
61 | BLK 48;2;33;34;44;38;2;241;250;140;01 # block device driver
62 | CHR 48;2;33;34;44;38;2;241;250;140;01 # character device driver
63 | ORPHAN 48;2;33;34;44;38;2;255;85;85;01 # symlink to nonexistent file, or non-stat'able file ...
64 | MISSING 00 # ... and the files they point to
65 | SETUID 38;2;248;248;242;48;2;255;85;85 # file that is setuid (u+s)
66 | SETGID 38;2;33;34;44;48;2;241;250;140 # file that is setgid (g+s)
67 | CAPABILITY 00 # file with capability (very expensive to lookup)
68 | STICKY_OTHER_WRITABLE 38;2;33;34;44;48;2;80;250;123 # dir that is sticky and other-writable (+t,o+w)
69 | OTHER_WRITABLE 38;2;189;147;249;48;2;80;250;123 # dir that is other-writable (o+w) and not sticky
70 | STICKY 38;2;248;248;242;48;2;189;147;249 # dir with the sticky bit set (+t) and not other-writable
71 |
72 | # This is for files with execute permission:
73 | EXEC 01;38;2;80;250;123
74 |
75 | # List any file extensions like '.gz' or '.tar' that you would like ls
76 | # to color below. Put the extension, a space, and the color init string.
77 | # (and any comments you want to add after a '#')
78 |
79 | # If you use DOS-style suffixes, you may want to uncomment the following:
80 | #.cmd 01;38;2;80;250;123 # executables (bright green)
81 | #.exe 01;38;2;80;250;123
82 | #.com 01;38;2;80;250;123
83 | #.btm 01;38;2;80;250;123
84 | #.bat 01;38;2;80;250;123
85 | # Or if you want to color scripts even if they do not have the
86 | # executable bit actually set.
87 | #.sh 01;38;2;80;250;123
88 | #.csh 01;38;2;80;250;123
89 |
90 | # archives or compressed (bright red)
91 | .tar 01;38;2;255;85;85
92 | .tgz 01;38;2;255;85;85
93 | .arc 01;38;2;255;85;85
94 | .arj 01;38;2;255;85;85
95 | .taz 01;38;2;255;85;85
96 | .lha 01;38;2;255;85;85
97 | .lz4 01;38;2;255;85;85
98 | .lzh 01;38;2;255;85;85
99 | .lzma 01;38;2;255;85;85
100 | .tlz 01;38;2;255;85;85
101 | .txz 01;38;2;255;85;85
102 | .tzo 01;38;2;255;85;85
103 | .t7z 01;38;2;255;85;85
104 | .zip 01;38;2;255;85;85
105 | .z 01;38;2;255;85;85
106 | .dz 01;38;2;255;85;85
107 | .gz 01;38;2;255;85;85
108 | .lrz 01;38;2;255;85;85
109 | .lz 01;38;2;255;85;85
110 | .lzo 01;38;2;255;85;85
111 | .xz 01;38;2;255;85;85
112 | .zst 01;38;2;255;85;85
113 | .tzst 01;38;2;255;85;85
114 | .bz2 01;38;2;255;85;85
115 | .bz 01;38;2;255;85;85
116 | .tbz 01;38;2;255;85;85
117 | .tbz2 01;38;2;255;85;85
118 | .tz 01;38;2;255;85;85
119 | .deb 01;38;2;255;85;85
120 | .rpm 01;38;2;255;85;85
121 | .jar 01;38;2;255;85;85
122 | .war 01;38;2;255;85;85
123 | .ear 01;38;2;255;85;85
124 | .sar 01;38;2;255;85;85
125 | .rar 01;38;2;255;85;85
126 | .alz 01;38;2;255;85;85
127 | .ace 01;38;2;255;85;85
128 | .zoo 01;38;2;255;85;85
129 | .cpio 01;38;2;255;85;85
130 | .7z 01;38;2;255;85;85
131 | .rz 01;38;2;255;85;85
132 | .cab 01;38;2;255;85;85
133 | .wim 01;38;2;255;85;85
134 | .swm 01;38;2;255;85;85
135 | .dwm 01;38;2;255;85;85
136 | .esd 01;38;2;255;85;85
137 |
138 | # image formats
139 | .avif 01;38;2;255;121;198
140 | .jpg 01;38;2;255;121;198
141 | .jpeg 01;38;2;255;121;198
142 | .mjpg 01;38;2;255;121;198
143 | .mjpeg 01;38;2;255;121;198
144 | .gif 01;38;2;255;121;198
145 | .bmp 01;38;2;255;121;198
146 | .pbm 01;38;2;255;121;198
147 | .pgm 01;38;2;255;121;198
148 | .ppm 01;38;2;255;121;198
149 | .tga 01;38;2;255;121;198
150 | .xbm 01;38;2;255;121;198
151 | .xpm 01;38;2;255;121;198
152 | .tif 01;38;2;255;121;198
153 | .tiff 01;38;2;255;121;198
154 | .png 01;38;2;255;121;198
155 | .svg 01;38;2;255;121;198
156 | .svgz 01;38;2;255;121;198
157 | .mng 01;38;2;255;121;198
158 | .pcx 01;38;2;255;121;198
159 | .mov 01;38;2;255;121;198
160 | .mpg 01;38;2;255;121;198
161 | .mpeg 01;38;2;255;121;198
162 | .m2v 01;38;2;255;121;198
163 | .mkv 01;38;2;255;121;198
164 | .webm 01;38;2;255;121;198
165 | .webp 01;38;2;255;121;198
166 | .ogm 01;38;2;255;121;198
167 | .mp4 01;38;2;255;121;198
168 | .m4v 01;38;2;255;121;198
169 | .mp4v 01;38;2;255;121;198
170 | .vob 01;38;2;255;121;198
171 | .qt 01;38;2;255;121;198
172 | .nuv 01;38;2;255;121;198
173 | .wmv 01;38;2;255;121;198
174 | .asf 01;38;2;255;121;198
175 | .rm 01;38;2;255;121;198
176 | .rmvb 01;38;2;255;121;198
177 | .flc 01;38;2;255;121;198
178 | .avi 01;38;2;255;121;198
179 | .fli 01;38;2;255;121;198
180 | .flv 01;38;2;255;121;198
181 | .gl 01;38;2;255;121;198
182 | .dl 01;38;2;255;121;198
183 | .xcf 01;38;2;255;121;198
184 | .xwd 01;38;2;255;121;198
185 | .yuv 01;38;2;255;121;198
186 | .cgm 01;38;2;255;121;198
187 | .emf 01;38;2;255;121;198
188 |
189 | # https://wiki.xiph.org/MIME_Types_and_File_Extensions
190 | .ogv 01;38;2;255;121;198
191 | .ogx 01;38;2;255;121;198
192 |
193 | # audio formats
194 | .aac 00;38;2;139;233;253
195 | .au 00;38;2;139;233;253
196 | .flac 00;38;2;139;233;253
197 | .m4a 00;38;2;139;233;253
198 | .mid 00;38;2;139;233;253
199 | .midi 00;38;2;139;233;253
200 | .mka 00;38;2;139;233;253
201 | .mp3 00;38;2;139;233;253
202 | .mpc 00;38;2;139;233;253
203 | .ogg 00;38;2;139;233;253
204 | .ra 00;38;2;139;233;253
205 | .wav 00;38;2;139;233;253
206 |
207 | # https://wiki.xiph.org/MIME_Types_and_File_Extensions
208 | .oga 00;38;2;139;233;253
209 | .opus 00;38;2;139;233;253
210 | .spx 00;38;2;139;233;253
211 | .xspf 00;38;2;139;233;253
212 |
213 | # backup files
214 | *~ 00;38;2;98;114;164
215 | *# 00;38;2;98;114;164
216 | .bak 00;38;2;98;114;164
217 | .old 00;38;2;98;114;164
218 | .orig 00;38;2;98;114;164
219 | .part 00;38;2;98;114;164
220 | .rej 00;38;2;98;114;164
221 | .swp 00;38;2;98;114;164
222 | .tmp 00;38;2;98;114;164
223 | .dpkg-dist 00;38;2;98;114;164
224 | .dpkg-old 00;38;2;98;114;164
225 | .ucf-dist 00;38;2;98;114;164
226 | .ucf-new 00;38;2;98;114;164
227 | .ucf-old 00;38;2;98;114;164
228 | .rpmnew 00;38;2;98;114;164
229 | .rpmorig 00;38;2;98;114;164
230 | .rpmsave 00;38;2;98;114;164
231 |
232 | # Subsequent TERM or COLORTERM entries, can be used to add / override
233 | # config specific to those matching environment variables.
234 |
--------------------------------------------------------------------------------
/githooks/pre-push:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # This script can be run as a pre-push hook locally on repositories to add messages / ensure we're not pushing to the wrong branch etc...
4 |
5 | branch_name=$(git symbolic-ref --short HEAD)
6 | if [ "$branch_name" == "main" ] || [ "$branch_name" == "master" ]; then
7 | echo "WARNING: You are pushing to the $branch_name branch!"
8 | read -r -p "Are you sure you want to push to $branch_name? [y/N] " response
9 | if [[ "$response" =~ ^([yY][eE][sS]|[yY])$ ]]; then
10 | echo "Pushing to $branch_name"
11 | else
12 | echo "Aborting push"
13 | exit 1
14 | fi
15 | fi
16 |
--------------------------------------------------------------------------------
/htoprc:
--------------------------------------------------------------------------------
1 | # Beware! This file is rewritten by htop when settings are changed in the interface.
2 | # The parser is also very primitive, and not human-friendly.
3 | htop_version=3.2.2
4 | config_reader_min_version=3
5 | fields=0 48 17 18 38 39 40 2 52 46 47 111 115 116 49 1
6 | hide_kernel_threads=1
7 | hide_userland_threads=1
8 | hide_running_in_container=0
9 | shadow_other_users=1
10 | show_thread_names=0
11 | show_program_path=1
12 | highlight_base_name=1
13 | highlight_deleted_exe=1
14 | shadow_distribution_path_prefix=1
15 | highlight_megabytes=1
16 | highlight_threads=1
17 | highlight_changes=0
18 | highlight_changes_delay_secs=5
19 | find_comm_in_cmdline=1
20 | strip_exe_from_cmdline=1
21 | show_merged_command=1
22 | header_margin=1
23 | screen_tabs=1
24 | detailed_cpu_time=1
25 | cpu_count_from_one=0
26 | show_cpu_usage=1
27 | show_cpu_frequency=1
28 | show_cpu_temperature=1
29 | degree_fahrenheit=0
30 | update_process_names=0
31 | account_guest_in_cpu_meter=0
32 | color_scheme=6
33 | enable_mouse=0
34 | delay=15
35 | hide_function_bar=0
36 | header_layout=two_50_50
37 | column_meters_0=AllCPUs2 Memory
38 | column_meter_modes_0=1 1
39 | column_meters_1=Tasks Systemd Swap LoadAverage DiskIO NetworkIO Uptime
40 | column_meter_modes_1=2 2 1 2 2 2 2
41 | tree_view=0
42 | sort_key=47
43 | tree_sort_key=46
44 | sort_direction=-1
45 | tree_sort_direction=-1
46 | tree_view_always_by_pid=0
47 | all_branches_collapsed=0
48 | screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT M_SHARE STATE PERCENT_NORM_CPU PERCENT_CPU PERCENT_MEM IO_RATE PERCENT_CPU_DELAY PERCENT_IO_DELAY TIME Command
49 | .sort_key=PERCENT_MEM
50 | .tree_sort_key=PERCENT_CPU
51 | .tree_view=0
52 | .tree_view_always_by_pid=0
53 | .sort_direction=-1
54 | .tree_sort_direction=-1
55 | .all_branches_collapsed=0
56 | screen:I/O=PID USER IO_PRIORITY IO_RATE IO_READ_RATE IO_WRITE_RATE PERCENT_SWAP_DELAY PERCENT_IO_DELAY Command
57 | .sort_key=IO_RATE
58 | .tree_sort_key=PID
59 | .tree_view=0
60 | .tree_view_always_by_pid=0
61 | .sort_direction=-1
62 | .tree_sort_direction=1
63 | .all_branches_collapsed=0
64 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": ["github>sammcj/renovate-config"],
4 | "description": "This file is managed in automation-repo",
5 | "assignees": ["sammcj"],
6 | "ignorePaths": [
7 | ".github/workflows/codeball.yml",
8 | ".github/workflows/detect-secrets.yml",
9 | ".github/workflows/label-sync.yml",
10 | ".github/workflows/lint-docker.yml",
11 | ".github/workflows/lint-pr-actions-skip.yml",
12 | ".github/workflows/lint-pr-actions.yml",
13 | ".github/workflows/lint-pr-markdown.yml",
14 | ".github/workflows/lint-tf.yml",
15 | ".github/workflows/mirror.yml",
16 | ".github/workflows/pr-labeller.yml",
17 | ".github/workflows/todo.yml",
18 | ".github/workflows/workflows_disabled/*.yml",
19 | ".github/workflows/delete-disabled-workflows.yml",
20 | "files/**",
21 | "themes/**",
22 | "dist/**",
23 | "node_modules/**"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/rsyncd.conf:
--------------------------------------------------------------------------------
1 | # ~/.rsyncd.conf
2 |
3 | exclude=lost+found/ .DS_Store
4 | ignore_nonreadable=yes
5 | rsync_long_args=--partial --progress --verbose
6 |
--------------------------------------------------------------------------------
/run_tests.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #
3 | # Assumptions
4 | # - shellcheck is installed `brew install shellcheck`
5 |
6 | echo "Testing bootstrap_shells.sh for bash errors..."
7 | shellcheck bootstrap_shell.sh
8 |
9 | echo "Testing this script (run_tests.sh) for bash errors..."
10 | shellcheck run_tests.sh
11 |
12 | echo "Testing included .rc files for bash errors..."
13 | shellcheck -e SC1090 -e SC2148 -e SC2034 ./*.rc
14 |
--------------------------------------------------------------------------------
/tmux.conf:
--------------------------------------------------------------------------------
1 | # vim: ft=tmux
2 |
3 | # List of plugins
4 | set -g @plugin 'tmux-plugins/tpm'
5 | set -g @plugin 'tmux-plugins/tmux-sensible'
6 | set -g @plugin '27medkamal/tmux-session-wizard'
7 | set -g @plugin 'dracula/tmux'
8 | set -g @plugin 'laktak/extrakto'
9 | # Don't forget to run prefix + I to install plugins
10 |
11 | # Source .tmux.conf as suggested in `man tmux`
12 | unbind r
13 | bind r source-file ~/.tmux.conf \; display-message 'Configuration reloaded.'
14 |
15 |
16 | # Dracula
17 | set -g @dracula-show-fahrenheit false
18 | set -g @dracula-show-weather false
19 | set -g @dracula-show-location false
20 | set -g @dracula-show-empty-plugins false
21 | set -g @dracula-show-timezone false
22 | set -g @dracula-show-battery false
23 | set -g @dracula-cpu-display-load false
24 | set -g @dracula-cpu-display-temperature false
25 | set -g @dracula-cpu-display-frequency false
26 | set -g @dracula-cpu-display-usage false
27 | set -g @dracula-cpu-display-cores false
28 | set -g @dracula-cpu-display-threads false
29 | set -g @dracula-cpu-display-temperature false
30 | set -g @dracula-plugins "git time"
31 |
32 | # Bind to CTRL+z
33 | unbind C-b
34 | set-option -g prefix C-z
35 | bind-key C-z send-prefix
36 | bind z last-window
37 |
38 | # bind CTRL+a to go to start of line
39 | unbind C-a
40 | bind C-a send-prefix
41 | # bind-key C-a send-key C-a
42 |
43 | # Bind to CTRL+a
44 | # unbind C-b
45 | # set-option -g prefix C-a
46 | # bind-key C-a send-prefix
47 | # bind a last-window
48 |
49 | # Dont break CTRL+Left/Right
50 | # also in ~/.zshrc:
51 | # bindkey "^[[1;5C" forward-word #control left in xterm/tmux
52 | # bindkey "^[[1;5D" backward-word #control right in xterm/tmux
53 | set-window-option -g xterm-keys on
54 | set -g xterm-keys on
55 | unbind C-Left
56 | unbind C-Right
57 |
58 | # Improve colors
59 | set -g default-terminal xterm-256color
60 |
61 | # Increase scrollback buffer
62 | set -g history-limit 30000
63 |
64 | # Increase tmux messages display duration from 750ms to 4s
65 | set -g display-time 4000
66 |
67 | # Refresh 'status-left' and 'status-right' more often, from every 15s to 5s
68 | set -g status-interval 5
69 |
70 | # Customize the status line
71 | set -g status-fg green
72 | set -g status-bg black
73 |
74 | # Emacs key bindings in tmux command prompt (prefix + :) are better than
75 | # vi keys, even for vim users
76 | set -g status-keys emacs
77 |
78 | setw -g mode-keys emacs
79 |
80 | # split panes using | and -
81 | bind | split-window -h
82 | bind - split-window -v
83 | unbind '"'
84 | unbind %
85 |
86 |
87 | # switch panes using Alt-arrow without prefix
88 | bind -n M-Left select-pane -L
89 | bind -n M-Right select-pane -R
90 | bind -n M-Up select-pane -U
91 | bind -n M-Down select-pane -D
92 |
93 | # Window navigation
94 | bind-key C-Tab next-window
95 | bind-key C-S-Tab previous-window
96 | bind C-p previous-window
97 | bind C-n next-window
98 |
99 | # dim inactive window text
100 | set -g window-style fg=colour15
101 | set -g window-active-style fg=colour7
102 |
103 | # Focus events enabled for terminals that support them
104 | set -g focus-events on
105 |
106 | # Super useful when using "grouped sessions" and multi-monitor setup
107 | setw -g aggressive-resize on
108 |
109 | # Extract output using FZF
110 | # set -g @extrakto_key 'e'
111 |
112 | # Enable mouse mode (tmux 2.1 and above)
113 | set -g mouse on
114 |
115 | # Address vim mode switching delay (http://superuser.com/a/252717/65504)
116 | set -s escape-time 0
117 |
118 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
119 | run '~/.tmux/plugins/tpm/tpm'
120 |
--------------------------------------------------------------------------------
/zshrc:
--------------------------------------------------------------------------------
1 | # Amazon Q pre block. Keep at the top of this file.
2 | ### q slow debugging ###
3 | # date
4 | # echo "STARTING: amazon q pre block loading from .zshrc"
5 | # # set zsh to echo verbose
6 | # set -x
7 | # ###
8 | # only run if LOADING_Q is true
9 | if [[ "$LOADING_Q" == "true" ]]; then
10 | # Amazon Q post block. Keep at the bottom of this file.
11 | [[ -f "${HOME}/Library/Application Support/amazon-q/shell/zshrc.pre.zsh" ]] && builtin source "${HOME}/Library/Application Support/amazon-q/shell/zshrc.pre.zsh"
12 | fi
13 | # ### q slow debugging ###
14 | # date
15 | # # unset zsh to echo verbose
16 | # set +x
17 | # echo "DONE: amazon q pre block loaded from .zshrc"
18 | ###
19 | ## AMAZON Q MAKES EVERYTHING SLOWWWWWW
20 |
21 | # shellcheck disable=SC2148 disable=SC1090 shell=bash
22 | # ~/.zshrc
23 |
24 | # set +x
25 |
26 | # only run set +m if we're interactive
27 | if [[ $- == *i* ]]; then
28 | set +m # Make jobs quiet by default
29 | fi
30 | # There is an alias to jump to the directory with the various
31 | # included zsh configs, simply type `zshconfig` at the prompt.
32 |
33 | ####### PROFILING #######
34 | # Uncomment below to enable debug timing
35 | # zmodload zsh/zprof
36 | # Remember to uncomment zprof at the end of the file!
37 | #### END PROFILING ######
38 |
39 | bg_silent() {
40 | # background a task quietly and disown
41 | { "$@" 2>&3 & } 3>&2 2>/dev/null
42 | disown &>/dev/null
43 | }
44 |
45 | ## Source all configs
46 |
47 | if [[ -d $HOME/Library/Mobile\ Documents/com\~apple\~CloudDocs/Dropbox\ Import/dotfiles/shell_config ]]; then
48 | for file in "$HOME"/Library/Mobile\ Documents/com\~apple\~CloudDocs/Dropbox\ Import/dotfiles/shell_config/*.rc; do
49 | source "$file"
50 | done
51 | fi
52 |
53 | ## Add ssh keys to agent if not already added
54 | # ssh-add-keys # TODO: disabled 2025-03-16 to see if it helps performance, reenable if ssh stops working
55 |
56 | ### Below are items added by installer scripts (usually homebrew) ####
57 |
58 | [ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
59 | source /opt/homebrew/Cellar/fzf/*/shell/key-bindings.zsh
60 |
61 | # Enable direnv - https://direnv.net
62 | # eval "$(direnv hook zsh)"
63 |
64 | if_not_in_vscode bg_silent test -e "${HOME}/.iterm2_shell_integration.zsh" && bg_silent source "${HOME}/.iterm2_shell_integration.zsh"
65 |
66 | zstyle ':completion:*' menu select
67 | fpath+=~/.zfunc
68 |
69 | # only run set -m if we're interactive
70 | if [[ $- == *i* ]]; then
71 | set -m # reenable job output
72 | fi
73 |
74 | # >>> mamba initialize >>>
75 | # !! Contents within this block are managed by 'mamba init' !!
76 | # export MAMBA_EXE='/opt/homebrew/opt/micromamba/bin/micromamba';
77 | # export MAMBA_ROOT_PREFIX='/Users/samm/micromamba';
78 | # __mamba_setup="$("$MAMBA_EXE" shell hook --shell zsh --root-prefix "$MAMBA_ROOT_PREFIX" 2> /dev/null)"
79 | # if [ $? -eq 0 ]; then
80 | # eval "$__mamba_setup"
81 | # else
82 | # alias micromamba="$MAMBA_EXE" # Fallback on help from mamba activate
83 | # fi
84 | # unset __mamba_setup
85 | # # <<< mamba initialize <<<
86 |
87 | # >>> conda initialize >>>
88 | # !! Contents within this block are managed by 'conda init' !!
89 | # __conda_setup="$('/opt/homebrew/Caskroom/mambaforge/base/bin/conda' 'shell.zsh' 'hook' 2> /dev/null)"
90 | # if [ $? -eq 0 ]; then
91 | # eval "$__conda_setup"
92 | # else
93 | # if [ -f "/opt/homebrew/Caskroom/mambaforge/base/etc/profile.d/conda.sh" ]; then
94 | # . "/opt/homebrew/Caskroom/mambaforge/base/etc/profile.d/conda.sh"
95 | # else
96 | # export PATH="/opt/homebrew/Caskroom/mambaforge/base/bin:$PATH"
97 | # fi
98 | # fi
99 | # unset __conda_setup
100 |
101 | # if [ -f "/opt/homebrew/Caskroom/mambaforge/base/etc/profile.d/mamba.sh" ]; then
102 | # . "/opt/homebrew/Caskroom/mambaforge/base/etc/profile.d/mamba.sh"
103 | # fi
104 | # <<< conda initialize <<<
105 |
106 | ### zoxide ###
107 | eval "$(zoxide init zsh)"
108 | ### zoxide ###
109 |
110 | # Load custom aliases
111 | export PATH="$PATH:/Users/samm/Fltr"
112 |
113 | # tabtab source for electron-forge package
114 | # uninstall by removing these lines or running `tabtab uninstall electron-forge`
115 | # [[ -f /Users/samm/.npm/_npx/6913fdfd1ea7a741/node_modules/tabtab/.completions/electron-forge.zsh ]] && . /Users/samm/.npm/_npx/6913fdfd1ea7a741/node_modules/tabtab/.completions/electron-forge.zsh
116 |
117 | # Added by LM Studio CLI tool (lms)
118 | export PATH="$PATH:/Users/samm/.cache/lm-studio/bin"
119 | if [ -f "/Users/samm/.config/fabric/fabric-bootstrap.inc" ] && if_not_in_vscode; then . "/Users/samm/.config/fabric/fabric-bootstrap.inc"; fi
120 |
121 | fpath+=~/.zfunc
122 |
123 | export PATH="/opt/homebrew/opt/tcl-tk@8/bin:$PATH"
124 |
125 | # # The next line updates PATH for the Google Cloud SDK.
126 | if [ -f '/Users/samm/Downloads/google-cloud-sdk/path.zsh.inc' ] && if_not_in_vscode; then . '/Users/samm/Downloads/google-cloud-sdk/path.zsh.inc'; fi
127 |
128 | # The next line enables shell command completion for gcloud.
129 | if [ -f '/Users/samm/Downloads/google-cloud-sdk/completion.zsh.inc' ] && if_not_in_vscode; then . '/Users/samm/Downloads/google-cloud-sdk/completion.zsh.inc'; fi
130 |
131 | # # Amazon Q post block. Keep at the bottom of this file.
132 | if [[ "$LOADING_Q" == "true" ]]; then
133 | # Amazon Q post block. Keep at the bottom of this file.
134 | [[ -f "${HOME}/Library/Application Support/amazon-q/shell/zshrc.post.zsh" ]] && builtin source "${HOME}/Library/Application Support/amazon-q/shell/zshrc.post.zsh"
135 | fi
136 |
137 | # ####### PROFILING #######
138 | # # Uncomment below to enable debug timing
139 | # zprof
140 | # #### END PROFILING ######
141 |
142 | # echo ".zshrc loaded now"
143 |
144 | # >>> CLOI_HISTORY_SETTINGS >>>
145 | setopt INC_APPEND_HISTORY
146 | setopt SHARE_HISTORY
147 | # <<< CLOI_HISTORY_SETTINGS <<<
148 |
--------------------------------------------------------------------------------