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
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
dist
templates/init
1 change: 0 additions & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ export default [
}
}
},

{
rules: {
'no-console': 'off',
Expand Down
24 changes: 21 additions & 3 deletions src/configs/juno.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@ import {JUNO_CONFIG_FILENAME} from '../constants/constants';
import {
TEMPLATE_INIT_PATH,
TEMPLATE_JUNO_PREDEPLOY_CONFIG_FILENAME,
TEMPLATE_RUNNER_CONFIG_FILENAME,
TEMPLATE_RUNNER_PREDEPLOY_CONFIG_FILENAME,
TEMPLATE_SKYLAB_CONFIG_FILENAME,
TEMPLATE_SKYLAB_PREDEPLOY_CONFIG_FILENAME
} from '../constants/templates.constants';
import {type JunoConfigWithPlaceholder, type JunoConfigWithSatelliteId} from '../types/config';
import {type EmulatorConfigWithoutConsole} from '../types/emulator';
import type {PackageManager} from '../types/pm';
import {readTemplateFile} from '../utils/fs.utils';

Expand All @@ -37,9 +40,11 @@ export const writeJunoConfigPlaceholder = async ({
config,
configType,
configPath,
pm
pm,
emulatorConfig
}: {config: JunoConfigWithPlaceholder} & PartialConfigFile & {
pm: PackageManager | undefined;
emulatorConfig?: EmulatorConfigWithoutConsole;
}): Promise<void> => {
switch (configType) {
case 'ts':
Expand All @@ -50,14 +55,27 @@ export const writeJunoConfigPlaceholder = async ({

const withPredeploy = nonNullish(pm);

const templateFilename = nonNullish(emulatorConfig)
? withPredeploy
? TEMPLATE_RUNNER_PREDEPLOY_CONFIG_FILENAME
: TEMPLATE_RUNNER_CONFIG_FILENAME
: withPredeploy
? TEMPLATE_SKYLAB_PREDEPLOY_CONFIG_FILENAME
: TEMPLATE_SKYLAB_CONFIG_FILENAME;

const template = await readTemplateFile({
template: `${withPredeploy ? TEMPLATE_SKYLAB_PREDEPLOY_CONFIG_FILENAME : TEMPLATE_SKYLAB_CONFIG_FILENAME}.${configType}`,
template: `${templateFilename}.${configType}`,
sourceFolder: TEMPLATE_INIT_PATH
});

const content = template
.replace('<SOURCE>', source ?? DEPLOY_DEFAULT_SOURCE)
.replace('<COMMAND>', pm === 'npm' ? 'npm run' : (pm ?? ''));
.replace('<COMMAND>', pm === 'npm' ? 'npm run' : (pm ?? ''))
.replace('<RUNNER>', emulatorConfig?.runner?.type ?? '')
.replace(
'<IMAGE>',
nonNullish(emulatorConfig) ? ('satellite' in emulatorConfig ? 'satellite' : 'skylab') : ''
);

await writeFile(configPath ?? `${JUNO_CONFIG_FILENAME}.${configType}`, content, 'utf-8');
break;
Expand Down
4 changes: 4 additions & 0 deletions src/constants/templates.constants.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
export const TEMPLATE_INIT_PATH = '../templates/init';

export const TEMPLATE_SKYLAB_CONFIG_FILENAME = `juno.skylab.config`;

export const TEMPLATE_JUNO_PREDEPLOY_CONFIG_FILENAME = `juno.predeploy.config`;
export const TEMPLATE_SKYLAB_PREDEPLOY_CONFIG_FILENAME = `juno.skylab.predeploy.config`;

export const TEMPLATE_RUNNER_CONFIG_FILENAME = `juno.runner.config`;
export const TEMPLATE_RUNNER_PREDEPLOY_CONFIG_FILENAME = `juno.runner.predeploy.config`;
77 changes: 54 additions & 23 deletions src/services/dev/_runner.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,13 @@ import {
EMULATOR_PORT_SERVER,
EMULATOR_SKYLAB
} from '../../constants/emulator.constants';
import {type CliEmulatorConfig, type CliEmulatorDerivedConfig} from '../../types/emulator';
import {
type CliEmulatorConfig,
type CliEmulatorDerivedConfig,
type EmulatorRunnerType,
type EmulatorType
} from '../../types/emulator';
import {isHeadless} from '../../utils/process.utils';
import {confirmAndExit} from '../../utils/prompt.utils';
import {
assertContainerRunnerRunning,
checkDockerVersion,
Expand All @@ -25,6 +29,8 @@ import {createDeployTargetDir} from '../emulator/emulator.fs.services';
import {initConfigNoneInteractive} from '../init.services';

export const startContainer = async () => {
await assertAndInitConfig();

const parsedResult = await readEmulatorConfig();

if (!parsedResult.success) {
Expand All @@ -42,8 +48,6 @@ export const startContainer = async () => {

await assertContainerRunnerRunning({runner: config.derivedConfig.runner});

await assertAndInitConfig();

await startEmulator({config});
};

Expand All @@ -68,29 +72,43 @@ export const stopContainer = async () => {
await stopEmulator({config});
};

const initJunoConfigFile = async () => {
await confirmAndExit(`Your project needs a config file for Juno. Should we create one now?`);
const promptEmulatorType = async (): Promise<{emulatorType: Exclude<EmulatorType, 'console'>}> => {
const {emulatorType}: {emulatorType: Exclude<EmulatorType, 'console'> | undefined} =
await prompts({
type: 'select',
name: 'emulatorType',
message: 'What kind of emulator would you like to run locally?',
choices: [
{
title: `Complete environment with Console and known services`,
value: `skylab`
},
{title: `Minimal headless setup`, value: `satellite`}
]
});

assertAnswerCtrlC(emulatorType);

await initConfigNoneInteractive();
return {emulatorType};
};

const promptEmulatorType = async (): Promise<{emulatorType: 'skylab' | 'satellite'}> => {
const {emulatorType}: {emulatorType: 'skylab' | 'satellite' | undefined} = await prompts({
const promptRunnerType = async (): Promise<{runnerType: EmulatorRunnerType}> => {
const {runnerType}: {runnerType: EmulatorRunnerType | undefined} = await prompts({
type: 'select',
name: 'emulatorType',
message: 'What kind of emulator would you like to run locally?',
name: 'runnerType',
message: 'Which container runtime would you like to use?',
choices: [
{
title: `Production-like setup with Console UI and known services`,
value: `skylab`
title: 'Docker',
value: `docker`
},
{title: `Minimal setup without any UI`, value: `satellite`}
{title: `Podman`, value: `podman`}
]
});

assertAnswerCtrlC(emulatorType);
assertAnswerCtrlC(runnerType);

return {emulatorType};
return {runnerType};
};

const assertAndInitConfig = async () => {
Expand All @@ -100,15 +118,28 @@ const assertAndInitConfig = async () => {
return;
}

const {emulatorType} = await promptEmulatorType();

await initConfigFile(emulatorType === 'skylab');
await initConfigFile();
};

const initConfigFile = async (_skylab: boolean) => {
// TODO: if not skyLab, emulator satellite {}
// or remove question?
await initJunoConfigFile();
const initConfigFile = async () => {
const {emulatorType} = await promptEmulatorType();

const {runnerType} = await promptRunnerType();

// Default skylab and docker, no need to specify those options in the config if they were picked.
const emulatorConfig =
emulatorType === 'skylab' && runnerType === 'docker'
? undefined
: {
runner: {
type: runnerType
},
...(emulatorType === 'satellite' ? {satellite: {}} : {skylab: {}})
};

await initConfigNoneInteractive({
emulatorConfig
});
};

const startEmulator = async ({config: extendedConfig}: {config: CliEmulatorConfig}) => {
Expand Down
8 changes: 6 additions & 2 deletions src/services/init.services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
writeJunoConfigPlaceholder
} from '../configs/juno.config';
import type {CliOrbiterConfig, CliSatelliteConfig} from '../types/cli.config';
import {type EmulatorConfigWithoutConsole} from '../types/emulator';
import type {PackageManager} from '../types/pm';
import {detectPackageManager} from '../utils/pm.utils';
import {NEW_CMD_LINE} from '../utils/prompt.utils';
Expand Down Expand Up @@ -41,13 +42,16 @@ export type InitConfigParams = PartialConfigFile & {pm: PackageManager | undefin
source: string;
};

export const initConfigNoneInteractive = async () => {
export const initConfigNoneInteractive = async ({
emulatorConfig
}: {emulatorConfig?: EmulatorConfigWithoutConsole} = {}) => {
const writeFn = async ({source, ...rest}: InitConfigParams) => {
await writeJunoConfigPlaceholder({
...rest,
config: {
satellite: {source}
}
},
emulatorConfig
});
};

Expand Down
12 changes: 9 additions & 3 deletions src/types/emulator.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import type {EmulatorConfig, EmulatorRunner} from '@junobuild/config';
import type {EmulatorConfig, EmulatorConsole, EmulatorRunner} from '@junobuild/config';

export type EmulatorType = 'skylab' | 'satellite' | 'console';

export type EmulatorRunnerType = EmulatorRunner['type'];

export type EmulatorConfigWithoutConsole = Exclude<EmulatorConfig, {console: EmulatorConsole}>;

export interface CliEmulatorDerivedConfig {
containerName: string;
runner: EmulatorRunner['type'];
emulatorType: 'skylab' | 'satellite' | 'console';
runner: EmulatorRunnerType;
emulatorType: EmulatorType;
targetDeploy: string;
}

Expand Down
18 changes: 18 additions & 0 deletions templates/init/juno.runner.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {defineConfig} from '@junobuild/config';

/** @type {import('@junobuild/config').JunoConfig} */
export default defineConfig({
satellite: {
ids: {
development: '<DEV_SATELLITE_ID>',
production: '<PROD_SATELLITE_ID>'
},
source: '<SOURCE>'
},
emulator: {
runner: {
type: '<RUNNER>'
},
<IMAGE>: {}
}
});
17 changes: 17 additions & 0 deletions templates/init/juno.runner.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import {defineConfig} from '@junobuild/config';

export default defineConfig({
satellite: {
ids: {
development: '<DEV_SATELLITE_ID>',
production: '<PROD_SATELLITE_ID>'
},
source: '<SOURCE>'
},
emulator: {
runner: {
type: '<RUNNER>'
},
<IMAGE>: {}
}
});
19 changes: 19 additions & 0 deletions templates/init/juno.runner.predeploy.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import {defineConfig} from '@junobuild/config';

/** @type {import('@junobuild/config').JunoConfig} */
export default defineConfig({
satellite: {
ids: {
development: '<DEV_SATELLITE_ID>',
production: '<PROD_SATELLITE_ID>'
},
source: '<SOURCE>',
predeploy: ['<COMMAND> build']
},
emulator: {
runner: {
type: '<RUNNER>'
},
<IMAGE>: {}
}
});
18 changes: 18 additions & 0 deletions templates/init/juno.runner.predeploy.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {defineConfig} from '@junobuild/config';

export default defineConfig({
satellite: {
ids: {
development: '<DEV_SATELLITE_ID>',
production: '<PROD_SATELLITE_ID>'
},
source: '<SOURCE>',
predeploy: ['<COMMAND> build']
},
emulator: {
runner: {
type: '<RUNNER>'
},
<IMAGE>: {}
}
});
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@
"moduleResolution": "bundler",
"outDir": "dist",
"resolveJsonModule": true
}
},
"exclude": ["templates"]
}