ssh-keyman 1.0.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/BADGE-SUMMARY.md +244 -0
- package/.github/BADGES.md +214 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +36 -0
- package/.github/workflows/ci.yml +69 -0
- package/.github/workflows/publish.yml +32 -0
- package/.github/workflows/test-report.yml +50 -0
- package/CONTRIBUTING.md +128 -0
- package/STATUS.md +134 -0
- package/codecov.yml +29 -0
- package/package.json +34 -3
- package/readme.md +160 -25
- package/src/__tests__/cliOptions.test.js +78 -0
- package/src/__tests__/commands.test.js +369 -0
- package/src/__tests__/constants.test.js +44 -0
- package/src/__tests__/extendFs.test.js +105 -0
- package/src/__tests__/helpers.js +113 -0
- package/src/__tests__/testUtils.js +113 -0
- package/src/commands.js +170 -96
- package/src/constants.js +7 -36
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const fs = require("fs-extra");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const os = require("os");
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create a mock file system structure for testing
|
|
7
|
+
*/
|
|
8
|
+
function createMockFileSystem(baseDir) {
|
|
9
|
+
const sshPath = path.join(baseDir, ".ssh");
|
|
10
|
+
const keymanPath = path.join(baseDir, ".sshkeyman");
|
|
11
|
+
const keymanFile = path.join(keymanPath, ".sshkeyman");
|
|
12
|
+
const defaultEnvPath = path.join(keymanPath, "default");
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
sshPath,
|
|
16
|
+
keymanPath,
|
|
17
|
+
keymanFile,
|
|
18
|
+
defaultEnvPath,
|
|
19
|
+
setup: () => {
|
|
20
|
+
if (!fs.existsSync(baseDir)) {
|
|
21
|
+
fs.mkdirSync(baseDir, { recursive: true });
|
|
22
|
+
}
|
|
23
|
+
if (!fs.existsSync(sshPath)) {
|
|
24
|
+
fs.mkdirSync(sshPath, { recursive: true });
|
|
25
|
+
fs.writeFileSync(path.join(sshPath, "id_rsa"), "mock private key");
|
|
26
|
+
fs.writeFileSync(path.join(sshPath, "id_rsa.pub"), "mock public key");
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
cleanup: () => {
|
|
30
|
+
if (fs.existsSync(baseDir)) {
|
|
31
|
+
fs.rmSync(baseDir, { recursive: true, force: true });
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
initializeKeyman: () => {
|
|
35
|
+
if (!fs.existsSync(keymanPath)) {
|
|
36
|
+
fs.mkdirSync(keymanPath, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
if (!fs.existsSync(defaultEnvPath)) {
|
|
39
|
+
fs.mkdirSync(defaultEnvPath, { recursive: true });
|
|
40
|
+
fs.copySync(sshPath, defaultEnvPath);
|
|
41
|
+
}
|
|
42
|
+
fs.writeFileSync(
|
|
43
|
+
keymanFile,
|
|
44
|
+
JSON.stringify({ active: "default", available: ["default"] })
|
|
45
|
+
);
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Mock console methods
|
|
52
|
+
*/
|
|
53
|
+
function mockConsole() {
|
|
54
|
+
const originalLog = console.log;
|
|
55
|
+
const originalError = console.error;
|
|
56
|
+
const logs = [];
|
|
57
|
+
const errors = [];
|
|
58
|
+
|
|
59
|
+
console.log = (...args) => {
|
|
60
|
+
logs.push(args.join(" "));
|
|
61
|
+
};
|
|
62
|
+
console.error = (...args) => {
|
|
63
|
+
errors.push(args.join(" "));
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
logs,
|
|
68
|
+
errors,
|
|
69
|
+
restore: () => {
|
|
70
|
+
console.log = originalLog;
|
|
71
|
+
console.error = originalError;
|
|
72
|
+
},
|
|
73
|
+
getLogs: () => logs,
|
|
74
|
+
getErrors: () => errors,
|
|
75
|
+
clear: () => {
|
|
76
|
+
logs.length = 0;
|
|
77
|
+
errors.length = 0;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Mock inquirer prompts
|
|
84
|
+
*/
|
|
85
|
+
function mockInquirer(answers = {}) {
|
|
86
|
+
const inquirer = require("inquirer");
|
|
87
|
+
const originalPrompt = inquirer.prompt;
|
|
88
|
+
|
|
89
|
+
inquirer.prompt = jest.fn((questions) => {
|
|
90
|
+
const responses = {};
|
|
91
|
+
questions.forEach((q) => {
|
|
92
|
+
if (answers[q.name] !== undefined) {
|
|
93
|
+
responses[q.name] = answers[q.name];
|
|
94
|
+
} else if (q.default !== undefined) {
|
|
95
|
+
responses[q.name] = q.default;
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
return Promise.resolve(responses);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
restore: () => {
|
|
103
|
+
inquirer.prompt = originalPrompt;
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
module.exports = {
|
|
109
|
+
createMockFileSystem,
|
|
110
|
+
mockConsole,
|
|
111
|
+
mockInquirer,
|
|
112
|
+
};
|
|
113
|
+
|
package/src/commands.js
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
const fs = require("fs-extra");
|
|
2
2
|
const os = require("os");
|
|
3
3
|
const path = require("path");
|
|
4
|
-
const
|
|
5
|
-
const
|
|
4
|
+
const inquirer = require("inquirer");
|
|
5
|
+
const chalk = require("chalk");
|
|
6
|
+
const autocompletePrompt = require("inquirer-autocomplete-prompt");
|
|
7
|
+
const { options } = require("./constants");
|
|
6
8
|
const { delAndCopySync, delDirSync } = require("./extendFs");
|
|
7
9
|
|
|
10
|
+
// Register autocomplete prompt
|
|
11
|
+
inquirer.registerPrompt("autocomplete", autocompletePrompt);
|
|
12
|
+
|
|
8
13
|
const SSH_PATH = path.join(os.homedir(), ".ssh");
|
|
9
14
|
const KEYMAN_DIR_PATH = path.join(os.homedir(), ".sshkeyman");
|
|
10
15
|
const KEYMAN_PATH = path.join(KEYMAN_DIR_PATH, ".sshkeyman");
|
|
@@ -14,191 +19,260 @@ let KEYMAN_CONTENT = IS_INITIALIZED
|
|
|
14
19
|
? JSON.parse(fs.readFileSync(KEYMAN_PATH))
|
|
15
20
|
: undefined;
|
|
16
21
|
|
|
17
|
-
const rl = readline.createInterface({
|
|
18
|
-
input: process.stdin,
|
|
19
|
-
output: process.stdout,
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
const question = (q) =>
|
|
23
|
-
new Promise((resolve) => {
|
|
24
|
-
rl.question(q, (a) => {
|
|
25
|
-
resolve(a);
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
rl.on("close", () => {
|
|
30
|
-
console.log("closed");
|
|
31
|
-
});
|
|
32
|
-
|
|
33
22
|
const logger = (type, message) => {
|
|
34
23
|
if (Array.isArray(message)) {
|
|
35
24
|
message = message.join(" ");
|
|
36
25
|
}
|
|
37
|
-
let color;
|
|
38
26
|
switch (type) {
|
|
39
|
-
case "success":
|
|
40
|
-
|
|
27
|
+
case "success":
|
|
28
|
+
console.log(chalk.green(message ? message : ""));
|
|
41
29
|
break;
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
color = consoleColors.FgRed;
|
|
30
|
+
case "error":
|
|
31
|
+
console.log(chalk.red(message ? message : ""));
|
|
45
32
|
break;
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
33
|
+
case "warning":
|
|
34
|
+
console.log(chalk.yellow(message ? message : ""));
|
|
35
|
+
break;
|
|
36
|
+
case "info":
|
|
37
|
+
console.log(chalk.cyan(message ? message : ""));
|
|
38
|
+
break;
|
|
39
|
+
default:
|
|
40
|
+
console.log(message ? message : "");
|
|
49
41
|
break;
|
|
50
|
-
}
|
|
51
42
|
}
|
|
52
|
-
console.log(color, message ? message : "");
|
|
53
43
|
};
|
|
54
44
|
|
|
55
45
|
const help = function () {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
]);
|
|
63
|
-
logger(null, "Commands:");
|
|
46
|
+
console.log();
|
|
47
|
+
console.log(chalk.bold.cyan("SSH KeyMan") + chalk.gray(" - SSH Key Environment Manager"));
|
|
48
|
+
console.log();
|
|
49
|
+
console.log(chalk.bold("Usage:") + " ssh-keyman <command> [options]");
|
|
50
|
+
console.log();
|
|
51
|
+
console.log(chalk.bold("Commands:"));
|
|
64
52
|
for (let option of options) {
|
|
65
|
-
|
|
53
|
+
console.log(chalk.gray(option.help));
|
|
66
54
|
}
|
|
67
|
-
|
|
55
|
+
console.log();
|
|
56
|
+
console.log(chalk.dim("Tip: Run commands without arguments for interactive mode"));
|
|
57
|
+
console.log();
|
|
68
58
|
};
|
|
69
59
|
|
|
70
60
|
const init = function () {
|
|
71
61
|
if (!fs.existsSync(KEYMAN_DIR_PATH)) {
|
|
62
|
+
console.log(chalk.cyan("\n🔑 Initializing SSH KeyMan...\n"));
|
|
72
63
|
fs.mkdirSync(KEYMAN_DIR_PATH);
|
|
73
|
-
logger("success", "
|
|
64
|
+
logger("success", "✓ Created ssh-keyman directory: " + KEYMAN_DIR_PATH);
|
|
74
65
|
fs.mkdirSync(KEYMAN_DEFAULT_ENV_PATH);
|
|
75
66
|
fs.copySync(SSH_PATH, KEYMAN_DEFAULT_ENV_PATH);
|
|
76
|
-
logger(
|
|
77
|
-
"success",
|
|
78
|
-
"Initialized default environment " + KEYMAN_DEFAULT_ENV_PATH
|
|
79
|
-
);
|
|
67
|
+
logger("success", "✓ Created default environment");
|
|
80
68
|
fs.writeFileSync(
|
|
81
69
|
KEYMAN_PATH,
|
|
82
70
|
JSON.stringify({ active: "default", available: ["default"] })
|
|
83
71
|
);
|
|
84
|
-
logger("success", "Activated 'default' environment");
|
|
72
|
+
logger("success", "✓ Activated 'default' environment");
|
|
73
|
+
console.log(chalk.green("\n✨ SSH KeyMan initialized successfully!\n"));
|
|
85
74
|
return;
|
|
86
75
|
}
|
|
87
|
-
logger("
|
|
76
|
+
logger("info", "ssh-keyman is already initialized");
|
|
88
77
|
};
|
|
89
78
|
|
|
90
79
|
const create = async function (name) {
|
|
91
80
|
if (!IS_INITIALIZED) {
|
|
92
|
-
logger("error", "ssh-keyman is not
|
|
93
|
-
logger(null,
|
|
94
|
-
"Please initialize ssh-keyman using:",
|
|
95
|
-
"\n",
|
|
96
|
-
"ssh-keyman -i",
|
|
97
|
-
"\n",
|
|
98
|
-
]);
|
|
81
|
+
logger("error", "ssh-keyman is not initialized\n");
|
|
82
|
+
logger(null, "Please initialize ssh-keyman using: ssh-keyman -i\n");
|
|
99
83
|
return;
|
|
100
84
|
}
|
|
101
85
|
if (!name) {
|
|
102
|
-
|
|
86
|
+
const answer = await inquirer.prompt([
|
|
87
|
+
{
|
|
88
|
+
type: "input",
|
|
89
|
+
name: "envName",
|
|
90
|
+
message: "Enter name for the new environment:",
|
|
91
|
+
validate: (input) => {
|
|
92
|
+
if (!input || input.trim() === "") {
|
|
93
|
+
return "Environment name cannot be empty";
|
|
94
|
+
}
|
|
95
|
+
if (fs.existsSync(path.join(KEYMAN_DIR_PATH, input))) {
|
|
96
|
+
return "An environment with this name already exists";
|
|
97
|
+
}
|
|
98
|
+
return true;
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
]);
|
|
102
|
+
name = answer.envName;
|
|
103
103
|
}
|
|
104
104
|
let { active, available } = KEYMAN_CONTENT || {};
|
|
105
105
|
const exist = fs.existsSync(path.join(KEYMAN_DIR_PATH, name));
|
|
106
106
|
if (exist) {
|
|
107
|
-
return logger("error", "An environment with similar name already
|
|
107
|
+
return logger("error", "An environment with similar name already exists");
|
|
108
108
|
}
|
|
109
109
|
if (active) {
|
|
110
110
|
delAndCopySync(SSH_PATH, path.join(KEYMAN_DIR_PATH, active));
|
|
111
|
-
logger("success",
|
|
111
|
+
logger("success", `Saved current ssh config to ${active}`);
|
|
112
112
|
const NEW_ENV_PATH = path.join(KEYMAN_DIR_PATH, name);
|
|
113
113
|
fs.mkdirSync(NEW_ENV_PATH);
|
|
114
|
-
logger("success",
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
logger("success", `Created directory for new environment: ${NEW_ENV_PATH}`);
|
|
115
|
+
|
|
116
|
+
const { switchNow } = await inquirer.prompt([
|
|
117
|
+
{
|
|
118
|
+
type: "confirm",
|
|
119
|
+
name: "switchNow",
|
|
120
|
+
message: `Do you want to switch to newly created environment (${name})?`,
|
|
121
|
+
default: true,
|
|
122
|
+
},
|
|
117
123
|
]);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
)
|
|
121
|
-
if (ans.toLowerCase() === "y" || ans.toLowerCase() === 'yes') {
|
|
122
|
-
available.push(name);
|
|
124
|
+
|
|
125
|
+
available.push(name);
|
|
126
|
+
if (switchNow) {
|
|
123
127
|
fs.writeFileSync(
|
|
124
128
|
KEYMAN_PATH,
|
|
125
129
|
JSON.stringify({ active: name, available })
|
|
126
130
|
);
|
|
127
131
|
delDirSync(SSH_PATH);
|
|
128
132
|
fs.mkdirSync(SSH_PATH);
|
|
129
|
-
return logger("success",
|
|
133
|
+
return logger("success", `Activated environment '${name}'`);
|
|
130
134
|
}
|
|
131
|
-
available.push(name);
|
|
132
135
|
fs.writeFileSync(
|
|
133
136
|
KEYMAN_PATH,
|
|
134
137
|
JSON.stringify({ active: active, available })
|
|
135
138
|
);
|
|
136
|
-
return logger("success",
|
|
139
|
+
return logger("success", `Successfully created environment ${name}`);
|
|
137
140
|
}
|
|
138
141
|
};
|
|
139
142
|
|
|
140
143
|
const list = function () {
|
|
141
144
|
if (!IS_INITIALIZED) {
|
|
142
|
-
logger("error", "ssh-keyman is not
|
|
143
|
-
logger(null,
|
|
144
|
-
"Please initialize ssh-keyman using:",
|
|
145
|
-
"\n",
|
|
146
|
-
"ssh-keyman -i",
|
|
147
|
-
"\n",
|
|
148
|
-
]);
|
|
145
|
+
logger("error", "ssh-keyman is not initialized\n");
|
|
146
|
+
logger(null, "Please initialize ssh-keyman using: ssh-keyman -i\n");
|
|
149
147
|
return;
|
|
150
148
|
}
|
|
151
|
-
|
|
149
|
+
console.log(chalk.bold("\nAvailable environments:"));
|
|
152
150
|
if (KEYMAN_CONTENT) {
|
|
153
151
|
const { active, available } = KEYMAN_CONTENT;
|
|
154
152
|
available.forEach((env) => {
|
|
155
153
|
if (env === active) {
|
|
156
|
-
|
|
154
|
+
console.log(chalk.green(` ✓ ${env}`) + chalk.gray(" (active)"));
|
|
157
155
|
} else {
|
|
158
|
-
|
|
156
|
+
console.log(chalk.white(` • ${env}`));
|
|
159
157
|
}
|
|
160
158
|
});
|
|
161
159
|
}
|
|
162
|
-
|
|
160
|
+
console.log();
|
|
163
161
|
};
|
|
164
162
|
|
|
165
|
-
const switchEnv = function (name) {
|
|
163
|
+
const switchEnv = async function (name) {
|
|
166
164
|
if (!IS_INITIALIZED) {
|
|
167
|
-
logger("error", "ssh-keyman is not
|
|
168
|
-
logger(null,
|
|
169
|
-
"Please initialize ssh-keyman using:",
|
|
170
|
-
"\n",
|
|
171
|
-
"ssh-keyman -i",
|
|
172
|
-
"\n",
|
|
173
|
-
]);
|
|
165
|
+
logger("error", "ssh-keyman is not initialized\n");
|
|
166
|
+
logger(null, "Please initialize ssh-keyman using: ssh-keyman -i\n");
|
|
174
167
|
return;
|
|
175
168
|
}
|
|
176
169
|
if (KEYMAN_CONTENT) {
|
|
177
170
|
const { active, available } = KEYMAN_CONTENT;
|
|
171
|
+
|
|
172
|
+
// If no name provided, show interactive autocomplete menu
|
|
173
|
+
if (!name) {
|
|
174
|
+
const otherEnvs = available.filter((env) => env !== active);
|
|
175
|
+
|
|
176
|
+
if (otherEnvs.length === 0) {
|
|
177
|
+
return logger("warning", "No other environments available to switch to");
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const answer = await inquirer.prompt([
|
|
181
|
+
{
|
|
182
|
+
type: "autocomplete",
|
|
183
|
+
name: "envName",
|
|
184
|
+
message: "Select environment to switch to:",
|
|
185
|
+
source: async (answersSoFar, input) => {
|
|
186
|
+
const filtered = otherEnvs.filter((env) =>
|
|
187
|
+
env.toLowerCase().includes((input || "").toLowerCase())
|
|
188
|
+
);
|
|
189
|
+
return filtered.map((env) => ({
|
|
190
|
+
name: env,
|
|
191
|
+
value: env,
|
|
192
|
+
}));
|
|
193
|
+
},
|
|
194
|
+
pageSize: 10,
|
|
195
|
+
},
|
|
196
|
+
]);
|
|
197
|
+
name = answer.envName;
|
|
198
|
+
}
|
|
199
|
+
|
|
178
200
|
const env = available.find((env) => env === name);
|
|
201
|
+
|
|
202
|
+
if (!env) {
|
|
203
|
+
return logger("error", `Environment '${name}' not found`);
|
|
204
|
+
}
|
|
205
|
+
|
|
179
206
|
if (env === active) {
|
|
180
|
-
return logger(
|
|
181
|
-
"error",
|
|
182
|
-
`${name} is already selected as existing environment`
|
|
183
|
-
);
|
|
207
|
+
return logger("warning", `${name} is already the active environment`);
|
|
184
208
|
}
|
|
185
209
|
|
|
186
210
|
delAndCopySync(SSH_PATH, path.join(KEYMAN_DIR_PATH, active));
|
|
187
|
-
logger("success",
|
|
211
|
+
logger("success", `Saved current ssh config to '${active}'`);
|
|
188
212
|
const NEW_ENV_PATH = path.join(KEYMAN_DIR_PATH, name);
|
|
189
213
|
delAndCopySync(NEW_ENV_PATH, SSH_PATH);
|
|
190
214
|
fs.writeFileSync(KEYMAN_PATH, JSON.stringify({ available, active: name }));
|
|
191
215
|
logger("success", `Activated environment '${name}'`);
|
|
192
216
|
} else {
|
|
193
|
-
logger("error",
|
|
217
|
+
logger("error", "Data directory is corrupt. Please try uninstalling and reinstalling the package.");
|
|
194
218
|
}
|
|
195
219
|
};
|
|
196
220
|
|
|
197
|
-
const deleteEnv = function (name) {
|
|
221
|
+
const deleteEnv = async function (name) {
|
|
222
|
+
if (!IS_INITIALIZED) {
|
|
223
|
+
logger("error", "ssh-keyman is not initialized\n");
|
|
224
|
+
logger(null, "Please initialize ssh-keyman using: ssh-keyman -i\n");
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
let { active, available } = KEYMAN_CONTENT || {};
|
|
229
|
+
|
|
230
|
+
// If no name provided, show interactive autocomplete menu
|
|
231
|
+
if (!name) {
|
|
232
|
+
const deletableEnvs = available.filter((env) => env !== "default" && env !== active);
|
|
233
|
+
|
|
234
|
+
if (deletableEnvs.length === 0) {
|
|
235
|
+
return logger("warning", "No environments available to delete");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const answer = await inquirer.prompt([
|
|
239
|
+
{
|
|
240
|
+
type: "autocomplete",
|
|
241
|
+
name: "envName",
|
|
242
|
+
message: "Select environment to delete:",
|
|
243
|
+
source: async (answersSoFar, input) => {
|
|
244
|
+
const filtered = deletableEnvs.filter((env) =>
|
|
245
|
+
env.toLowerCase().includes((input || "").toLowerCase())
|
|
246
|
+
);
|
|
247
|
+
return filtered.map((env) => ({
|
|
248
|
+
name: env,
|
|
249
|
+
value: env,
|
|
250
|
+
}));
|
|
251
|
+
},
|
|
252
|
+
pageSize: 10,
|
|
253
|
+
},
|
|
254
|
+
]);
|
|
255
|
+
name = answer.envName;
|
|
256
|
+
|
|
257
|
+
// Confirm deletion
|
|
258
|
+
const { confirmDelete } = await inquirer.prompt([
|
|
259
|
+
{
|
|
260
|
+
type: "confirm",
|
|
261
|
+
name: "confirmDelete",
|
|
262
|
+
message: `Are you sure you want to delete environment '${name}'?`,
|
|
263
|
+
default: false,
|
|
264
|
+
},
|
|
265
|
+
]);
|
|
266
|
+
|
|
267
|
+
if (!confirmDelete) {
|
|
268
|
+
return logger("info", "Deletion cancelled");
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
198
272
|
if (name === "default") {
|
|
199
273
|
return logger("error", "Default environment cannot be deleted");
|
|
200
274
|
}
|
|
201
|
-
|
|
275
|
+
|
|
202
276
|
const exist = fs.existsSync(path.join(KEYMAN_DIR_PATH, name));
|
|
203
277
|
if (active === name) {
|
|
204
278
|
return logger(
|
|
@@ -220,8 +294,8 @@ const deleteEnv = function (name) {
|
|
|
220
294
|
};
|
|
221
295
|
|
|
222
296
|
const version = function() {
|
|
223
|
-
const
|
|
224
|
-
|
|
297
|
+
const pkg = require('../package.json');
|
|
298
|
+
console.log(chalk.cyan('ssh-keyman') + chalk.gray(' version ') + chalk.bold(pkg.version));
|
|
225
299
|
}
|
|
226
300
|
|
|
227
301
|
module.exports = {
|
package/src/constants.js
CHANGED
|
@@ -1,45 +1,16 @@
|
|
|
1
1
|
const cliOptions = [
|
|
2
|
-
["i", "init", " -i
|
|
3
|
-
["c", "create", " -c [name]
|
|
4
|
-
["s", "switch", " -s [name]
|
|
5
|
-
["d", "delete", " -d [name]
|
|
6
|
-
["ls", "list", " -ls
|
|
7
|
-
["h", "help", " -h
|
|
8
|
-
["v", "version", " -v
|
|
2
|
+
["i", "init", " -i Initialize keyman directory and default environment"],
|
|
3
|
+
["c", "create", " -c [name] Create new ssh environment (interactive if no name)"],
|
|
4
|
+
["s", "switch", " -s [name] Switch to another ssh environment (interactive if no name)"],
|
|
5
|
+
["d", "delete", " -d [name] Delete ssh environment (interactive if no name)"],
|
|
6
|
+
["ls", "list", " -ls List all environments"],
|
|
7
|
+
["h", "help", " -h Show help"],
|
|
8
|
+
["v", "version", " -v Show version"],
|
|
9
9
|
];
|
|
10
10
|
|
|
11
11
|
const options = [];
|
|
12
12
|
|
|
13
|
-
const consoleColors = {
|
|
14
|
-
Reset: "\x1b[0m",
|
|
15
|
-
Bright: "\x1b[1m",
|
|
16
|
-
Dim: "\x1b[2m",
|
|
17
|
-
Underscore: "\x1b[4m",
|
|
18
|
-
Blink: "\x1b[5m",
|
|
19
|
-
Reverse: "\x1b[7m",
|
|
20
|
-
Hidden: "\x1b[8m",
|
|
21
|
-
|
|
22
|
-
FgBlack: "\x1b[30m",
|
|
23
|
-
FgRed: "\x1b[31m",
|
|
24
|
-
FgGreen: "\x1b[32m",
|
|
25
|
-
FgYellow: "\x1b[33m",
|
|
26
|
-
FgBlue: "\x1b[34m",
|
|
27
|
-
FgMagenta: "\x1b[35m",
|
|
28
|
-
FgCyan: "\x1b[36m",
|
|
29
|
-
FgWhite: "\x1b[37m",
|
|
30
|
-
|
|
31
|
-
BgBlack: "\x1b[40m",
|
|
32
|
-
BgRed: "\x1b[41m",
|
|
33
|
-
BgGreen: "\x1b[42m",
|
|
34
|
-
BgYellow: "\x1b[43m",
|
|
35
|
-
BgBlue: "\x1b[44m",
|
|
36
|
-
BgMagenta: "\x1b[45m",
|
|
37
|
-
BgCyan: "\x1b[46m",
|
|
38
|
-
BgWhite: "\x1b[47m",
|
|
39
|
-
};
|
|
40
|
-
|
|
41
13
|
module.exports = {
|
|
42
14
|
cliOptions,
|
|
43
15
|
options,
|
|
44
|
-
consoleColors
|
|
45
16
|
};
|