-
-
Notifications
You must be signed in to change notification settings - Fork 203
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(npm): add programmatic API for TypeScript (#523)
* feat: add programmatic api * fix: return the execa result from the programmatic API instead of exiting the process * feat: make it possible to customize execa when using the programmatic api * fix: fixed dev script * refactor: remove unnecessary await * chore: update lockfile and let yarn resort dependencies * style: formatting in tsup config * chore(npm): log the error in case of exe path is not found --------- Co-authored-by: Orhun Parmaksız <[email protected]>
- Loading branch information
Showing
13 changed files
with
4,053 additions
and
955 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
enableGlobalCache: true | ||
|
||
nodeLinker: node-modules | ||
|
||
yarnPath: .yarn/releases/yarn-4.1.0.cjs |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,13 +2,32 @@ | |
"name": "git-cliff", | ||
"version": "2.1.0-rc.0", | ||
"description": "A highly customizable Changelog Generator that follows Conventional Commit specifications ⛰️", | ||
"bin": "lib/index.js", | ||
"type": "module", | ||
"main": "lib/cjs/index.d.cts", | ||
"module": "lib/esm/index.d.ts", | ||
"types": "lib/cjs/index.d.cts", | ||
"bin": "lib/cli/cli.js", | ||
"exports": { | ||
"./cli": { | ||
"import": "./lib/cli/cli.js" | ||
}, | ||
".": { | ||
"import": { | ||
"types": "./lib/esm/index.d.ts", | ||
"default": "./lib/esm/index.js" | ||
}, | ||
"require": { | ||
"types": "./lib/cjs/index.d.cts", | ||
"default": "./lib/cjs/index.cjs" | ||
} | ||
} | ||
}, | ||
"scripts": { | ||
"typecheck": "tsc --noEmit", | ||
"typecheck": "tsc", | ||
"lint": "eslint .", | ||
"lint:fix": "eslint . --fix", | ||
"build": "tsc", | ||
"dev": "yarn build && node lib/index.js" | ||
"build": "tsup", | ||
"dev": "yarn build && node lib/cli/cli.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
|
@@ -54,20 +73,24 @@ | |
"url": "https://github.com/orhun/git-cliff/issues" | ||
}, | ||
"homepage": "https://github.com/orhun/git-cliff#readme", | ||
"dependencies": { | ||
"execa": "^8.0.1" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.11.18", | ||
"@typescript-eslint/eslint-plugin": "^5.48.0", | ||
"@typescript-eslint/parser": "^5.48.0", | ||
"eslint": "^8.31.0", | ||
"typescript": "^4.9.4" | ||
"@types/node": "^20.11.22", | ||
"@typescript-eslint/eslint-plugin": "^7.1.0", | ||
"@typescript-eslint/parser": "^7.1.0", | ||
"eslint": "^8.57.0", | ||
"tsup": "^8.0.2", | ||
"typescript": "^5.3.3" | ||
}, | ||
"optionalDependencies": { | ||
"git-cliff-linux-x64": "2.1.0-rc.0", | ||
"git-cliff-linux-arm64": "2.1.0-rc.0", | ||
"git-cliff-darwin-x64": "2.1.0-rc.0", | ||
"git-cliff-darwin-arm64": "2.1.0-rc.0", | ||
"git-cliff-windows-x64": "2.1.0-rc.0", | ||
"git-cliff-windows-arm64": "2.1.0-rc.0" | ||
"git-cliff-darwin-x64": "2.1.0-rc.0", | ||
"git-cliff-linux-arm64": "2.1.0-rc.0", | ||
"git-cliff-linux-x64": "2.1.0-rc.0", | ||
"git-cliff-windows-arm64": "2.1.0-rc.0", | ||
"git-cliff-windows-x64": "2.1.0-rc.0" | ||
}, | ||
"eslintConfig": { | ||
"extends": [ | ||
|
@@ -82,5 +105,6 @@ | |
"lib/*" | ||
], | ||
"root": true | ||
} | ||
}, | ||
"packageManager": "[email protected]" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/env node | ||
|
||
import { runGitCliff } from "./index.js"; | ||
|
||
async function run() { | ||
const args = process.argv.slice(2); | ||
const processResult = await runGitCliff(args); | ||
|
||
process.exit(processResult.exitCode ?? 0); | ||
} | ||
|
||
void run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { arch as getArch, platform as getPlatform } from "os"; | ||
|
||
/** | ||
* Returns the executable path for git-cliff located inside node_modules | ||
* The naming convention is git-cliff-${os}-${arch} | ||
* If the platform is `win32` or `cygwin`, executable will include a `.exe` extension | ||
* @see https://nodejs.org/api/os.html#osarch | ||
* @see https://nodejs.org/api/os.html#osplatform | ||
* @example "x/xx/node_modules/git-cliff-darwin-arm64" | ||
*/ | ||
export async function getExePath() { | ||
const platform = getPlatform(); | ||
const arch = getArch(); | ||
|
||
let os = platform as string; | ||
let extension = ""; | ||
|
||
if (platform === "win32" || platform === "cygwin") { | ||
os = "windows"; | ||
extension = ".exe"; | ||
} | ||
|
||
try { | ||
// Since the bin will be located inside `node_modules`, we can simply call import.meta.resolve | ||
return import.meta.resolve( | ||
`git-cliff-${os}-${arch}/bin/git-cliff${extension}`, | ||
); | ||
} catch (e) { | ||
throw new Error( | ||
`Couldn't find git-cliff binary inside node_modules for ${os}-${arch} (${e})`, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,39 +1,61 @@ | ||
#!/usr/bin/env node | ||
import { execa, type Options as ExecaOptions, type ExecaReturnValue, } from "execa"; | ||
import { fileURLToPath } from "node:url"; | ||
import { getExePath } from "./getExePath.js"; | ||
import type { Options } from "./options.js"; | ||
import { optionsToStringArgs } from "./optionsToStringArgs.js"; | ||
|
||
import { spawnSync } from "child_process" | ||
export type { Options } from "./options.js"; | ||
|
||
/** | ||
* Returns the executable path for git-cliff located inside node_modules | ||
* The naming convention is git-cliff-${os}-${arch} | ||
* If the platform is `win32` or `cygwin`, executable will include a `.exe` extension | ||
* @see https://nodejs.org/api/os.html#osarch | ||
* @see https://nodejs.org/api/os.html#osplatform | ||
* @example "x/xx/node_modules/git-cliff-darwin-arm64" | ||
*/ | ||
function getExePath() { | ||
const arch = process.arch; | ||
let os = process.platform as string; | ||
let extension = ''; | ||
if (['win32', 'cygwin'].includes(process.platform)) { | ||
os = 'windows'; | ||
extension = '.exe'; | ||
} | ||
|
||
try { | ||
// Since the bin will be located inside `node_modules`, we can simply call require.resolve | ||
return require.resolve(`git-cliff-${os}-${arch}/bin/git-cliff${extension}`) | ||
} catch (e) { | ||
throw new Error(`Couldn't find git-cliff binary inside node_modules for ${os}-${arch}`) | ||
} | ||
} | ||
|
||
* Runs `git-cliff` with the provided options as a JavaScript object. | ||
* | ||
* @param options - The options to pass to `git-cliff`. | ||
* These get transformed into an array strings. | ||
* - Values that are `true` will be passed as flags (`--flag`). | ||
* - Values that are `false` or `null` will be ignored. | ||
* - All other values will be passed as options (`--option value`). | ||
* | ||
* @param execaOptions - Options to pass to {@link execa}. | ||
*/ | ||
export async function runGitCliff(options: Options, execaOptions?: ExecaOptions): Promise<ExecaReturnValue<string>>; | ||
/** | ||
* Runs `git-cliff` with args using nodejs spawn | ||
*/ | ||
function runGitCliff() { | ||
const args = process.argv.slice(2) | ||
const processResult = spawnSync(getExePath(), args, { stdio: "inherit" }) | ||
process.exit(processResult.status ?? 0) | ||
} | ||
* Runs the `git-cliff` with the provided arguments. | ||
* | ||
* @param args - The arguments to pass to `git-cliff`. | ||
* These should be in an array of string format. | ||
* Every option and their value should be its own entry in the array. | ||
* | ||
* @param execaOptions - Options to pass to {@link execa}. | ||
* | ||
* @returns A promise that resolves when the `git-cliff` has finished running. | ||
* | ||
* @example | ||
* Options with values | ||
* ```typescript | ||
* await runGitCliff(["--tag", "1.0.0", "--config", "github"]); | ||
* ``` | ||
* | ||
* @example | ||
* Boolean flags | ||
* ```typescript | ||
* await runGitCliff(["--unreleased", "--topo-order"]); | ||
* ``` | ||
* | ||
* @example | ||
* Combining options and flags | ||
* ```typescript | ||
* await runGitCliff(["--tag", "1.0.0", "--config", "github", "--topo-order"]); | ||
* ``` | ||
*/ | ||
export async function runGitCliff(args: string[], execaOptions?: ExecaOptions): Promise<ExecaReturnValue<string>>; | ||
export async function runGitCliff(argsOrOptions: Options | string[], execaOptions?: ExecaOptions): Promise<ExecaReturnValue<string>> { | ||
const exePath = await getExePath(); | ||
const args = Array.isArray(argsOrOptions) | ||
? argsOrOptions | ||
: optionsToStringArgs(argsOrOptions); | ||
|
||
runGitCliff() | ||
return execa(fileURLToPath(exePath), args, { | ||
stdio: "inherit", | ||
...execaOptions, | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
export type Options = Partial<{ | ||
help: boolean; | ||
version: boolean; | ||
verbose: boolean; | ||
init: boolean | string; | ||
config: string; | ||
workdir: string; | ||
repository: string; | ||
includePath: string; | ||
excludePath: string; | ||
withCommit: string; | ||
skipCommit: string; | ||
prepend: string; | ||
output: string; | ||
tag: string; | ||
bump: boolean; | ||
bumpedVersion: boolean; | ||
body: string; | ||
latest: boolean; | ||
current: boolean; | ||
unreleased: boolean; | ||
topoOrder: boolean; | ||
noExec: boolean; | ||
context: boolean; | ||
strip: "header" | "footer" | "all"; | ||
sort: "oldest" | "newest"; | ||
githubToken: string; | ||
githubRepo: string; | ||
}>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import type { Options } from "./options.js"; | ||
|
||
/** | ||
* Transforms a JavaScript object of options into an array | ||
* of strings that can be passed to {@link execa} for calling `git-cliff` | ||
* | ||
* @param options The options to transform | ||
* @returns The options as an array of strings | ||
*/ | ||
export function optionsToStringArgs(options: Options): string[] { | ||
const args: string[] = []; | ||
|
||
for (const [key, value] of Object.entries(options)) { | ||
const hyphenCaseKey = key.replace(/([A-Z])/g, "-$1").toLowerCase(); | ||
|
||
if (value === true) { | ||
args.push(`--${hyphenCaseKey}`); | ||
} else if (value === false || value === null) { | ||
continue; | ||
} else { | ||
args.push(`--${hyphenCaseKey}`, value); | ||
} | ||
} | ||
|
||
return args; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,12 @@ | ||
{ | ||
"compilerOptions": { | ||
"target": "es2016", | ||
"module": "commonjs", | ||
"module": "node16", | ||
"moduleResolution": "node16", | ||
"esModuleInterop": true, | ||
"baseUrl": "./", | ||
"outDir": "lib", | ||
"forceConsistentCasingInFileNames": true, | ||
"strict": true, | ||
"skipLibCheck": true | ||
"resolveJsonModule": true, | ||
"noEmit": true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { defineConfig, type Options } from "tsup"; | ||
import { dependencies } from "./package.json"; | ||
|
||
const baseOptions: Options = { | ||
clean: true, | ||
dts: true, | ||
entry: ["src/index.ts"], | ||
minify: false, | ||
external: Object.keys(dependencies), | ||
sourcemap: true, | ||
target: "es2020", | ||
tsconfig: "tsconfig.json", | ||
keepNames: true, | ||
treeshake: true, | ||
}; | ||
|
||
export default [ | ||
defineConfig({ | ||
...baseOptions, | ||
outDir: "lib/cjs", | ||
format: "cjs", | ||
}), | ||
defineConfig({ | ||
...baseOptions, | ||
outDir: "lib/esm", | ||
format: "esm", | ||
}), | ||
defineConfig({ | ||
...baseOptions, | ||
outDir: "lib/cli", | ||
entry: ["src/cli.ts"], | ||
dts: false, | ||
sourcemap: false, | ||
format: "esm", | ||
}), | ||
]; |
Oops, something went wrong.