Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions src/commands/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ import {red} from 'kleur';
import {logHelpDevBuild} from '../help/dev.build.help';
import {logHelpDevEject} from '../help/dev.eject.help';
import {logHelpDev} from '../help/dev.help';
import {logHelpDevStart} from '../help/dev.start.help';
import {build} from '../services/build/build.services';
import {start, stop} from '../services/docker.services';
import {eject} from '../services/eject/eject.services';
import {stop} from '../services/start/docker.services';
import {start} from '../services/start/start.services';

export const dev = async (args?: string[]) => {
const [subCommand] = args ?? [];
Expand All @@ -17,7 +19,7 @@ export const dev = async (args?: string[]) => {
await build(args);
break;
case 'start':
await start();
await start(args);
break;
case 'stop':
await stop();
Expand All @@ -32,6 +34,9 @@ export const helpDev = (args?: string[]) => {
const [subCommand] = args ?? [];

switch (subCommand) {
case 'start':
logHelpDevStart(args);
break;
case 'build':
logHelpDevBuild(args);
break;
Expand Down
8 changes: 8 additions & 0 deletions src/constants/help.constants.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {magenta} from 'kleur';

export const CLEAR_DESCRIPTION =
'Clear existing dapp code by removing JavaScript, HTML, CSS, and other files from your satellite.';
export const CONFIG_DESCRIPTION = 'Apply configuration to satellite.';
Expand All @@ -19,6 +21,12 @@ export const VERSION_DESCRIPTION = 'Check the version of the modules and CLI.';
export const WHOAMI_DESCRIPTION =
'Display your current profile, controller, and links to your satellite.';

export const DEV_START_DESCRIPTION = 'Start a local Internet Computer network in a container.';
export const DEV_BUILD_DESCRIPTION = 'Build your serverless functions.';
export const DEV_EJECT_DESCRIPTION =
'Generate the required files to begin developing serverless functions in your project.';

export const DEV_BUILD_NOTES = `- If no language is provided, the CLI attempts to determine the appropriate build.
- Language can be shortened to ${magenta('rs')} for Rust, ${magenta('ts')} for TypeScript and ${magenta('mjs')} for JavaScript.
- The path option maps to ${magenta('--manifest-path')} for Rust (Cargo) or to the source file for TypeScript and JavaScript (e.g. ${magenta('index.ts')} or ${magenta('index.mjs')}).
- The watch option rebuilds when source files change, with a default debounce delay of 10 seconds; optionally, pass a delay in milliseconds.`;
7 changes: 2 additions & 5 deletions src/help/dev.build.help.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {cyan, green, magenta, yellow} from 'kleur';
import {DEV_BUILD_DESCRIPTION} from '../constants/help.constants';
import {DEV_BUILD_DESCRIPTION, DEV_BUILD_NOTES} from '../constants/help.constants';
import {helpOutput} from './common.help';
import {TITLE} from './help';

Expand All @@ -13,10 +13,7 @@ Options:

Notes:

- If no language is provided, the CLI attempts to determine the appropriate build.
- Language can be shortened to ${magenta('rs')} for Rust, ${magenta('ts')} for TypeScript and ${magenta('mjs')} for JavaScript.
- The path option maps to ${magenta('--manifest-path')} for Rust (Cargo) or to the source file for TypeScript and JavaScript (e.g. ${magenta('index.ts')} or ${magenta('index.mjs')}).
- The watch option rebuilds when source files change, with a default debounce delay of 10 seconds; optionally, pass a delay in milliseconds.`;
${DEV_BUILD_NOTES}`;

const doc = `${DEV_BUILD_DESCRIPTION}

Expand Down
6 changes: 2 additions & 4 deletions src/help/dev.help.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import {cyan, green, magenta, yellow} from 'kleur';
import {DEV_DESCRIPTION} from '../constants/help.constants';
import {DEV_DESCRIPTION, DEV_START_DESCRIPTION} from '../constants/help.constants';
import {helpOutput} from './common.help';
import {TITLE} from './help';

const helpDevStart = `${magenta(
'start'
)} Start a local Internet Computer network in a container.`;
const helpDevStart = `${magenta('start')} ${DEV_START_DESCRIPTION}`;

const helpDevBuild = `${magenta('build')} Build your serverless functions. The local server supports live reloading.`;

Expand Down
35 changes: 35 additions & 0 deletions src/help/dev.start.help.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import {cyan, green, magenta, yellow} from 'kleur';
import {DEV_BUILD_NOTES, DEV_START_DESCRIPTION} from '../constants/help.constants';
import {helpOutput} from './common.help';
import {TITLE} from './help';

const usage = `Usage: ${green('juno')} ${cyan('dev')} ${magenta('start')} ${yellow('[options]')}

Options:
${yellow('-l, --lang')} Language used when watching for file changes: ${magenta('rust')}, ${magenta('typescript')} or ${magenta('javascript')}.
${yellow('-p, --path')} Path to the source file or manifest used when watching.
${yellow('-w, --watch')} Rebuild your functions automatically when source files change.
${yellow('-h, --help')} Output usage information.

Notes:

- The language and path options are only used in combination with watch.
${DEV_BUILD_NOTES}`;

const doc = `${DEV_START_DESCRIPTION}

\`\`\`
${usage}
\`\`\`
`;

const help = `${TITLE}

${DEV_START_DESCRIPTION}

${usage}
`;

export const logHelpDevStart = (args?: string[]) => {
console.log(helpOutput(args) === 'doc' ? doc : help);
};
39 changes: 2 additions & 37 deletions src/services/build/build.services.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import {debounce, nonNullish} from '@dfinity/utils';
import {hasArgs, nextArg} from '@junobuild/cli-tools';
import chokidar from 'chokidar';
import {red} from 'kleur';
import {existsSync} from 'node:fs';
Expand All @@ -12,6 +11,7 @@ import {
} from '../../constants/dev.constants';
import {SMALL_TITLE} from '../../help/help';
import {type BuildArgs} from '../../types/build';
import {buildArgs} from '../../utils/build.utils';
import {buildJavaScript, buildTypeScript} from './build.javascript';
import {buildRust} from './build.rust.services';

Expand Down Expand Up @@ -86,7 +86,7 @@ const executeBuild = async ({lang, path}: Omit<BuildArgs, 'watch'>) => {
);
};

const watchBuild = ({watch, path, ...params}: BuildArgs) => {
export const watchBuild = ({watch, path, ...params}: BuildArgs) => {
const doBuild = async () => {
console.log(`\n⏱ Rebuilding serverless functions...`);
await executeBuild({path, ...params});
Expand Down Expand Up @@ -118,38 +118,3 @@ const watchBuild = ({watch, path, ...params}: BuildArgs) => {
console.log(red('️‼️ Unexpected error while live reloading:'), err);
});
};

const buildArgs = (args?: string[]): BuildArgs => {
const path = nextArg({args, option: '-p'}) ?? nextArg({args, option: '--path'});

const {lang} = buildLang(args);

const watch = hasArgs({args, options: ['-w', '--watch']});
const watchValue = nextArg({args, option: '-w'}) ?? nextArg({args, option: '--watch'});

return {
path,
lang,
watch: watchValue ?? watch
};
};

const buildLang = (args?: string[]): Pick<BuildArgs, 'lang'> => {
const lang = nextArg({args, option: '-l'}) ?? nextArg({args, option: '--lang'});

switch (lang?.toLowerCase()) {
case 'rs':
case 'rust':
return {lang: 'rs'};
case 'ts':
case 'mts':
case 'typescript':
return {lang: 'ts'};
case 'js':
case 'mjs':
case 'javascript':
return {lang: 'mjs'};
default:
return {};
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ import {
detectJunoDevConfigType,
junoDevConfigExist,
junoDevConfigFile
} from '../configs/juno.dev.config';
import {JUNO_DEV_CONFIG_FILENAME} from '../constants/constants';
import {assertDockerRunning, checkDockerVersion} from '../utils/env.utils';
import {copyTemplateFile, readTemplateFile} from '../utils/fs.utils';
import {confirmAndExit} from '../utils/prompt.utils';
import {promptConfigType} from './init.services';
} from '../../configs/juno.dev.config';
import {JUNO_DEV_CONFIG_FILENAME} from '../../constants/constants';
import {assertDockerRunning, checkDockerVersion} from '../../utils/env.utils';
import {copyTemplateFile, readTemplateFile} from '../../utils/fs.utils';
import {confirmAndExit} from '../../utils/prompt.utils';
import {promptConfigType} from '../init.services';

const TEMPLATE_PATH = '../templates/docker';
const DESTINATION_PATH = process.cwd();

export const start = async () => {
export const startContainer = async () => {
const {valid} = await checkDockerVersion();

if (valid === 'error' || !valid) {
Expand Down
14 changes: 14 additions & 0 deletions src/services/start/start.services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {nonNullish} from '@dfinity/utils';
import {buildArgs} from '../../utils/build.utils';
import {watchBuild} from '../build/build.services';
import {startContainer} from './docker.services';

export const start = async (args?: string[]) => {
const {watch, ...params} = buildArgs(args);

if (nonNullish(watch) && watch !== false) {
watchBuild({watch, ...params});
}

await startContainer();
};
37 changes: 37 additions & 0 deletions src/utils/build.utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {hasArgs, nextArg} from '@junobuild/cli-tools';
import type {BuildArgs} from '../types/build';

export const buildArgs = (args?: string[]): BuildArgs => {
const path = nextArg({args, option: '-p'}) ?? nextArg({args, option: '--path'});

const {lang} = buildLang(args);

const watch = hasArgs({args, options: ['-w', '--watch']});
const watchValue = nextArg({args, option: '-w'}) ?? nextArg({args, option: '--watch'});

return {
path,
lang,
watch: watchValue ?? watch
};
};

const buildLang = (args?: string[]): Pick<BuildArgs, 'lang'> => {
const lang = nextArg({args, option: '-l'}) ?? nextArg({args, option: '--lang'});

switch (lang?.toLowerCase()) {
case 'rs':
case 'rust':
return {lang: 'rs'};
case 'ts':
case 'mts':
case 'typescript':
return {lang: 'ts'};
case 'js':
case 'mjs':
case 'javascript':
return {lang: 'mjs'};
default:
return {};
}
};