Skip to content

Commit

Permalink
💥 Improve CLI DX (#16)
Browse files Browse the repository at this point in the history
Adds Commander to improve CLI developer experience. Commander
out-of-the-box features delivers a help system, error handling, and
(most notably to css-typed users) better argument/option handling. (You
can finally pass `--dashes` before the pattern.)

Closes #5

BREAKING CHANGE: Removes specific exit codes.

Upgrades glob dependency given breaking change already.

+semver:minor (0.x semver)
  • Loading branch information
connorjs authored Jul 30, 2024
1 parent 193962d commit 775b0b3
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 75 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/pipeline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ jobs:
- name: Run css-typed (the test)
# `node dist/main.js` is executing local `css-typed` as if installed (same as `bin`)
# Use `-I '//.*'` to ignore the first line (comment) which has generated path and timestamp
# Test --dashes in both positions
run: |
cp src/fixtures/kebab-case/kebab-case.css "$RUNNER_TEMP/kebab-case.css"
Expand All @@ -87,6 +88,9 @@ jobs:
node dist/main.js "$RUNNER_TEMP/*.css" --dashes
diff --strip-trailing-cr -uI '//.*' src/fixtures/kebab-case/kebab-case-dashes.d.css.ts "$RUNNER_TEMP/kebab-case.d.css.ts"
node dist/main.js --dashes "$RUNNER_TEMP/*.css"
diff --strip-trailing-cr -uI '//.*' src/fixtures/kebab-case/kebab-case-dashes.d.css.ts "$RUNNER_TEMP/kebab-case.d.css.ts"
Publish:
if: ${{ github.ref == 'refs/heads/main' }}
name: Publish
Expand All @@ -109,7 +113,10 @@ jobs:
registry-url: https://registry.npmjs.org

- name: Set version
run: sed -i 's/0.0.0-gitversion/${{ env.GitVersion_SemVer }}/g' package.json
run: |
expr='s/0.0.0-gitversion/${{ env.GitVersion_SemVer }}/g'
sed -i "$expr" package.json
sed -i "$expr" src/version.js
- name: Install
run: npm install --omit=dev
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# css-typed

Basic TypeScript declaration generator for CSS files.
TypeScript declaration generator for CSS files.

**Table of contents**

Expand Down
85 changes: 50 additions & 35 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "css-typed",
"version": "0.0.0-gitversion",
"description": "Basic TypeScript declaration generator for CSS files",
"description": "TypeScript declaration generator for CSS files",
"keywords": [
"CSS",
"modules",
Expand Down Expand Up @@ -33,7 +33,7 @@
"dist"
],
"scripts": {
"build": "rm -rf dist && mkdir -p dist && cp src/main.js src/logic.js dist",
"build": "rm -rf dist && mkdir -p dist && cp src/main.js src/logic.js src/version.js dist",
"ci-build": "npm-run-all -l -p build eslint prettier test",
"eslint": "eslint -f pretty .",
"eslint:fix": "npm run eslint -- --fix",
Expand All @@ -44,8 +44,10 @@
},
"engineStrict": true,
"dependencies": {
"@commander-js/extra-typings": "^12.1.0",
"commander": "^12.1.0",
"css-tree": "^2.3.1",
"glob": "^10.3.14"
"glob": "^11.0.0"
},
"devDependencies": {
"@types/css-tree": "^2.3.8",
Expand Down
2 changes: 1 addition & 1 deletion src/logic.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { parse as parseCss, walk } from "css-tree";
* @returns {Promise<string | undefined>} TypeScript declaration file content or
* `undefined` if no declarations to write.
*/
export async function generateDeclaration(stylesheetPath, time, options) {
export async function generateDeclaration(stylesheetPath, time, options = {}) {
// Handle case where the file got deleted by the time we got here
if (!existsSync(stylesheetPath)) return undefined;

Expand Down
5 changes: 1 addition & 4 deletions src/logic.test.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import { readFileSync } from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";

import { describe, expect, it } from "vitest";

import { dtsPath, generateDeclaration } from "./logic.js";

const __dirname = path.dirname(fileURLToPath(import.meta.url));

describe(`css-typed`, () => {
it(`should not generate an empty declaration file [#9]`, async () => {
const path = fixtureFile(`no-declaration-file.css`);
Expand Down Expand Up @@ -46,5 +43,5 @@ describe(`css-typed`, () => {
});

function fixtureFile(filename) {
return path.join(__dirname, `fixtures`, filename);
return path.join(import.meta.dirname, `fixtures`, filename);
}
64 changes: 34 additions & 30 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,44 @@

import { writeFile } from "node:fs/promises";

import { Command } from "@commander-js/extra-typings";
import { glob } from "glob";

import { dtsPath, generateDeclaration } from "./logic.js";

/* globals process -- Node/CLI tool */
await main(process.argv[2], process.argv[3] === `--dashes`);
// See https://github.com/connorjs/css-typed/issues/5 for "proper" CLI arg handling

async function main(pattern, dashesEnabled) {
if (!pattern) {
console.error(`Expected glob pattern`);
process.exit(2);
}
const options = dashesEnabled ? { localsConvention: `dashes` } : {};

const files = await glob(pattern);

const time = new Date().toISOString();
const results = await Promise.all(
files.map((file) =>
generateDeclaration(file, time, options).then((ts) =>
writeDeclarationFile(file, ts),
import { version } from "./version.js";

await new Command()
.name(`css-typed`)
.description(`TypeScript declaration generator for CSS files.`)
.version(version)
.argument(`<pattern>`, `Glob path for CSS files to target.`)
.option(
`--dashes`,
`Transform kebab-case classes (dashed names) to camelCase.`,
false,
)
.action(async function (pattern, options, program) {
const declarationOptions = options.dashes
? { localsConvention: `dashes` }
: {};

const files = await glob(pattern);

const time = new Date().toISOString();
const results = await Promise.all(
files.map((file) =>
generateDeclaration(file, time, declarationOptions).then((ts) =>
writeDeclarationFile(file, ts),
),
),
),
);

const errors = results.filter(Boolean);
if (errors.length > 0) {
console.error(`Errors encountered`, errors);
process.exit(3);
}

process.exit(0);
}
);

const errors = results.filter(Boolean);
if (errors.length > 0) {
program.error(`Errors encountered: ${errors}`);
}
})
.parseAsync();

/**
* Writes the TypeScript declaration content to file. Handles the output path.
Expand Down
2 changes: 2 additions & 0 deletions src/version.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Replaced with actual version in Publish (see `pipeline.yaml`)
export const version = `0.0.0-gitversion`;

0 comments on commit 775b0b3

Please sign in to comment.