Compare commits

..

5 Commits
0.10 ... 0.12

Author SHA1 Message Date
cupcakearmy
8fdf5188ff cleaner error handling & version bump 2019-12-22 14:26:27 +01:00
cupcakearmy
22d93f0b9c fix self update in Debian systems 2019-12-22 14:25:52 +01:00
cupcakearmy
f940f23338 tidy up imports 2019-12-22 14:25:22 +01:00
cupcakearmy
678aa96c06 version bump 2019-12-21 23:38:07 +01:00
cupcakearmy
e51eacf13c support for tilde in optional arguments 2019-12-21 23:37:44 +01:00
4 changed files with 46 additions and 24 deletions

View File

@@ -25,20 +25,22 @@ export const { _: commands, ...flags } = minimist(process.argv.slice(2), {
string: ['l', 'b'],
})
export const VERSION = '0.10'
export const VERSION = '0.12'
export const INSTALL_DIR = '/usr/local/bin'
export const VERBOSE = flags.verbose
export const config = init()
function main() {
async function main() {
if (commands.length < 1) return help()
const command: string = commands[0]
const args: string[] = commands.slice(1)
;(handlers[command] || error)(args, flags)
const fn = handlers[command] || error
await fn(args, flags)
}
main()
main().catch((e: Error) => console.error(e.message))

View File

@@ -1,10 +1,12 @@
import { readFileSync, writeFileSync, statSync } from 'fs'
import { resolve } from 'path'
import { homedir } from 'os'
import yaml from 'js-yaml'
import { flags } from './autorestic'
import { Backend, Config } from './types'
import { makeArrayIfIsNot, makeObjectKeysLowercase, rand } from './utils'
import { homedir } from 'os'

View File

@@ -1,9 +1,10 @@
import axios from 'axios'
import { Writer } from 'clitastic'
import { unlinkSync } from 'fs'
import { chmodSync, renameSync, unlinkSync } from 'fs'
import { tmpdir } from 'os'
import { join, resolve } from 'path'
import axios from 'axios'
import { Writer } from 'clitastic'
import { config, INSTALL_DIR, VERSION } from './autorestic'
import { checkAndConfigureBackends, getBackendsFromLocations, getEnvFromBackend } from './backend'
import { backupAll } from './backup'
@@ -147,7 +148,7 @@ const handlers: Handlers = {
checkIfResticIsAvailable()
console.log('Restic is already installed')
return
} catch (e) {
} catch {
}
const w = new Writer('Checking latest version... ⏳')
@@ -164,9 +165,7 @@ const handlers: Handlers = {
}
w.replaceLn('Downloading binary... 🌎')
const name = `${json.name.replace(' ', '_')}_${process.platform}_${
archMap[process.arch]
}.bz2`
const name = `${json.name.replace(' ', '_')}_${process.platform}_${archMap[process.arch]}.bz2`
const dl = json.assets.find((asset: any) => asset.name === name)
if (!dl)
return console.log(
@@ -184,8 +183,8 @@ const handlers: Handlers = {
unlinkSync(tmp)
w.replaceLn(`Moving to ${INSTALL_DIR} 🚙`)
exec('chmod', ['+x', extracted])
exec('mv', [extracted, INSTALL_DIR + '/restic'])
chmodSync(extracted, 0o755)
renameSync(extracted, INSTALL_DIR + '/restic')
w.done(
`\nFinished! restic is installed under: ${INSTALL_DIR}`.underline + ' 🎉',

View File

@@ -1,8 +1,10 @@
import axios from 'axios'
import { spawnSync, SpawnSyncOptions } from 'child_process'
import { randomBytes } from 'crypto'
import { createWriteStream } from 'fs'
import { dirname, isAbsolute, resolve } from 'path'
import { createWriteStream, unlinkSync, renameSync } from 'fs'
import { dirname, isAbsolute, join, resolve } from 'path'
import { homedir, tmpdir } from 'os'
import axios from 'axios'
import { Duration, Humanizer } from 'uhrwerk'
import { CONFIG_FILE } from './config'
@@ -42,13 +44,14 @@ export const execPlain = (command: string, opt: SpawnSyncOptions = {}) => {
export const checkIfResticIsAvailable = () =>
checkIfCommandIsAvailable(
'restic',
'Restic is not installed'.red +
' https://restic.readthedocs.io/en/latest/020_installation.html#stable-releases',
'restic is not installed'.red +
'\nEither run ' + 'autorestic install'.green +
'\nOr go to https://restic.readthedocs.io/en/latest/020_installation.html#stable-releases',
)
export const checkIfCommandIsAvailable = (cmd: string, errorMsg?: string) => {
if (require('child_process').spawnSync(cmd).error)
throw new Error(errorMsg ? errorMsg : `"${errorMsg}" is not installed`.red)
if (spawnSync(cmd).error)
throw new Error(errorMsg ? errorMsg : `"${cmd}" is not installed`.red)
}
export const makeObjectKeysLowercase = (object: Object): any =>
@@ -81,11 +84,19 @@ export const downloadFile = async (url: string, to: string) =>
responseType: 'stream',
})
const stream = createWriteStream(to)
const tmp = join(tmpdir(), rand(64))
const stream = createWriteStream(tmp)
const writer = file.pipe(stream)
writer.on('close', () => {
stream.close()
try {
// Delete file if already exists. Needed if the binary wants to replace itself.
// Unix does not allow to overwrite a file that is being executed, but you can remove it and save other one at its place
unlinkSync(to)
} catch {
}
renameSync(tmp, to)
res()
})
})
@@ -95,6 +106,11 @@ export const pathRelativeToConfigFile = (path: string): string => isAbsolute(pat
? path
: resolve(dirname(CONFIG_FILE), path)
export const resolveTildePath = (path: string): string | null =>
(path.length === 0 || path[0] !== '~')
? null
: join(homedir(), path.slice(1))
export const ConfigError = new Error('Config file not found')
export const getFlagsFromLocation = (location: Location, command?: string): string[] => {
@@ -108,8 +124,11 @@ export const getFlagsFromLocation = (location: Location, command?: string): stri
let flags: string[] = []
// Map the flags to an array for the exec function.
for (let [flag, values] of Object.entries(all))
for (const value of makeArrayIfIsNot(values))
flags = [...flags, `--${String(flag)}`, String(value)]
for (const value of makeArrayIfIsNot(values)) {
const stringValue = String(value)
const resolvedTilde = resolveTildePath(stringValue)
flags = [...flags, `--${String(flag)}`, resolvedTilde === null ? stringValue : resolvedTilde]
}
return flags
}