Skip to content

Commit

Permalink
fix: respect config file when no explicit cli flags (#88)
Browse files Browse the repository at this point in the history
  • Loading branch information
hyoban committed Nov 27, 2023
1 parent 0402966 commit 27f3c2b
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 43 deletions.
41 changes: 15 additions & 26 deletions src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,32 +6,30 @@ import c from 'picocolors'
import { version } from '../package.json'
import { check } from './commands/check'
import { usage } from './commands/usage'
import { resolveConfig } from './config'
import { LOG_LEVELS, MODE_CHOICES } from './constants'
import type { CommonOptions } from './types'
import { LOGLEVELS, resolveConfig } from './config'
import type { SortOption } from './utils/sort'
import { SORT_CHOICES } from './utils/sort'
import { checkGlobal } from './commands/check/checkGlobal'

function commonOptions(args: Argv<object>): Argv<CommonOptions> {
return args
.option('cwd', {
alias: 'C',
default: '',
type: 'string',
describe: 'specify the current working directory',
})
.option('loglevel', {
default: 'info',
type: 'string',
describe: 'log level',
choices: LOGLEVELS,
choices: LOG_LEVELS,
})
.option('failOnOutdated', {
type: 'boolean',
describe: 'exit with code 1 if outdated dependencies are found',
})
.option('silent', {
alias: 's',
default: false,
type: 'boolean',
describe: 'complete silent',
})
Expand All @@ -45,12 +43,6 @@ function commonOptions(args: Argv<object>): Argv<CommonOptions> {
type: 'boolean',
describe: 'force fetching from server, bypass cache',
})
.option('sort', {
type: 'string',
default: 'diff-asc' as SortOption,
choices: ['time-asc', 'time-desc', 'diff-asc', 'diff-desc', 'name-asc', 'name-desc', 'time', 'diff', 'name'],
describe: 'sort by most outdated absolute or relative to dependency',
})
.option('ignore-paths', {
type: 'string',
describe: 'ignore paths for search package.json',
Expand All @@ -77,11 +69,6 @@ function commonOptions(args: Argv<object>): Argv<CommonOptions> {
describe: 'update only for dependencies',
conflicts: ['dev'],
})
.option('include-locked', {
alias: 'l',
type: 'boolean',
describe: 'include locked dependencies & devDependencies',
})
}

// eslint-disable-next-line no-unused-expressions
Expand All @@ -96,7 +83,6 @@ yargs(hideBin(process.argv))
.option('detail', {
alias: 'a',
type: 'boolean',
default: false,
describe: 'show more info',
})
.help()
Expand All @@ -110,47 +96,50 @@ yargs(hideBin(process.argv))
(args) => {
return commonOptions(args)
.positional('mode', {
default: 'default',
type: 'string',
describe: 'the mode how version range resolves, can be "default", "major", "minor", "latest" or "newest"',
choices: ['default', 'major', 'minor', 'patch', 'latest', 'newest'],
choices: MODE_CHOICES,
})
.option('write', {
alias: 'w',
default: false,
type: 'boolean',
describe: 'write to package.json',
})
.option('global', {
alias: 'g',
default: false,
type: 'boolean',
describe: 'update global packages',
})
.option('interactive', {
alias: 'I',
default: false, // TODO: enable by default: !process.env.CI && process.stdout.isTTY,
type: 'boolean',
describe: 'interactive mode',
})
.option('install', {
alias: 'i',
default: false,
type: 'boolean',
describe: 'install directly after bumping',
})
.option('update', {
alias: 'u',
default: false,
type: 'boolean',
describe: 'update directly after bumping',
})
.option('all', {
alias: 'a',
default: false,
type: 'boolean',
describe: 'show all packages up to date info',
})
.option('sort', {
type: 'string',
choices: SORT_CHOICES,
describe: 'sort by most outdated absolute or relative to dependency',
})
.option('includeLocked', {
alias: 'l',
type: 'boolean',
describe: 'include locked dependencies & devDependencies',
})
.help()
},
async (args) => {
Expand Down
12 changes: 7 additions & 5 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import _debug from 'debug'
import { createConfigLoader } from 'unconfig'
import type { CommonOptions } from './types'
import { toArray } from './utils/toArray'
import { DEFAULT_CHECK_OPTIONS, DEFAULT_USAGE_OPTIONS } from './constants'

const debug = _debug('taze:config')

export const LOGLEVELS = ['debug', 'info', 'warn', 'error', 'silent']

function normalizeConfig<T extends CommonOptions>(options: T) {
options.ignorePaths = toArray(options.ignorePaths)
options.exclude = toArray(options.exclude)
Expand All @@ -20,7 +19,10 @@ function normalizeConfig<T extends CommonOptions>(options: T) {
return options
}

export async function resolveConfig<T extends CommonOptions>(options: T): Promise<T> {
export async function resolveConfig<T extends CommonOptions>(
options: T & { _?: (string | number)[] },
): Promise<T> {
const defaults = options?._?.[0] === 'usage' ? DEFAULT_USAGE_OPTIONS : DEFAULT_CHECK_OPTIONS
options = normalizeConfig(options)

const loader = createConfigLoader<CommonOptions>({
Expand All @@ -44,10 +46,10 @@ export async function resolveConfig<T extends CommonOptions>(options: T): Promis
const config = await loader.load()

if (!config.sources.length)
return options
return deepmerge(defaults, options as T) as T

debug(`config file found ${config.sources[0]}`)
const configOptions = normalizeConfig(config.config)

return deepmerge(configOptions, options) as T
return deepmerge(deepmerge(defaults, configOptions), options as T) as T
}
39 changes: 39 additions & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { CheckOptions, CommonOptions, UsageOptions } from './types'

export const LOG_LEVELS = ['debug', 'info', 'warn', 'error', 'silent'] as const

export const MODE_CHOICES = ['default', 'major', 'minor', 'patch', 'latest', 'newest'] as const

export const DEFAULT_COMMON_OPTIONS: CommonOptions = {
cwd: '',
loglevel: 'info',
failOnOutdated: false,
silent: false,
recursive: false,
force: false,
ignorePaths: '',
include: '',
exclude: '',
dev: false,
prod: false,
}

export const DEFAULT_USAGE_OPTIONS: UsageOptions = {
...DEFAULT_COMMON_OPTIONS,
detail: false,
recursive: true,
}

export const DEFAULT_CHECK_OPTIONS: CheckOptions = {
...DEFAULT_COMMON_OPTIONS,
mode: 'default',
write: false,
global: false,
// TODO: enable by default: !process.env.CI && process.stdout.isTTY,
interactive: false,
install: false,
update: false,
all: false,
sort: 'diff-asc',
includeLocked: false,
}
2 changes: 1 addition & 1 deletion src/io/packages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export async function writePackage(pkg: PackageMeta, options: CommonOptions) {
}

export async function loadPackage(relative: string, options: CommonOptions, shouldUpdate: (name: string) => boolean): Promise<PackageMeta> {
const filepath = path.resolve(options.cwd, relative)
const filepath = path.resolve(options.cwd ?? '', relative)
const raw = await readJSON(filepath)
let deps: RawDep[] = []

Expand Down
9 changes: 5 additions & 4 deletions src/log.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import process from 'node:process'
import c from 'picocolors'
import { MultiBar, Presets } from 'cli-progress'
import { LOGLEVELS } from './config'
import { LOG_LEVELS } from './constants'
import { visualLength, visualPadEnd, visualPadStart } from './render'
import type { LogLevel } from './types'

interface Options {
columns: number
pending: number
align: string
loglevel: string
loglevel: LogLevel
}

export function shouldLog(level: string, messageLevel: string) {
return LOGLEVELS.indexOf(level) <= LOGLEVELS.indexOf(messageLevel)
export function shouldLog(level: LogLevel, messageLevel: LogLevel) {
return LOG_LEVELS.indexOf(level) <= LOG_LEVELS.indexOf(messageLevel)
}

export class TableLogger {
Expand Down
16 changes: 9 additions & 7 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,30 +41,32 @@ export interface ResolvedDepChange extends RawDep {
aliasName?: string
}

export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'silent'

export interface CommonOptions {
cwd: string
cwd?: string
recursive?: boolean
ignorePaths?: string | string[]
include?: string | string[]
exclude?: string | string[]
prod?: boolean
dev?: boolean
loglevel?: string
loglevel?: LogLevel
failOnOutdated?: boolean
silent?: boolean
force?: boolean
packageMode?: { [name: string]: PackageMode }
}

export interface UsageOptions extends CommonOptions {
detail: boolean
recursive: true
detail?: boolean
recursive?: true
}

export interface CheckOptions extends CommonOptions {
mode: string
write: boolean
all: boolean
mode?: RangeMode
write?: boolean
all?: boolean
sort?: SortOption
interactive?: boolean
install?: boolean
Expand Down
8 changes: 8 additions & 0 deletions src/utils/sort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ export type SortKey = 'time' | 'diff' | 'name'
export type SortOrder = 'asc' | 'desc'

export type SortOption = `${SortKey}-${SortOrder}`
export const SORT_CHOICES = [
'time-asc',
'time-desc',
'diff-asc',
'diff-desc',
'name-asc',
'name-desc',
] as const

export function parseSortOption(option: SortOption) {
return option.split('-') as [SortKey, SortOrder]
Expand Down

0 comments on commit 27f3c2b

Please sign in to comment.