From 6ac9e78e60f0ffaf0c7aa09e8e5593b71cf68d45 Mon Sep 17 00:00:00 2001 From: Webber Date: Sun, 7 Aug 2022 03:08:16 +0200 Subject: [PATCH] fix: broken run command that was reading from input buffer --- .eslintrc.json | 4 ++- src/dependencies.ts | 2 ++ src/model/action.ts | 2 ++ src/model/system.ts | 59 +++++++++++++++++++++++++++++++++---- src/model/versioning.ts | 23 +++++++-------- src/modules/actions/exec.ts | 4 ++- 6 files changed, 74 insertions(+), 20 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 166ddbf1..af43ec76 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -81,6 +81,8 @@ // Null is useful when explicit value is passed "unicorn/no-null": "off", // (enable to add improvements) - "unicorn/prefer-export-from": "off" + "unicorn/prefer-export-from": "off", + // Deno uses const a=new Buffer(new TextEncoder().encode('Hello World')); + "unicorn/no-new-buffer": "off" } } diff --git a/src/dependencies.ts b/src/dependencies.ts index 115d3c9c..e99510c6 100644 --- a/src/dependencies.ts +++ b/src/dependencies.ts @@ -18,6 +18,7 @@ import * as http from 'https://deno.land/std@0.145.0/node/http.ts'; import * as string from 'https://deno.land/std@0.36.0/strings/mod.ts'; import { Command } from 'https://deno.land/x/cmd@v1.2.0/commander/index.ts'; import { getUnityChangeset as getUnityChangeSet } from 'https://deno.land/x/unity_changeset@2.0.0/src/index.ts'; +import { Buffer } from 'https://deno.land/std@0.151.0/io/buffer.ts'; // Internally managed import waitUntil from './modules/wait-until.ts'; @@ -45,6 +46,7 @@ export { assert, aws, base64, + Buffer, Command, compress, core, diff --git a/src/model/action.ts b/src/model/action.ts index 8619b96e..7b01948a 100644 --- a/src/model/action.ts +++ b/src/model/action.ts @@ -30,6 +30,8 @@ class Action { } static get workspace() { + if (Action.isRunningLocally) return Deno.cwd(); + return Deno.env.get('GITHUB_WORKSPACE'); } diff --git a/src/model/system.ts b/src/model/system.ts index 3fce57c4..516d2152 100644 --- a/src/model/system.ts +++ b/src/model/system.ts @@ -1,6 +1,45 @@ -import { core, exec } from '../dependencies.ts'; +import { exec } from '../dependencies.ts'; class System { + static async shellRun(command) { + return System.newRun('sh', ['-c', command]); + } + + /** + * Example: + * System.newRun(sh, ['-c', 'echo something']) + * + * private for now, but could become public if this happens to be a great replacement for the other run method. + */ + private static async newRun(command, args: string | string[] = []) { + if (!Array.isArray(args)) args = [args]; + + const argsString = args.join(' '); + const process = Deno.run({ + cmd: [command, ...args], + stdout: 'piped', + stderr: 'piped', + }); + + const status = await process.status(); + const outputBuffer = await process.output(); + const errorBuffer = await process.stderrOutput(); + + process.close(); + + const output = new TextDecoder().decode(outputBuffer); + const error = new TextDecoder().decode(errorBuffer); + + const result = { status, output }; + const symbol = status.success ? '✅' : '❗'; + + log.debug('Command:', command, argsString, symbol, result); + + if (error) throw new Error(error); + + return result; + } + static async run(command, arguments_: any = [], options = {}, shouldLog = true) { let result = ''; let error = ''; @@ -48,17 +87,25 @@ class System { throw new Error(`Failed to execute empty command`); } - const { exitCode } = await exec(command, arguments_, { silent: true, listeners, ...options }); + const { exitCode, success, output } = await exec(command, arguments_, { silent: true, listeners, ...options }); showOutput(); - if (exitCode !== 0) { - throwContextualError(`Command returned non-zero exit code.\nError: ${error}`); + if (!success) { + throwContextualError(`Command returned non-zero exit code (${exitCode}).\nError: ${error}`); } + + // Todo - remove this after verifying it works as expected + const trimmedResult = result.replace(/\n+$/, ''); + if (!output && trimmedResult) { + log.warning('returning result instead of output for backward compatibility'); + + return trimmedResult; + } + + return output; } catch (inCommandError) { showOutput(); throwContextualError(`In-command error caught: ${inCommandError}`); } - - return result.replace(/\n+$/, ''); } } diff --git a/src/model/versioning.ts b/src/model/versioning.ts index 6c84d0f0..7a60b40b 100644 --- a/src/model/versioning.ts +++ b/src/model/versioning.ts @@ -1,4 +1,4 @@ -import { core } from '../dependencies.ts'; +import { Buffer } from '../dependencies.ts'; import NotImplementedException from './error/not-implemented-exception.ts'; import ValidationError from './error/validation-error.ts'; import Input from './input.ts'; @@ -62,10 +62,9 @@ export default class Versioning { */ static async logDiff() { const diffCommand = `git --no-pager diff | head -n ${this.maxDiffLines.toString()}`; - await System.run('sh', undefined, { - input: Buffer.from(diffCommand), - silent: true, - }); + const result = await System.shellRun(diffCommand); + + log.debug(result.output); } /** @@ -129,7 +128,7 @@ export default class Versioning { await this.fetch(); } - await this.logDiff(); + await Versioning.logDiff(); if ((await this.isDirty()) && !this.isDirtyAllowed) { throw new Error('Branch is dirty. Refusing to base semantic version on uncommitted changes'); @@ -226,7 +225,7 @@ export default class Versioning { static async isShallow() { const output = await this.git(['rev-parse', '--is-shallow-repository']); - return output !== 'false\n'; + return output !== 'false'; } /** @@ -240,9 +239,7 @@ export default class Versioning { try { await this.git(['fetch', '--unshallow']); } catch { - log.warning( - `fetch --unshallow did not work, falling back to regular fetch (which probably just means it's not running on GH actions)`, - ); + log.warning(`fetch --unshallow did not work, falling back to regular fetch`); await this.git(['fetch']); } } @@ -267,8 +264,10 @@ export default class Versioning { const isDirty = output !== ''; if (isDirty) { - log.warning('Changes were made to the following files and folders:\n'); - log.warning(output); + log.warning( + `Changes were made to the following files and folders:\n\n A = addition, M = modification, D = deletion\n\n`, + output, + ); } return isDirty; diff --git a/src/modules/actions/exec.ts b/src/modules/actions/exec.ts index 0015d96c..4b24cd4f 100644 --- a/src/modules/actions/exec.ts +++ b/src/modules/actions/exec.ts @@ -40,6 +40,8 @@ const exec = async ( continueOnError: false, }; + // log.debug('Command:', command, args); + const { silent = false, ignoreReturnCode } = ghActionsOptions; if (silent) options.output = OutputMode.Capture; if (ignoreReturnCode) options.continueOnError = true; @@ -53,7 +55,7 @@ const exec = async ( const symbol = success ? '✅' : '❗'; log.debug('Command:', command, argsString, symbol, result); - return { exitCode, success, output: output.trim() }; + return { exitCode, success, output: output.replace(/\n+$/, '') }; }; export { exec };