#!/usr/bin/env node import fs from "fs"; import { confirm, select, input } from "@inquirer/prompts"; import { exit } from "process"; import { addProject, configPath, generateDefaultConfig, getConfiguration, getProjects, type Project, } from "./configuration/configuration"; import { execSync } from "child_process"; import { program } from "commander"; import packageJson from "./package.json"; export const VERSION = packageJson.version; const CLI_NAME = "pcli"; program .name("project-cli") .description("A cli for managing projects") .version(VERSION) .action(async () => { if (!fs.existsSync(configPath + "config.json")) { const createConfig = await confirm({ message: "No cofig has been found. Would you like to generate a new one?", }); if (createConfig) { generateDefaultConfig(); } else { console.log( "This project can not run without the config. Either create it yourself or generate the default.", ); exit(1); } } if ( !getProjects() || getProjects().length == 0 || getProjects().length == undefined ) { const anwser = await select({ message: "Create a new Project", choices: ["Clone a project with git", "Create a new empty Project"], }); if (anwser == "Clone a project with git") { const repoUrl = await input({ message: "What is the url of the repo?", }); const wantsCustomName = await confirm({ message: "Would you like to give this project a custom name?", default: false, }); let customName = ""; if (wantsCustomName) { customName = await input({ message: "What would you like the custom name to be?", }); } execSync( "cd " + getConfiguration().projectsDirectory + " && " + getConfiguration() .cloningCommand.replace("%s", repoUrl) .replace("%n", customName), ); const newProject: Project = { name: customName, }; addProject(newProject); } else if (anwser == "Create a new empty Project") { const name = await input({ message: "What would you like to call the project?", }); fs.mkdirSync(getConfiguration().projectsDirectory + "/" + name); const newProject: Project = { name: name, }; addProject(newProject); } } const pickedProject = await select({ message: "Which Project would you like to go to?", choices: getProjects().map((project: Project) => project.name), }); console.log( "__EXEC__ cd " + getConfiguration().projectsDirectory + "/" + pickedProject, ); console.log(getProjects()); }); program.command("init").action(() => { console.log(`# Real-time output processing version function pcli() { local cli_command="$1" shift # Use unbuffer to force line buffering, or stdbuf if available if command -v unbuffer >/dev/null 2>&1; then # unbuffer from expect package - best option unbuffer "$cli_command" "$@" | while IFS= read -r line; do if [[ "$line" =~ ^__EXEC__[[:space:]]*(.*) ]]; then local cmd="\${match[1]}" echo "Executing: $cmd" eval "$cmd" else echo "$line" fi done elif command -v stdbuf >/dev/null 2>&1; then # stdbuf - force line buffering stdbuf -oL "$cli_command" "$@" | while IFS= read -r line; do if [[ "$line" =~ ^__EXEC__[[:space:]]*(.*) ]]; then local cmd="\${match[1]}" echo "Executing: $cmd" eval "$cmd" else echo "$line" fi done else # Fallback using script to simulate a terminal script -q /dev/null "$cli_command" "$@" | while IFS= read -r line; do # Remove any terminal escape sequences that script might add line=$(echo "$line" | sed 's/\\x1b\\[[0-9;]*m//g') if [[ "$line" =~ ^__EXEC__[[:space:]]*(.*) ]]; then local cmd="\${match[1]}" echo "Executing: $cmd" eval "$cmd" else echo "$line" fi done fi }`); }); program.parse();