Skip to content

Commit

Permalink
Merge branch 'release/0.4.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
msudgh committed Aug 9, 2024
2 parents 7570a51 + afe398d commit b9cbadb
Show file tree
Hide file tree
Showing 9 changed files with 86 additions and 60 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ Example config file for following [Commands](#commands) section is as follows:
> The content used in the examples below is for illustrative purposes only. e.g. In the output sections, the vaults are stored in `~/Documents/` directory. The actual output may vary.
### `ovm config init`

Aliases: `ovm ci`

Configure an ovm.json config file in user's home directory.
Expand All @@ -110,6 +111,7 @@ $ cat ~/ovm.json
```

### `ovm plugins install`

Aliases: `ovm pi`

Install plugin(s) in specified vaults.
Expand Down Expand Up @@ -137,6 +139,7 @@ info: Installed 3 plugins {"vault":{"name":"Goals","path":"~/Documents/obsidian/
```

### `ovm plugins prune`

Aliases: `ovm pp`

Prune existing plugin(s) from vaults that are unspecified in the config file.
Expand All @@ -154,6 +157,7 @@ info: Pruned 1 plugins {"vault":{"name":"Test","path":"~/Documents/obsidian/Test
```

### `ovm plugins uninstall`

Aliases: `ovm pu`

Uninstall plugin(s) from vaults.
Expand Down Expand Up @@ -182,6 +186,7 @@ info: Uninstalled 3 plugins {"vault":{"name":"Goals","path":"~/Documents/obsidia
```

### `ovm reports stats`

Aliases: `ovm rs`

Statistics of vaults and installed plugins.
Expand Down Expand Up @@ -210,6 +215,7 @@ $ ovm reports stats
```

### `ovm vaults run`

Aliases: `ovm vr` / `ovm r` / `ovm run`

Run a shell command on selected vaults (using Node.js child_process).
Expand Down Expand Up @@ -261,6 +267,7 @@ info: Run operation finished! {"custom_commands_log_path":"/var/folders/_v/j4w6k
A custom command can be executed on vault(s) by using reserved placeholders as string value within the shell command. The placeholders are replaced with the actual values during the execution.

List of placeholders:

- `{0}`: Vault path
- `{1}`: Vault name

Expand Down
13 changes: 11 additions & 2 deletions eslint.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,24 @@ const tsEslint = require('typescript-eslint')
const rulesConfig = [
{
rules: {
'no-unused-vars': 'warn',
'no-unused-vars': [
'error',
{
'vars': 'all',
'args': 'after-used',
'ignoreRestSiblings': true,
'varsIgnorePattern': '^_', // Ignore variables that start with _
'argsIgnorePattern': '^_' // Ignore arguments that start with _
}
],
'no-undef': 'warn',
'prefer-arrow-callback': ['error', {allowNamedFunctions: false}],
'func-style': ['error', 'expression', {allowArrowFunctions: true}],
},
},
]

const ignoresConfig = [{ignores: ['dist', 'bin']}]
const ignoresConfig = [{ignores: ['dist', 'bin', 'eslint.config.cjs']}]

module.exports = [
{files: ['**/*.{ts}', '**/*.test.ts', '**/*.spec.ts']},
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "ovm",
"description": "Obsidian Vaults Manager",
"type": "commonjs",
"version": "0.4.0",
"version": "0.4.1",
"license": "MIT",
"author": "Masoud Ghorbani",
"homepage": "https://github.com/msudgh/ovm",
Expand Down
9 changes: 9 additions & 0 deletions src/commands.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,12 @@ export interface UninstallPluginVaultOpts {
vault: Vault
config: Config
}

export type CommandsExecutedOnVaults = Record<
string,
{
success: null | boolean
duration: string
error: null | Error | string
}
>
3 changes: 2 additions & 1 deletion src/commands/plugins/install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,10 +161,11 @@ export default class Install extends FactoryCommand {
}
}

installedPlugins.length &&
if (installedPlugins.length) {
logger.info(`Installed ${installedPlugins.length} plugins`, {
vault,
})
}

return { installedPlugins, failedPlugins }
}
Expand Down
3 changes: 2 additions & 1 deletion src/commands/plugins/uninstall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,11 @@ export default class Uninstall extends FactoryCommand {
}
}

uninstalledPlugins.length &&
if (uninstalledPlugins.length) {
logger.info(`Uninstalled ${uninstalledPlugins.length} plugins`, {
vault,
})
}

return { uninstalledPlugins, failedPlugins }
}
Expand Down
103 changes: 51 additions & 52 deletions src/commands/vaults/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { each, eachSeries, ErrorCallback } from 'async'
import { exec, ExecException } from 'child_process'
import { formatDuration, intervalToDuration } from 'date-fns'
import { Vault } from 'obsidian-utils'
import { CommandsExecutedOnVaults } from '../../commands'
import FactoryCommand, { FactoryFlags } from '../../providers/command'
import { safeLoadConfig } from '../../providers/config'
import { vaultsSelector } from '../../providers/vaults'
Expand Down Expand Up @@ -128,12 +129,12 @@ export default class Run extends FactoryCommand {

const vaults = await this.loadVaults(path)
const selectedVaults = await vaultsSelector(vaults)
const vaultsWithCommand = selectedVaults.map((vault: any) => ({
const vaultsWithCommand = selectedVaults.map((vault: Vault) => ({
vault,
command: this.commandInterpolation(vault, command),
}))

const taskExecutedOnVaults: Record<string, any> = {}
const taskExecutedOnVaults: CommandsExecutedOnVaults = {}

const commandVaultIterator = async (opts: {
vault: Vault
Expand All @@ -142,54 +143,56 @@ export default class Run extends FactoryCommand {
const { vault, command } = opts
logger.debug(`Execute command`, { vault, command })

const startDate = new Date()
const { error, result } = await this.asyncExecCustomCommand(
command,
flags.runFromVaultDirectoryAsWorkDir,
vault,
)
const endDate = new Date()
const durationLessThanSecond = endDate.getTime() - startDate.getTime()
const durationMoreThanSecond = intervalToDuration({
start: startDate,
end: endDate,
})
try {
const startDate = new Date()
const result = await this.asyncExecCustomCommand(
command,
flags.runFromVaultDirectoryAsWorkDir,
vault,
)
const endDate = new Date()
const durationLessThanSecond = endDate.getTime() - startDate.getTime()
const durationMoreThanSecond = intervalToDuration({
start: startDate,
end: endDate,
})

const formattedDuration =
formatDuration(durationMoreThanSecond, {
format: ['hours', 'minutes', 'seconds'],
}) || `${durationLessThanSecond} ms`
const formattedDuration =
formatDuration(durationMoreThanSecond, {
format: ['hours', 'minutes', 'seconds'],
}) || `${durationLessThanSecond} ms`

taskExecutedOnVaults[vault.name] = {
success: null,
duration: formattedDuration,
error: null,
}
taskExecutedOnVaults[vault.name] = {
success: null,
duration: formattedDuration,
error: null,
}

if (error) {
if (result) {
taskExecutedOnVaults[vault.name]['success'] = true
customCommandLogger.info('Executed successfully', {
result,
vault,
command,
})
if (!flags.silent) {
logger.info(`Run command`, { vault, command })
console.log(result)
}
}
} catch (error) {
taskExecutedOnVaults[vault.name]['error'] = JSON.stringify(error)
customCommandLogger.error('Execution failed', {
error: JSON.stringify(error),
vault,
command,
})
}

if (result) {
taskExecutedOnVaults[vault.name]['success'] = true
customCommandLogger.info('Executed successfully', {
result,
vault,
command,
})
if (!flags.silent) {
logger.info(`Run command`, { vault, command })
console.log(result)
}
}
}

const commandVaultErrorCallback: ErrorCallback<Error> = (error: any) => {
const commandVaultErrorCallback: ErrorCallback<Error> = (
error: Error | null | undefined,
) => {
if (error) {
logger.debug('UnhandledException', {
error: JSON.stringify(error),
Expand All @@ -200,13 +203,10 @@ export default class Run extends FactoryCommand {
} else {
const sortedTaskExecutedOnVaults = Object.entries(taskExecutedOnVaults)
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
.reduce(
(acc, [key, value]) => {
acc[key] = value
return acc
},
{} as Record<string, boolean>,
)
.reduce((acc, [key, value]) => {
acc[key] = value
return acc
}, {} as CommandsExecutedOnVaults)

logger.info('Run operation finished!', {
custom_commands_log_path: CUSTOM_COMMAND_LOGGER_FILE,
Expand Down Expand Up @@ -238,17 +238,16 @@ export default class Run extends FactoryCommand {
command: string,
runFromVaultDirectoryAsWorkDir: boolean,
vault: Vault,
): Promise<
Pick<ExecuteCustomCommandResult, 'error'> & {
result: string
}
> {
): Promise<Pick<ExecuteCustomCommandResult, 'error'> | string> {
return new Promise((resolve, reject) => {
exec(
command,
{ cwd: runFromVaultDirectoryAsWorkDir ? vault.path : __dirname },
(error: any, stdout: any, stderr: any) => {
resolve({ result: `${stderr}\n${stdout}`, error })
(error, stdout, stderr) => {
if (error) {
return reject(error)
}
resolve(`${stderr}\n${stdout}`)
},
)
})
Expand Down
4 changes: 2 additions & 2 deletions src/providers/config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ describe('Config', () => {

const config = await safeLoadConfig(configPath)

expect(config.success).to.be.true
expect(config.error).to.be.undefined
expect(config.success).to.be.true.equal(true)
expect(config.error).to.be.undefined.equal(undefined)
expect(config.data).to.deep.equal(sampleDefaultConfig)
mock.restore()
})
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts → src/types.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Vault } from 'obsidian-utils'

type CommandOnVault = (vault: Vault, ...args: string[]) => string
export type CommandOnVault = (_vault: Vault, ..._args: string[]) => string
export type ReservedVariables = {
[key: string]: CommandOnVault
}

0 comments on commit b9cbadb

Please sign in to comment.