blob: 307f7ed99c00a5d95e2c260396728da91c754988 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
import {readFile} from 'fs/promises';
import {resolve} from 'path';
import process from 'process';
import {createInterface} from 'readline';
import {globalWatcher} from './watch';
import {expandEnv} from './env_utils';
const { parse } = await import('shell-quote');
export let globalProc = undefined;
/**
* Read a key from OpenServerless configuration added to a `package.json` file in the
* root of the project
* @param key the key to read
* @param defaultValue a default value to be returned when the key is not found
* @returns {*}
*/
export async function getOpenServerlessConfig(key, defaultValue) {
try {
const dir = process.env.OPS_PWD || '/do_not_exists';
const file = resolve(dir, 'package.json');
const json = await readFile(file, 'utf8');
const info = JSON.parse(json);
return info.openserverless?.[key] || defaultValue;
} catch {
return defaultValue;
}
}
/**
* This function creates a line-by-line interface over the provided input stream
* and logs each line to the console as it is received.
* @param {ReadableStream} inp - The input stream to read lines from.
* @returns {void}
*/
function readlines(inp) {
const rl = createInterface({input: inp, terminal: false});
rl.on('line', (line) => {
console.log(line);
});
}
/**
* laungh a process with the command taken from OpenServerless Config
* (see `getOpenServerlessConfig`)
* @param key
* @param defaultValue
*/
export async function launch(key, defaultValue) {
const cmd = await getOpenServerlessConfig(key, defaultValue);
const cmdArgs = parse(cmd).filter(arg => typeof arg === "string");
const proc = Bun.spawn(cmdArgs, {
shell: true,
env: process.env,
cwd: process.env.OPS_PWD,
stdio: ['inherit', 'inherit', 'inherit']
});
}
/**
* start `ops ide serve` or a custom devel function specified
* through `getOpenServerlessConfig` mechanism
*/
export async function serve() {
await launch('devel', 'ops ide serve');
}
/**
* start `ops activation poll` or a custom logs function
* through `getOpenServerlessConfig` mechanism
*/
export async function logs() {
await launch('logs', 'ops activation poll');
}
async function signalHandler() {
console.log(`🔥Killing process pid ${globalProc.pid}`);
if (globalWatcher) {
console.log("☠️ Stopping watcher");
await globalWatcher.close();
}
globalProc.kill();
process.exit(0);
}
/**
* start a custom deploy function if required from the user
* through `getOpenServerlessConfig` mechanism
*/
export async function build() {
let deploy = await getOpenServerlessConfig('deploy', 'true');
deploy = expandEnv(deploy);
const deployArgs = parse(deploy).filter(arg => typeof arg === "string");
if (globalProc !== undefined) {
globalProc.kill();
}
globalProc = Bun.spawn(deployArgs, {
shell: true,
env: process.env,
cwd: process.env.OPS_PWD,
stdio: ['inherit', 'inherit', 'inherit']
});
console.log(`✈️ Deploy Child process: ${deploy} has PID: ${globalProc.pid}`);
// Register signal handlers
process.on('SIGINT', signalHandler);
process.on('SIGTERM', signalHandler);
// Await its completion
try {
const code = await globalProc.exited;
console.log(`build process exited with code ${code}`);
} catch (err) {
console.error("Error awaiting process exit:", err);
}
}