tenseleyflow/shtick / 5cc9c10

Browse files

readme, update sample

Authored by espadonne
SHA
5cc9c109b909ba435e0f2799c3d09b0fb2940177
Parents
29658f6
Tree
11aa911

2 changed files

StatusFile+-
A README.md 274 0
M config.sample.toml 1 5
README.mdadded
@@ -0,0 +1,274 @@
1
+# shtick 
2
+#### shell-agnostic-shell-configuration-generation
3
+(noun) : something cl[ever]
4
+(see also) : pedantic
5
+
6
+### what is this?
7
+this is a tool I use to manage groups of shell configurations (aliases, env vars, functions). It started out written in C for a presentation on unix shells to a group of TAs. I asked an LLM to help me port it to python because I got sick of remembering about memory and waking up in cold sweats over a presentation to a bunch of 20 y/o's, and chap and I got carried away. That's the disclaimer - AI helped. But this tool is for me and I use it actively, if you think it could help you too, continue on.  
8
+
9
+It's useful if you use multiple shells regularly and would like a single source of truth for your shell ..config (...within reason).  
10
+
11
+- Define aliases, env vars, and shell functions in one place (~/.config/shtick/config.toml); 
12
+- Manage persistent aliases, env vars, shell functions
13
+- Define toggleable groups of aliases, e.g. `dev`, `personal`
14
+
15
+If you decide you want to use this yourself, do all the usual cloning, then from your local run `make install`. 
16
+
17
+
18
+`usage: shtick [-h] [--debug] {generate,add,add-persistent,alias,env,function,remove,remove-persistent,activate,deactivate,status,list,shells,source} ...`
19
+
20
+Usage examples:
21
+```
22
+shtick generate [--terse] # generate shell files for all items in config
23
+
24
+shtick list             # list all managed items
25
+shtick status           # see all active items
26
+shtick activate work    # activate items in work group
27
+shtick deactivate dev   # deactivate items in dev group
28
+eval "$(shtick source)"   # IMPORTANT! load changes in shell. See tip below
29
+
30
+shtick alias ll='ls -la'            # add persistent alias
31
+shtick add alias work up='cd ../'   # add alias to specified group
32
+shtick remove alias work up         # remove alias from specified group
33
+
34
+shtick env EDITOR='micro'               # add persistent environment variable
35
+shtick remove env project DEBUG='true'  # add env var to project group
36
+shtick remove env persistent XDG_HAM    # remove persistent environment variable
37
+
38
+shtick function mkcd='mkdir -p "$1" && cd "$1"'                       # add persistent function
39
+shtick add function util backup='cp "$1" "$1.backup.$(date +%Y%m%d)"' # add function to util group
40
+
41
+# Recommended: add the following:
42
+# Add alias for instant sourcing  
43
+shtick alias ss='eval "$(shtick source)"'  # or your own command to source
44
+
45
+# Use it after any shtick command to 'auto' source changes  
46
+shtick alias deploy='./deploy.sh' && ss  
47
+shtick activate work && ss  
48
+```
49
+
50
+Sample config (pulled from my config):
51
+`~/.config/shtick/config.toml. Also see [sample](/config.sample.toml)
52
+```
53
+# Persistent items - always active in every shell session
54
+[persistent.aliases]
55
+pls="sudo !!"
56
+bk = "- || cd -"
57
+wttr = "curl wttr.in"
58
+refresh = "source ${HOME}/.zshrc"
59
+goclass = "cd ${HOME}/Documents/Class/"
60
+goproj = "cd ${HOME}/Documents/Project/"
61
+goorg = "cd ${HOME}/Documents/GithubOrgs/"
62
+gad="git add"
63
+gall="git add --all"
64
+gputt="git push origin trunk"
65
+gcamm="git commit --all --message"
66
+glogg="git log --online --graph --decorate --all"
67
+
68
+[persistent.env_vars] 
69
+PAGER = "less"
70
+EDITOR = "micro"
71
+BROWSER = "firefox"
72
+
73
+[persistent.functions]
74
+backup = "cp \"$1\" \"$1.backup.$(date +%Y%m%d_%H%M%S)\""
75
+
76
+[dev.aliases]
77
+mk = "make"
78
+mkr =  "make run"
79
+mki =  "make install"
80
+gfort = "gfortran"
81
+ni = "npm --install"
82
+serve = "python manage.py runserver"
83
+pyserve = "python3 -m http.server 8000"
84
+brewup = "brew update && brew upgrade && brew cleanup"
85
+
86
+[dev.env_vars]
87
+JOM = "terry"
88
+
89
+[dev.functions]
90
+newproject = "mkdir -p \"$HOME/projects/$1\" && cd \"$HOME/projects/$1\" && git init"
91
+
92
+[personal.aliases]
93
+myip = "curl ifconfig.me"
94
+
95
+[personal.env_vars]
96
+TOM = "JERRY"
97
+
98
+[personal.functions]
99
+note = "echo \"$(date): $*\" >> $HOME/notes.txt"
100
+```  
101
+
102
+## Python API Usage
103
+We also expose a public API for using shtick functionality as library functions.  
104
+
105
+### Basic Usage
106
+```
107
+from shtick import ShtickManager
108
+
109
+# Initialize the manager
110
+manager = ShtickManager()
111
+
112
+# Add persistent aliases (always active)
113
+manager.add_persistent_alias('ll', 'ls -la')
114
+manager.add_persistent_alias('grep', 'grep --color=auto')
115
+
116
+# Add environment variables
117
+manager.add_persistent_env('EDITOR', 'vim')
118
+manager.add_persistent_env('BROWSER', 'firefox')
119
+
120
+# Check status
121
+status = manager.get_status()
122
+print(f"Active groups: {status['active_groups']}")
123
+print(f"Persistent items: {status['persistent_items']}")
124
+```
125
+
126
+### Working with groups
127
+```
128
+from shtick import ShtickManager
129
+
130
+manager = ShtickManager()
131
+
132
+# Create project-specific configuration
133
+project_aliases = {
134
+    'start': 'npm start',
135
+    'test': 'npm test',
136
+    'build': 'npm run build',
137
+    'deploy': 'npm run deploy'
138
+}
139
+
140
+# Add all aliases to a group
141
+for alias, command in project_aliases.items():
142
+    manager.add_alias(alias, command, 'frontend')
143
+
144
+# Add environment variables for the project
145
+manager.add_env('NODE_ENV', 'development', 'frontend')
146
+manager.add_env('API_URL', 'http://localhost:3000', 'frontend')
147
+
148
+# Activate the group
149
+manager.activate_group('frontend')
150
+
151
+# Get information about what's configured
152
+items = manager.list_items('frontend')
153
+for item in items:
154
+    print(f"{item['type']}: {item['key']} = {item['value']}")
155
+```
156
+
157
+### Automation and scripting
158
+
159
+from shtick import ShtickManager
160
+```
161
+def setup_development_environment():
162
+    """Set up a complete development environment"""
163
+    manager = ShtickManager()
164
+    
165
+    # Docker aliases
166
+    docker_aliases = {
167
+        'dps': 'docker ps',
168
+        'dimg': 'docker images',
169
+        'dlog': 'docker logs -f',
170
+        'dexec': 'docker exec -it',
171
+        'dstop': 'docker stop $(docker ps -q)',
172
+    }
173
+    
174
+    for alias, command in docker_aliases.items():
175
+        manager.add_alias(alias, command, 'docker')
176
+    
177
+    # Git aliases
178
+    git_aliases = {
179
+        'gst': 'git status',
180
+        'gco': 'git checkout',
181
+        'gcb': 'git checkout -b',
182
+        'gpl': 'git pull',
183
+        'gps': 'git push',
184
+    }
185
+    
186
+    for alias, command in git_aliases.items():
187
+        manager.add_alias(alias, command, 'git')
188
+    
189
+    # Development environment variables
190
+    dev_env = {
191
+        'DOCKER_BUILDKIT': '1',
192
+        'COMPOSE_DOCKER_CLI_BUILD': '1',
193
+        'NODE_ENV': 'development',
194
+    }
195
+    
196
+    for var, value in dev_env.items():
197
+        manager.add_env(var, value, 'development')
198
+    
199
+    # Activate all development groups
200
+    groups = ['docker', 'git', 'development']
201
+    for group in groups:
202
+        success = manager.activate_group(group)
203
+        print(f"{'✓' if success else '✗'} Activated {group} group")
204
+    
205
+    # Generate shell files
206
+    manager.generate_shell_files()
207
+    
208
+    # Show source command for immediate use
209
+    source_cmd = manager.get_source_command()
210
+    if source_cmd:
211
+        print(f"\nTo use immediately, run: {source_cmd}")
212
+
213
+def clean_inactive_groups():
214
+    """Remove aliases from inactive groups"""
215
+    manager = ShtickManager()
216
+    
217
+    active_groups = manager.get_active_groups()
218
+    all_groups = manager.get_groups()
219
+    
220
+    inactive_groups = set(all_groups) - set(active_groups) - {'persistent'}
221
+    
222
+    for group in inactive_groups:
223
+        items = manager.list_items(group)
224
+        if items:
225
+            print(f"Found {len(items)} items in inactive group '{group}'")
226
+            # Could prompt user or automatically clean up
227
+    
228
+    return inactive_groups
229
+
230
+# Example usage
231
+if __name__ == '__main__':
232
+    setup_development_environment()
233
+```
234
+
235
+### Error handling and validation
236
+```
237
+from shtick import ShtickManager
238
+def safe_alias_management():
239
+    """Example with proper error handling"""
240
+    manager = ShtickManager(debug=True)  # Enable debug output
241
+    
242
+    # Try to add an alias
243
+    success = manager.add_persistent_alias('test', 'echo "Hello World"')
244
+    if success:
245
+        print("✓ Alias added successfully")
246
+    else:
247
+        print("✗ Failed to add alias")
248
+    
249
+    # Check current status before making changes
250
+    status = manager.get_status()
251
+    if 'error' in status:
252
+        print(f"Configuration error: {status['error']}")
253
+        return False
254
+    
255
+    # Validate shell integration
256
+    if not status['loader_exists']:
257
+        print("Warning: Shell loader not found. Run 'shtick generate'")
258
+    
259
+    # List current items to avoid conflicts
260
+    existing_items = manager.list_items()
261
+    existing_aliases = [item['key'] for item in existing_items 
262
+                       if item['type'] == 'alias']
263
+    
264
+    new_alias = 'myalias'
265
+    if new_alias in existing_aliases:
266
+        print(f"Alias '{new_alias}' already exists")
267
+    else:
268
+        manager.add_persistent_alias(new_alias, 'echo "New alias"')
269
+    
270
+    return True
271
+
272
+# Run the example
273
+safe_alias_management()
274
+```
config.sample.tomlmodified
@@ -6,6 +6,7 @@ c = "clear"
66
 gad="git add"
77
 pls="sudo !!"
88
 bk = "- || cd -"
9
+wttr = "curl wttr.in"
910
 refresh = "source ${HOME}/.zshrc"
1011
 goclass = "cd ${HOME}/Documents/Class/"
1112
 goproj = "cd ${HOME}/Documents/Project/"
@@ -22,9 +23,6 @@ gputt="git push origin trunk"
2223
 gcamm="git commit --all --message"
2324
 glogg="git log --online --graph --decorate --all"
2425
 
25
-wttr = "curl wttr.in"
26
-
27
-
2826
 [persistent.env_vars] 
2927
 PAGER = "less"
3028
 EDITOR = "micro"
@@ -54,7 +52,6 @@ serve = "python manage.py runserver"
5452
 pyserve = "python3 -m http.server 8000"
5553
 brewup = "brew update && brew upgrade && brew cleanup"
5654
 
57
-
5855
 [dev.env_vars]
5956
 JOM = "terry"
6057
 
@@ -62,7 +59,6 @@ JOM = "terry"
6259
 newproject = "mkdir -p \"$HOME/projects/$1\" && cd \"$HOME/projects/$1\" && git init"
6360
 
6461
 
65
-
6662
 [personal.aliases]
6763
 myip = "curl ifconfig.me"
6864