mirror of
https://github.com/cupcakearmy/autorestic.git
synced 2025-01-22 14:56:24 +00:00
check config in the beginning to avoid doing it all over the place
This commit is contained in:
parent
db436587ee
commit
abeaacf182
@ -3,6 +3,7 @@ import minimist from 'minimist'
|
|||||||
|
|
||||||
import { init } from './config'
|
import { init } from './config'
|
||||||
import handlers, { error, help } from './handlers'
|
import handlers, { error, help } from './handlers'
|
||||||
|
import { Config } from './types'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -25,14 +26,19 @@ export const { _: commands, ...flags } = minimist(process.argv.slice(2), {
|
|||||||
string: ['l', 'b'],
|
string: ['l', 'b'],
|
||||||
})
|
})
|
||||||
|
|
||||||
export const VERSION = '0.16'
|
export const VERSION = '0.17'
|
||||||
export const INSTALL_DIR = '/usr/local/bin'
|
export const INSTALL_DIR = '/usr/local/bin'
|
||||||
export const VERBOSE = flags.verbose
|
export const VERBOSE = flags.verbose
|
||||||
|
|
||||||
export const config = init()
|
export let config: Config
|
||||||
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
config = await init()
|
||||||
|
|
||||||
|
// For dev
|
||||||
|
// return await handlers['check']([], { ...flags, all: true })
|
||||||
|
|
||||||
if (commands.length < 1 || commands[0] === 'help') return help()
|
if (commands.length < 1 || commands[0] === 'help') return help()
|
||||||
|
|
||||||
const command: string = commands[0]
|
const command: string = commands[0]
|
||||||
|
@ -2,7 +2,7 @@ import { Writer } from 'clitastic'
|
|||||||
|
|
||||||
import { config, VERBOSE } from './autorestic'
|
import { config, VERBOSE } from './autorestic'
|
||||||
import { Backend, Backends, Locations } from './types'
|
import { Backend, Backends, Locations } from './types'
|
||||||
import { exec, ConfigError, pathRelativeToConfigFile } from './utils'
|
import { exec, pathRelativeToConfigFile } from './utils'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -60,10 +60,8 @@ export const checkAndConfigureBackend = (name: string, backend: Backend) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const checkAndConfigureBackends = (backends?: Backends) => {
|
export const checkAndConfigureBackends = (backends?: Backends) => {
|
||||||
if (!backends) {
|
if (!backends)
|
||||||
if (!config) throw ConfigError
|
|
||||||
backends = config.backends
|
backends = config.backends
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\nConfiguring Backends'.grey.underline)
|
console.log('\nConfiguring Backends'.grey.underline)
|
||||||
for (const [name, backend] of Object.entries(backends))
|
for (const [name, backend] of Object.entries(backends))
|
||||||
|
@ -7,7 +7,6 @@ import { LocationFromPrefixes } from './config'
|
|||||||
import { Locations, Location, Backend } from './types'
|
import { Locations, Location, Backend } from './types'
|
||||||
import {
|
import {
|
||||||
exec,
|
exec,
|
||||||
ConfigError,
|
|
||||||
pathRelativeToConfigFile,
|
pathRelativeToConfigFile,
|
||||||
getFlagsFromLocation,
|
getFlagsFromLocation,
|
||||||
makeArrayIfIsNot,
|
makeArrayIfIsNot,
|
||||||
@ -54,7 +53,6 @@ export const backupFromVolume = (volume: string, location: Location, backend: Ba
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const backupSingle = (name: string, to: string, location: Location) => {
|
export const backupSingle = (name: string, to: string, location: Location) => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
const delta = new MeasureDuration()
|
const delta = new MeasureDuration()
|
||||||
const writer = new Writer(name + to.blue + ' : ' + 'Backing up... ⏳')
|
const writer = new Writer(name + to.blue + ' : ' + 'Backing up... ⏳')
|
||||||
|
|
||||||
@ -104,10 +102,8 @@ export const backupLocation = (name: string, location: Location) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const backupAll = (locations?: Locations) => {
|
export const backupAll = (locations?: Locations) => {
|
||||||
if (!locations) {
|
if (!locations)
|
||||||
if (!config) throw ConfigError
|
|
||||||
locations = config.locations
|
locations = config.locations
|
||||||
}
|
|
||||||
|
|
||||||
console.log('\nBacking Up'.underline.grey)
|
console.log('\nBacking Up'.underline.grey)
|
||||||
for (const [name, location] of Object.entries(locations))
|
for (const [name, location] of Object.entries(locations))
|
||||||
|
@ -39,16 +39,16 @@ export const normalizeAndCheckBackends = (config: Config) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const normalizeAndCheckBackups = (config: Config) => {
|
export const normalizeAndCheckLocations = async (config: Config) => {
|
||||||
config.locations = makeObjectKeysLowercase(config.locations)
|
config.locations = makeObjectKeysLowercase(config.locations)
|
||||||
const backends = Object.keys(config.backends)
|
const backends = Object.keys(config.backends)
|
||||||
|
|
||||||
const checkDestination = (backend: string, backup: string) => {
|
const checkDestination = (backend: string, location: string) => {
|
||||||
if (!backends.includes(backend))
|
if (!backends.includes(backend))
|
||||||
throw new Error(`Cannot find the backend "${backend}" for "${backup}"`)
|
throw new Error(`Cannot find the backend "${backend}" for "${location}"`)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const [name, { from, to, ...rest }] of Object.entries(
|
for (const [name, { from, to, cron, ...rest }] of Object.entries(
|
||||||
config.locations,
|
config.locations,
|
||||||
)) {
|
)) {
|
||||||
if (!from || !to)
|
if (!from || !to)
|
||||||
@ -61,7 +61,7 @@ export const normalizeAndCheckBackups = (config: Config) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const findConfigFile = (): string | undefined => {
|
const findConfigFile = (): string => {
|
||||||
const config = '.autorestic.yml'
|
const config = '.autorestic.yml'
|
||||||
const paths = [
|
const paths = [
|
||||||
resolve(flags.config || ''),
|
resolve(flags.config || ''),
|
||||||
@ -75,14 +75,14 @@ const findConfigFile = (): string | undefined => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
throw new Error('Config file not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
export let CONFIG_FILE: string = ''
|
export let CONFIG_FILE: string = ''
|
||||||
|
|
||||||
export const init = (): Config | undefined => {
|
export const init = async (): Promise<Config> => {
|
||||||
const file = findConfigFile()
|
const file = findConfigFile()
|
||||||
if (file) CONFIG_FILE = file
|
CONFIG_FILE = file
|
||||||
else return
|
|
||||||
|
|
||||||
const raw: Config = makeObjectKeysLowercase(
|
const raw: Config = makeObjectKeysLowercase(
|
||||||
yaml.safeLoad(readFileSync(CONFIG_FILE).toString()),
|
yaml.safeLoad(readFileSync(CONFIG_FILE).toString()),
|
||||||
@ -91,7 +91,7 @@ export const init = (): Config | undefined => {
|
|||||||
const current = JSON.stringify(raw)
|
const current = JSON.stringify(raw)
|
||||||
|
|
||||||
normalizeAndCheckBackends(raw)
|
normalizeAndCheckBackends(raw)
|
||||||
normalizeAndCheckBackups(raw)
|
await normalizeAndCheckLocations(raw)
|
||||||
|
|
||||||
const changed = JSON.stringify(raw) !== current
|
const changed = JSON.stringify(raw) !== current
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import { LocationFromPrefixes } from './config'
|
|||||||
import { Locations, Location, Flags } from './types'
|
import { Locations, Location, Flags } from './types'
|
||||||
import {
|
import {
|
||||||
exec,
|
exec,
|
||||||
ConfigError,
|
|
||||||
pathRelativeToConfigFile,
|
pathRelativeToConfigFile,
|
||||||
getFlagsFromLocation,
|
getFlagsFromLocation,
|
||||||
makeArrayIfIsNot,
|
makeArrayIfIsNot,
|
||||||
@ -16,7 +15,6 @@ import {
|
|||||||
|
|
||||||
|
|
||||||
export const forgetSingle = (name: string, to: string, location: Location, dryRun: boolean) => {
|
export const forgetSingle = (name: string, to: string, location: Location, dryRun: boolean) => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
const base = name + to.blue + ' : '
|
const base = name + to.blue + ' : '
|
||||||
const writer = new Writer(base + 'Removing old snapshots… ⏳')
|
const writer = new Writer(base + 'Removing old snapshots… ⏳')
|
||||||
|
|
||||||
@ -64,7 +62,6 @@ export const forgetLocation = (name: string, backup: Location, dryRun: boolean)
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const forgetAll = (backups?: Locations, flags?: Flags) => {
|
export const forgetAll = (backups?: Locations, flags?: Flags) => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
if (!backups) {
|
if (!backups) {
|
||||||
backups = config.locations
|
backups = config.locations
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ import {
|
|||||||
downloadFile,
|
downloadFile,
|
||||||
exec,
|
exec,
|
||||||
filterObjectByKey,
|
filterObjectByKey,
|
||||||
ConfigError, makeArrayIfIsNot,
|
makeArrayIfIsNot,
|
||||||
} from './utils'
|
} from './utils'
|
||||||
|
|
||||||
|
|
||||||
@ -28,7 +28,6 @@ export type Handlers = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const parseBackend = (flags: Flags): Backends => {
|
const parseBackend = (flags: Flags): Backends => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
if (!flags.all && !flags.backend)
|
if (!flags.all && !flags.backend)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'No backends specified.'.red +
|
'No backends specified.'.red +
|
||||||
@ -46,7 +45,6 @@ const parseBackend = (flags: Flags): Backends => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const parseLocations = (flags: Flags): Locations => {
|
const parseLocations = (flags: Flags): Locations => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
if (!flags.all && !flags.location)
|
if (!flags.all && !flags.location)
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'No locations specified.'.red +
|
'No locations specified.'.red +
|
||||||
@ -72,7 +70,6 @@ const handlers: Handlers = {
|
|||||||
checkAndConfigureBackends(backends)
|
checkAndConfigureBackends(backends)
|
||||||
},
|
},
|
||||||
backup(args, flags) {
|
backup(args, flags) {
|
||||||
if (!config) throw ConfigError
|
|
||||||
checkIfResticIsAvailable()
|
checkIfResticIsAvailable()
|
||||||
const locations: Locations = parseLocations(flags)
|
const locations: Locations = parseLocations(flags)
|
||||||
|
|
||||||
@ -84,7 +81,6 @@ const handlers: Handlers = {
|
|||||||
console.log('\nFinished!'.underline + ' 🎉')
|
console.log('\nFinished!'.underline + ' 🎉')
|
||||||
},
|
},
|
||||||
restore(args, flags) {
|
restore(args, flags) {
|
||||||
if (!config) throw ConfigError
|
|
||||||
checkIfResticIsAvailable()
|
checkIfResticIsAvailable()
|
||||||
|
|
||||||
const locations = parseLocations(flags)
|
const locations = parseLocations(flags)
|
||||||
@ -95,7 +91,6 @@ const handlers: Handlers = {
|
|||||||
restoreSingle(keys[0], flags.from, flags.to)
|
restoreSingle(keys[0], flags.from, flags.to)
|
||||||
},
|
},
|
||||||
forget(args, flags) {
|
forget(args, flags) {
|
||||||
if (!config) throw ConfigError
|
|
||||||
checkIfResticIsAvailable()
|
checkIfResticIsAvailable()
|
||||||
const locations: Locations = parseLocations(flags)
|
const locations: Locations = parseLocations(flags)
|
||||||
|
|
||||||
|
@ -1,11 +1,9 @@
|
|||||||
import { config } from './autorestic'
|
import { config } from './autorestic'
|
||||||
import { ConfigError, fill, treeToString } from './utils'
|
import { fill, treeToString } from './utils'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const showAll = () => {
|
const showAll = () => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
|
|
||||||
console.log('\n\n' + fill(32, '_') + 'LOCATIONS:'.underline)
|
console.log('\n\n' + fill(32, '_') + 'LOCATIONS:'.underline)
|
||||||
for (const [key, data] of Object.entries(config.locations)) {
|
for (const [key, data] of Object.entries(config.locations)) {
|
||||||
console.log(`\n${key.blue.underline}:`)
|
console.log(`\n${key.blue.underline}:`)
|
||||||
|
@ -7,7 +7,6 @@ import { LocationFromPrefixes } from './config'
|
|||||||
import { Backend } from './types'
|
import { Backend } from './types'
|
||||||
import {
|
import {
|
||||||
checkIfDockerVolumeExistsOrFail,
|
checkIfDockerVolumeExistsOrFail,
|
||||||
ConfigError,
|
|
||||||
decodeLocationFromPrefix,
|
decodeLocationFromPrefix,
|
||||||
exec,
|
exec,
|
||||||
execPlain,
|
execPlain,
|
||||||
@ -43,8 +42,6 @@ export const restoreToVolume = (volume: string, backend: Backend) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const restoreSingle = (locationName: string, from: string, to?: string) => {
|
export const restoreSingle = (locationName: string, from: string, to?: string) => {
|
||||||
if (!config) throw ConfigError
|
|
||||||
|
|
||||||
const location = config.locations[locationName]
|
const location = config.locations[locationName]
|
||||||
|
|
||||||
const baseText = locationName.green + '\t\t'
|
const baseText = locationName.green + '\t\t'
|
||||||
|
@ -71,6 +71,7 @@ export type Backends = { [name: string]: Backend }
|
|||||||
export type Location = {
|
export type Location = {
|
||||||
from: string
|
from: string
|
||||||
to: StringOrArray
|
to: StringOrArray
|
||||||
|
cron?: string
|
||||||
hooks?: {
|
hooks?: {
|
||||||
before?: StringOrArray
|
before?: StringOrArray
|
||||||
after?: StringOrArray
|
after?: StringOrArray
|
||||||
|
@ -103,8 +103,6 @@ export const resolveTildePath = (path: string): string | null =>
|
|||||||
? null
|
? null
|
||||||
: join(homedir(), path.slice(1))
|
: join(homedir(), path.slice(1))
|
||||||
|
|
||||||
export const ConfigError = new Error('Config file not found')
|
|
||||||
|
|
||||||
export const getFlagsFromLocation = (location: Location, command?: string): string[] => {
|
export const getFlagsFromLocation = (location: Location, command?: string): string[] => {
|
||||||
if (!location.options) return []
|
if (!location.options) return []
|
||||||
|
|
||||||
@ -197,4 +195,3 @@ export const checkIfDockerVolumeExistsOrFail = (volume: string) => {
|
|||||||
if (cmd.err.length > 0)
|
if (cmd.err.length > 0)
|
||||||
throw new Error('Volume not found')
|
throw new Error('Volume not found')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user