diff --git a/package.json b/package.json index 8987276..78efff4 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "clitastic": "0.0.1", "colors": "^1.3.3", "js-yaml": "^3.13.1", - "minimist": "^1.2.0" + "minimist": "^1.2.0", + "uhrwerk": "^1.0.0" } -} \ No newline at end of file +} diff --git a/src/backup.ts b/src/backup.ts index c7d8501..5cc1c14 100644 --- a/src/backup.ts +++ b/src/backup.ts @@ -3,12 +3,21 @@ import { Writer } from 'clitastic' import { config, VERBOSE } from './autorestic' import { getEnvFromBackend } from './backend' import { Locations, Location } from './types' -import { exec, ConfigError, pathRelativeToConfigFile, getFlagsFromLocation, makeArrayIfIsNot, execPlain } from './utils' +import { + exec, + ConfigError, + pathRelativeToConfigFile, + getFlagsFromLocation, + makeArrayIfIsNot, + execPlain, + MeasureDuration, fill, +} from './utils' export const backupSingle = (name: string, to: string, location: Location) => { if (!config) throw ConfigError + const delta = new MeasureDuration() const writer = new Writer(name + to.blue + ' : ' + 'Backing up... ⏳') const backend = config.backends[to] @@ -21,12 +30,12 @@ export const backupSingle = (name: string, to: string, location: Location) => { ) if (VERBOSE) console.log(cmd.out, cmd.err) - writer.done(name + to.blue + ' : ' + 'Done ✓'.green) + writer.done(`${name}${to.blue} : ${'Done ✓'.green} (${delta.finished(true)})`) } export const backupLocation = (name: string, location: Location) => { const display = name.yellow + ' ▶ ' - const filler = new Array(name.length + 3).fill(' ').join('') + const filler = fill(name.length + 3) let first = true if (location.hooks && location.hooks.before) diff --git a/src/forget.ts b/src/forget.ts index 640a7d8..ad00547 100644 --- a/src/forget.ts +++ b/src/forget.ts @@ -3,7 +3,14 @@ import { Writer } from 'clitastic' import { config, VERBOSE } from './autorestic' import { getEnvFromBackend } from './backend' import { Locations, Location, Flags } from './types' -import { exec, ConfigError, pathRelativeToConfigFile, getFlagsFromLocation, makeArrayIfIsNot } from './utils' +import { + exec, + ConfigError, + pathRelativeToConfigFile, + getFlagsFromLocation, + makeArrayIfIsNot, + fill, +} from './utils' @@ -35,7 +42,7 @@ export const forgetSingle = (name: string, to: string, location: Location, dryRu export const forgetLocation = (name: string, backup: Location, dryRun: boolean) => { const display = name.yellow + ' ▶ ' - const filler = new Array(name.length + 3).fill(' ').join('') + const filler = fill(name.length + 3) let first = true for (const t of makeArrayIfIsNot(backup.to)) { diff --git a/src/utils.ts b/src/utils.ts index f9ca0fd..5ece944 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -3,6 +3,8 @@ import { spawnSync, SpawnSyncOptions } from 'child_process' import { randomBytes } from 'crypto' import { createWriteStream } from 'fs' import { dirname, isAbsolute, resolve } from 'path' +import { Duration, Humanizer } from 'uhrwerk' + import { CONFIG_FILE } from './config' import { Location } from './types' @@ -113,3 +115,44 @@ export const getFlagsFromLocation = (location: Location, command?: string): stri } export const makeArrayIfIsNot = (maybeArray: T | T[]): T[] => Array.isArray(maybeArray) ? maybeArray : [maybeArray] + +export const fill = (length: number, filler = ' '): string => new Array(length).fill(filler).join('') + +export const capitalize = (string: string): string => string.charAt(0).toUpperCase() + string.slice(1) + +export const treeToString = (obj: Object, highlight = [] as string[]): string => { + let cleaned = JSON.stringify(obj, null, 2) + .replace(/[{}"\[\],]/g, '') + .replace(/^ {2}/mg, '') + .replace(/\n\s*\n/g, '\n') + .trim() + + for (const word of highlight) + cleaned = cleaned.replace(word, capitalize(word).green) + + return cleaned +} + + +export class MeasureDuration { + private static Humanizer: Humanizer = [ + [d => d.hours() > 0, d => `${d.hours()}h ${d.minutes()}min`], + [d => d.minutes() > 0, d => `${d.minutes()}min ${d.seconds()}s`], + [d => d.seconds() > 0, d => `${d.seconds()}s`], + [() => true, d => `${d.milliseconds()}ms`], + ] + + private start = Date.now() + + + finished(human?: false): number + finished(human?: true): string + finished(human?: boolean): number | string { + const delta = Date.now() - this.start + + return human + ? new Duration(delta, 'ms').humanize(MeasureDuration.Humanizer) + : delta + } + +}