Skip to content

Commit

Permalink
Publish
Browse files Browse the repository at this point in the history
  • Loading branch information
thedrlambda committed Jan 25, 2024
1 parent 2d132dd commit dc0b124
Show file tree
Hide file tree
Showing 15 changed files with 275 additions and 158 deletions.
15 changes: 11 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
# NEXT:
# NEXT:
## Breaking changes
-
-
## Added features
-
-
## Fixes and improvements
-
-

# 1.8.1
## Fixes and improvements
- Insert ssh host config in the top of the file, to avoid being shadowed by *
- Ability to call CLI from shell script (without TTY)
- Rename `Name` to `Description` in `key` command, and make it dynamic width
- Add warning when creating anonymous account

# 1.8.0

Expand Down
Binary file modified dist/windows.zip
Binary file not shown.
50 changes: 37 additions & 13 deletions executors.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const detect_project_type_1 = require("@merrymake/detect-project-type");
const child_process_1 = require("child_process");
const prompt_1 = require("./prompt");
const args_1 = require("./args");
const process_1 = require("process");
function clone(struct, name) {
return __awaiter(this, void 0, void 0, function* () {
try {
Expand Down Expand Up @@ -192,10 +193,10 @@ function createService(pth, group, name) {
throw e;
}
yield (0, utils_1.execPromise)(`git symbolic-ref HEAD refs/heads/main`, name);
(0, utils_1.addExitMessage)(`Use '${prompt_1.YELLOW}cd ${pth
(0, utils_1.addExitMessage)(`Use '${prompt_1.GREEN}cd ${pth
.with(name)
.toString()
.replace(/\\/g, "\\\\")}${prompt_1.NORMAL_COLOR}' to go to the new service. \nThen use '${prompt_1.YELLOW}${process.env["COMMAND"]} deploy${prompt_1.NORMAL_COLOR}' to deploy it.`);
.replace(/\\/g, "\\\\")}${prompt_1.NORMAL_COLOR}' to go to the new service. \nThen use '${prompt_1.GREEN}${process.env["COMMAND"]} deploy${prompt_1.NORMAL_COLOR}' to deploy it.`);
process.chdir(before);
}
catch (e) {
Expand Down Expand Up @@ -242,9 +243,13 @@ exports.addKnownHost = addKnownHost;
function do_register(keyAction, email) {
return __awaiter(this, void 0, void 0, function* () {
try {
let key = yield keyAction();
let { key, keyFile } = yield keyAction();
console.log("Registering...");
addKnownHost();
if (email === "") {
(0, utils_1.addExitMessage)(`Notice: Anonymous accounts are automatically deleted permanently after ~2 weeks, without warning. To add an email and avoid automatic deletion, run the command:
${prompt_1.YELLOW}${process.env["COMMAND"]} register ${keyFile}${prompt_1.NORMAL_COLOR}`);
}
let result = yield (0, utils_1.urlReq)(`${config_1.HTTP_HOST}/admin/user`, "POST", JSON.stringify({
email,
key,
Expand All @@ -267,8 +272,8 @@ function do_register(keyAction, email) {
}
exports.do_register = do_register;
function saveSSHConfig(path) {
console.log(`Saving preference...`);
let lines = [];
let changed = false;
let foundHost = false;
if (fs_1.default.existsSync(`${os_1.default.homedir()}/.ssh/config`)) {
lines = fs_1.default
Expand All @@ -279,13 +284,17 @@ function saveSSHConfig(path) {
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if ((line.startsWith("\t") || line.startsWith(" ")) && inHost) {
if (line.includes("User "))
if (line.includes("User ")) {
lines[i] =
line.substring(0, line.indexOf("User ")) + `User ${config_1.SSH_USER}`;
else if (line.includes("IdentityFile "))
changed = true;
}
else if (line.includes("IdentityFile ")) {
lines[i] =
line.substring(0, line.indexOf("IdentityFile ")) +
`IdentityFile ~/.ssh/${path}`;
changed = true;
}
}
else if (line.startsWith("\t") || line.startsWith(" ")) {
}
Expand All @@ -299,16 +308,23 @@ function saveSSHConfig(path) {
}
}
if (!foundHost) {
lines.push(`Host ${config_1.API_URL}`, `\tUser ${config_1.SSH_USER}`, `\tHostName ${config_1.API_URL}`, `\tPreferredAuthentications publickey`, `\tIdentityFile ~/.ssh/${path}\n`);
lines.unshift(`Host ${config_1.API_URL}`, `\tUser ${config_1.SSH_USER}`, `\tHostName ${config_1.API_URL}`, `\tPreferredAuthentications publickey`, `\tIdentityFile ~/.ssh/${path}\n`);
changed = true;
}
if (changed) {
console.log(`Saving preference...`);
fs_1.default.writeFileSync(`${os_1.default.homedir()}/.ssh/config`, lines.join("\n"));
}
fs_1.default.writeFileSync(`${os_1.default.homedir()}/.ssh/config`, lines.join("\n"));
}
function useExistingKey(path) {
return __awaiter(this, void 0, void 0, function* () {
try {
saveSSHConfig(path);
console.log(`Reading ${path}.pub...`);
return "" + fs_1.default.readFileSync(os_1.default.homedir() + `/.ssh/${path}.pub`);
return {
key: "" + fs_1.default.readFileSync(os_1.default.homedir() + `/.ssh/${path}.pub`),
keyFile: path,
};
}
catch (e) {
throw e;
Expand All @@ -324,7 +340,10 @@ function generateNewKey() {
fs_1.default.mkdirSync(os_1.default.homedir() + "/.ssh");
yield (0, utils_1.execPromise)(`ssh-keygen -t rsa -b 4096 -f "${os_1.default.homedir()}/.ssh/merrymake" -N ""`);
saveSSHConfig("merrymake");
return "" + fs_1.default.readFileSync(os_1.default.homedir() + "/.ssh/merrymake.pub");
return {
key: "" + fs_1.default.readFileSync(os_1.default.homedir() + "/.ssh/merrymake.pub"),
keyFile: "merrymake",
};
}
catch (e) {
throw e;
Expand Down Expand Up @@ -424,7 +443,7 @@ function do_key(org, key, name, duration) {
if (key === null) {
let { key, expiry } = JSON.parse(yield (0, utils_1.sshReq)(...cmd));
(0, utils_1.output2)(`${key} expires on ${new Date(expiry).toLocaleString()}.`);
(0, utils_1.addExitMessage)(`Key: ${prompt_1.YELLOW}${key}${prompt_1.NORMAL_COLOR}`);
(0, utils_1.addExitMessage)(`Key: ${prompt_1.GREEN}${key}${prompt_1.NORMAL_COLOR}`);
}
else {
cmd.push(`--update`, key);
Expand Down Expand Up @@ -493,14 +512,19 @@ exports.alignLeft = alignLeft;
function printTableHeader(prefix, widths) {
if ((0, args_1.getArgs)().length > 0)
return;
let totalWidth = process_1.stdout.getWindowSize()[0] - prefix.length;
let vals = Object.values(widths);
let rest = totalWidth -
vals.reduce((acc, x) => acc + Math.max(x, 0)) -
3 * (vals.length - 1);
let header = prefix +
Object.keys(widths)
.map((k) => k.trim().padEnd(widths[k]))
.map((k) => k.trim().padEnd(widths[k] < 0 ? Math.max(rest, -widths[k]) : widths[k]))
.join(" │ ");
(0, utils_1.output2)(header);
let divider = prefix +
Object.keys(widths)
.map((k) => "─".repeat(widths[k]))
.map((k) => "─".repeat(widths[k] < 0 ? Math.max(rest, -widths[k]) : widths[k]))
.join("─┼─");
(0, utils_1.output2)(divider);
}
Expand Down
60 changes: 43 additions & 17 deletions executors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { ExecOptions, spawn } from "child_process";
import { RED, BLUE, YELLOW, NORMAL_COLOR, GREEN } from "./prompt";
import path from "path";
import { getArgs } from "./args";
import { stdout } from "process";

async function clone(struct: any, name: string) {
try {
Expand Down Expand Up @@ -198,13 +199,13 @@ export async function createService(pth: Path, group: string, name: string) {
}
await execPromise(`git symbolic-ref HEAD refs/heads/main`, name);
addExitMessage(
`Use '${YELLOW}cd ${pth
`Use '${GREEN}cd ${pth
.with(name)
.toString()
.replace(
/\\/g,
"\\\\"
)}${NORMAL_COLOR}' to go to the new service. \nThen use '${YELLOW}${
)}${NORMAL_COLOR}' to go to the new service. \nThen use '${GREEN}${
process.env["COMMAND"]
} deploy${NORMAL_COLOR}' to deploy it.`
);
Expand Down Expand Up @@ -267,14 +268,16 @@ export function addKnownHost() {
}
}

export async function do_register(
keyAction: () => Promise<string>,
email: string
) {
export type KeyAction = () => Promise<{ key: string; keyFile: string }>;
export async function do_register(keyAction: KeyAction, email: string) {
try {
let key = await keyAction();
let { key, keyFile } = await keyAction();
console.log("Registering...");
addKnownHost();
if (email === "") {
addExitMessage(`Notice: Anonymous accounts are automatically deleted permanently after ~2 weeks, without warning. To add an email and avoid automatic deletion, run the command:
${YELLOW}${process.env["COMMAND"]} register ${keyFile}${NORMAL_COLOR}`);
}
let result = await urlReq(
`${HTTP_HOST}/admin/user`,
"POST",
Expand All @@ -298,8 +301,8 @@ export async function do_register(
}

function saveSSHConfig(path: string) {
console.log(`Saving preference...`);
let lines: string[] = [];
let changed = false;
let foundHost = false;
if (fs.existsSync(`${os.homedir()}/.ssh/config`)) {
lines = fs
Expand All @@ -310,13 +313,16 @@ function saveSSHConfig(path: string) {
for (let i = 0; i < lines.length; i++) {
let line = lines[i];
if ((line.startsWith("\t") || line.startsWith(" ")) && inHost) {
if (line.includes("User "))
if (line.includes("User ")) {
lines[i] =
line.substring(0, line.indexOf("User ")) + `User ${SSH_USER}`;
else if (line.includes("IdentityFile "))
changed = true;
} else if (line.includes("IdentityFile ")) {
lines[i] =
line.substring(0, line.indexOf("IdentityFile ")) +
`IdentityFile ~/.ssh/${path}`;
changed = true;
}
} else if (line.startsWith("\t") || line.startsWith(" ")) {
} else if (line.startsWith(`Host ${API_URL}`)) {
inHost = true;
Expand All @@ -327,22 +333,29 @@ function saveSSHConfig(path: string) {
}
}
if (!foundHost) {
lines.push(
lines.unshift(
`Host ${API_URL}`,
`\tUser ${SSH_USER}`,
`\tHostName ${API_URL}`,
`\tPreferredAuthentications publickey`,
`\tIdentityFile ~/.ssh/${path}\n`
);
changed = true;
}
if (changed) {
console.log(`Saving preference...`);
fs.writeFileSync(`${os.homedir()}/.ssh/config`, lines.join("\n"));
}
fs.writeFileSync(`${os.homedir()}/.ssh/config`, lines.join("\n"));
}

export async function useExistingKey(path: string) {
try {
saveSSHConfig(path);
console.log(`Reading ${path}.pub...`);
return "" + fs.readFileSync(os.homedir() + `/.ssh/${path}.pub`);
return {
key: "" + fs.readFileSync(os.homedir() + `/.ssh/${path}.pub`),
keyFile: path,
};
} catch (e) {
throw e;
}
Expand All @@ -357,7 +370,10 @@ export async function generateNewKey() {
`ssh-keygen -t rsa -b 4096 -f "${os.homedir()}/.ssh/merrymake" -N ""`
);
saveSSHConfig("merrymake");
return "" + fs.readFileSync(os.homedir() + "/.ssh/merrymake.pub");
return {
key: "" + fs.readFileSync(os.homedir() + "/.ssh/merrymake.pub"),
keyFile: "merrymake",
};
} catch (e) {
throw e;
}
Expand Down Expand Up @@ -454,7 +470,7 @@ export async function do_key(
await sshReq(...cmd)
);
output2(`${key} expires on ${new Date(expiry).toLocaleString()}.`);
addExitMessage(`Key: ${YELLOW}${key}${NORMAL_COLOR}`);
addExitMessage(`Key: ${GREEN}${key}${NORMAL_COLOR}`);
} else {
cmd.push(`--update`, key);
let { count, expiry }: { count: number; expiry: string } = JSON.parse(
Expand Down Expand Up @@ -570,16 +586,26 @@ export function printTableHeader(
widths: { [key: string]: number }
) {
if (getArgs().length > 0) return;
let totalWidth = stdout.getWindowSize()[0] - prefix.length;
let vals = Object.values(widths);
let rest =
totalWidth -
vals.reduce((acc, x) => acc + Math.max(x, 0)) -
3 * (vals.length - 1);
let header =
prefix +
Object.keys(widths)
.map((k) => k.trim().padEnd(widths[k]))
.map((k) =>
k.trim().padEnd(widths[k] < 0 ? Math.max(rest, -widths[k]) : widths[k])
)
.join(" │ ");
output2(header);
let divider =
prefix +
Object.keys(widths)
.map((k) => "─".repeat(widths[k]))
.map((k) =>
"─".repeat(widths[k] < 0 ? Math.max(rest, -widths[k]) : widths[k])
)
.join("─┼─");
output2(divider);
}
Expand Down
40 changes: 22 additions & 18 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@ const utils_1 = require("./utils");
const questions_1 = require("./questions");
const args_1 = require("./args");
const executors_1 = require("./executors");
if (!node_process_1.stdin.isTTY || node_process_1.stdin.setRawMode === undefined) {
console.log("This console does not support TTY, please use 'winpty mm' or the 'mmk'-command instead.");
process.exit(1);
}
// if (!stdin.isTTY || stdin.setRawMode === undefined) {
// console.log(
// "This console does not support TTY, please use 'winpty mm' or the 'mmk'-command instead."
// );
// process.exit(1);
// }
// TODO make type for command
// if (
// process.argv[0]
Expand All @@ -37,20 +39,22 @@ if (process.argv[0] === "dryrun") {
.split("")
.map((x) => `-${x}`)
: [x]));
// without this, we would only get streams once enter is pressed
node_process_1.stdin.setRawMode(true);
// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
node_process_1.stdin.resume();
// i don't want binary, do you?
node_process_1.stdin.setEncoding("utf8");
// You can always exit with crtl-c
node_process_1.stdin.on("data", (key) => {
let k = key.toString();
if (k === prompt_1.CTRL_C) {
(0, utils_1.abort)();
}
});
if (node_process_1.stdin.isTTY) {
// without this, we would only get streams once enter is pressed
node_process_1.stdin.setRawMode(true);
// resume stdin in the parent process (node app won't quit all by itself
// unless an error or process.exit() happens)
node_process_1.stdin.resume();
// i don't want binary, do you?
node_process_1.stdin.setEncoding("utf8");
// You can always exit with crtl-c
node_process_1.stdin.on("data", (key) => {
let k = key.toString();
if (k === prompt_1.CTRL_C) {
(0, utils_1.abort)();
}
});
}
// TODO Change join to invite
// TODO roles
(() => __awaiter(void 0, void 0, void 0, function* () {
Expand Down
Loading

0 comments on commit dc0b124

Please sign in to comment.