Skip to content

Commit

Permalink
feat: added option to preserve newlines
Browse files Browse the repository at this point in the history
  • Loading branch information
aryanjassal committed Nov 13, 2024
1 parent 2396734 commit 074595b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 12 deletions.
16 changes: 9 additions & 7 deletions src/secrets/CommandEdit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ class CommandEdit extends CommandPolykey {
this.addOption(binOptions.nodeId);
this.addOption(binOptions.clientHost);
this.addOption(binOptions.clientPort);
this.action(async (secretPath, options) => {
this.action(async (fullSecretPath, options) => {
const vaultName = fullSecretPath[0];
const secretPath = fullSecretPath[1] ?? '/';
const os = await import('os');
const { spawn } = await import('child_process');
const vaultsErrors = await import('polykey/dist/vaults/errors');
Expand Down Expand Up @@ -60,13 +62,13 @@ class CommandEdit extends CommandPolykey {
},
logger: this.logger.getChild(PolykeyClient.name),
});
const tmpFile = path.join(tmpDir, path.basename(secretPath[1]));
const tmpFile = path.join(tmpDir, path.basename(secretPath));
const secretExists = await binUtils.retryAuthentication(
async (auth) => {
let exists = true;
const response = await pkClient.rpcClient.methods.vaultsSecretsGet({
nameOrId: secretPath[0],
secretName: secretPath[1] ?? '/',
nameOrId: vaultName,
secretName: secretPath,
metadata: auth,
});
try {
Expand All @@ -86,7 +88,7 @@ class CommandEdit extends CommandPolykey {
// First, write the inline error to standard error like other
// secrets commands do.
process.stderr.write(
`edit: ${secretPath[1] ?? '/'}: No such file or directory\n`,
`edit: ${secretPath}: No such file or directory\n`,
);
// Then, throw an error to get the non-zero exit code. As this
// command is Polykey-specific, the code doesn't really matter
Expand Down Expand Up @@ -160,8 +162,8 @@ class CommandEdit extends CommandPolykey {
async (auth) =>
await pkClient.rpcClient.methods.vaultsSecretsWriteFile({
metadata: auth,
nameOrId: secretPath[0],
secretName: secretPath[1],
nameOrId: vaultName,
secretName: secretPath,
secretContent: content,
}),
meta,
Expand Down
32 changes: 29 additions & 3 deletions src/secrets/CommandEnv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class CommandEnv extends CommandPolykey {
this.addOption(binOptions.envDuplicate);
this.addOption(binOptions.preserveNewline);
this.argument(
'<args...>',
'[args...]',
'command and arguments formatted as [envPaths...][-- cmd [cmdArgs...]]',
binParsers.parseEnvArgs,
);
Expand All @@ -34,7 +34,17 @@ class CommandEnv extends CommandPolykey {
args: [Array<[string, string?, string?]>, Array<string>],
options,
) => {
args[1].shift();
// The parser sets the default value for args. If no arguments are
// provided, then args is an empty array []. This is different from the
// expected structure. This block ensure that the structure is preserved.
args = args[0] == null && args[1] == null ? [[], []] : args;

// There needs to be at least one argument or preserved argument provided
if (args[0].length === 0 && options.preserveNewline.length === 0) {
this.help();
}
// Remove the -- from the command arguments
args[1]?.shift();
const { default: PolykeyClient } = await import(
'polykey/dist/PolykeyClient'
);
Expand All @@ -55,6 +65,10 @@ class CommandEnv extends CommandPolykey {
// b. output the env variables in the desired format

const [envVariables, [cmd, ...argv]] = args;
// Append the secret paths which we want to preserve the newlines of
if (options.preserveNewline) {
envVariables.push(...options.preserveNewline);
}
const clientOptions = await binProcessors.processClientOptions(
options.nodePath,
options.nodeId,
Expand Down Expand Up @@ -161,8 +175,20 @@ class CommandEnv extends CommandPolykey {
utils.never();
}
}

// Find if we need to preserve the newline for this secret
let preserveNewline = false;
if (options.preserveNewline) {
for (const pair of options.preserveNewline) {
if (pair[1] === secretName) {
preserveNewline = true;
break;
}
}
}

// Trim the single trailing newline if it exists
if (secretContent.endsWith('\n')) {
if (!preserveNewline && secretContent.endsWith('\n')) {
envp[newName] = secretContent.slice(0, -1);
} else {
envp[newName] = secretContent;
Expand Down
8 changes: 6 additions & 2 deletions src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,14 @@ const parents = new commander.Option(
).default(false);

const preserveNewline = new commander.Option(
'--preserve-newline <path>',
'-pn --preserve-newline <path>',
'Preserve the last trailing newline for the secret content',
)
.argParser(binParsers.parseSecretPathEnv)
.argParser((value: string, previous: Array<[string, string?, string?]>) => {
const out = previous ?? [];
out.push(binParsers.parseSecretPathEnv(value));
return out;
})
.default(undefined);

export {
Expand Down

0 comments on commit 074595b

Please sign in to comment.