Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: fix value parser policy #53

Merged
merged 12 commits into from
Jul 23, 2024
5 changes: 5 additions & 0 deletions .changeset/cuddly-kiwis-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': patch
---

Fix context args annotations to `Record<string, any>`
5 changes: 5 additions & 0 deletions .changeset/cyan-goats-pretend.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': minor
---

Refactor arguments parsing policy and support global options
5 changes: 5 additions & 0 deletions .changeset/eleven-deers-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': patch
---

Refactor merge arguments matches policy
5 changes: 5 additions & 0 deletions .changeset/eleven-points-carry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': patch
---

Remove `{ length: 1}` annotation
5 changes: 5 additions & 0 deletions .changeset/three-hounds-live.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': patch
---

Refactor `Vec<String>` to `Vec<&str>`
5 changes: 5 additions & 0 deletions .changeset/witty-islands-compete.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'archons': patch
---

Improve parser resolver and determine default parser by action
12 changes: 12 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ jobs:
with:
name: bindings-${{ matrix.settings.target }}
path: .
- name: Build Examples
run: yarn build:examples
- name: List packages
run: ls -R .
shell: bash
Expand Down Expand Up @@ -240,6 +242,8 @@ jobs:
with:
name: bindings-x86_64-unknown-linux-gnu
path: .
- name: Build Examples
run: yarn build:examples
- name: List packages
run: ls -R .
shell: bash
Expand Down Expand Up @@ -272,6 +276,8 @@ jobs:
with:
name: bindings-x86_64-unknown-linux-musl
path: .
- name: Build Examples
run: yarn build:examples
- name: List packages
run: ls -R .
shell: bash
Expand Down Expand Up @@ -303,6 +309,8 @@ jobs:
yarn config set supportedArchitectures.cpu "arm64"
yarn config set supportedArchitectures.libc "glibc"
yarn install
- name: Build Examples
run: yarn build:examples
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
Expand Down Expand Up @@ -337,6 +345,8 @@ jobs:
yarn config set supportedArchitectures.cpu "arm64"
yarn config set supportedArchitectures.libc "musl"
yarn install
- name: Build Examples
run: yarn build:examples
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
Expand Down Expand Up @@ -375,6 +385,8 @@ jobs:
run: |
yarn config set supportedArchitectures.cpu "arm"
yarn install
- name: Build Examples
run: yarn build:examples
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
Expand Down
55 changes: 40 additions & 15 deletions __test__/index.spec.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
import test from 'ava'
import { spawnSync } from 'child_process'

import { Command, defineCommand, run } from '../index'

test('define command', (t) => {
const cmd: Command = {
meta: {
name: 'test',
version: '1.0.0',
about: 'test command',
},
options: {
foo: {
type: 'positional',
},
},
callback: (ctx: any) => {
console.log(ctx)
const cmd: Command = {
meta: {
name: 'test',
version: '1.0.0',
about: 'test command',
},
options: {
foo: {
type: 'positional',
action: 'set',
},
}
},
callback: (_: any) => {},
}

const main = defineCommand(cmd)

test('define command', (t) => {
t.deepEqual(defineCommand(cmd), cmd)
})

test('run command', (t) => {
t.notThrows(() => {
run(main, ['node', 'test.js'])
})
})

test('run help', (t) => {
const result = spawnSync('node', [`examples/simple.cjs`, '--help'])
t.is(result.error, undefined)
t.is(result.stderr.length, 0)
t.deepEqual(result.status ?? 0, 0)
})

test('run version', (t) => {
const version = spawnSync('node', [`examples/simple.cjs`, '--version'])
const no_version = spawnSync('node', [`examples/no_version.cjs`, '--version'])
t.is(version.error, undefined)
t.is(version.stderr.length, 0)
t.deepEqual(version.status ?? 0, 0)
t.not(no_version.stderr.length, 0)
})
60 changes: 60 additions & 0 deletions __test__/options.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import test from 'ava'
import { spawnSync } from 'child_process'

import { Context, defineCommand, run } from '../index'

test('positional option', (t) => {
const main = defineCommand({
meta: {
name: 'test',
},
options: {
foo: {
type: 'positional',
},
},
callback: (ctx: Context) => {
t.is(ctx.args.foo, 'foo')
},
})
t.notThrows(() => {
run(main, ['node', 'test.js', 'foo'])
})
})

test('required positional option', (t) => {
const result = spawnSync('node', [`examples/positional_required.cjs`, 'foo'])
const should_fail = spawnSync('node', [`examples/positional_required.cjs`])
t.is(result.error, undefined)
t.is(result.stderr.length, 0)
t.deepEqual(result.status ?? 0, 0)
t.not(should_fail.stderr.length, 0)
})

test('boolean flag', (t) => {
const main = defineCommand({
meta: {
name: 'test',
},
options: {
verbose: {
type: 'option',
action: 'store',
},
eq: {
type: 'option',
action: 'store',
alias: ['e'],
},
},
callback: (ctx: Context) => {
t.is(ctx.args.verbose, ctx.args.eq)
},
})
t.notThrows(() => {
run(main, ['node', 'test.js', '--verbose', '-e'])
})
t.notThrows(() => {
run(main, ['node', 'test.js'])
})
})
29 changes: 29 additions & 0 deletions __test__/subcommand.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import test from 'ava'

import { Context, defineCommand, run } from '../index'

test('sub command', (t) => {
const cmd = defineCommand({
meta: {},
options: {
foo: {
type: 'positional',
},
},
callback: (ctx: Context) => {
t.deepEqual(ctx.args, { foo: 'foo' })
},
})
const main = defineCommand({
meta: {
name: 'test',
},
options: {},
subcommands: {
cmd,
},
})
t.notThrows(() => {
run(main, ['node.exe', 'test.js', 'cmd', 'foo'])
})
})
11 changes: 11 additions & 0 deletions examples/no_version.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineCommand, run, type Context } from '../index'

const main = defineCommand({
meta: {
name: 'simple',
},
options: {},
callback: (_: Context) => {},
})

run(main)
16 changes: 16 additions & 0 deletions examples/positional_required.cts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Context, defineCommand, run } from '..'

const main = defineCommand({
meta: {
name: 'test',
},
options: {
foo: {
type: 'positional',
required: true,
},
},
callback: (_: Context) => {},
})

run(main)
10 changes: 10 additions & 0 deletions examples/simple.cts
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,25 @@ const main = defineCommand({
styled: true,
},
options: {
name: {
type: 'positional',
required: true,
help: 'Name of the person to greet',
},
verbose: {
type: 'option',
parser: 'boolean',
action: 'store',
help: 'Enable verbose output',
global: true
},
},
subcommands: {
dev,
},
callback: (ctx: Context) => {
console.log(ctx);
}
})

run(main)
8 changes: 4 additions & 4 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export interface Context {
* The keys of the object are the names of the arguments and
* the values are the parsed values.
*/
args: object
args: Record<string, any>
/**
* Raw arguments
*
Expand Down Expand Up @@ -101,7 +101,7 @@ export interface CommandOption {
*
* Defaults to the first character of the long option name.
*/
short?: string & { length: 1 }
short?: string
/**
* Long option name
*
Expand All @@ -118,9 +118,9 @@ export interface CommandOption {
/** Hidden option aliases */
hiddenAlias?: Array<string>
/** Short option aliases */
shortAlias?: Array<string & { length: 1 }>
shortAlias?: Array<string>
/** Hidden short option aliases */
hiddenShortAlias?: Array<string & { length: 1 }>
hiddenShortAlias?: Array<string>
/** Option description */
help?: string
/**
Expand Down
4 changes: 2 additions & 2 deletions scripts/watch.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const dirPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..')
const ignored = ['node_modules', '.git', '.github', '.vscode', 'dist', 'build', 'bin', '.md', '.d.ts', 'target', '.cjs']

console.log('[Archons] Initial building...')
tryBuild('yarn build', 'Building module...')
tryBuild('yarn build:debug', 'Building module...')
tryBuild('yarn build:examples', 'Building examples...')
console.log('[Archons] Build complete.\n')
console.log(`[Archons] Watching on ${dirPath} for changes...`)
Expand All @@ -35,7 +35,7 @@ fs.watch(dirPath, { recursive: true }, (eventType, filename) => {
if (filename && !isIgnored(filename)) {
console.log(`[Archons] File ${filename} was ${eventType}d, rebuilding...`)
if (filename.endsWith('.rs') || filename.endsWith('.toml')) {
tryBuild('yarn build', 'Rebuilding module...')
tryBuild('yarn build:debug', 'Rebuilding module...')
}
tryBuild('yarn build:examples', 'Rebuilding examples...')
console.log('[Archons] Build complete.\n')
Expand Down
Loading
Loading