diff --git a/CHANGELOG.md b/CHANGELOG.md index 0648d86..52edc76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,17 @@ ## Fixes and improvements - +# 4.5.0 +## Added features +- `repo` option to `duplicate` an existing repo +- `hosting` asks which bitbucket branch should be the release branch +## Fixes and improvements +- Breadcrumb is again printing "mm" or "mmk" instead of "undefined" +- Fix `deploy` fails with "origin/main not found" on the first deploy +- More space for change message in `deploy` +- Fix `sim` fails on Mac when started inside group or repo +- Merge the sequential choices "template vs empty" and "language" + # 4.4.4 ## Fixes and improvements - Simulator serves bytes correctly diff --git a/Execute.js b/Execute.js index b5f839b..64d3fd2 100644 --- a/Execute.js +++ b/Execute.js @@ -14,10 +14,10 @@ function timedOutput(str, prefix) { spacerTimer = setTimeout(() => console.log(""), 10000); } function prep(folder, runCommand, env, displayFolder) { - const runCmd = runCommand(folder); + const runCmd = runCommand(folder.toString()); const [cmd, ...args] = runCmd.split(" "); const options = { - cwd: folder, + cwd: folder.toString(), env, shell: "sh", }; @@ -97,8 +97,8 @@ function execute(handle, pathToRoot, group, repo, action, envelope, payload) { server.listen(() => { }); const env = process.env || {}; env.RAPIDS = `localhost:${server.address().port}`; - if (fs.existsSync(pathToRoot + "/" + group + "/env.kv")) { - fs.readFileSync(pathToRoot + "/" + group + "/env.kv", "utf-8") + if (fs.existsSync(pathToRoot.with(group).with("env.kv").toString())) { + fs.readFileSync(pathToRoot.with(group).with("env.kv").toString(), "utf-8") .split(/\r?\n/) .forEach((x) => { if (!x.includes("=")) @@ -107,16 +107,16 @@ function execute(handle, pathToRoot, group, repo, action, envelope, payload) { env[b[0]] = b[1]; }); } - const folder = `${pathToRoot}/${group}/${repo}`; - const type = detectProjectType(folder); + const folder = pathToRoot.with(group).with(repo); + const type = detectProjectType(folder.toString()); const runCommand = RUN_COMMAND[type]; const p = prep(folder, runCommand, env, `${envelope.traceId}:${group}/${repo}`); return run(p, action, envelope, payload); } function parseMerrymakeJson(folder, event) { - if (!fs.existsSync(`${folder}/merrymake.json`)) + if (!fs.existsSync(folder.with("merrymake.json").toString())) throw "Missing merrymake.json"; - const config = JSON.parse(fs.readFileSync(`${folder}/merrymake.json`, "utf-8")); + const config = JSON.parse(fs.readFileSync(folder.with("merrymake.json").toString(), "utf-8")); return Object.keys(config.hooks) .filter((x) => x.endsWith(`/${event}`)) .map((x) => { @@ -127,18 +127,22 @@ function parseMerrymakeJson(folder, event) { } function processFolders(pathToRoot, event) { const rivers = {}; - fs.readdirSync(pathToRoot, { withFileTypes: true }) + fs.readdirSync(pathToRoot.toString(), { withFileTypes: true }) .filter((x) => x.isDirectory() && !x.name.startsWith("(deleted) ") && !x.name.endsWith(".DS_Store")) .forEach((g) => { const group = g.name; - fs.readdirSync(`${pathToRoot}/${group}`) + fs.readdirSync(pathToRoot.with(group).toString()) .filter((x) => !x.startsWith("(deleted) ") && !x.endsWith(".DS_Store")) .forEach((repo) => { - if (!fs.existsSync(`${pathToRoot}/${group}/${repo}/merrymake.json`)) + if (!fs.existsSync(pathToRoot + .with(group) + .with(repo) + .with("merrymake.json") + .toString())) return; - parseMerrymakeJson(`${pathToRoot}/${group}/${repo}`, event).forEach(([river, action]) => { + parseMerrymakeJson(pathToRoot.with(group).with(repo), event).forEach(([river, action]) => { if (rivers[river] === undefined) rivers[river] = []; rivers[river].push({ group, repo, action }); @@ -369,7 +373,7 @@ ${NORMAL_COLOR}`); sessionId = "s" + Math.random(); resp.cookie("sessionId", sessionId); } - const api_json = JSON.parse(fs.readFileSync(`${this.pathToRoot}/event-catalogue/api.json`, "utf-8")); + const api_json = JSON.parse(fs.readFileSync(this.pathToRoot.with("event-catalogue").with("api.json").toString(), "utf-8")); const conf = api_json[event]; const traceId = generateString(3, all); this.pendingReplies[traceId] = { diff --git a/Execute.ts b/Execute.ts index 6eb0d42..2cbe4bd 100644 --- a/Execute.ts +++ b/Execute.ts @@ -16,6 +16,7 @@ import { generateString, printWithPrefix, } from "./utils.js"; +import { PathTo, PathToOrganization, PathToRepository } from "./types.js"; interface Envelope { messageId: string; @@ -50,15 +51,15 @@ function timedOutput(str: string, prefix?: string) { } function prep( - folder: string, + folder: PathToRepository, runCommand: (folder: string) => string, env: NodeJS.ProcessEnv, displayFolder: string ) { - const runCmd = runCommand(folder); + const runCmd = runCommand(folder.toString()); const [cmd, ...args] = runCmd.split(" "); const options: ExecOptions = { - cwd: folder, + cwd: folder.toString(), env, shell: "sh", }; @@ -109,7 +110,7 @@ function pack(...buffers: Buffer[]) { function execute( handle: (event: string, payload: Buffer) => void, - pathToRoot: string, + pathToRoot: PathToOrganization, group: string, repo: string, action: string, @@ -161,8 +162,8 @@ function execute( server.listen(() => {}); const env = process.env || {}; env.RAPIDS = `localhost:${(server.address() as net.AddressInfo).port}`; - if (fs.existsSync(pathToRoot + "/" + group + "/env.kv")) { - fs.readFileSync(pathToRoot + "/" + group + "/env.kv", "utf-8") + if (fs.existsSync(pathToRoot.with(group).with("env.kv").toString())) { + fs.readFileSync(pathToRoot.with(group).with("env.kv").toString(), "utf-8") .split(/\r?\n/) .forEach((x) => { if (!x.includes("=")) return; @@ -170,8 +171,8 @@ function execute( env[b[0]] = b[1]; }); } - const folder = `${pathToRoot}/${group}/${repo}`; - const type = detectProjectType(folder); + const folder = pathToRoot.with(group).with(repo); + const type = detectProjectType(folder.toString()); const runCommand = RUN_COMMAND[type]; const p = prep( folder, @@ -182,11 +183,11 @@ function execute( return run(p, action, envelope, payload); } -function parseMerrymakeJson(folder: string, event: string) { - if (!fs.existsSync(`${folder}/merrymake.json`)) +function parseMerrymakeJson(folder: PathTo, event: string) { + if (!fs.existsSync(folder.with("merrymake.json").toString())) throw "Missing merrymake.json"; const config: MerrymakeJson = JSON.parse( - fs.readFileSync(`${folder}/merrymake.json`, "utf-8") + fs.readFileSync(folder.with("merrymake.json").toString(), "utf-8") ); return Object.keys(config.hooks) .filter((x) => x.endsWith(`/${event}`)) @@ -197,11 +198,11 @@ function parseMerrymakeJson(folder: string, event: string) { }); } -function processFolders(pathToRoot: string, event: string) { +function processFolders(pathToRoot: PathToOrganization, event: string) { const rivers: { [river: string]: { group: string; repo: string; action: string }[]; } = {}; - fs.readdirSync(pathToRoot, { withFileTypes: true }) + fs.readdirSync(pathToRoot.toString(), { withFileTypes: true }) .filter( (x) => x.isDirectory() && @@ -210,12 +211,20 @@ function processFolders(pathToRoot: string, event: string) { ) .forEach((g) => { const group = g.name; - fs.readdirSync(`${pathToRoot}/${group}`) + fs.readdirSync(pathToRoot.with(group).toString()) .filter((x) => !x.startsWith("(deleted) ") && !x.endsWith(".DS_Store")) .forEach((repo) => { - if (!fs.existsSync(`${pathToRoot}/${group}/${repo}/merrymake.json`)) + if ( + !fs.existsSync( + pathToRoot + .with(group) + .with(repo) + .with("merrymake.json") + .toString() + ) + ) return; - parseMerrymakeJson(`${pathToRoot}/${group}/${repo}`, event).forEach( + parseMerrymakeJson(pathToRoot.with(group).with(repo), event).forEach( ([river, action]) => { if (rivers[river] === undefined) rivers[river] = []; rivers[river].push({ group, repo, action }); @@ -326,7 +335,7 @@ function reply( class Simulator { private pendingReplies: PendingReplies = {}; private channels: Channels = {}; - constructor(private pathToRoot: string) {} + constructor(private pathToRoot: PathToOrganization) {} start() { return new Promise((resolve) => { const app = express(); @@ -481,7 +490,10 @@ ${NORMAL_COLOR}`); resp.cookie("sessionId", sessionId); } const api_json: ApiJson = JSON.parse( - fs.readFileSync(`${this.pathToRoot}/event-catalogue/api.json`, "utf-8") + fs.readFileSync( + this.pathToRoot.with("event-catalogue").with("api.json").toString(), + "utf-8" + ) ); const conf = api_json[event]; const traceId = generateString(3, all); @@ -522,7 +534,7 @@ ${NORMAL_COLOR}`); } } -export function do_startSimulator(pathToRoot: string) { +export function do_startSimulator(pathToRoot: PathToOrganization) { const sim = new Simulator(pathToRoot); addToExecuteQueue(() => sim.start()); return finish(); diff --git a/contexts.js b/contexts.js index 322a684..1a427cb 100644 --- a/contexts.js +++ b/contexts.js @@ -88,6 +88,7 @@ export const CONTEXTS = { join: NOT_ORGANIZATION_CONTEXT, key: ORGANIZATION_CONTEXT, org: NOT_ORGANIZATION_CONTEXT, + start: NOT_ORGANIZATION_CONTEXT, rapids: ORGANIZATION_CONTEXT, rename: NOT_SERVICE_GROUP_CONTEXT, repo: SERVICE_GROUP_CONTEXT, diff --git a/contexts.ts b/contexts.ts index 4261c7c..40d3a22 100644 --- a/contexts.ts +++ b/contexts.ts @@ -96,6 +96,7 @@ export const CONTEXTS: { [cmd: string]: (cmd: string) => string } = { join: NOT_ORGANIZATION_CONTEXT, key: ORGANIZATION_CONTEXT, org: NOT_ORGANIZATION_CONTEXT, + start: NOT_ORGANIZATION_CONTEXT, rapids: ORGANIZATION_CONTEXT, rename: NOT_SERVICE_GROUP_CONTEXT, repo: SERVICE_GROUP_CONTEXT, diff --git a/mm.js b/mm.js index 40cf98e..9245dca 100644 --- a/mm.js +++ b/mm.js @@ -1,5 +1,6 @@ #!/usr/bin/env node -process.env["COMMAND"] = "mm"; +import { setCommand } from "./mmCommand.js"; +setCommand("mm"); import { YELLOW, NORMAL_COLOR } from "./prompt.js"; process.env["UPDATE_MESSAGE"] = `to update run the command: ${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`; diff --git a/mm.ts b/mm.ts index 40cf98e..9245dca 100644 --- a/mm.ts +++ b/mm.ts @@ -1,5 +1,6 @@ #!/usr/bin/env node -process.env["COMMAND"] = "mm"; +import { setCommand } from "./mmCommand.js"; +setCommand("mm"); import { YELLOW, NORMAL_COLOR } from "./prompt.js"; process.env["UPDATE_MESSAGE"] = `to update run the command: ${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`; diff --git a/mmCommand.js b/mmCommand.js new file mode 100644 index 0000000..84af279 --- /dev/null +++ b/mmCommand.js @@ -0,0 +1,7 @@ +let command = "$ mm"; +export function setCommand(mm) { + command = "$ " + mm; +} +export function getCommand() { + return command; +} diff --git a/mmCommand.ts b/mmCommand.ts new file mode 100644 index 0000000..c5dc68e --- /dev/null +++ b/mmCommand.ts @@ -0,0 +1,7 @@ +let command = "$ mm"; +export function setCommand(mm: string) { + command = "$ " + mm; +} +export function getCommand() { + return command; +} diff --git a/mmk.js b/mmk.js index ec71a71..61cb125 100644 --- a/mmk.js +++ b/mmk.js @@ -1,5 +1,6 @@ #!/usr/bin/env winpty node -process.env["COMMAND"] = "mmk"; +import { setCommand } from "./mmCommand.js"; +setCommand("mmk"); import { YELLOW, NORMAL_COLOR } from "./prompt.js"; process.env["UPDATE_MESSAGE"] = `to update run the command: ${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`; diff --git a/mmk.ts b/mmk.ts index ec71a71..61cb125 100644 --- a/mmk.ts +++ b/mmk.ts @@ -1,5 +1,6 @@ #!/usr/bin/env winpty node -process.env["COMMAND"] = "mmk"; +import { setCommand } from "./mmCommand.js"; +setCommand("mmk"); import { YELLOW, NORMAL_COLOR } from "./prompt.js"; process.env["UPDATE_MESSAGE"] = `to update run the command: ${YELLOW}npm install --global @merrymake/cli@latest${NORMAL_COLOR}`; diff --git a/newCommands/deploy.js b/newCommands/deploy.js index 2634d6a..64e88d4 100644 --- a/newCommands/deploy.js +++ b/newCommands/deploy.js @@ -1,4 +1,4 @@ -import { choice, Formatting, shortText } from "../prompt.js"; +import { choice, Formatting, output, shortText } from "../prompt.js"; import { addToExecuteQueue, execStreamPromise, finish, outputGit, spawnPromise, } from "../utils.js"; /* [remove .gitignored files] @@ -66,7 +66,7 @@ function redeploy() { } async function rebaseOntoMain() { try { - const output = await executeAndPrint(`git fetch && git rebase origin/main && git push origin HEAD:main 2>&1`); + const output = await executeAndPrint(`git fetch && ({ ! git ls-remote --exit-code origin main; } || git rebase origin/main) && git push origin HEAD:main 2>&1`); if (output.trimEnd().endsWith("Everything up-to-date")) return choice("Would you like to redeploy?", [ { @@ -83,7 +83,8 @@ async function rebaseOntoMain() { } async function getMessage() { try { - const message = await shortText("Describe your changes: This commit will ", "Write in future tense 'refactor module X'", null, { formatting: Formatting.Minimal }); + output("Describe your changes (optional):\n"); + const message = await shortText("This commit will ", "Write in future tense 'refactor module X'", null, { formatting: Formatting.Minimal }); const msg = message.length === 0 ? "[No message]" : message[0].toUpperCase() + message.substring(1); diff --git a/newCommands/deploy.ts b/newCommands/deploy.ts index aa8301c..0d0702a 100644 --- a/newCommands/deploy.ts +++ b/newCommands/deploy.ts @@ -1,4 +1,4 @@ -import { choice, Formatting, shortText } from "../prompt.js"; +import { choice, Formatting, output, shortText } from "../prompt.js"; import { PathToRepository } from "../types.js"; import { addToExecuteQueue, @@ -84,7 +84,7 @@ function redeploy() { async function rebaseOntoMain() { try { const output = await executeAndPrint( - `git fetch && git rebase origin/main && git push origin HEAD:main 2>&1` + `git fetch && ({ ! git ls-remote --exit-code origin main; } || git rebase origin/main) && git push origin HEAD:main 2>&1` ); if (output.trimEnd().endsWith("Everything up-to-date")) return choice( @@ -106,8 +106,9 @@ async function rebaseOntoMain() { async function getMessage() { try { + output("Describe your changes (optional):\n"); const message = await shortText( - "Describe your changes: This commit will ", + "This commit will ", "Write in future tense 'refactor module X'", null, { formatting: Formatting.Minimal } diff --git a/newCommands/hosting.js b/newCommands/hosting.js index a7f460a..4ca1e82 100644 --- a/newCommands/hosting.js +++ b/newCommands/hosting.js @@ -26,7 +26,7 @@ export function bitbucketStep(group_service, repo) { .toString() .replace(/\\/g, "/")} ${repo}`; } -export async function do_bitbucket(organization, host, key) { +export async function do_bitbucket(organization, host, key, releaseBranch) { try { const structure = await do_fetch(organization); fs.writeFileSync(organization.pathTo.with(".merrymake").with("deploy.sh").toString(), `set -o errexit @@ -47,7 +47,7 @@ case $RES in "Everything up-to-date"*) exit 0 ;; *"Releasing service"*) exit 0 ; const pipelineFile = [ `pipelines: branches: - master: + ${releaseBranch}: - parallel: # SERVICES ARE AUTOMATICALLY ADDED BELOW`, ]; @@ -97,9 +97,15 @@ case $RES in "Everything up-to-date"*) exit 0 ;; *"Releasing service"*) exit 0 ; throw e; } } -function hosting_bitbucket_key_host(organization, host, key) { - addToExecuteQueue(() => do_bitbucket(organization, host, key)); - return finish(); +async function hosting_bitbucket_key_host(organization, host, key) { + try { + const branch = await shortText("Release branch", "Pushes or pull requests to this branch will trigger a deploy. Normally: main, master, trunk, or release", `master`).then(); + addToExecuteQueue(() => do_bitbucket(organization, host, key, branch)); + return finish(); + } + catch (e) { + throw e; + } } async function hosting_bitbucket_key(organization, file) { try { diff --git a/newCommands/hosting.ts b/newCommands/hosting.ts index a25690e..b3c0256 100644 --- a/newCommands/hosting.ts +++ b/newCommands/hosting.ts @@ -50,7 +50,8 @@ export function bitbucketStep(group_service: PathTo, repo: string) { export async function do_bitbucket( organization: Organization, host: string, - key: string + key: string, + releaseBranch: string ) { try { const structure = await do_fetch(organization); @@ -75,7 +76,7 @@ case $RES in "Everything up-to-date"*) exit 0 ;; *"Releasing service"*) exit 0 ; const pipelineFile = [ `pipelines: branches: - master: + ${releaseBranch}: - parallel: # SERVICES ARE AUTOMATICALLY ADDED BELOW`, ]; @@ -137,13 +138,22 @@ case $RES in "Everything up-to-date"*) exit 0 ;; *"Releasing service"*) exit 0 ; } } -function hosting_bitbucket_key_host( +async function hosting_bitbucket_key_host( organization: Organization, host: string, key: string ) { - addToExecuteQueue(() => do_bitbucket(organization, host, key)); - return finish(); + try { + const branch = await shortText( + "Release branch", + "Pushes or pull requests to this branch will trigger a deploy. Normally: main, master, trunk, or release", + `master` + ).then(); + addToExecuteQueue(() => do_bitbucket(organization, host, key, branch)); + return finish(); + } catch (e) { + throw e; + } } async function hosting_bitbucket_key(organization: Organization, file: string) { diff --git a/newCommands/index.js b/newCommands/index.js index dcb2006..6bce702 100644 --- a/newCommands/index.js +++ b/newCommands/index.js @@ -23,7 +23,7 @@ async function getContext() { let organization; let inGit = false; const cwd = process.cwd().split(/\/|\\/); - let out = "."; + let out = "." + path.sep; for (let i = cwd.length - 1; i >= 0; i--) { if (fs.existsSync(path.join(out, ".git"))) inGit = true; @@ -57,7 +57,7 @@ async function getContext() { }; return { repository, serviceGroup, organization, inGit }; } - out += ".." + path.sep; + out = path.join(out, ".."); } return { repository, @@ -159,7 +159,7 @@ export async function index() { short: "s", text: "simulate your system locally", weight: 700, - action: () => do_startSimulator(organization.pathTo.toString()), + action: () => do_startSimulator(organization.pathTo), }, { long: "key", short: "k", diff --git a/newCommands/index.ts b/newCommands/index.ts index 9a5c8a0..6dc7819 100644 --- a/newCommands/index.ts +++ b/newCommands/index.ts @@ -35,7 +35,7 @@ async function getContext() { let organization: Organization | undefined; let inGit = false; const cwd = process.cwd().split(/\/|\\/); - let out = "."; + let out = "." + path.sep; for (let i = cwd.length - 1; i >= 0; i--) { if (fs.existsSync(path.join(out, ".git"))) inGit = true; if (fs.existsSync(path.join(out, "merrymake.json"))) { @@ -71,7 +71,7 @@ async function getContext() { }; return { repository, serviceGroup, organization, inGit }; } - out += ".." + path.sep; + out = path.join(out, ".."); } return { repository, @@ -188,7 +188,7 @@ export async function index() { short: "s", text: "simulate your system locally", weight: 700, - action: () => do_startSimulator(organization.pathTo.toString()), + action: () => do_startSimulator(organization.pathTo), }, { long: "key", diff --git a/newCommands/repo.js b/newCommands/repo.js index adf89aa..53cf597 100644 --- a/newCommands/repo.js +++ b/newCommands/repo.js @@ -160,21 +160,45 @@ export async function repo_create(organization, serviceGroup) { const pathToRepository = serviceGroup.pathTo.with(folderName); const repositoryId = await do_createService(organization, serviceGroup, folderName, displayName); const options = []; - // const repositories = await listRepos(serviceGroupId); - // if (repositories.length > 0) { - // options.push({ - // long: "duplicate", - // short: "d", - // text: "duplicate an existing service", - // action: () => duplicate(pathToRepository, org, group), - // }); - // } - Object.keys(templates).forEach((x) => options.push({ - long: templates[x].long, - short: templates[x].short, - text: templates[x].text, - action: () => service_template(pathToRepository, organization.id, x), + const repositories = await listRepos(serviceGroup.id); + console.log(repositories); + if (repositories.length === 1) { + options.push({ + long: "duplicate", + short: "d", + text: `duplicate ${repositories[0].name}`, + action: () => duplicate_then(pathToRepository, organization.id, serviceGroup.id, new RepositoryId(repositories[0].id)), + }); + } + else if (repositories.length > 0) { + options.push({ + long: "duplicate", + short: "d", + text: "duplicate an existing service", + action: () => duplicate(pathToRepository, organization.id, serviceGroup.id), + }); + } + const langs = await Promise.all(templates.basic.languages.map((x, i) => (async () => ({ + ...languages[x], + weight: (await Promise.all(Object.keys(VERSION_CMD[languages[x].projectType]).map((k) => execPromise(VERSION_CMD[languages[x].projectType][k]) + .then((r) => 1) + .catch((e) => -1)))).reduce((a, x) => a * x, i), + }))())); + langs.sort((a, b) => b.weight - a.weight); + langs.forEach((x) => options.push({ + long: x.long, + short: x.short, + text: `initialize with the basic ${x.long} template`, + action: () => service_template_language(pathToRepository, organization.id, "basic", x.projectType), })); + // Object.keys(templates).forEach((x) => + // options.push({ + // long: templates[x].long, + // short: templates[x].short, + // text: templates[x].text, + // action: () => service_template(pathToRepository, organization.id, x), + // }) + // ); options.push({ long: "empty", short: "e", diff --git a/newCommands/repo.ts b/newCommands/repo.ts index 2bea1d9..0ecc9ed 100644 --- a/newCommands/repo.ts +++ b/newCommands/repo.ts @@ -286,23 +286,69 @@ export async function repo_create( displayName ); const options: Option[] = []; - // const repositories = await listRepos(serviceGroupId); - // if (repositories.length > 0) { - // options.push({ - // long: "duplicate", - // short: "d", - // text: "duplicate an existing service", - // action: () => duplicate(pathToRepository, org, group), - // }); - // } - Object.keys(templates).forEach((x) => + const repositories = await listRepos(serviceGroup.id); + console.log(repositories); + if (repositories.length === 1) { options.push({ - long: templates[x].long, - short: templates[x].short, - text: templates[x].text, - action: () => service_template(pathToRepository, organization.id, x), + long: "duplicate", + short: "d", + text: `duplicate ${repositories[0].name}`, + action: () => + duplicate_then( + pathToRepository, + organization.id, + serviceGroup.id, + new RepositoryId(repositories[0].id) + ), + }); + } else if (repositories.length > 0) { + options.push({ + long: "duplicate", + short: "d", + text: "duplicate an existing service", + action: () => + duplicate(pathToRepository, organization.id, serviceGroup.id), + }); + } + const langs = await Promise.all( + templates.basic.languages.map((x, i) => + (async () => ({ + ...languages[x], + weight: ( + await Promise.all( + Object.keys(VERSION_CMD[languages[x].projectType]).map((k) => + execPromise(VERSION_CMD[languages[x].projectType][k]) + .then((r) => 1) + .catch((e) => -1) + ) + ) + ).reduce((a, x) => a * x, i), + }))() + ) + ); + langs.sort((a, b) => b.weight - a.weight); + langs.forEach((x) => + options.push({ + long: x.long, + short: x.short, + text: `initialize with the basic ${x.long} template`, + action: () => + service_template_language( + pathToRepository, + organization.id, + "basic", + x.projectType + ), }) ); + // Object.keys(templates).forEach((x) => + // options.push({ + // long: templates[x].long, + // short: templates[x].short, + // text: templates[x].text, + // action: () => service_template(pathToRepository, organization.id, x), + // }) + // ); options.push({ long: "empty", short: "e", diff --git a/package.json b/package.json index 3500fa5..312b54d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@merrymake/cli", - "version": "4.4.4", + "version": "4.5.0", "description": "", "main": "index.js", "type": "module", diff --git a/pkg.js b/pkg.js index 0f62614..3497c11 100644 --- a/pkg.js +++ b/pkg.js @@ -1,5 +1,6 @@ #!/usr/bin/env node -process.env["COMMAND"] = "mm"; +import { setCommand } from "./mmCommand.js"; +setCommand("mm"); import { stdin } from "node:process"; if (!stdin.isTTY || stdin.setRawMode === undefined) { console.log("This console does not support TTY, please use 'winpty mm' instead."); diff --git a/pkg.ts b/pkg.ts index 4fbe8bb..a0ff62e 100644 --- a/pkg.ts +++ b/pkg.ts @@ -1,5 +1,6 @@ #!/usr/bin/env node -process.env["COMMAND"] = "mm"; +import { setCommand } from "./mmCommand.js"; +setCommand("mm"); import { stdin } from "node:process"; if (!stdin.isTTY || stdin.setRawMode === undefined) { console.log( diff --git a/prompt.js b/prompt.js index 35229b5..210b82b 100644 --- a/prompt.js +++ b/prompt.js @@ -2,6 +2,7 @@ import { stdin, stdout } from "node:process"; import { getArgs } from "./args.js"; import { CONTEXTS } from "./contexts.js"; import { abort } from "./utils.js"; +import { getCommand } from "./mmCommand.js"; export const CTRL_C = "\u0003"; // const CR = "\u000D"; export const BACKSPACE = "\b"; @@ -122,9 +123,11 @@ function moveToBottom() { function getCursorPosition() { return [xOffset, yOffset]; } -let command = "$ " + process.env["COMMAND"]; +let command = ""; let hasSecret = false; function makeSelectionSuperInternal(action, extra = () => { }) { + if (command.length === 0) + command = getCommand(); moveToBottom(); cleanup(); extra(); diff --git a/prompt.ts b/prompt.ts index 597ae52..2e9d384 100644 --- a/prompt.ts +++ b/prompt.ts @@ -2,6 +2,7 @@ import { stdin, stdout } from "node:process"; import { getArgs } from "./args.js"; import { CONTEXTS } from "./contexts.js"; import { abort } from "./utils.js"; +import { getCommand } from "./mmCommand.js"; export const CTRL_C = "\u0003"; // const CR = "\u000D"; @@ -136,13 +137,14 @@ function getCursorPosition() { return [xOffset, yOffset]; } -let command = "$ " + process.env["COMMAND"]; +let command = ""; let hasSecret = false; function makeSelectionSuperInternal( action: () => Promise, extra: () => void = () => {} ) { + if (command.length === 0) command = getCommand(); moveToBottom(); cleanup(); extra();