Skip to content

Commit 6d5a6a4

Browse files
committed
build: update bin/env to new node.js app
1 parent a64e79a commit 6d5a6a4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1807
-990
lines changed

bin/_env/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
.package.hash
2+
.env.hash
23
package-lock.json
34
node_modules

bin/_env/addons/core.addon.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type {AddonEntrypoint} from '@/loadAddons.ts';
2+
import {EnvFileMigrator} from '@/env/EnvFileMigrator.ts';
3+
4+
export const addon: AddonEntrypoint = async (context) => ({
5+
commands: async (program) => {
6+
program
7+
.command('env:reset')
8+
.description('Resets your current .env file back to the default definition')
9+
.action(async () => {
10+
await ((new EnvFileMigrator(context.events, context.paths)).setForced(true).migrate(context.env));
11+
});
12+
}
13+
});

bin/_env/addons/docker.addon.ts

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import type {AddonEntrypoint} from '@/loadAddons.ts';
2+
import {DockerContext} from './docker/DockerContext.ts';
3+
import {Installer} from './docker/installer/Installer.ts';
4+
import {defineDockerEnv} from './docker/defineDockerEnv.ts';
5+
import type {Command} from 'commander';
6+
import {exec} from 'node:child_process';
7+
8+
export const addon: AddonEntrypoint = async (context) => ({
9+
context: async () => {
10+
return {
11+
docker: () => new DockerContext(context),
12+
installer: () => new Installer(context)
13+
};
14+
},
15+
env: defineDockerEnv(context.paths),
16+
events: async events => {
17+
// Create hook to ensure loopback IP is registered before docker:up
18+
events.on('docker:up:before', async () => {
19+
if (context.docker.isInstalled) {
20+
await context.installer.ensureLoopbackIp();
21+
}
22+
});
23+
},
24+
commands: async (program) => {
25+
program.hook('preSubcommand', async (_, subcommand) => {
26+
// Stupid workaround to ensure context.docker.getComposeCommandHelp() works correctly.
27+
if (subcommand.name().startsWith('docker:')) {
28+
await context.docker.getComposeExecutable();
29+
}
30+
});
31+
32+
program
33+
.command('docker:install')
34+
.alias('install')
35+
.description('Installs the project on your device; sets up a unique url, ip address, hosts entry and ssl certificate')
36+
.action(() => context.installer.install());
37+
38+
program
39+
.command('docker:up')
40+
.alias('up')
41+
.description('Starts the docker containers (docker compose up)')
42+
.addHelpText('after', () => context.docker.getComposeCommandHelp('up'))
43+
.option('-f, --attach', 'follows the output of your app like docker compose does', false)
44+
.allowExcessArguments(true)
45+
.allowUnknownOption(true)
46+
.action((options, command) => context.docker.up({
47+
follow: options.attach,
48+
args: command.args
49+
}).then());
50+
51+
program
52+
.command('docker:stop')
53+
.alias('stop')
54+
.description('Stops the docker containers (docker compose stop)')
55+
.addHelpText('after', () => context.docker.getComposeCommandHelp('stop'))
56+
.allowExcessArguments(true)
57+
.allowUnknownOption(true)
58+
.action((_, command) => context.docker.stop(command.args));
59+
60+
program
61+
.command('docker:down')
62+
.alias('down')
63+
.description('Stops and removes the docker containers (docker compose down)')
64+
.addHelpText('after', () => context.docker.getComposeCommandHelp('down'))
65+
.allowExcessArguments(true)
66+
.allowUnknownOption(true)
67+
.action((_, command) => context.docker.down(command.args));
68+
69+
program
70+
.command('docker:restart')
71+
.alias('restart')
72+
.description('Restarts the docker containers (docker compose restart), all arguments and flags are passed to the "up" command')
73+
.option('--force', 'instead of stopping the containers, a "down" and "up" is performed', false)
74+
.option('-f, --attach', 'follows the output of your app (after the restart) like docker compose does', false)
75+
.allowExcessArguments(true)
76+
.allowUnknownOption(true)
77+
.action((options, command) => context.docker.restart({
78+
follow: options.attach,
79+
args: command.args
80+
}).then());
81+
82+
program
83+
.command('docker:clean')
84+
.alias('clean')
85+
.description('Stops the project and removes all containers, networks, volumes and images')
86+
.option('-y, --yes', 'skips the confirmation prompt', false)
87+
.action((options) => context.docker.clean(options.yes));
88+
89+
program
90+
.command('docker:logs')
91+
.alias('logs')
92+
.description('Shows the logs of the docker containers (docker compose logs) - by default only the logs of the main container are shown, use "--all" to show all logs')
93+
.option('-a, --all', 'shows all logs, instead only the logs of the main container', false)
94+
.option('-f, --follow', 'follows the output of the logs', false)
95+
.addHelpText('after', () => context.docker.getComposeCommandHelp('logs'))
96+
.allowExcessArguments(true)
97+
.allowUnknownOption(true)
98+
.action(async (options, command: Command) => {
99+
return context.docker.logs({all: options.all, args: [(options.follow ? '-f' : ''), ...command.args]});
100+
});
101+
102+
program
103+
.command('docker:ssh')
104+
.alias('ssh')
105+
.description('Opens a shell in a docker container (docker compose exec)')
106+
.argument('[service]', 'the service to open the shell in')
107+
.option('-c, --cmd <cmd>', 'the command to execute in the container')
108+
.action((service, options) => context.docker.ssh(service, options.cmd));
109+
110+
program
111+
.command('docker:ps')
112+
.alias('ps')
113+
.description('Shows the docker containers of the project (docker compose ps)')
114+
.addHelpText('after', () => context.docker.getComposeCommandHelp('ps'))
115+
.allowExcessArguments(true)
116+
.allowUnknownOption(true)
117+
.action((_, command) => context.docker.ps(command.args));
118+
119+
program
120+
.command('docker:open')
121+
.alias('open')
122+
.description('opens the current project in your browser.')
123+
.action(() => {
124+
exec(`open ${context.docker.projectHost}`);
125+
});
126+
127+
program
128+
.command('docker:build:prod')
129+
.description('Builds the production image for the project')
130+
.option('--tag <tag>', 'Tag to use for the image', context.docker.projectName)
131+
.action(async (options) => {
132+
await context.docker.executeDockerCommand(
133+
['build', '--target', 'app_prod', '--pull', '-t', options.tag, context.paths.projectDir],
134+
{foreground: true}
135+
);
136+
});
137+
}
138+
});

0 commit comments

Comments
 (0)