@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
119 lines • 3.99 kB
JavaScript
import { spawn } from 'child_process';
import { rimraf } from 'rimraf';
import killPort from 'kill-port';
import chokidar from 'chokidar';
import fs from 'fs';
import link from './link.js';
import { logger, execSync, parseEnv, debounce } from '../../utils/index.js';
let start;
let watcher;
const validateEnv = () => {
if (fs.existsSync('./app/.env.local')) {
const env = parseEnv('./app/.env.local');
if (!env.REACT_APP_API_TOKEN && !env.REACT_APP_TOKEN) {
logger.error('Missing REACT_APP_API_TOKEN variable in .env.local file.' + 'Please run `atlas auth print-developer-token` to get a token.');
}
if (!env.REACT_APP_API_LOGIN && !env.REACT_APP_LOGIN) {
logger.error('Missing REACT_APP_API_LOGIN variable in .env.local file. ' + 'This should be your email address used to login to Atlas, which is usually the same as your Google Cloud Platform account.');
}
} else {
logger.error('Missing .env.local file. Please create one and add the REACT_APP_API_TOKEN variable.');
}
};
const validateDocker = () => {
if (!fs.existsSync('./docker-compose.yml')) {
logger.error('Missing docker-compose.yml file. Please create one.');
}
try {
execSync('docker --version');
} catch (err) {
logger.error('Docker is not installed. Please install Docker and try again. https://docs.docker.com/get-docker/');
}
};
const stopDevServer = () => {
if (start) {
start.kill();
}
killPort(3000);
};
const startDevServer = () => {
try {
killPort(3000);
start = spawn('npm run start', {
cwd: './app',
shell: true,
stdio: 'inherit',
detached: false
});
start.on('message', data => {
logger.info(data.toString());
});
start.on('error', err => {
logger.error(err);
});
process.on('SIGTERM', () => {
start.kill();
});
} catch (err) {
logger.break();
logger.warning('Shutting down...');
process.exit(1);
}
};
const watchLocalPackages = async deps => {
if (watcher) {
watcher.close();
}
watcher = chokidar.watch(Array.from(deps.values()), {
atomic: 1000,
ignoreInitial: true,
ignored: /node_modules|dist|\.git|\.test/
}).on('change', debounce(async path => {
const formattedTimestamp = new Date().toLocaleTimeString();
logger.log(chalk => [chalk.green(`[${formattedTimestamp}]`), chalk.yellow('Reload:'), chalk.cyan(path)]);
logger.break();
stopDevServer();
await link(path);
logger.break();
logger.callout(' Restarting the development server... ', 'yellow');
startDevServer();
}, 2e3));
};
export default async options => {
if (!fs.existsSync('./app/package.json')) {
logger.error('package.json not found. Make sure you run this command in the root directory of your project.');
}
validateEnv();
validateDocker();
if (options['clear-cache']) {
logger.info('Clearing cache...');
rimraf.sync('./app/node_modules/.cache');
}
if (options.link) {
logger.info('Looking to link local packages from link.json...');
const deps = await link();
if (deps.size === 0) {
logger.info('[link] No local packages to link');
} else if (options.watch) {
logger.break();
logger.callout(' Watching local packages for changes... ', 'yellow');
logger.break();
watchLocalPackages(deps);
}
}
try {
execSync('docker compose up -d');
} catch (err) {
logger.break();
logger.error('Could not start the backend server. Please check the error above', false);
logger.break();
logger.log('1. Make sure Docker is running.');
logger.log('2. Make sure no other Atlas project instance is currently running.');
logger.log('3. Make sure Docker is configured to access the Artifact Registry:');
logger.log(chalk => chalk.italic(' gcloud auth configure-docker europe-west1-docker.pkg.dev'));
logger.log('4. Restart Docker if the problem persists.');
logger.break();
process.exit(1);
}
startDevServer();
};