Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/actions/test/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Test
description: "Run tests, generate coverage reports, and upload coverage badge to GitHub Gist"

inputs:
version:
required: false
description: "Package version (latest or beta)"
gist_id:
required: false
description: 'The ID of the GitHub Gist where the coverage badge will be uploaded'
gist_token:
required: false
description: 'GitHub personal access token with Gist permissions for authentication'

runs:
using: "composite"
steps:
- name: Run tests with coverage
shell: bash
run: |
npm run test -- --coverage --coverageReporters lcovonly json-summary

- name: Generate coverage badge
if: ${{ inputs.gist_id && inputs.gist_token }}
shell: bash
run: |
echo "REPO_NAME=${GITHUB_REPOSITORY#*/}" >> $GITHUB_ENV

- name: Upload coverage badge to GitHub Gist
if: ${{ (inputs.version == 'latest' || inputs.version == 'beta') && inputs.gist_id && inputs.gist_token }}
uses: exuanbo/actions-deploy-gist@v1
continue-on-error: true
with:
token: ${{ inputs.gist_token }}
gist_id: ${{ inputs.gist_id }}
gist_file_name: "coverage-${{ env.REPO_NAME }}-${{ inputs.version }}.svg"
file_path: "./coverage/badge.svg"
file_type: "text"
81 changes: 21 additions & 60 deletions .github/workflows/publish-beta.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish beta
name: Beta

on:
pull_request:
Expand All @@ -17,90 +17,51 @@ on:
- submitted

jobs:
test:
name: Test
runs-on: ubuntu-latest
environment: test
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org'

- name: Setup version
run: |
PACKAGE_NAME=$(npm pkg get name | sed -e 's/^"//' -e 's/"$//')
PACKAGE_VERSION=$(npm pkg get version | sed -e 's/^"//' -e 's/"$//')
PUBLISHED_VERSION=$(npm view $PACKAGE_NAME@beta version 2>/dev/null || echo "")
if [[ "$PUBLISHED_VERSION" == "$PACKAGE_VERSION"* ]]; then
INDEX=$(echo $PUBLISHED_VERSION | sed -r -e 's/^[0-9]+\.[0-9]+\.[0-9]+-beta\.//' | awk '{print $0+1}')
else
INDEX=0
fi
npm pkg set version=$PACKAGE_VERSION-beta.$INDEX

- name: Cache dependencies
uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package.json') }}
restore-keys: |
${{ runner.os }}-npm-

- name: Install dependencies
run: npm install

- name: Test
run: npm run test

publish-beta:
name: Publish beta version
if: github.repository_owner == 'kearisp'
needs: test
runs-on: ubuntu-latest
environment: publish
permissions:
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
registry-url: 'https://registry.npmjs.org'

- name: Setup version
run: |
PACKAGE_NAME=$(npm pkg get name | sed -e 's/^"//' -e 's/"$//')
PACKAGE_VERSION=$(npm pkg get version | sed -e 's/^"//' -e 's/"$//')
PUBLISHED_VERSION=$(npm view $PACKAGE_NAME@beta version 2>/dev/null || echo "")
if [[ "$PUBLISHED_VERSION" == "$PACKAGE_VERSION"* ]]; then
INDEX=$(echo $PUBLISHED_VERSION | sed -r -e 's/^[0-9]+\.[0-9]+\.[0-9]+-beta\.//' | awk '{print $0+1}')
else
INDEX=0
fi
npm pkg set version=$PACKAGE_VERSION-beta.$INDEX
uses: kearisp/npm-version-action@v0.0.3
with:
tag: beta

- name: Cache dependencies
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package.json') }}
restore-keys: |
${{ runner.os }}-npm-

- name: Install dependencies
shell: bash
run: npm install

- name: Test
uses: ./.github/actions/test
timeout-minutes: 2
with:
version: "beta"
gist_token: ${{ secrets.GIST_TOKEN }}
gist_id: ${{ secrets.GIST_ID }}

- name: Publish Beta to NPM
if: github.repository_owner == 'kearisp'
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
run: |
npm publish --provenance --tag beta
run: npm publish --provenance --tag beta
37 changes: 22 additions & 15 deletions .github/workflows/publish-latest.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Publish latest
name: Latest

on:
release:
Expand All @@ -8,37 +8,43 @@ on:
jobs:
publish:
name: Publish latest version
if: ${{ github.repository_owner == 'kearisp' }}
runs-on: ubuntu-latest
environment: publish
permissions:
contents: read
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
registry-url: 'https://registry.npmjs.org'

- name: Cache dependencies
uses: actions/cache@v4
uses: actions/cache@v5
with:
path: ~/.npm
key: ${{ runner.os }}-npm-${{ hashFiles('**/package.json') }}
restore-keys: |
${{ runner.os }}-npm-

- name: Install dependencies
shell: bash
run: npm install

- name: Build
run: npm run build
- name: Test
uses: ./.github/actions/test
with:
version: "latest"
gist_token: ${{ secrets.GIST_TOKEN }}
gist_id: ${{ secrets.GIST_ID }}

- name: Publish to NPM
if: ${{ github.repository_owner == 'kearisp' }}
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
run: npm publish --provenance
Expand All @@ -51,23 +57,24 @@ jobs:
needs: publish
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
registry-url: 'https://registry.npmjs.org'

- name: Unpublish previous beta versions
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
run: |
PACKAGE_NAME=$(npm pkg get name | sed -e 's/^"//' -e 's/"$//')
PACKAGE_VERSION=$(npm pkg get version | sed -e 's/^"//' -e 's/"$//')
BETA_VERSIONS=$(npm view $PACKAGE_NAME versions --json | jq -r '.[]' | grep -E "$PACKAGE_VERSION-beta\.[0-9]+$")
VERSIONS=$(npm view $PACKAGE_NAME versions --json | jq -r '.[]')
BETA_VERSIONS=$(echo $VERSIONS | grep -E "$PACKAGE_VERSION-beta\.[0-9]+$" || echo "")

for VERSION in $BETA_VERSIONS; do
npm unpublish $PACKAGE_NAME@$VERSION --force 2>/dev/null || npm deprecate $PACKAGE_NAME@$VERSION "This is the beta version. Why can't it be deleted?"
done

9 changes: 5 additions & 4 deletions .github/workflows/unpublish-latest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,16 @@ jobs:
environment: publish
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@v6

- name: Set up Node.js
uses: actions/setup-node@v4
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 22
node-version: 24
registry-url: 'https://registry.npmjs.org'

- name: Delete package version
shell: bash
env:
NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }}
run: |
Expand Down
7 changes: 1 addition & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kearisp/cli",
"version": "2.0.8",
"version": "2.0.9",
"license": "MIT",
"author": "Kris Papercut <krispcut@gmail.com>",
"description": "Command line interface for node.js",
Expand Down Expand Up @@ -28,14 +28,9 @@
"test-watch:command": "jest --colors --watchAll --runTestsByPath ./src/makes/Command.spec.ts",
"test-watch:parser": "jest --colors --watchAll --runTestsByPath ./src/makes/Parser.spec.ts"
},
"dependencies": {
"os": "^0.1.2",
"path": "^0.12.7"
},
"devDependencies": {
"@types/jest": "^29.5.14",
"@types/node": "^22.13.0",
"fs": "^0.0.1-security",
"jest": "^29.7.0",
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
Expand Down
20 changes: 20 additions & 0 deletions src/makes/Cli.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,4 +116,24 @@ describe("Cli.run", () => {
expect(res).toContain("--name");
expect(res).toContain("--option");
});

it("Should handle empty command with options", async (): Promise<void> => {
const cli = new Cli();

cli.command("")
.option("version", {
alias: "v",
type: "boolean"
})
.action((input) => {
if(input.option("version")) {
return "v1.0.0";
}

return "Some result";
});

expect(await cli.run(["node", "cli"]).catch((err) => err)).toBe("Some result");
expect(await cli.run(["node", "cli", "-v"]).catch((err) => err)).toBe("v1.0.0");
});
});
11 changes: 7 additions & 4 deletions src/makes/Command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,19 @@ export class Command {
}

public parse(parts: string[]): CommandInput {
const commands = this._command
? this._command.split(/\s+/g)
: [];
const commands = [
"command",
...this._command
? this._command.trim().split(/\s+/g)
: []
];

const args: {
[name: string]: string | boolean | number | string[];
} = {};
const optionValues: OptionValue[] = [];

const parser = new Parser(parts);
const parser = new Parser(["command", ...parts]);

for(let i = 0; i < commands.length; i++) {
const command = commands[i];
Expand Down
Loading