Skip to content

Commit

Permalink
Merge branch 'feature/improve-code-coverage' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
msudgh committed Jan 2, 2025
2 parents 616ad99 + 6ce73f4 commit 42c0344
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 90 deletions.
13 changes: 6 additions & 7 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,14 +176,13 @@ info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6k
$ ovm r "echo 'Path: {0}'"
info: Run command {"command":"echo 'Path: ~/Documents/obsidian/Career'","vault":{"name":"Career","path":"~/Documents/obsidian/Career"}}

Path: ~/Documents/obsidian/Career

info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6kv1s27b6xjfzvl5k6lqm0000gn/T/ovm-custom-command.json"}
┌─────────┬─────────┬──────────┬───────┐
│ (index) │ success │ duration │ error │
├─────────┼─────────┼──────────┼───────┤
│ Career │ true'10 ms' │ null │
└─────────┴─────────┴──────────┴───────┘

┌─────────┬─────────┬──────────┬───────┬─────────────────────────────────────────┐
│ (index) │ success │ duration │ error │ stdout │
├─────────┼─────────┼──────────┼───────┼─────────────────────────────────────────┤
│ Career │ true'10 ms' │ null │ 'Path: ~/Documents/obsidian/Career'
└─────────┴─────────┴──────────┴───────┴─────────────────────────────────────────┘
```

### Reserved placeholders
Expand Down
3 changes: 2 additions & 1 deletion src/commands/config/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
InitCommandCallback,
InitFlags,
} from '../../types/commands'
import { flagsInterceptor } from '../../utils/command'

/**
* Init command configure an ovm.json config file in user's home dir.
Expand All @@ -31,7 +32,7 @@ export default class Init extends FactoryCommand {
public async run() {
try {
const { args, flags } = await this.parse(Init)
return action(args, this.flagsInterceptor(flags))
return action(args, flagsInterceptor<FactoryFlags<InitFlags>>(flags))
} catch (error) {
this.handleError(error)
} finally {
Expand Down
7 changes: 6 additions & 1 deletion src/commands/plugins/install.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Args, Flags, flush } from '@oclif/core'
import { FactoryCommandWithVaults } from '../../providers/command'
import installService from '../../services/install'
import { FactoryFlagsWithVaults, InstallFlags } from '../../types/commands'
import { flagsInterceptor } from '../../utils/command'

const { action } = installService

Expand Down Expand Up @@ -42,7 +44,10 @@ export default class Install extends FactoryCommandWithVaults {
public async run(): Promise<void> {
try {
const { args, flags } = await this.parse(Install)
return action(args, this.flagsInterceptor(flags))
return action(
args,
flagsInterceptor<FactoryFlagsWithVaults<InstallFlags>>(flags),
)
} catch (error) {
this.handleError(error)
throw error
Expand Down
7 changes: 6 additions & 1 deletion src/commands/plugins/prune.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { flush } from '@oclif/core'
import { FactoryCommandWithVaults } from '../../providers/command'
import pruneService from '../../services/prune'
import { FactoryFlagsWithVaults, PruneFlags } from '../../types/commands'
import { flagsInterceptor } from '../../utils/command'

const { action } = pruneService

Expand All @@ -27,7 +29,10 @@ export default class Prune extends FactoryCommandWithVaults {
public async run() {
try {
const { args, flags } = await this.parse(Prune)
await action(args, this.flagsInterceptor(flags))
await action(
args,
flagsInterceptor<FactoryFlagsWithVaults<PruneFlags>>(flags),
)
} catch (error) {
this.handleError(error)
} finally {
Expand Down
7 changes: 6 additions & 1 deletion src/commands/plugins/uninstall.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Args, flush } from '@oclif/core'
import { FactoryCommandWithVaults } from '../../providers/command'
import uninstallService from '../../services/uninstall'
import { FactoryFlagsWithVaults, UninstallFlags } from '../../types/commands'
import { flagsInterceptor } from '../../utils/command'

const { action } = uninstallService

Expand Down Expand Up @@ -34,7 +36,10 @@ export default class Uninstall extends FactoryCommandWithVaults {
public async run() {
try {
const { args, flags } = await this.parse(Uninstall)
await action(args, this.flagsInterceptor(flags))
await action(
args,
flagsInterceptor<FactoryFlagsWithVaults<UninstallFlags>>(flags),
)
} catch (error) {
this.handleError(error)
} finally {
Expand Down
7 changes: 6 additions & 1 deletion src/commands/reports/stats.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Flags, flush } from '@oclif/core'
import { FactoryCommandWithVaults } from '../../providers/command'
import statsService from '../../services/stats'
import { FactoryFlagsWithVaults, StatsFlags } from '../../types/commands'
import { flagsInterceptor } from '../../utils/command'

const { action } = statsService

Expand Down Expand Up @@ -33,7 +35,10 @@ export default class Stats extends FactoryCommandWithVaults {
public async run(): Promise<void> {
try {
const { args, flags } = await this.parse(Stats)
return await action(args, this.flagsInterceptor(flags))
return await action(
args,
flagsInterceptor<FactoryFlagsWithVaults<StatsFlags>>(flags),
)
} catch (error) {
this.handleError(error)
throw error
Expand Down
17 changes: 11 additions & 6 deletions src/commands/vaults/run.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Args, Flags, flush } from '@oclif/core'
import { FactoryCommandWithVaults } from '../../providers/command'
import runService from '../../services/run'
import { FactoryFlagsWithVaults, RunFlags } from '../../types/commands'
import { flagsInterceptor } from '../../utils/command'

const { action } = runService

Expand All @@ -13,7 +15,7 @@ export default class Run extends FactoryCommandWithVaults {
'<%= config.bin %> <%= command.id %> --path=/path/to/vaults/**/.obsidian --output=json --unescape=false',
'<%= config.bin %> <%= command.id %> --output=json --async=false',
'<%= config.bin %> <%= command.id %> --output=json --silent=true',
'<%= config.bin %> <%= command.id %> --output=json --runFromVaultDirectoryAsWorkDir=false',
'<%= config.bin %> <%= command.id %> --output=json --cwd=/path/to/vaults',
]
static override readonly flags = {
output: Flags.string({
Expand All @@ -38,10 +40,10 @@ export default class Run extends FactoryCommandWithVaults {
description: 'Silent on results of the custom command on vault(s).',
default: false,
}),
runFromVaultDirectoryAsWorkDir: Flags.boolean({
char: 'r',
description: 'Run the command from the vault directory as working dir.',
default: true,
cwd: Flags.string({
char: 'w',
description:
'[default: vault path] Set working directory for custom command.',
}),
...this.commonFlagsWithPath,
}
Expand All @@ -65,7 +67,10 @@ export default class Run extends FactoryCommandWithVaults {
public async run(): Promise<void> {
try {
const { args, flags } = await this.parse(Run)
await action(args, this.flagsInterceptor(flags))
await action(
args,
flagsInterceptor<FactoryFlagsWithVaults<RunFlags>>(flags),
)
} catch (error) {
this.handleError(error)
} finally {
Expand Down
61 changes: 3 additions & 58 deletions src/providers/command.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { Command, Flags } from '@oclif/core'
import { ParserInput } from '@oclif/core/lib/interfaces/parser'
import { exec } from 'child_process'
import { Vault } from 'obsidian-utils'
import { homedir } from 'os'
import path from 'path'
import { FactoryFlags, FactoryFlagsWithVaults } from '../types/commands'
import { handlerCommandError } from '../utils/command'
import {
OVM_CONFIG_FILENAME,
RESERVED_VARIABLES,
VAULTS_PATH_FLAG_DESCRIPTION,
} from '../utils/constants'
import { logger } from '../utils/logger'

const DEFAULT_CONFIG_PATH = path.join(homedir(), OVM_CONFIG_FILENAME)

Expand Down Expand Up @@ -41,33 +38,6 @@ class FactoryCommand extends Command {
throw new Error('Method not implemented.')
}

public enableLoggingTimestamp(timestamp: boolean): void {
process.env.OVM_ENABLE_LOG_TIMESTAMP = timestamp ? '0' : '1'
}

public enableDebugLogLevel(
debug: boolean,
flags: ParserInput['flags'],
): void {
if (debug) {
logger.level = 'debug'
logger.debug(`Command called`, { flags })
}
}

public flagsInterceptor<T>(flags: FactoryFlags<T>): FactoryFlags<T> {
const { debug, timestamp } = flags

this.enableLoggingTimestamp(timestamp)

if (debug) {
logger.level = 'debug'
logger.debug(`Command called`, { flags })
}

return flags
}

public handleError(error: unknown) {
handlerCommandError(error)
}
Expand All @@ -89,31 +59,6 @@ class FactoryCommandWithVaults extends Command {
throw new Error('Method not implemented.')
}

public enableLoggingTimestamp(timestamp: boolean): void {
process.env.OVM_ENABLE_LOG_TIMESTAMP = timestamp ? '0' : '1'
}

public enableDebugLogLevel(
debug: boolean,
flags: ParserInput['flags'],
): void {
if (debug) {
logger.level = 'debug'
logger.debug(`Command called`, { flags })
}
}

public flagsInterceptor<T>(
flags: FactoryFlagsWithVaults<T>,
): FactoryFlagsWithVaults<T> {
const { debug, timestamp } = flags

this.enableLoggingTimestamp(timestamp)
this.enableDebugLogLevel(debug, flags as ParserInput['flags'])

return flags
}

public handleError(error: unknown) {
handlerCommandError(error)
}
Expand All @@ -137,13 +82,13 @@ const commandInterpolation = (vault: Vault, command: string): string => {

const asyncExecCustomCommand = async (
vault: Vault,
command = '',
runFromVaultDirectoryAsWorkDir = true,
command: string,
cwd: string,
): Promise<string> =>
new Promise((resolve, reject) => {
exec(
commandInterpolation(vault, command),
{ cwd: runFromVaultDirectoryAsWorkDir ? vault.path : __dirname },
{ cwd },
(error, stdout, stderr) => {
if (error) {
reject(error)
Expand Down
40 changes: 36 additions & 4 deletions src/services/run.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { expect } from 'chai'
import { tmpdir } from 'os'
import proxyquire from 'proxyquire'
import sinon from 'sinon'
import { RunCommandIterator } from '../types/commands'
Expand Down Expand Up @@ -26,7 +27,6 @@ describe('Command: run', () => {
flags: {
...getTestCommonWithVaultPathFlags(config.path, vault.path),
output: 'json',
runFromVaultDirectoryAsWorkDir: false,
},
args: {
command: '',
Expand All @@ -45,7 +45,6 @@ describe('Command: run', () => {
config,
flags: {
...getTestCommonWithVaultPathFlags(config.path, vault.path),
runFromVaultDirectoryAsWorkDir: false,
},
args: { command: "echo 'Path: {0} {1}'" },
})
Expand All @@ -64,7 +63,6 @@ describe('Command: run', () => {
config,
flags: {
...getTestCommonWithVaultPathFlags(config.path, vault.path),
runFromVaultDirectoryAsWorkDir: false,
},
args: { command: "echo 'Path: {0} {1} {10000}'" },
})
Expand Down Expand Up @@ -94,7 +92,6 @@ describe('Command: run', () => {
config,
flags: {
...getTestCommonWithVaultPathFlags(config.path, vault.path),
runFromVaultDirectoryAsWorkDir: false,
},
args: { command: 'invalid-command' },
})
Expand All @@ -106,4 +103,39 @@ describe('Command: run', () => {

destroyVault(vault.path)
})

it('should not run command from vault directory', async () => {
const { vault, config } = setupVault()
const result = await runCommandVaultIterator({
vault,
config,
flags: {
...getTestCommonWithVaultPathFlags(config.path, vault.path),
cwd: tmpdir(),
},
args: { command: 'echo $PWD' },
})

expect(result.success).to.be.true
expect(result.stdout?.toString().trim()).to.match(new RegExp(tmpdir()))

destroyVault(vault.path)
})

it('should run command from vault directory', async () => {
const { vault, config } = setupVault()
const result = await runCommandVaultIterator({
vault,
config,
flags: {
...getTestCommonWithVaultPathFlags(config.path, vault.path),
},
args: { command: 'echo $PWD' },
})

expect(result.success).to.be.true
expect(result.stdout?.toString().trim()).to.match(new RegExp(vault.path))

destroyVault(vault.path)
})
})
12 changes: 5 additions & 7 deletions src/services/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const runCommandVaultIterator: RunCommandIterator = async (item) => {

internalCustomLogger.debug(`Execute command`)

const vaultPathHash = btoa(vault.path)
const vaultPathHash = btoa(`${vault.name}:${vault.path}`)
taskExecutedOnVaults[vaultPathHash] = {
success: null,
duration: '',
Expand All @@ -46,11 +46,8 @@ const runCommandVaultIterator: RunCommandIterator = async (item) => {

try {
const startDate = new Date()
const result = await asyncExecCustomCommand(
vault,
command,
flags?.runFromVaultDirectoryAsWorkDir,
)
const cwd = flags.cwd ? flags.cwd : vault.path
const result = await asyncExecCustomCommand(vault, command, cwd)
const endDate = new Date()
const durationLessThanSecond = endDate.getTime() - startDate.getTime()
const durationMoreThanSecond = intervalToDuration({
Expand Down Expand Up @@ -134,7 +131,8 @@ const action = async (
result.sortedTaskExecutedOnVaults = Object.entries(taskExecutedOnVaults)
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
.reduce<CommandsExecutedOnVaults>((acc, [key, value]) => {
acc[key] = value
const [vaultName] = atob(key).split(':')
acc[vaultName] = value
return acc
}, {})

Expand Down
2 changes: 1 addition & 1 deletion src/types/commands.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export interface StatsFlags {
export type StatsArgs = Record<string, unknown>

export interface RunFlags {
runFromVaultDirectoryAsWorkDir: boolean
cwd?: string
output?: string
unescape?: boolean
async?: boolean
Expand Down
Loading

0 comments on commit 42c0344

Please sign in to comment.