Skip to content
Open
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
17 changes: 2 additions & 15 deletions actions/docker.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import * as chalk from 'chalk';
import * as fs from 'fs';
import * as yaml from 'js-yaml';
import { join } from 'path';
import { getSpecFilePath } from '../lib/utils/specFilePath';

export class DockerAction extends AbstractAction {
private manager!: AbstractPackageManager;
Expand All @@ -17,7 +18,7 @@ export class DockerAction extends AbstractAction {

const serviceName = commandInputs[0].value as string;

const specFilePath = await this.getSpecFilePath();
const specFilePath = await getSpecFilePath();

if (specFilePath) {
await this.updateSpecFile(specFilePath, serviceName);
Expand All @@ -40,20 +41,6 @@ export class DockerAction extends AbstractAction {
}
}
}
private async getSpecFilePath(): Promise<string | null> {
try {
const nestCliConfig = await fs.promises.readFile('nest-cli.json', 'utf-8');
const config = JSON.parse(nestCliConfig);
if (config.specFile) {
return config.specFile;
} else {
return null;
}
} catch (error) {
console.error(chalk.red('Error reading nest-cli.json'), error);
return null;
}
}

private async updateSpecFile(specFilePath: string, serviceName: string): Promise<boolean> {
try {
Expand Down
3 changes: 2 additions & 1 deletion actions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export * from './list.action';
export * from './new.action';
export * from './start.action';
export * from './add.action';
export * from './pull.action';
export * from './spec.action';
export * from './docker.action';
export * from './docker.action';
175 changes: 175 additions & 0 deletions actions/pull.action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import * as chalk from 'chalk';
import * as fs from 'fs';
import * as inquirer from 'inquirer';
import * as yaml from 'js-yaml';
import { AbstractPackageManager, PackageManagerFactory } from '../lib/package-managers';
import { AbstractAction } from './abstract.action';
import { Input } from '../commands/command.input';
import { repositories } from '../lib/utils/pull-utils/repositories';
import { cloneRepo, setupWithDockerfile, setupWithScript, checkDockerContainerExists } from '../lib/utils/pull-utils/serviceUtils';
import { getSpecFilePath } from '../lib/utils/specFilePath';
import { exec } from 'child_process';
import { StencilRunner } from '../lib/runners/stencil.runner';
import { join } from 'path';
import { NpmRunner } from '../lib/runners/npm.runner';
import { MESSAGES } from '../lib/ui';

export class PullAction extends AbstractAction {
private manager!: AbstractPackageManager;

public async handle(commandInputs: Input[],options: Input[]) {
this.manager = await PackageManagerFactory.find();
const serviceName = commandInputs[0].value as string;
const init = options.find((option) => option.name === 'init')!.value as boolean;

if (init) {
if (!fs.existsSync('frontend')) {
console.info(MESSAGES.INITIALIZING_FRONTEND);
await this.runStencilPullService();
console.info(MESSAGES.INSTALLING_DEPENDENCIES);
await this.installDependencies();
} else {
console.info(chalk.yellow(MESSAGES.FRONTEND_ALREADY_INITIALIZED));
}
}

if (serviceName === 'preview') {
const specFilePath = await getSpecFilePath();
if (specFilePath) {
await this.launchAstroFrontend(specFilePath);
return;
} else {
console.error(chalk.red(MESSAGES.NO_SPEC_FOUND));
return;
}
}
if (serviceName in repositories.services) {
await cloneRepo(serviceName, repositories.services);
const specFilePath = await getSpecFilePath();
if (specFilePath) {
this.addServiceToSpec(specFilePath, serviceName);
}
await this.setupService(serviceName);

} else {
console.error(chalk.red(`Service ${serviceName} is not supported.`));
}
}
private async runStencilPullService() {
const stencilRunner = new StencilRunner();
const prismaUpdateCommand = 'g pullservice';
const commandArgs = `${prismaUpdateCommand}`;

try {
console.info(chalk.green(MESSAGES.PULL_INSTALLATION_IN_PROGRESS));
await stencilRunner.run(
commandArgs,
false,
join(process.cwd()),
);
} catch (error) {
console.error(chalk.red(MESSAGES.PULL_INSTALLATION_ERROR));
}

}

private async installDependencies() {
const npmRunner = new NpmRunner();
const userServiceCommand = 'install';
const commandArgs = `${userServiceCommand}`;

try {
await npmRunner.run(
commandArgs,
false,
join(process.cwd(), 'frontend'),
);
} catch (error) {
console.error(chalk.red(MESSAGES.PULL_INSTALLATION_ERROR));
}

}

private async setupService(serviceName: string): Promise<void> {
const prompt = inquirer.createPromptModule();
const { setupMethod } = await prompt([
{
type: 'list',
name: 'setupMethod',
message: `How do you want to set up the ${serviceName}?`,
choices: ['Dockerfile', 'Startup script', 'Skip'],
},
]);

if (setupMethod === 'Dockerfile') {
await setupWithDockerfile(serviceName);
} else if (setupMethod === 'Startup script') {
await setupWithScript(serviceName);
} else{
console.info(chalk.yellow(`Skipping setup for ${serviceName}.`));
return;
}
}

private addServiceToSpec(specFilePath: string, serviceName: string): void {

if (fs.existsSync(specFilePath)) {
let specFileContent = fs.readFileSync(specFilePath, 'utf8');
let specData = yaml.load(specFileContent) as any;

if (!specData.services) {
specData.services = [];
}

if (!specData.services.includes(serviceName)) {
specData.services.push(serviceName);
console.info(chalk.green(`Service ${serviceName} added to spec.yaml.`));

fs.writeFileSync(specFilePath, yaml.dump(specData), 'utf8');
} else {
console.info(chalk.yellow(`Service ${serviceName} is already listed in spec.yaml.`));
}
} else {
const specData = {
services: [serviceName]
};
fs.writeFileSync(specFilePath, yaml.dump(specData), 'utf8');
console.info(chalk.green(`spec.yaml created and ${serviceName} added.`));
}
}
private async launchAstroFrontend(specFilePath: string): Promise<void> {
console.info(chalk.green('Building Astro frontend...'));

try{
exec('npx astro build', { cwd: './frontend' }, (error, stdout, stderr) => {
if (error) {
console.error(chalk.red(`Error building Astro frontend: ${error.message}`));
return;
}

console.info(chalk.green(stdout));

if (stderr) {
console.error(chalk.yellow(stderr));
}

console.info(chalk.green('Serving Astro frontend...'));
exec('npx serve ./frontend/dist', (serveError, serveOut, serveErr) => {
if (serveError) {
console.error(chalk.red(`Error serving Astro frontend: ${serveError.message}`));
return;
}

console.info(chalk.green(serveOut));
if (serveErr) {
console.error(chalk.yellow(serveErr));
}
});
});

}catch(error){
console.error(chalk.red(`Error building Astro frontend: ${error.message}`));
return;
}
}
}
4 changes: 4 additions & 0 deletions commands/command.loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
ListAction,
NewAction,
StartAction,
PullAction,
DockerAction,
} from '../actions';
import { ERROR_PREFIX } from '../lib/ui';
Expand All @@ -20,7 +21,9 @@ import { SpecCommand } from './spec.command';
import { ListCommand } from './list.command';
import { NewCommand } from './new.command';
import { StartCommand } from './start.command';
import { PullCommand } from './pull.command';
import { DockerCommand } from './docker.command';

export class CommandLoader {
public static async load(program: CommanderStatic): Promise<void> {
new NewCommand(new NewAction()).load(program);
Expand All @@ -30,6 +33,7 @@ export class CommandLoader {
new SpecCommand(new SpecAction()).load(program);
new ListCommand(new ListAction()).load(program);
new AddCommand(new AddAction()).load(program);
new PullCommand(new PullAction()).load(program);
new DockerCommand(new DockerAction()).load(program);
await new GenerateCommand(new GenerateAction()).load(program);

Expand Down
29 changes: 29 additions & 0 deletions commands/pull.command.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { Command, CommanderStatic } from 'commander';
import { AbstractCommand } from './abstract.command';
import { Input } from './command.input';

export class PullCommand extends AbstractCommand{
public load(program: CommanderStatic) {
program
.command('pull <services...>')
.alias('pu')
.description('Pull services and modules from a repository or a docker service.')
.option(
'--init',
'initialization of the preview folder',
false
)
.action(async (services: string[],
command: Command,
) => {
const options: Input[] = [
{ name: 'init', value: command.init || false }
];

const inputs: Input[] = services.map(service => ({ name: 'name', value: service }));
for (const input of inputs) {
await this.action.handle([input], options);
}
});
}
}
5 changes: 5 additions & 0 deletions lib/schematics/nest.collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,11 @@ export class NestCollection extends AbstractCollection {
alias: 'fu',
description: 'If you want to have fileUpload setup in the project.',
},
{
name: 'pullservice',
alias: 'ps',
description: 'If you want to have pullService frontend setup in the project.',
}
];
public static docker: Docker[] = [
{
Expand Down
6 changes: 6 additions & 0 deletions lib/ui/messages.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import * as chalk from 'chalk';
import { EMOJIS } from './emojis';
import { INITIALIZING_TYPE_CHECKER } from '../compiler/swc/constants';

export const MESSAGES = {
PROJECT_SELECTION_QUESTION: 'Which project would you like to generate to?',
Expand Down Expand Up @@ -88,4 +89,9 @@ export const MESSAGES = {
`Unable to install library ${name} because package did not install. Please check package name.`,
LIBRARY_INSTALLATION_FAILED_NO_LIBRARY: 'No library found.',
LIBRARY_INSTALLATION_STARTS: 'Starting library setup...',
INITIALIZING_FRONTEND: 'Initializing frontend directory for pull command...',
INSTALLING_DEPENDENCIES: 'Installing dependencies...',
FRONTEND_ALREADY_INITIALIZED: 'Frontend already initialized.',
PULL_INSTALLATION_IN_PROGRESS: 'Pull service installation in progress...',
PULL_INSTALLATION_ERROR: 'Failed to install stencil pull services',
};
7 changes: 7 additions & 0 deletions lib/utils/pull-utils/repositories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const repositories = {
services: {
geoquery: "https://github.com/ChakshuGautam/geoquery.in",
userService: "https://github.com/Samagra-Development/user-service",
},
};

Loading