Skip to content

Commit 43b869d

Browse files
authored
Merge pull request #122 from atomantic/software_split
BrewFile support and splitting software into prompts/files
2 parents 45e7a79 + 8ec17e9 commit 43b869d

10 files changed

Lines changed: 319 additions & 36 deletions

File tree

README.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ Do the following to upgrade your ~/.dotfiles safely:
102102
2. `cd ~/.dotfiles`
103103
3. update dotfiles: `git up` or `git pull`
104104
4. remove old submodule location: `rm -rf .vim` (now lives in `homedir/.vim`)
105-
5. inspect `install.sh` and `config.js` to make sure all the software you want is installed
105+
5. inspect `install.sh` and the `software/` directory to make sure all the software you want is installed
106106
6. inspect `homedir/*` for any changes you want to port from `./dotfiles_old`
107107
7. run `install.sh` again
108108

@@ -253,7 +253,40 @@ The following will only happen if you agree on the prompt
253253
# Software Installation
254254

255255
homebrew, fontconfig, git, nvm (node + npm), and zsh (latest) are all installed inside the `install.sh` as foundational software for running this project.
256-
Additional software is configured in `config.js` and can be customized in your own fork/branch (you can change everything in your own fork/brance).
256+
257+
Additional software is configured in separate files within the `software/` directory and can be customized in your own fork/branch:
258+
259+
- `software/brew.js` - Homebrew utilities and command-line tools
260+
- `software/cask.js` - Homebrew desktop applications (GUI apps)
261+
- `software/npm.js` - Global NPM packages
262+
- `software/mas.js` - Mac App Store applications
263+
- `software/gem.js` - Ruby gems
264+
265+
## .BrewFile Support
266+
267+
You can add additional Homebrew packages by creating a `.BrewFile` in the `homedir/` directory. This file should contain one package per line, with comments starting with `#`.
268+
269+
Example `.BrewFile`:
270+
```
271+
# Additional Homebrew packages
272+
htop
273+
neofetch
274+
ripgrep
275+
fd
276+
exa
277+
```
278+
279+
## Installation Prompts
280+
281+
When running the installation script, you'll be prompted for each software type:
282+
283+
1. **Homebrew utilities** - Command-line tools and utilities
284+
2. **Homebrew desktop apps** - GUI applications
285+
3. **NPM global packages** - Node.js packages installed globally
286+
4. **Mac App Store apps** - Applications from the Mac App Store
287+
5. **Ruby gems** - Ruby packages
288+
289+
Each prompt allows you to choose whether to install that category of software or skip it.
257290

258291
# License
259292

homedir/.BrewFile

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Additional Homebrew packages
2+
# Add your custom packages here, one per line
3+
# Lines starting with # are comments and will be ignored
4+
5+
# Example packages:
6+
# htop
7+
# neofetch
8+
# ripgrep
9+
# fd
10+
# exa

index.js

Lines changed: 72 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import { confirm } from "@inquirer/prompts";
22
import * as emoji from "node-emoji";
33
import fs from "fs";
4-
// import series from "async.series"; // Remove this line
54
import command from "./lib_node/command.js";
6-
import config from "./config.js";
75
import { dirname } from "path";
86
import { fileURLToPath } from "url";
97

@@ -17,7 +15,8 @@ async function run() {
1715

1816
if (answers) {
1917
// additional brew packages needed to support gitshots
20-
config.brew.push("imagemagick", "imagesnap");
18+
const brewConfig = (await import("./software/brew.js")).default;
19+
brewConfig.packages.push("imagemagick", "imagesnap");
2120
// ensure ~/.gitshots exists
2221
await command("mkdir -p ~/.gitshots", __dirname);
2322
// add post-commit hook
@@ -36,44 +35,84 @@ async function run() {
3635
}
3736
}
3837

39-
const packagesAnswer = await confirm({
40-
message: "Do you want to install packages from config.js?",
41-
default: false,
42-
});
43-
44-
if (!packagesAnswer) {
45-
return console.log("skipping package installs");
38+
// Check for .BrewFile in homedir
39+
const brewFileExists = fs.existsSync(path.join(__dirname, "homedir", ".BrewFile"));
40+
let brewFilePackages = [];
41+
42+
if (brewFileExists) {
43+
const brewFileContent = fs.readFileSync(path.join(__dirname, "homedir", ".BrewFile"), "utf8");
44+
brewFilePackages = brewFileContent
45+
.split("\n")
46+
.map(line => line.trim())
47+
.filter(line => line && !line.startsWith("#"));
4648
}
4749

4850
const tasks = [];
4951

50-
["brew", "cask", "npm", "gem", "mas"].forEach((type) => {
51-
if (config[type] && config[type].length) {
52-
tasks.push(async () => {
53-
console.info(emoji.get("coffee"), " installing " + type + " packages");
52+
// Dynamically read all software configuration files
53+
const softwareFiles = [
54+
"brew.js",
55+
"cask.js",
56+
"npm.js",
57+
"mas.js",
58+
"gem.js"
59+
];
60+
61+
for (const file of softwareFiles) {
62+
try {
63+
const config = (await import(`./software/${file}`)).default;
64+
65+
if (!config.packages || config.packages.length === 0) {
66+
console.log(`${config.name} has no packages to install`);
67+
continue;
68+
}
69+
const shouldInstall = await confirm({
70+
message: `Do you want to install ${config.name}?`,
71+
default: false,
5472
});
55-
config[type].forEach((item) => {
73+
74+
if (!shouldInstall) {
75+
console.log(`Skipping ${config.name} installation`);
76+
continue;
77+
}
78+
79+
// Combine config packages with .BrewFile packages for brew type
80+
let packages = config.packages;
81+
if (config.type === "brew" && brewFilePackages.length > 0) {
82+
packages = [...new Set([...config.packages, ...brewFilePackages])];
83+
console.log(`Found ${brewFilePackages.length} additional packages in .BrewFile`);
84+
}
85+
86+
if (packages && packages.length) {
5687
tasks.push(async () => {
57-
console.info(type + ":", item);
58-
try {
59-
await command(
60-
`. lib_sh/echos.sh && . lib_sh/requirers.sh && require_` +
61-
type +
62-
` ` +
63-
item,
64-
__dirname,
65-
);
66-
} catch (err) {
67-
console.error(emoji.get("fire"), err, err.stderr);
68-
}
88+
console.info(emoji.get("coffee"), ` installing ${config.type} packages`);
6989
});
70-
});
71-
} else {
72-
tasks.push(async () => {
73-
console.info(emoji.get("coffee"), type + " has no packages");
74-
});
90+
91+
packages.forEach((item) => {
92+
tasks.push(async () => {
93+
console.info(`${config.type}:`, item);
94+
try {
95+
await command(
96+
`. lib_sh/echos.sh && . lib_sh/requirers.sh && require_` +
97+
config.type +
98+
` ` +
99+
item,
100+
__dirname,
101+
);
102+
} catch (err) {
103+
console.error(emoji.get("fire"), err, err.stderr);
104+
}
105+
});
106+
});
107+
} else {
108+
tasks.push(async () => {
109+
console.info(emoji.get("coffee"), `${config.type} has no packages`);
110+
});
111+
}
112+
} catch (error) {
113+
console.error(`Error loading software configuration from ${file}:`, error.message);
75114
}
76-
});
115+
}
77116

78117
for (const task of tasks) {
79118
await task();

install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ bot "installing npm tools needed to run this project..."
361361
npm install
362362
ok
363363

364-
bot "installing packages from config.js..."
364+
bot "installing packages from software configuration files..."
365365
node index.js
366366
ok
367367

software/README.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Software Configuration
2+
3+
This directory contains split configuration files for different types of software packages.
4+
5+
## Files
6+
7+
Each configuration file exports an object with the following structure:
8+
9+
```javascript
10+
export default {
11+
name: "Display name for prompts",
12+
type: "package-manager-type",
13+
packages: [
14+
"package1",
15+
"package2",
16+
// ...
17+
],
18+
};
19+
```
20+
21+
### Available Files
22+
23+
- `brew.js` - Homebrew utilities and command-line tools
24+
- `cask.js` - Homebrew desktop applications (GUI apps)
25+
- `npm.js` - Global NPM packages
26+
- `mas.js` - Mac App Store applications
27+
- `gem.js` - Ruby gems
28+
29+
## .BrewFile Support
30+
31+
You can add additional Homebrew packages by creating a `.BrewFile` in the `homedir/` directory. This file should contain one package per line, with comments starting with `#`.
32+
33+
Example `.BrewFile`:
34+
```
35+
# Additional Homebrew packages
36+
htop
37+
neofetch
38+
ripgrep
39+
fd
40+
exa
41+
```
42+
43+
## Usage
44+
45+
When running the installation script, you'll be prompted for each software type:
46+
47+
1. **Homebrew utilities** - Command-line tools and utilities
48+
2. **Homebrew desktop apps** - GUI applications
49+
3. **NPM global packages** - Node.js packages installed globally
50+
4. **Mac App Store apps** - Applications from the Mac App Store
51+
5. **Ruby gems** - Ruby packages
52+
53+
Each prompt allows you to choose whether to install that category of software or skip it.
54+
55+
## Adding Packages
56+
57+
To add packages to any category, simply edit the corresponding `.js` file in this directory and add the package name to the `packages` array. The packages will be automatically installed when you run the installation script and choose to install that category.
58+
59+
## Adding New Software Types
60+
61+
To add a new software type:
62+
63+
1. Create a new `.js` file in this directory
64+
2. Export an object with `name`, `type`, and `packages` properties
65+
3. Add the filename to the `softwareFiles` array in `index.js`
66+
4. Ensure the corresponding `require_*` function exists in `lib_sh/requirers.sh`
67+
68+
Example new software type:
69+
```javascript
70+
// software/pip.js
71+
export default {
72+
name: "Python packages",
73+
type: "pip",
74+
packages: [
75+
"requests",
76+
"flask",
77+
"pytest",
78+
],
79+
};
80+
```

software/brew.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
export default {
2+
name: "Homebrew utilities",
3+
type: "brew",
4+
packages: [
5+
// http://conqueringthecommandline.com/book/ack_ag
6+
"ack",
7+
"ag",
8+
// https://github.com/wting/autojump
9+
"autojump",
10+
// alternative to `cat`: https://github.com/sharkdp/bat
11+
"bat",
12+
// Install GNU core utilities (PATH updated automatically during install)
13+
"coreutils",
14+
"dos2unix",
15+
// Install GNU `find`, `locate`, `updatedb`, and `xargs`, `g`-prefixed
16+
"findutils",
17+
"fortune",
18+
"fzf",
19+
"readline", // ensure gawk gets good readline
20+
"gawk",
21+
// http://www.lcdf.org/gifsicle/ (because I'm a gif junky)
22+
"gifsicle",
23+
"gnupg",
24+
// Install GNU `sed` (PATH updated automatically during install)
25+
"gnu-sed",
26+
// Install GNU grep (PATH updated automatically during install)
27+
"grep",
28+
// https://github.com/jkbrzt/httpie
29+
"httpie",
30+
// jq is a sort of JSON grep
31+
"jq",
32+
// Mac App Store CLI: https://github.com/mas-cli/mas
33+
"mas",
34+
// Install some other useful utilities like `sponge`
35+
"moreutils",
36+
"nmap",
37+
// 'openconnect',
38+
"reattach-to-user-namespace",
39+
"ripgrep",
40+
// better/more recent version of screen
41+
"homebrew/dupes/screen",
42+
"tmux",
43+
"todo-txt",
44+
"tree",
45+
"ttyrec",
46+
// better, more recent vim
47+
"vim --with-client-server --with-override-system-vi",
48+
"watch",
49+
// Install wget with IRI support
50+
"wget --enable-iri",
51+
],
52+
};

software/cask.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
export default {
2+
name: "Homebrew desktop apps",
3+
type: "cask",
4+
packages: [
5+
//'adium',
6+
//'amazon-cloud-drive',
7+
//'atom',
8+
//'box-sync',
9+
//'comicbooklover',
10+
//'diffmerge',
11+
"docker", // docker for mac
12+
//'dropbox',
13+
//'evernote',
14+
//'flux',
15+
// "gpg-suite",
16+
//'ireadfast',
17+
"iterm2",
18+
//'little-snitch',
19+
// 'macbreakz',
20+
//'micro-snitch',
21+
// 'signal',
22+
//'macvim',
23+
// "sizeup",
24+
//'sketchup',
25+
"slack",
26+
// 'the-unarchiver',
27+
//'torbrowser',
28+
//'transmission',
29+
"visual-studio-code",
30+
//'vlc',
31+
// "xquartz",
32+
],
33+
};

software/gem.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default {
2+
name: "Ruby gems",
3+
type: "gem",
4+
packages: [
5+
// Add your Ruby gems here
6+
],
7+
};

0 commit comments

Comments
 (0)