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
5 changes: 5 additions & 0 deletions .changeset/curly-mice-create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@variableland/run-run": patch
---

Add version flag
5 changes: 5 additions & 0 deletions .changeset/odd-rabbits-press.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@variableland/run-run": minor
---

Add typecheck cmd
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ jobs:
release:
runs-on: ubuntu-latest
needs: ci
if: ${{ github.ref == 'refs/heads/main' }}
permissions:
contents: write
packages: write
Expand Down
2 changes: 1 addition & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pnpm run dev test:static --fix-staged
RR_ENV=dev pnpm rr test:static --fix-staged
git update-index --again
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
{
"name": "run-run-monorepo",
"version": "0.0.0",
"private": true,
"scripts": {
"build": "turbo build",
"dev": "RR_ENV=dev rr",
"debug:dev": "DEBUG=run-run:* RR_ENV=dev rr",
"test": "turbo test",
"prepare": "husky"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
"dependencies": {
"chalk": "^5.4.1",
"commander": "^13.1.0",
"debug": "^4.4.0",
"is-ci": "^4.1.0",
"lilconfig": "^3.1.3",
"read-package-up": "^11.0.0",
"supports-color": "^10.0.0",
"wait-on": "^8.0.2",
"zx": "^8.4.0"
Expand Down
15 changes: 15 additions & 0 deletions packages/cli/src/logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @ts-expect-error type defs not found
import createDebug from "debug";

type DebugFn = (message: string, ...args: unknown[]) => void;

const ROOT_DEBUG_LABEL = "run-run";
const rootDebug = createDebug(`${ROOT_DEBUG_LABEL}:cli`);

export const Logger = {
...console,
debug: (message: string, ...args: unknown[]) => {
rootDebug(message, ...args);
},
subdebug: (label: string): DebugFn => createDebug(`${ROOT_DEBUG_LABEL}:${label}`),
};
15 changes: 13 additions & 2 deletions packages/cli/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
import { createProgram } from "./program";
import { createStore, runContext } from "./store";

async function main(argv = process.argv) {
const program = createProgram();
await program.parseAsync(argv);
try {
const program = createProgram();

const store = await createStore();

runContext(store, async () => {
await program.parseAsync(argv);
});
} catch (error) {
console.error("Cannot run main successfully", error);
process.exit(1);
}
}

main();
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ exports[`should display help message 1`] = `
format the code 🎨

Options:
-c, --check check if the code is formatted (default: true)
-f, --fix format all the code
--fix-staged format staged files only
-h, --help display help for command
-c, --check check if the code is formatted (default: true)
-f, --fix format all the code
-h, --help display help for command

Under the hood, this command uses the biome CLI to format the code.
"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ Options:
Commands:
format|fmt [options] format the code 🎨
lint [options] lint the code 🧹
test:static [options] check format and lint issues over all the code
test:static [options] check format and lint issues ✅
clean [options] delete dirty folders or files such as node_modules, etc
🗑️
typecheck|tsc check if TypeScript code is well typed 🎨
help [command] display help for command

Acknowledgment:
Expand All @@ -36,9 +37,10 @@ Options:
Commands:
format|fmt [options] format the code 🎨
lint [options] lint the code 🧹
test:static [options] check format and lint issues over all the code
test:static [options] check format and lint issues ✅
clean [options] delete dirty folders or files such as node_modules, etc
🗑️
typecheck|tsc check if TypeScript code is well typed 🎨
help [command] display help for command

Acknowledgment:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ exports[`should display help message 1`] = `
lint the code 🧹

Options:
-c, --check check if the code is valid (default: true)
-f, --fix try to fix all the code
--fix-staged try to fix staged files only
-h, --help display help for command
-c, --check check if the code is valid (default: true)
-f, --fix try to fix all the code
-h, --help display help for command

Under the hood, this command uses the biome CLI to lint the code.
"
Expand Down
23 changes: 23 additions & 0 deletions packages/cli/src/program/commands/typecheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { createCommand } from "commander";
import { Logger } from "~/logger";
import { $ } from "~/shell";
import { useStore } from "~/store";

export const typecheckCommand = createCommand("typecheck")
.alias("tsc")
.description("check if TypeScript code is well typed 🎨")
.action(async function typecheckAction() {
const d = Logger.subdebug("typecheck");
const store = useStore();

try {
if (store.hasFile("tsconfig.json")) {
await $`tsc --noEmit`;
} else {
d("No tsconfig.json found. Skipping type checking.");
}
} catch {
process.exit(1);
}
})
.addHelpText("afterAll", "\nUnder the hood, this command uses the TSC CLI to check the code.");
6 changes: 5 additions & 1 deletion packages/cli/src/program/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ import { cleanCommand } from "./commands/clean";
import { formatCommand } from "./commands/format";
import { lintCommand } from "./commands/lint";
import { testStaticCommand } from "./commands/test-static";
import { typecheckCommand } from "./commands/typecheck";
import { getVersion } from "./version";

export function createProgram() {
return new Command("run-run")
.alias("rr")
.version(getVersion(), "-v, --version")
.addHelpText("before", BANNER_TEXT)
.addHelpText("after", CREDITS_TEXT)
.addCommand(formatCommand)
.addCommand(lintCommand)
.addCommand(testStaticCommand)
.addCommand(cleanCommand);
.addCommand(cleanCommand)
.addCommand(typecheckCommand);
}
13 changes: 13 additions & 0 deletions packages/cli/src/program/version.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { Logger } from "~/logger";
import pkg from "../../package.json";

export function getVersion() {
const d = Logger.subdebug("get-version");

const version = process.env.VERSION || pkg.version;

d("resolved version: %s", version);
d("VERSION in env: %s", process.env.VERSION);

return version;
}
3 changes: 2 additions & 1 deletion packages/cli/src/shell.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { $ as make$ } from "zx";
import { cwd } from "./utils/cwd";
import { isRaw } from "./utils/is-raw";
import { quote } from "./utils/quote";

export const $ = make$({
cwd: process.env.RR_PWD ?? process.cwd(),
cwd,
verbose: true,
quote: (arg: unknown) => {
if (typeof arg === "string") {
Expand Down
26 changes: 26 additions & 0 deletions packages/cli/src/store/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import path from "node:path";
import { readPackageUp } from "read-package-up";
import { Logger } from "~/logger";
import { cwd } from "~/utils/cwd";
import { Store } from "./store";

export async function createStore() {
const d = Logger.subdebug("create-store");

d("RR_PWD %s", process.env.RR_PWD);
d("process cwd %s", process.cwd());
d("cwd used for creating store %s", cwd);

const result = await readPackageUp({ cwd });

if (!result) {
throw new Error("Could not find app package.json");
}

const { packageJson: pkg, path: pkgPath } = result;

d("pkg %O", pkg);
d("pkgPath %s", pkgPath);

return new Store(pkg, path.dirname(pkgPath));
}
18 changes: 18 additions & 0 deletions packages/cli/src/store/context.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { AsyncLocalStorage } from "node:async_hooks";
import type { Store } from "./store";

const asyncLocalStorage = new AsyncLocalStorage<Store>();

export function runContext(store: Store, callback: () => Promise<void>) {
asyncLocalStorage.run(store, callback);
}

export function useStore() {
const store = asyncLocalStorage.getStore();

if (!store) {
throw new Error("Store not found, please call createStore() first");
}

return store;
}
2 changes: 2 additions & 0 deletions packages/cli/src/store/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { useStore, runContext } from "./context";
export { createStore } from "./app";
21 changes: 21 additions & 0 deletions packages/cli/src/store/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import fs from "node:fs";
import path from "node:path";
import type { NormalizedPackageJson } from "read-package-up";

export class Store {
appPkg: NormalizedPackageJson;
appPath: string;

constructor(appPkg: NormalizedPackageJson, appPath: string) {
this.appPkg = appPkg;
this.appPath = appPath;
}

hasFile(name: string) {
return fs.existsSync(this.#fromApp(name));
}

#fromApp(...args: string[]) {
return path.join(this.appPath, ...args);
}
}
3 changes: 3 additions & 0 deletions packages/cli/src/utils/cwd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import fs from "node:fs";

export const cwd = fs.realpathSync(process.env.RR_PWD ?? process.cwd());
Loading