git-stack-cli
Advanced tools
@@ -19,2 +19,6 @@ import * as React from "react"; | ||
| " install..."), function: async () => { | ||
| // await Promise.all([ | ||
| // cli(`for i in $(seq 1 5); do echo $i; sleep 1; done`), | ||
| // cli(`for i in $(seq 5 1); do printf "$i "; sleep 1; done; echo`), | ||
| // ]); | ||
| if (is_command_available("git")) { | ||
@@ -21,0 +25,0 @@ return; |
@@ -56,7 +56,18 @@ import * as React from "react"; | ||
| } | ||
| const git_cherry_pick_command = [`git cherry-pick ${commit.sha}`]; | ||
| await cli(`git format-patch -1 ${commit.sha} --stdout > ${PATCH_FILE}`); | ||
| await cli(`git apply ${PATCH_FILE}`); | ||
| await cli(`rm ${PATCH_FILE}`); | ||
| await cli(`git add --all`); | ||
| let new_message; | ||
| if (commit.branch_id) { | ||
| new_message = await Metadata.write(commit.message, commit.branch_id); | ||
| } | ||
| else { | ||
| new_message = commit.message; | ||
| } | ||
| const git_commit_comand = [`git commit -m "${new_message}"`]; | ||
| if (argv.verify === false) { | ||
| git_cherry_pick_command.push("--no-verify"); | ||
| git_commit_comand.push("--no-verify"); | ||
| } | ||
| await cli(git_cherry_pick_command); | ||
| await cli(git_commit_comand); | ||
| if (commit.branch_id && !commit_pr) { | ||
@@ -99,2 +110,4 @@ if (actions.isDebug()) { | ||
| const spawn_options = { ignoreExitCode: true }; | ||
| // always clean up any patch files | ||
| cli.sync(`rm ${PATCH_FILE}`, spawn_options); | ||
| // always put self back in original branch | ||
@@ -124,1 +137,2 @@ cli.sync(`git checkout ${branch_name}`, spawn_options); | ||
| } | ||
| const PATCH_FILE = "mypatch.patch"; |
@@ -60,11 +60,12 @@ import * as React from "react"; | ||
| for (const commit of group.commits) { | ||
| const git_cherry_pick_command = [`git cherry-pick ${commit.sha}`]; | ||
| await cli(`git format-patch -1 ${commit.sha} --stdout > ${PATCH_FILE}`); | ||
| await cli(`git apply ${PATCH_FILE}`); | ||
| await cli(`rm ${PATCH_FILE}`); | ||
| await cli(`git add --all`); | ||
| const new_message = await Metadata.write(commit.message, group.id); | ||
| const git_commit_comand = [`git commit -m "${new_message}"`]; | ||
| if (argv.verify === false) { | ||
| git_cherry_pick_command.push("--no-verify"); | ||
| git_commit_comand.push("--no-verify"); | ||
| } | ||
| await cli(git_cherry_pick_command); | ||
| if (commit.branch_id !== group.id) { | ||
| const new_message = await Metadata.write(commit.message, group.id); | ||
| await cli(`git commit --amend -m "${new_message}"`); | ||
| } | ||
| await cli(git_commit_comand); | ||
| } | ||
@@ -168,2 +169,4 @@ actions.output(React.createElement(FormatText, { wrapper: React.createElement(Ink.Text, { color: colors.yellow, wrap: "truncate-end" }), message: "Syncing {group}\u2026", values: { | ||
| const spawn_options = { ignoreExitCode: true }; | ||
| // always clean up any patch files | ||
| cli.sync(`rm ${PATCH_FILE}`, spawn_options); | ||
| // always put self back in original branch | ||
@@ -194,1 +197,2 @@ cli.sync(`git checkout ${branch_name}`, spawn_options); | ||
| const get_group_url = (group) => group.pr?.url || group.id; | ||
| const PATCH_FILE = "mypatch.patch"; |
+13
-3
@@ -6,5 +6,15 @@ import * as React from "react"; | ||
| const output = Store.useState((state) => state.output); | ||
| return (React.createElement(Ink.Static, { items: output }, (node, i) => { | ||
| return React.createElement(Ink.Box, { key: i }, node); | ||
| })); | ||
| const pending_output = Store.useState((state) => state.pending_output); | ||
| const pending_output_items = Object.values(pending_output); | ||
| return (React.createElement(React.Fragment, null, | ||
| React.createElement(Ink.Static, { items: output }, (node, i) => { | ||
| return React.createElement(Ink.Box, { key: i }, node); | ||
| }), | ||
| pending_output_items.map((node_list, i) => { | ||
| return (React.createElement(Ink.Box, { key: i }, | ||
| React.createElement(Ink.Text, null, node_list.map((text, j) => { | ||
| return (React.createElement(React.Fragment, { key: j }, | ||
| React.createElement(Ink.Text, null, text))); | ||
| })))); | ||
| }))); | ||
| } |
+43
-11
@@ -21,2 +21,3 @@ import * as React from "react"; | ||
| output: [], | ||
| pending_output: {}, | ||
| pr: {}, | ||
@@ -26,3 +27,4 @@ actions: { | ||
| set((state) => { | ||
| state.mutate.output(state, React.createElement(Exit, { clear: clear, code: code })); | ||
| const node = React.createElement(Exit, { clear: clear, code: code }); | ||
| state.mutate.output(state, { node }); | ||
| }); | ||
@@ -38,3 +40,4 @@ }, | ||
| set((state) => { | ||
| state.mutate.output(state, ""); | ||
| const node = ""; | ||
| state.mutate.output(state, { node }); | ||
| }); | ||
@@ -44,3 +47,4 @@ }, | ||
| set((state) => { | ||
| state.mutate.output(state, JSON.stringify(value, null, 2)); | ||
| const node = JSON.stringify(value, null, 2); | ||
| state.mutate.output(state, { node }); | ||
| }); | ||
@@ -50,3 +54,4 @@ }, | ||
| set((state) => { | ||
| state.mutate.output(state, React.createElement(Ink.Text, { color: colors.red }, message)); | ||
| const node = React.createElement(Ink.Text, { color: colors.red }, message); | ||
| state.mutate.output(state, { node }); | ||
| }); | ||
@@ -56,9 +61,15 @@ }, | ||
| set((state) => { | ||
| state.mutate.output(state, node); | ||
| state.mutate.output(state, { node }); | ||
| }); | ||
| }, | ||
| debug(node) { | ||
| debug(node, id) { | ||
| if (get().actions.isDebug()) { | ||
| const debug = true; | ||
| set((state) => { | ||
| state.mutate.output(state, React.createElement(Ink.Text, { dimColor: true }, node)); | ||
| if (id) { | ||
| state.mutate.pending_output(state, { id, node, debug }); | ||
| } | ||
| else { | ||
| state.mutate.output(state, { node, debug }); | ||
| } | ||
| }); | ||
@@ -83,12 +94,33 @@ } | ||
| mutate: { | ||
| output(state, node) { | ||
| switch (typeof node) { | ||
| output(state, args) { | ||
| switch (typeof args.node) { | ||
| case "boolean": | ||
| case "number": | ||
| case "string": | ||
| state.output.push(React.createElement(Ink.Text, null, String(node))); | ||
| state.output.push(React.createElement(Ink.Text, { dimColor: args.debug }, String(args.node))); | ||
| return; | ||
| } | ||
| state.output.push(node); | ||
| state.output.push(args.node); | ||
| }, | ||
| pending_output(state, args) { | ||
| const { id } = args; | ||
| if (!id) { | ||
| return; | ||
| } | ||
| if (!state.pending_output[id]) { | ||
| state.pending_output[id] = []; | ||
| } | ||
| switch (typeof args.node) { | ||
| case "boolean": | ||
| case "number": | ||
| case "string": { | ||
| state.pending_output[id].push(React.createElement(Ink.Text, { dimColor: args.debug }, String(args.node))); | ||
| return; | ||
| } | ||
| } | ||
| state.pending_output[id].push(args.node); | ||
| }, | ||
| end_pending_output(state, id) { | ||
| delete state.pending_output[id]; | ||
| }, | ||
| }, | ||
@@ -95,0 +127,0 @@ select: { |
+24
-13
| import * as child from "node:child_process"; | ||
| import { Store } from "../app/Store.js"; | ||
| let i = 0; | ||
| export async function cli(unsafe_command, unsafe_options) { | ||
@@ -18,11 +19,30 @@ const state = Store.getState(); | ||
| let output = ""; | ||
| const id = `${++i}-${command}`; | ||
| state.actions.debug(`[start] ${command}`); | ||
| state.actions.debug(`[start] ${command}\n`, id); | ||
| function write_output(value) { | ||
| output += value; | ||
| state.actions.debug(value, id); | ||
| } | ||
| childProcess.stdout?.on("data", (data) => { | ||
| stdout += data.toString(); | ||
| output += data.toString(); | ||
| const value = String(data); | ||
| stdout += value; | ||
| write_output(value); | ||
| }); | ||
| childProcess.stderr?.on("data", (data) => { | ||
| stderr += data.toString(); | ||
| output += data.toString(); | ||
| const value = String(data); | ||
| stderr += value; | ||
| write_output(value); | ||
| }); | ||
| childProcess.on("close", (code) => { | ||
| const result = { | ||
| command, | ||
| code: code || 0, | ||
| stdout: stdout.trimEnd(), | ||
| stderr: stderr.trimEnd(), | ||
| output: output.trimEnd(), | ||
| }; | ||
| state.actions.set((state) => state.mutate.end_pending_output(state, id)); | ||
| state.actions.debug(`[end] ${command}`); | ||
| state.actions.debug(result.output); | ||
| if (!options.ignoreExitCode && code !== 0) { | ||
@@ -32,11 +52,2 @@ reject(new Error(`[${command}] (${code})`)); | ||
| else { | ||
| const result = { | ||
| command, | ||
| code: code || 0, | ||
| stdout: stdout.trimEnd(), | ||
| stderr: stderr.trimEnd(), | ||
| output: output.trimEnd(), | ||
| }; | ||
| state.actions.debug(`$ ${command}`); | ||
| state.actions.debug(result.output); | ||
| resolve(result); | ||
@@ -43,0 +54,0 @@ } |
+1
-1
| { | ||
| "name": "git-stack-cli", | ||
| "version": "0.7.5", | ||
| "version": "0.7.6", | ||
| "description": "", | ||
@@ -5,0 +5,0 @@ "author": "magus", |
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
223552
1.39%5586
1.36%