@fredlackey/devutils 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/package.json +1 -1
- package/src/commands/install.js +374 -36
- package/src/installs/adobe-creative-cloud.js +527 -25
- package/src/installs/adobe-creative-cloud.md +605 -0
- package/src/installs/appcleaner.js +303 -26
- package/src/installs/appcleaner.md +699 -0
- package/src/installs/apt-transport-https.js +390 -0
- package/src/installs/apt-transport-https.md +678 -0
- package/src/installs/atomicparsley.js +624 -26
- package/src/installs/atomicparsley.md +795 -0
- package/src/installs/aws-cli.js +779 -26
- package/src/installs/aws-cli.md +727 -0
- package/src/installs/balena-etcher.js +688 -26
- package/src/installs/balena-etcher.md +761 -0
- package/src/installs/bambu-studio.js +912 -26
- package/src/installs/bambu-studio.md +780 -0
- package/src/installs/bash-completion.js +554 -23
- package/src/installs/bash-completion.md +833 -0
- package/src/installs/bash.js +399 -26
- package/src/installs/bash.md +993 -0
- package/src/installs/beyond-compare.js +585 -26
- package/src/installs/beyond-compare.md +813 -0
- package/src/installs/build-essential.js +511 -26
- package/src/installs/build-essential.md +977 -0
- package/src/installs/ca-certificates.js +618 -0
- package/src/installs/ca-certificates.md +937 -0
- package/src/installs/caffeine.js +490 -26
- package/src/installs/caffeine.md +839 -0
- package/src/installs/camtasia.js +577 -25
- package/src/installs/camtasia.md +762 -0
- package/src/installs/chatgpt.js +458 -26
- package/src/installs/chatgpt.md +814 -0
- package/src/installs/chocolatey.js +447 -0
- package/src/installs/chocolatey.md +661 -0
- package/src/installs/chrome-canary.js +472 -26
- package/src/installs/chrome-canary.md +641 -0
- package/src/installs/chromium.js +645 -26
- package/src/installs/chromium.md +838 -0
- package/src/installs/claude-code.js +558 -26
- package/src/installs/claude-code.md +1173 -0
- package/src/installs/curl.js +361 -26
- package/src/installs/curl.md +714 -0
- package/src/installs/cursor.js +561 -26
- package/src/installs/cursor.md +970 -0
- package/src/installs/dbschema.js +674 -26
- package/src/installs/dbschema.md +925 -0
- package/src/installs/dependencies.md +435 -0
- package/src/installs/development-tools.js +600 -0
- package/src/installs/development-tools.md +977 -0
- package/src/installs/docker.js +1010 -25
- package/src/installs/docker.md +1109 -0
- package/src/installs/drawio.js +1001 -26
- package/src/installs/drawio.md +795 -0
- package/src/installs/elmedia-player.js +328 -25
- package/src/installs/elmedia-player.md +556 -0
- package/src/installs/ffmpeg.js +870 -25
- package/src/installs/ffmpeg.md +852 -0
- package/src/installs/file.js +464 -0
- package/src/installs/file.md +987 -0
- package/src/installs/gemini-cli.js +793 -26
- package/src/installs/gemini-cli.md +1153 -0
- package/src/installs/git.js +382 -26
- package/src/installs/git.md +907 -0
- package/src/installs/gitego.js +931 -26
- package/src/installs/gitego.md +1172 -0
- package/src/installs/go.js +913 -26
- package/src/installs/go.md +958 -0
- package/src/installs/google-chrome.js +801 -25
- package/src/installs/google-chrome.md +862 -0
- package/src/installs/gpg.js +412 -73
- package/src/installs/gpg.md +1056 -0
- package/src/installs/homebrew.js +1015 -26
- package/src/installs/homebrew.md +988 -0
- package/src/installs/imageoptim.js +950 -26
- package/src/installs/imageoptim.md +1119 -0
- package/src/installs/installers.json +2297 -0
- package/src/installs/jq.js +382 -26
- package/src/installs/jq.md +809 -0
- package/src/installs/keyboard-maestro.js +701 -26
- package/src/installs/keyboard-maestro.md +825 -0
- package/src/installs/latex.js +771 -26
- package/src/installs/latex.md +1095 -0
- package/src/installs/lftp.js +338 -26
- package/src/installs/lftp.md +907 -0
- package/src/installs/lsb-release.js +346 -0
- package/src/installs/lsb-release.md +814 -0
- package/src/installs/messenger.js +829 -26
- package/src/installs/messenger.md +900 -0
- package/src/installs/microsoft-office.js +550 -26
- package/src/installs/microsoft-office.md +760 -0
- package/src/installs/microsoft-teams.js +782 -25
- package/src/installs/microsoft-teams.md +886 -0
- package/src/installs/node.js +886 -26
- package/src/installs/node.md +1153 -0
- package/src/installs/nordpass.js +698 -26
- package/src/installs/nordpass.md +921 -0
- package/src/installs/nvm.js +977 -26
- package/src/installs/nvm.md +1057 -0
- package/src/installs/openssh.js +734 -64
- package/src/installs/openssh.md +1056 -0
- package/src/installs/pandoc.js +644 -26
- package/src/installs/pandoc.md +1036 -0
- package/src/installs/pinentry.js +492 -26
- package/src/installs/pinentry.md +1142 -0
- package/src/installs/pngyu.js +851 -26
- package/src/installs/pngyu.md +896 -0
- package/src/installs/postman.js +781 -26
- package/src/installs/postman.md +940 -0
- package/src/installs/procps.js +425 -0
- package/src/installs/procps.md +851 -0
- package/src/installs/safari-tech-preview.js +355 -25
- package/src/installs/safari-tech-preview.md +533 -0
- package/src/installs/sfnt2woff.js +640 -26
- package/src/installs/sfnt2woff.md +795 -0
- package/src/installs/shellcheck.js +463 -26
- package/src/installs/shellcheck.md +1005 -0
- package/src/installs/slack.js +722 -25
- package/src/installs/slack.md +865 -0
- package/src/installs/snagit.js +566 -25
- package/src/installs/snagit.md +844 -0
- package/src/installs/software-properties-common.js +372 -0
- package/src/installs/software-properties-common.md +805 -0
- package/src/installs/spotify.js +858 -25
- package/src/installs/spotify.md +901 -0
- package/src/installs/studio-3t.js +803 -26
- package/src/installs/studio-3t.md +918 -0
- package/src/installs/sublime-text.js +780 -25
- package/src/installs/sublime-text.md +914 -0
- package/src/installs/superwhisper.js +687 -25
- package/src/installs/superwhisper.md +630 -0
- package/src/installs/tailscale.js +727 -26
- package/src/installs/tailscale.md +1100 -0
- package/src/installs/tar.js +389 -0
- package/src/installs/tar.md +946 -0
- package/src/installs/termius.js +780 -26
- package/src/installs/termius.md +844 -0
- package/src/installs/terraform.js +761 -26
- package/src/installs/terraform.md +899 -0
- package/src/installs/tidal.js +752 -25
- package/src/installs/tidal.md +864 -0
- package/src/installs/tmux.js +328 -26
- package/src/installs/tmux.md +1030 -0
- package/src/installs/tree.js +393 -26
- package/src/installs/tree.md +833 -0
- package/src/installs/unzip.js +460 -0
- package/src/installs/unzip.md +879 -0
- package/src/installs/vim.js +403 -26
- package/src/installs/vim.md +1040 -0
- package/src/installs/vlc.js +803 -26
- package/src/installs/vlc.md +927 -0
- package/src/installs/vscode.js +825 -26
- package/src/installs/vscode.md +1002 -0
- package/src/installs/wget.js +415 -0
- package/src/installs/wget.md +791 -0
- package/src/installs/whatsapp.js +710 -25
- package/src/installs/whatsapp.md +854 -0
- package/src/installs/winpty.js +352 -0
- package/src/installs/winpty.md +620 -0
- package/src/installs/woff2.js +535 -26
- package/src/installs/woff2.md +977 -0
- package/src/installs/wsl.js +572 -0
- package/src/installs/wsl.md +699 -0
- package/src/installs/xcode-clt.js +520 -0
- package/src/installs/xcode-clt.md +351 -0
- package/src/installs/xcode.js +542 -26
- package/src/installs/xcode.md +573 -0
- package/src/installs/yarn.js +806 -26
- package/src/installs/yarn.md +1074 -0
- package/src/installs/yq.js +636 -26
- package/src/installs/yq.md +944 -0
- package/src/installs/yt-dlp.js +683 -26
- package/src/installs/yt-dlp.md +946 -0
- package/src/installs/yum-utils.js +297 -0
- package/src/installs/yum-utils.md +648 -0
- package/src/installs/zoom.js +740 -25
- package/src/installs/zoom.md +884 -0
- package/src/scripts/README.md +567 -45
- package/src/scripts/STATUS.md +208 -0
- package/src/scripts/afk.js +395 -7
- package/src/scripts/backup-all.js +731 -9
- package/src/scripts/backup-source.js +711 -8
- package/src/scripts/brewd.js +373 -7
- package/src/scripts/brewi.js +505 -9
- package/src/scripts/brewr.js +512 -9
- package/src/scripts/brews.js +462 -9
- package/src/scripts/brewu.js +488 -7
- package/src/scripts/c.js +185 -7
- package/src/scripts/ccurl.js +325 -8
- package/src/scripts/certbot-crontab-init.js +488 -8
- package/src/scripts/certbot-init.js +641 -9
- package/src/scripts/ch.js +339 -7
- package/src/scripts/claude-danger.js +253 -8
- package/src/scripts/clean-dev.js +419 -8
- package/src/scripts/clear-dns-cache.js +525 -7
- package/src/scripts/clone.js +417 -7
- package/src/scripts/code-all.js +420 -7
- package/src/scripts/count-files.js +195 -8
- package/src/scripts/count-folders.js +195 -8
- package/src/scripts/count.js +248 -8
- package/src/scripts/d.js +203 -7
- package/src/scripts/datauri.js +373 -8
- package/src/scripts/delete-files.js +363 -7
- package/src/scripts/docker-clean.js +410 -8
- package/src/scripts/dp.js +426 -7
- package/src/scripts/e.js +375 -9
- package/src/scripts/empty-trash.js +497 -7
- package/src/scripts/evm.js +428 -9
- package/src/scripts/fetch-github-repos.js +441 -10
- package/src/scripts/get-channel.js +329 -8
- package/src/scripts/get-course.js +384 -11
- package/src/scripts/get-dependencies.js +290 -9
- package/src/scripts/get-folder.js +783 -10
- package/src/scripts/get-tunes.js +411 -10
- package/src/scripts/get-video.js +352 -9
- package/src/scripts/git-backup.js +561 -9
- package/src/scripts/git-clone.js +477 -9
- package/src/scripts/git-pup.js +303 -7
- package/src/scripts/git-push.js +380 -8
- package/src/scripts/h.js +607 -9
- package/src/scripts/hide-desktop-icons.js +483 -7
- package/src/scripts/hide-hidden-files.js +522 -7
- package/src/scripts/install-dependencies-from.js +440 -9
- package/src/scripts/ips.js +647 -10
- package/src/scripts/iso.js +354 -8
- package/src/scripts/killni.js +561 -7
- package/src/scripts/ll.js +451 -8
- package/src/scripts/local-ip.js +310 -8
- package/src/scripts/m.js +508 -8
- package/src/scripts/map.js +293 -8
- package/src/scripts/mkd.js +287 -7
- package/src/scripts/ncu-update-all.js +441 -8
- package/src/scripts/nginx-init.js +702 -12
- package/src/scripts/npmi.js +366 -7
- package/src/scripts/o.js +495 -8
- package/src/scripts/org-by-date.js +321 -7
- package/src/scripts/p.js +208 -7
- package/src/scripts/packages.js +313 -8
- package/src/scripts/path.js +209 -7
- package/src/scripts/ports.js +582 -8
- package/src/scripts/q.js +290 -8
- package/src/scripts/refresh-files.js +378 -10
- package/src/scripts/remove-smaller-files.js +500 -8
- package/src/scripts/rename-files-with-date.js +517 -9
- package/src/scripts/resize-image.js +523 -9
- package/src/scripts/rm-safe.js +653 -8
- package/src/scripts/s.js +525 -9
- package/src/scripts/set-git-public.js +349 -7
- package/src/scripts/show-desktop-icons.js +459 -7
- package/src/scripts/show-hidden-files.js +456 -7
- package/src/scripts/tpa.js +265 -8
- package/src/scripts/tpo.js +264 -7
- package/src/scripts/u.js +489 -7
- package/src/scripts/vpush.js +422 -8
- package/src/scripts/y.js +267 -7
- package/src/utils/common/os.js +94 -2
- package/src/utils/ubuntu/apt.js +13 -7
- package/src/utils/windows/choco.js +82 -26
- package/src/utils/windows/winget.js +89 -27
package/src/scripts/map.js
CHANGED
|
@@ -1,24 +1,309 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* map - Execute a command for each line of input
|
|
5
|
+
*
|
|
6
|
+
* Migrated from legacy dotfiles alias.
|
|
7
|
+
* Original: alias map="xargs -n1"
|
|
8
|
+
*
|
|
9
|
+
* This script reads lines from stdin and executes the specified command
|
|
10
|
+
* for each line, similar to `xargs -n1`. It allows you to "map" a command
|
|
11
|
+
* over a list of inputs.
|
|
12
|
+
*
|
|
13
|
+
* Usage examples:
|
|
14
|
+
* echo -e "file1.txt\nfile2.txt" | map cat
|
|
15
|
+
* ls *.js | map wc -l
|
|
16
|
+
* git branch | map git log -1 --oneline
|
|
17
|
+
*
|
|
18
|
+
* The input line is passed as the last argument to the command. For example:
|
|
19
|
+
* echo "hello" | map echo "Processing:"
|
|
20
|
+
* # Executes: echo "Processing:" "hello"
|
|
21
|
+
*
|
|
5
22
|
* @module scripts/map
|
|
6
23
|
*/
|
|
7
24
|
|
|
25
|
+
const os = require('../utils/common/os');
|
|
26
|
+
const { spawn } = require('child_process');
|
|
27
|
+
const readline = require('readline');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Pure Node.js implementation that works on any platform.
|
|
31
|
+
*
|
|
32
|
+
* This function reads lines from stdin and executes the specified command
|
|
33
|
+
* for each line. The input line is appended as the last argument to the command.
|
|
34
|
+
*
|
|
35
|
+
* Why this works cross-platform:
|
|
36
|
+
* - readline module handles stdin consistently across all platforms
|
|
37
|
+
* - spawn works identically on macOS, Linux, and Windows
|
|
38
|
+
* - No platform-specific shell features are used
|
|
39
|
+
*
|
|
40
|
+
* @param {string[]} args - Command and its arguments. The first element is the
|
|
41
|
+
* command to run, remaining elements are arguments.
|
|
42
|
+
* The input line is appended as the final argument.
|
|
43
|
+
* @returns {Promise<void>}
|
|
44
|
+
*/
|
|
45
|
+
async function do_map_nodejs(args) {
|
|
46
|
+
// If no command provided, show usage information
|
|
47
|
+
if (args.length === 0) {
|
|
48
|
+
console.log('Usage: map <command> [arguments...]');
|
|
49
|
+
console.log('');
|
|
50
|
+
console.log('Reads lines from stdin and executes the command for each line.');
|
|
51
|
+
console.log('The input line is passed as the last argument to the command.');
|
|
52
|
+
console.log('');
|
|
53
|
+
console.log('Examples:');
|
|
54
|
+
console.log(' echo -e "file1.txt\\nfile2.txt" | map cat');
|
|
55
|
+
console.log(' ls *.js | map wc -l');
|
|
56
|
+
console.log(' find . -name "*.txt" | map head -1');
|
|
57
|
+
console.log('');
|
|
58
|
+
console.log('Similar to: xargs -n1');
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Extract the command (first argument) and its base arguments (remaining arguments)
|
|
63
|
+
const command = args[0];
|
|
64
|
+
const baseArgs = args.slice(1);
|
|
65
|
+
|
|
66
|
+
// Create readline interface to read lines from stdin
|
|
67
|
+
const rl = readline.createInterface({
|
|
68
|
+
input: process.stdin,
|
|
69
|
+
// Don't output to terminal - we're reading piped data
|
|
70
|
+
terminal: false
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Collect all lines first, then process them sequentially
|
|
74
|
+
// This ensures commands complete in order and errors are handled properly
|
|
75
|
+
const lines = [];
|
|
76
|
+
|
|
77
|
+
for await (const line of rl) {
|
|
78
|
+
// Skip empty lines to avoid passing empty arguments
|
|
79
|
+
const trimmedLine = line.trim();
|
|
80
|
+
if (trimmedLine !== '') {
|
|
81
|
+
lines.push(trimmedLine);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// If no input was provided (empty stdin), inform the user
|
|
86
|
+
if (lines.length === 0) {
|
|
87
|
+
console.error('No input received. Pipe data to this command:');
|
|
88
|
+
console.error(' echo "item1\\nitem2" | map <command>');
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Process each line sequentially
|
|
93
|
+
// Sequential processing ensures output is predictable and ordered
|
|
94
|
+
for (const inputLine of lines) {
|
|
95
|
+
// Build the full argument list: base args + the input line
|
|
96
|
+
const fullArgs = [...baseArgs, inputLine];
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
// Execute the command and wait for it to complete
|
|
100
|
+
await executeCommand(command, fullArgs);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
// Continue processing remaining lines even if one fails
|
|
103
|
+
// This matches xargs behavior by default
|
|
104
|
+
console.error(`Error processing "${inputLine}": ${error.message}`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Execute a command with given arguments and return a promise.
|
|
111
|
+
*
|
|
112
|
+
* Uses spawn instead of exec to:
|
|
113
|
+
* - Handle large output without buffer limits
|
|
114
|
+
* - Stream output in real-time
|
|
115
|
+
* - Better handle signals and process lifecycle
|
|
116
|
+
*
|
|
117
|
+
* @param {string} command - The command to execute
|
|
118
|
+
* @param {string[]} args - Arguments to pass to the command
|
|
119
|
+
* @returns {Promise<void>} Resolves when command completes, rejects on error
|
|
120
|
+
*/
|
|
121
|
+
function executeCommand(command, args) {
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
// Determine if we're on Windows to set appropriate shell option
|
|
124
|
+
const isWindows = process.platform === 'win32';
|
|
125
|
+
|
|
126
|
+
// Spawn the child process
|
|
127
|
+
// - shell: true allows running shell built-ins and handles PATH lookup
|
|
128
|
+
// - stdio: 'inherit' connects child's stdin/stdout/stderr to parent
|
|
129
|
+
const child = spawn(command, args, {
|
|
130
|
+
shell: true,
|
|
131
|
+
stdio: 'inherit',
|
|
132
|
+
// On Windows, use cmd.exe; on Unix, use default shell
|
|
133
|
+
...(isWindows && { windowsHide: true })
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
// Handle process completion
|
|
137
|
+
child.on('close', (code) => {
|
|
138
|
+
if (code === 0) {
|
|
139
|
+
resolve();
|
|
140
|
+
} else {
|
|
141
|
+
// Non-zero exit code indicates command failed
|
|
142
|
+
reject(new Error(`Command exited with code ${code}`));
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
// Handle spawn errors (command not found, permission denied, etc.)
|
|
147
|
+
child.on('error', (error) => {
|
|
148
|
+
reject(error);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Execute a command for each line of input on macOS.
|
|
155
|
+
*
|
|
156
|
+
* macOS can use the pure Node.js implementation since no platform-specific
|
|
157
|
+
* features are required for this functionality.
|
|
158
|
+
*
|
|
159
|
+
* @param {string[]} args - Command line arguments
|
|
160
|
+
* @returns {Promise<void>}
|
|
161
|
+
*/
|
|
162
|
+
async function do_map_macos(args) {
|
|
163
|
+
return do_map_nodejs(args);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Execute a command for each line of input on Ubuntu.
|
|
168
|
+
*
|
|
169
|
+
* Ubuntu can use the pure Node.js implementation since no platform-specific
|
|
170
|
+
* features are required for this functionality.
|
|
171
|
+
*
|
|
172
|
+
* @param {string[]} args - Command line arguments
|
|
173
|
+
* @returns {Promise<void>}
|
|
174
|
+
*/
|
|
175
|
+
async function do_map_ubuntu(args) {
|
|
176
|
+
return do_map_nodejs(args);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Execute a command for each line of input on Raspberry Pi OS.
|
|
181
|
+
*
|
|
182
|
+
* Raspberry Pi OS can use the pure Node.js implementation since no
|
|
183
|
+
* platform-specific features are required for this functionality.
|
|
184
|
+
*
|
|
185
|
+
* @param {string[]} args - Command line arguments
|
|
186
|
+
* @returns {Promise<void>}
|
|
187
|
+
*/
|
|
188
|
+
async function do_map_raspbian(args) {
|
|
189
|
+
return do_map_nodejs(args);
|
|
190
|
+
}
|
|
191
|
+
|
|
8
192
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
193
|
+
* Execute a command for each line of input on Amazon Linux.
|
|
194
|
+
*
|
|
195
|
+
* Amazon Linux can use the pure Node.js implementation since no
|
|
196
|
+
* platform-specific features are required for this functionality.
|
|
11
197
|
*
|
|
12
198
|
* @param {string[]} args - Command line arguments
|
|
13
|
-
* @param {string} args.0 - Command to execute for each input line
|
|
14
199
|
* @returns {Promise<void>}
|
|
15
200
|
*/
|
|
16
|
-
async function
|
|
17
|
-
|
|
201
|
+
async function do_map_amazon_linux(args) {
|
|
202
|
+
return do_map_nodejs(args);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Execute a command for each line of input in Windows Command Prompt.
|
|
207
|
+
*
|
|
208
|
+
* Windows CMD can use the pure Node.js implementation. The spawn command
|
|
209
|
+
* with shell: true automatically uses cmd.exe on Windows.
|
|
210
|
+
*
|
|
211
|
+
* @param {string[]} args - Command line arguments
|
|
212
|
+
* @returns {Promise<void>}
|
|
213
|
+
*/
|
|
214
|
+
async function do_map_cmd(args) {
|
|
215
|
+
return do_map_nodejs(args);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Execute a command for each line of input in Windows PowerShell.
|
|
220
|
+
*
|
|
221
|
+
* Windows PowerShell can use the pure Node.js implementation. The spawn
|
|
222
|
+
* command with shell: true works correctly from PowerShell.
|
|
223
|
+
*
|
|
224
|
+
* @param {string[]} args - Command line arguments
|
|
225
|
+
* @returns {Promise<void>}
|
|
226
|
+
*/
|
|
227
|
+
async function do_map_powershell(args) {
|
|
228
|
+
return do_map_nodejs(args);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Execute a command for each line of input in Git Bash.
|
|
233
|
+
*
|
|
234
|
+
* Git Bash can use the pure Node.js implementation since no platform-specific
|
|
235
|
+
* features are required for this functionality.
|
|
236
|
+
*
|
|
237
|
+
* @param {string[]} args - Command line arguments
|
|
238
|
+
* @returns {Promise<void>}
|
|
239
|
+
*/
|
|
240
|
+
async function do_map_gitbash(args) {
|
|
241
|
+
return do_map_nodejs(args);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Main entry point - detects environment and executes appropriate implementation.
|
|
246
|
+
*
|
|
247
|
+
* The "map" command reads lines from stdin and executes a command for each line,
|
|
248
|
+
* similar to `xargs -n1`. This is useful for applying a command to each item in
|
|
249
|
+
* a list, such as:
|
|
250
|
+
*
|
|
251
|
+
* - Processing each file from a directory listing
|
|
252
|
+
* - Applying a git command to multiple branches
|
|
253
|
+
* - Running a script on each item from a search result
|
|
254
|
+
*
|
|
255
|
+
* @param {string[]} args - Command line arguments. First argument is the command
|
|
256
|
+
* to run, remaining arguments are passed to that command.
|
|
257
|
+
* @returns {Promise<void>}
|
|
258
|
+
*/
|
|
259
|
+
async function do_map(args) {
|
|
260
|
+
const platform = os.detect();
|
|
261
|
+
|
|
262
|
+
const handlers = {
|
|
263
|
+
'macos': do_map_macos,
|
|
264
|
+
'ubuntu': do_map_ubuntu,
|
|
265
|
+
'debian': do_map_ubuntu,
|
|
266
|
+
'raspbian': do_map_raspbian,
|
|
267
|
+
'amazon_linux': do_map_amazon_linux,
|
|
268
|
+
'rhel': do_map_amazon_linux,
|
|
269
|
+
'fedora': do_map_ubuntu,
|
|
270
|
+
'linux': do_map_ubuntu,
|
|
271
|
+
'wsl': do_map_ubuntu,
|
|
272
|
+
'cmd': do_map_cmd,
|
|
273
|
+
'windows': do_map_cmd,
|
|
274
|
+
'powershell': do_map_powershell,
|
|
275
|
+
'gitbash': do_map_gitbash
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
const handler = handlers[platform.type];
|
|
279
|
+
if (!handler) {
|
|
280
|
+
console.error(`Platform '${platform.type}' is not supported for this command.`);
|
|
281
|
+
console.error('');
|
|
282
|
+
console.error('Supported platforms:');
|
|
283
|
+
console.error(' - macOS');
|
|
284
|
+
console.error(' - Ubuntu, Debian, and other Linux distributions');
|
|
285
|
+
console.error(' - Raspberry Pi OS');
|
|
286
|
+
console.error(' - Amazon Linux, RHEL, Fedora');
|
|
287
|
+
console.error(' - Windows (CMD, PowerShell, Git Bash)');
|
|
288
|
+
process.exit(1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
await handler(args);
|
|
18
292
|
}
|
|
19
293
|
|
|
20
|
-
module.exports = {
|
|
294
|
+
module.exports = {
|
|
295
|
+
main: do_map,
|
|
296
|
+
do_map,
|
|
297
|
+
do_map_nodejs,
|
|
298
|
+
do_map_macos,
|
|
299
|
+
do_map_ubuntu,
|
|
300
|
+
do_map_raspbian,
|
|
301
|
+
do_map_amazon_linux,
|
|
302
|
+
do_map_cmd,
|
|
303
|
+
do_map_powershell,
|
|
304
|
+
do_map_gitbash
|
|
305
|
+
};
|
|
21
306
|
|
|
22
307
|
if (require.main === module) {
|
|
23
|
-
|
|
308
|
+
do_map(process.argv.slice(2));
|
|
24
309
|
}
|
package/src/scripts/mkd.js
CHANGED
|
@@ -1,24 +1,304 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* mkd - Create a new directory and display navigation instructions
|
|
5
|
+
*
|
|
6
|
+
* Migrated from legacy dotfiles function.
|
|
7
|
+
* Original:
|
|
8
|
+
* mkd() {
|
|
9
|
+
* mkdir -p "$@" && cd "$@"
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* This script creates a new directory (including all necessary parent directories)
|
|
13
|
+
* and outputs instructions for navigating into it. The original shell function could
|
|
14
|
+
* change the working directory directly, but since Node.js scripts run in a subprocess,
|
|
15
|
+
* they cannot modify the parent shell's working directory.
|
|
16
|
+
*
|
|
17
|
+
* Usage:
|
|
18
|
+
* mkd my-project # Creates ./my-project
|
|
19
|
+
* mkd path/to/nested/directory # Creates all parent directories as needed
|
|
20
|
+
* mkd ~/projects/new-app # Works with home directory paths
|
|
21
|
+
*
|
|
5
22
|
* @module scripts/mkd
|
|
6
23
|
*/
|
|
7
24
|
|
|
25
|
+
const os = require('../utils/common/os');
|
|
26
|
+
const fs = require('fs');
|
|
27
|
+
const path = require('path');
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Expands a path that starts with ~ to the user's home directory.
|
|
31
|
+
*
|
|
32
|
+
* Node.js doesn't automatically expand tilde in paths like shells do,
|
|
33
|
+
* so we need to handle this manually for user convenience.
|
|
34
|
+
*
|
|
35
|
+
* @param {string} inputPath - The path that may contain a leading ~
|
|
36
|
+
* @returns {string} The expanded path with ~ replaced by home directory
|
|
37
|
+
*/
|
|
38
|
+
function expandTilde(inputPath) {
|
|
39
|
+
// If the path starts with ~, replace it with the home directory
|
|
40
|
+
if (inputPath.startsWith('~')) {
|
|
41
|
+
const homeDir = os.getHomeDir();
|
|
42
|
+
// Handle both ~/path and ~ alone
|
|
43
|
+
return inputPath.replace(/^~/, homeDir);
|
|
44
|
+
}
|
|
45
|
+
return inputPath;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Pure Node.js implementation for creating directories.
|
|
50
|
+
*
|
|
51
|
+
* Uses the Node.js fs module to create directories recursively,
|
|
52
|
+
* equivalent to the shell's `mkdir -p` command. This approach is:
|
|
53
|
+
* - Cross-platform (works identically on all OSes)
|
|
54
|
+
* - Native to Node.js (no shell commands needed)
|
|
55
|
+
* - Idempotent (safe to run multiple times)
|
|
56
|
+
*
|
|
57
|
+
* @param {string[]} args - Command line arguments
|
|
58
|
+
* @param {string} args.0 - Directory path to create
|
|
59
|
+
* @returns {Promise<void>}
|
|
60
|
+
*/
|
|
61
|
+
async function do_mkd_nodejs(args) {
|
|
62
|
+
// Validate arguments
|
|
63
|
+
if (args.length === 0) {
|
|
64
|
+
console.error('Usage: mkd <directory>');
|
|
65
|
+
console.error('');
|
|
66
|
+
console.error('Creates a new directory, including parent directories if needed.');
|
|
67
|
+
console.error('');
|
|
68
|
+
console.error('Examples:');
|
|
69
|
+
console.error(' mkd my-project');
|
|
70
|
+
console.error(' mkd path/to/nested/directory');
|
|
71
|
+
console.error(' mkd ~/projects/new-app');
|
|
72
|
+
process.exit(1);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Get the directory path from arguments
|
|
76
|
+
// The original bash function used "$@" which takes all arguments,
|
|
77
|
+
// but typically mkd is used with a single directory path
|
|
78
|
+
const rawPath = args.join(' ');
|
|
79
|
+
|
|
80
|
+
// Expand tilde if present (shells do this automatically, Node.js doesn't)
|
|
81
|
+
const expandedPath = expandTilde(rawPath);
|
|
82
|
+
|
|
83
|
+
// Resolve to absolute path for clearer output
|
|
84
|
+
const absolutePath = path.resolve(expandedPath);
|
|
85
|
+
|
|
86
|
+
// Check if the path already exists
|
|
87
|
+
if (fs.existsSync(absolutePath)) {
|
|
88
|
+
// Check if it's a directory or a file
|
|
89
|
+
const stats = fs.statSync(absolutePath);
|
|
90
|
+
if (stats.isDirectory()) {
|
|
91
|
+
// Directory already exists - this is fine (idempotent behavior)
|
|
92
|
+
console.log(`Directory already exists: ${absolutePath}`);
|
|
93
|
+
console.log('');
|
|
94
|
+
console.log(`To navigate there, run: cd "${absolutePath}"`);
|
|
95
|
+
return;
|
|
96
|
+
} else {
|
|
97
|
+
// A file with the same name exists - this is an error
|
|
98
|
+
console.error(`Error: A file with this name already exists: ${absolutePath}`);
|
|
99
|
+
console.error('Cannot create a directory with the same name as an existing file.');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Create the directory (and all parent directories)
|
|
105
|
+
// fs.mkdirSync with recursive:true is equivalent to mkdir -p
|
|
106
|
+
try {
|
|
107
|
+
fs.mkdirSync(absolutePath, { recursive: true });
|
|
108
|
+
} catch (error) {
|
|
109
|
+
// Handle permission errors and other filesystem errors
|
|
110
|
+
if (error.code === 'EACCES') {
|
|
111
|
+
console.error(`Error: Permission denied. Cannot create directory: ${absolutePath}`);
|
|
112
|
+
console.error('You may need to run this command with elevated privileges.');
|
|
113
|
+
} else if (error.code === 'ENOENT') {
|
|
114
|
+
console.error(`Error: Invalid path: ${absolutePath}`);
|
|
115
|
+
} else if (error.code === 'ENOTDIR') {
|
|
116
|
+
console.error(`Error: A component of the path is not a directory: ${absolutePath}`);
|
|
117
|
+
} else {
|
|
118
|
+
console.error(`Error: Failed to create directory: ${error.message}`);
|
|
119
|
+
}
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Verify the directory was created
|
|
124
|
+
if (!fs.existsSync(absolutePath)) {
|
|
125
|
+
console.error(`Error: Directory creation appeared to succeed but directory does not exist.`);
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Success! Print the result
|
|
130
|
+
// Note: Unlike the original shell function, we cannot change the parent shell's
|
|
131
|
+
// working directory. We provide instructions instead.
|
|
132
|
+
console.log(`Created directory: ${absolutePath}`);
|
|
133
|
+
console.log('');
|
|
134
|
+
console.log(`To navigate there, run: cd "${absolutePath}"`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Create directory on macOS.
|
|
139
|
+
*
|
|
140
|
+
* Uses the pure Node.js implementation since fs.mkdirSync works
|
|
141
|
+
* identically on macOS as on other platforms.
|
|
142
|
+
*
|
|
143
|
+
* @param {string[]} args - Command line arguments
|
|
144
|
+
* @returns {Promise<void>}
|
|
145
|
+
*/
|
|
146
|
+
async function do_mkd_macos(args) {
|
|
147
|
+
return do_mkd_nodejs(args);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Create directory on Ubuntu.
|
|
152
|
+
*
|
|
153
|
+
* Uses the pure Node.js implementation since fs.mkdirSync works
|
|
154
|
+
* identically on Linux as on other platforms.
|
|
155
|
+
*
|
|
156
|
+
* @param {string[]} args - Command line arguments
|
|
157
|
+
* @returns {Promise<void>}
|
|
158
|
+
*/
|
|
159
|
+
async function do_mkd_ubuntu(args) {
|
|
160
|
+
return do_mkd_nodejs(args);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Create directory on Raspberry Pi OS.
|
|
165
|
+
*
|
|
166
|
+
* Uses the pure Node.js implementation since fs.mkdirSync works
|
|
167
|
+
* identically on Raspberry Pi OS as on other platforms.
|
|
168
|
+
*
|
|
169
|
+
* @param {string[]} args - Command line arguments
|
|
170
|
+
* @returns {Promise<void>}
|
|
171
|
+
*/
|
|
172
|
+
async function do_mkd_raspbian(args) {
|
|
173
|
+
return do_mkd_nodejs(args);
|
|
174
|
+
}
|
|
175
|
+
|
|
8
176
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
177
|
+
* Create directory on Amazon Linux.
|
|
178
|
+
*
|
|
179
|
+
* Uses the pure Node.js implementation since fs.mkdirSync works
|
|
180
|
+
* identically on Amazon Linux as on other platforms.
|
|
181
|
+
*
|
|
182
|
+
* @param {string[]} args - Command line arguments
|
|
183
|
+
* @returns {Promise<void>}
|
|
184
|
+
*/
|
|
185
|
+
async function do_mkd_amazon_linux(args) {
|
|
186
|
+
return do_mkd_nodejs(args);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Create directory in Windows Command Prompt.
|
|
191
|
+
*
|
|
192
|
+
* Uses the pure Node.js implementation since fs.mkdirSync works
|
|
193
|
+
* identically on Windows as on other platforms. The Node.js fs module
|
|
194
|
+
* handles Windows path separators automatically.
|
|
195
|
+
*
|
|
196
|
+
* @param {string[]} args - Command line arguments
|
|
197
|
+
* @returns {Promise<void>}
|
|
198
|
+
*/
|
|
199
|
+
async function do_mkd_cmd(args) {
|
|
200
|
+
return do_mkd_nodejs(args);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Create directory in Windows PowerShell.
|
|
205
|
+
*
|
|
206
|
+
* Uses the pure Node.js implementation since fs.mkdirSync works
|
|
207
|
+
* identically across all platforms and shells.
|
|
208
|
+
*
|
|
209
|
+
* @param {string[]} args - Command line arguments
|
|
210
|
+
* @returns {Promise<void>}
|
|
211
|
+
*/
|
|
212
|
+
async function do_mkd_powershell(args) {
|
|
213
|
+
return do_mkd_nodejs(args);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* Create directory in Git Bash on Windows.
|
|
218
|
+
*
|
|
219
|
+
* Uses the pure Node.js implementation. Git Bash understands both
|
|
220
|
+
* Unix-style and Windows-style paths, and Node.js handles the conversion.
|
|
221
|
+
*
|
|
222
|
+
* @param {string[]} args - Command line arguments
|
|
223
|
+
* @returns {Promise<void>}
|
|
224
|
+
*/
|
|
225
|
+
async function do_mkd_gitbash(args) {
|
|
226
|
+
return do_mkd_nodejs(args);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* Main entry point - detects environment and executes appropriate implementation.
|
|
231
|
+
*
|
|
232
|
+
* The "mkd" (make directory) command is a developer convenience tool that:
|
|
233
|
+
* 1. Creates a new directory, including all parent directories if needed
|
|
234
|
+
* 2. Provides the cd command to navigate to the new directory
|
|
235
|
+
*
|
|
236
|
+
* This replicates the shell function pattern of creating a directory and
|
|
237
|
+
* immediately entering it, common in developer workflows when starting
|
|
238
|
+
* new projects or organizing files.
|
|
239
|
+
*
|
|
240
|
+
* Note: Unlike the original shell function, this script cannot change the
|
|
241
|
+
* parent shell's working directory. Node.js scripts run in a subprocess and
|
|
242
|
+
* cannot affect the parent process's environment. The script outputs the
|
|
243
|
+
* cd command for the user to run.
|
|
244
|
+
*
|
|
245
|
+
* For a true "mkdir and cd" experience, users can use a shell alias:
|
|
246
|
+
* alias mkd='function _mkd(){ mkd "$1" && cd "$1"; }; _mkd'
|
|
247
|
+
* Or use command substitution:
|
|
248
|
+
* cd $(mkd --quiet my-dir) # If --quiet flag were implemented
|
|
11
249
|
*
|
|
12
250
|
* @param {string[]} args - Command line arguments
|
|
13
251
|
* @param {string} args.0 - Directory path to create
|
|
14
252
|
* @returns {Promise<void>}
|
|
15
253
|
*/
|
|
16
|
-
async function
|
|
17
|
-
|
|
254
|
+
async function do_mkd(args) {
|
|
255
|
+
const platform = os.detect();
|
|
256
|
+
|
|
257
|
+
const handlers = {
|
|
258
|
+
'macos': do_mkd_macos,
|
|
259
|
+
'ubuntu': do_mkd_ubuntu,
|
|
260
|
+
'debian': do_mkd_ubuntu,
|
|
261
|
+
'raspbian': do_mkd_raspbian,
|
|
262
|
+
'amazon_linux': do_mkd_amazon_linux,
|
|
263
|
+
'rhel': do_mkd_amazon_linux,
|
|
264
|
+
'fedora': do_mkd_ubuntu,
|
|
265
|
+
'linux': do_mkd_ubuntu,
|
|
266
|
+
'wsl': do_mkd_ubuntu,
|
|
267
|
+
'cmd': do_mkd_cmd,
|
|
268
|
+
'windows': do_mkd_cmd,
|
|
269
|
+
'powershell': do_mkd_powershell,
|
|
270
|
+
'gitbash': do_mkd_gitbash
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const handler = handlers[platform.type];
|
|
274
|
+
if (!handler) {
|
|
275
|
+
console.error(`Platform '${platform.type}' is not supported for this command.`);
|
|
276
|
+
console.error('');
|
|
277
|
+
console.error('Supported platforms:');
|
|
278
|
+
console.error(' - macOS');
|
|
279
|
+
console.error(' - Ubuntu, Debian, and other Linux distributions');
|
|
280
|
+
console.error(' - Raspberry Pi OS');
|
|
281
|
+
console.error(' - Amazon Linux, RHEL, Fedora');
|
|
282
|
+
console.error(' - Windows (CMD, PowerShell, Git Bash)');
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
await handler(args);
|
|
18
287
|
}
|
|
19
288
|
|
|
20
|
-
module.exports = {
|
|
289
|
+
module.exports = {
|
|
290
|
+
main: do_mkd,
|
|
291
|
+
do_mkd,
|
|
292
|
+
do_mkd_nodejs,
|
|
293
|
+
do_mkd_macos,
|
|
294
|
+
do_mkd_ubuntu,
|
|
295
|
+
do_mkd_raspbian,
|
|
296
|
+
do_mkd_amazon_linux,
|
|
297
|
+
do_mkd_cmd,
|
|
298
|
+
do_mkd_powershell,
|
|
299
|
+
do_mkd_gitbash
|
|
300
|
+
};
|
|
21
301
|
|
|
22
302
|
if (require.main === module) {
|
|
23
|
-
|
|
303
|
+
do_mkd(process.argv.slice(2));
|
|
24
304
|
}
|