diff --git a/.github/workflows/json.yml b/.github/workflows/json.yml index 7623643..4b78406 100644 --- a/.github/workflows/json.yml +++ b/.github/workflows/json.yml @@ -7,7 +7,7 @@ on: branches: [main] paths: - src/config.ts - - src/emojis.jsonc + - src/presets/default.jsonc # Allows you to run this workflow manually from the Actions tab workflow_dispatch: diff --git a/README.md b/README.md index 412d73b..6d38d91 100644 --- a/README.md +++ b/README.md @@ -167,7 +167,7 @@ eemoji run ## 🦾 Config -The default configuration is here: [emojis.jsonc](./src/emojis.jsonc) and the [Emojis](#-emojis) section. +The default configuration is here: [default.jsonc](./src/presets/default.jsonc) and the [Emojis](#-emojis) section. This is used if no config file is found in the project. @@ -339,17 +339,53 @@ If it continues to fail to work, try this as well and restart everything: ### Adding a new emoji -To add a new emoji to the default config or modify it, please open an issue first. +To add a new emoji to a preset (even the default config) or modify it, open an issue first. Then, if it's okay: -- modify the [emojis.jsonc](./src/emojis.jsonc) file, add the emoji and a description +- modify the [default.jsonc](./src/presets/default.jsonc) file, add the emoji and a description - The Action will take care of the rest (copying it to the json, updating the readme emoji table and the json schema) - open a PR ### Creating a new emoji preset -SOONℒ️ +Add a new `jsonc` file to the **presets** folder and name it as you wish. +Describe the emoji using comments. + +Example: + +```json +{ + "fix": "πŸ”§", // general fix + "feat": "✨" // introduced a new feature +} +``` + +Locate the [presets.ts](./src/presets.ts) file and add your preset like this: + +```ts +export const [ + presetDefault, + presetMinimal, + /* ... */ + + // add your presetSomething here +] = createPresets([ + 'default.jsonc', + 'minimal.jsonc', + /* ... */ + + // make sure the path is relative to the root of the project +]) as [ + Preset, + Preset, + /* ... */ + + // and make TypeScript happy +] +``` + +Then, open a PR. ### Development diff --git a/TODO.md b/TODO.md index db5b3e7..b6d16cd 100644 --- a/TODO.md +++ b/TODO.md @@ -15,6 +15,6 @@ - [x] make the consola start and success logs sane in the cleanup command - [x] investigate speed, prepare script for init - [x] move bin scripts to `scripts` folder and also build them from typescript -- [x] Generate the readme emoji table from `emojis.jsonc` (jsonc for description) -- [ ] overwrite the default emojis in ts config too (import the default emojis, import other presets) +- [x] Generate the readme emoji table from `default.jsonc` (jsonc for description) +- [x] overwrite the default emojis in ts config too (import the default emojis, import other presets) - [ ] try astro and create a small website explaining which emoji to use and when, + stuff diff --git a/eslint.config.js b/eslint.config.js index cfae2ac..3b614a0 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -1,5 +1,3 @@ import antfu from '@antfu/eslint-config' -export default antfu({ - ignores: ['src/**/*.jsonc'], -}) +export default antfu() diff --git a/scripts/readme-table.ts b/scripts/readme-table.ts index a024b38..f650107 100644 --- a/scripts/readme-table.ts +++ b/scripts/readme-table.ts @@ -1,6 +1,5 @@ import fs from 'node:fs' import process from 'node:process' -import path from 'node:path' import type { CommentArray, CommentDescriptor, @@ -9,17 +8,17 @@ import type { } from 'comment-json' import { parse } from 'comment-json' import { markdownTable } from 'markdown-table' -import emojis from '../src/emojis.json' +import emojis from '../src/presets/default.json' +import { r } from '../src/utils/utils' -const cwd = process.env.INIT_CWD || process.cwd() -const eemojiPath = path.join(cwd, 'src/emojis.jsonc') -const readmePath = path.join(cwd, 'README.md') +const eemojiPath = r('src/presets/default.jsonc') +const readmePath = r('README.md') const emojiFile = fs.readFileSync(eemojiPath, 'utf8') const emojiJsonc = parse(emojiFile) if (!emojiJsonc) { - console.error('Failed to parse emojis.jsonc') + console.error('Failed to parse default.jsonc') process.exit(1) } diff --git a/scripts/schema.ts b/scripts/schema.ts index 39840f7..a0b79b9 100644 --- a/scripts/schema.ts +++ b/scripts/schema.ts @@ -2,9 +2,9 @@ import fs from 'node:fs' import * as jsonc from 'jsonc-parser' import schema from './../json/eemoji-config-schema.json' -const emojis = jsonc.parse(fs.readFileSync('./src/emojis.jsonc', 'utf8')) +const emojis = jsonc.parse(fs.readFileSync('./src/presets/default.jsonc', 'utf8')) schema.properties.emojis.default = emojis fs.writeFileSync('./json/eemoji-config-schema.json', `${JSON.stringify(schema, null, 2)}\n`) -fs.writeFileSync('./src/emojis.json', `${JSON.stringify(emojis, null, 2)}\n`) +fs.writeFileSync('./src/presets/default.json', `${JSON.stringify(emojis, null, 2)}\n`) diff --git a/src/commands/init.ts b/src/commands/init.ts index 8f63c34..3811acf 100644 --- a/src/commands/init.ts +++ b/src/commands/init.ts @@ -1,10 +1,10 @@ import * as fs from 'node:fs' -import * as path from 'node:path' import { defineCommand } from 'citty' import { consola } from 'consola' import { name } from '../../package.json' import type { ConfigType, JsFiles, JsonFiles } from '../config' import { ConfigObject, configTypes } from '../config' +import { r } from '../utils/utils' const C = new ConfigObject() @@ -68,8 +68,7 @@ export default defineCommand({ }) function createConfigFile(filename: JsonFiles | JsFiles, content: string): void { - const filePath = path.join(C.cwd, filename) - fs.writeFileSync(filePath, `${content}\n`) + fs.writeFileSync(r(filename), `${content}\n`) } async function checkGitHook(clean: boolean | undefined) { diff --git a/src/config.ts b/src/config.ts index 3e3ea31..71dacf1 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,10 +1,10 @@ import * as path from 'node:path' -import process from 'node:process' import { fileURLToPath } from 'node:url' import { dirname } from 'node:path' -import { merge, mergeWith } from 'lodash-es' +import { isArray, merge } from 'lodash-es' import { name } from '../package.json' -import emojis from './emojis.json' +import { r } from './utils/utils' +import emojis from './presets/default.json' globalThis.__eemoji_pkg__ = globalThis.__eemoji_pkg__ || { entryDir: dirname(fileURLToPath(import.meta.url)), @@ -15,15 +15,22 @@ type PipePropName = T extends `${infer First}|${infer _}` ? First : T type StringOrOptionalProp = { [K in keyof T as K extends 'breaking' ? never : PipePropName]: T[K] | Record -} | Record> +} -type EmojiType = StringOrOptionalProp & { breaking?: string } +type EmojiType = StringOrOptionalProp & { breaking: string } +export type EmojiConfig = Record> -export interface Config { +type DefineConfig = Partial<{ format: string strict: boolean - emojis: EmojiType -} + emojis: EmojiType | EmojiConfig | EmojiConfig[] +}> + +export type Config = Required<{ + [K in keyof DefineConfig]: DefineConfig[K] extends infer U + ? U extends unknown[] ? never : U + : never +}> export const configTypes = [ 'ts', @@ -87,25 +94,34 @@ export default defineDefaultConfig({ ], } - cwd = process.env.INIT_CWD || process.cwd() - vscodeSettingsFile = path.join(this.cwd, '.vscode/settings.json') - gitCommitFile = path.join(this.cwd, '.git/COMMIT_EDITMSG') - hooksDir = path.join(this.cwd, '.git/hooks') - hookFile = path.join(this.cwd, '.git/hooks/prepare-commit-msg') + vscodeSettingsFile = r('.vscode/settings.json') + gitCommitFile = r('.git/COMMIT_EDITMSG') + hooksDir = r('.git/hooks') + hookFile = r('.git/hooks/prepare-commit-msg') entryFile = path.join(globalThis.__eemoji_pkg__.entryDir, 'hook.sh') } -export function defineConfig(config: Partial): Config { +export function defineConfig(config: DefineConfig): Config { const defaultConfig = new ConfigObject().defaultConfig + const emojis = mergeEmojis(config.emojis) || defaultConfig.emojis - return mergeWith({}, defaultConfig, config, (_objValue, srcValue, key) => { - if (key === 'emojis') - return srcValue - }) + return { + ...defaultConfig, + ...config, + emojis, + } } -export function defineDefaultConfig(config: Partial): Config { +export function defineDefaultConfig(config: DefineConfig): Config { const defaultConfig = new ConfigObject().defaultConfig + const emojis = mergeEmojis(config.emojis) + + return merge({}, defaultConfig, config, { emojis }) +} + +function mergeEmojis(emojis: DefineConfig['emojis']): EmojiConfig { + if (isArray(emojis)) + return emojis.reduce((acc, cur) => merge(acc, cur), {}) - return merge({}, defaultConfig, config) + return emojis || {} } diff --git a/src/eemoji.ts b/src/eemoji.ts index 2143708..1814f44 100644 --- a/src/eemoji.ts +++ b/src/eemoji.ts @@ -62,7 +62,7 @@ export function eemojify(text: string, config: Config, DEBUG?: number): string { } function getEmoji(type: string, text: string, config: Config, DEBUG?: number): string | undefined { - if (text.includes('!') && config.emojis.breaking) + if (text.includes('!') && config.emojis.breaking && typeof config.emojis.breaking === 'string') return config.emojis.breaking type = type.toLowerCase().replace(/\(.*\)/, '').trim() diff --git a/src/emojis.jsonc b/src/emojis.jsonc deleted file mode 100644 index 9a90b20..0000000 --- a/src/emojis.jsonc +++ /dev/null @@ -1,57 +0,0 @@ - -{ - "fix": { - ".": "πŸ”§", // general fix - "typo": "✏️", // fixed typo in code, docs, ui, etc. - "bug": "πŸ›", // fixed a bug - "security": "πŸ”’" // fixed security issues - }, - "chore": { - ".": "πŸ—‘οΈ", // did some chores - "release": "πŸ”–", // new release commit (pairs well with [bumpp](https://github.com/antfu/bumpp)) - "cleanup": "🧹", // cleaned up code, removed logs and debug stuff, made everyting ready for production - "license": "πŸ“œ", // changed the license - "lint": "🧼", // fixed linting errors - "deps": "πŸ“¦", // changed dependencies - "readme": "πŸ“•,πŸ“—,πŸ“˜,πŸ“™" // update the README - }, - "release": "πŸ”–", - "cleanup": "🧹", - "lint": "🧼", - "deps": { - ".": "πŸ“¦", // added/removed/changed dependencies - "up": "⬆️", // updated dependencies - "down": "⬇️" // downgraded dependencies - }, - "up": "⬆️", - "down": "⬇️", - "build": { - ".": "🦺", // work regarding build processes - "deps": "πŸ“¦" // dependabot PRs (see the prefix in the [dependabot.yml](./.github/dependabot.yml) file on how to add an emoji to our friend's PRs) - }, - "docs": { - ".": "πŸ“", // documented something - "readme": "πŸ“•,πŸ“—,πŸ“˜,πŸ“™" - }, - "feat": { - ".": "✨", // introduced a new feature - "enhance": "πŸ’Ž" // made something a little better (but still include in release notes) - }, - "enhance": "πŸ’Ž", // made something a little better (omit from release notes) - "test": "πŸ§ͺ", // worked on tests - "refactor": "♻️", // refactored code, achieved the same with less - "init|initial": "πŸŽ‰", // started a new project! - "perf": "⚑", // improved performance, achieved the same faster - "breaking": "πŸ’₯", // *special type:* will be used if the commit contains an exclamation mark (`!`), indicates breaking changes - "ci": "🦾", // changed workflow files, CI stuff - "config": "βš™οΈ", // changed configuration files - "style": "🎨", // design changes, style changes - "ui": "πŸͺŸ", // worked on UI, UX or layout - "text": "πŸ’¬", // changed string literals, text content - "revert": "βͺ", // revert a commit - "i18n": "🌐", // translated something - "security": "πŸ”’", - "wip": "🚧", // wildcard type, works for anything - "add": "βž•", - "remove": "βž–" -} diff --git a/src/index.ts b/src/index.ts index b88d8ea..56cc3c9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,6 +1,7 @@ import { runMain as _runMain } from 'citty' import { main } from './main' +export * from './presets' export { defineConfig, defineDefaultConfig, type Config } from './config' export const runMain = () => _runMain(main) diff --git a/src/presets.ts b/src/presets.ts new file mode 100644 index 0000000..ac9652a --- /dev/null +++ b/src/presets.ts @@ -0,0 +1,28 @@ +import * as fs from 'node:fs' +import * as jsonc from 'jsonc-parser' +import type { EmojiConfig } from './config' +import { r } from './utils/utils' + +type Preset = () => EmojiConfig +type PathLiteral = `${string}.jsonc` + +function createPresets(pathes: PathLiteral[]) { + return pathes.map((path) => { + const config: EmojiConfig = jsonc.parse(fs.readFileSync(r(`src/presets/${path}`), 'utf-8')) + return () => ({ ...config }) + }) +} + +export const [ + presetDefault, + presetMinimal, + presetAoc, +] = createPresets([ + 'default.jsonc', + 'minimal.jsonc', + 'aoc.jsonc', +]) as [ + Preset, + Preset, + Preset, +] diff --git a/src/presets/aoc.jsonc b/src/presets/aoc.jsonc new file mode 100644 index 0000000..d20e1f5 --- /dev/null +++ b/src/presets/aoc.jsonc @@ -0,0 +1,4 @@ +{ + "add": "🎁,πŸŽ…,πŸŽ„,❄️,β˜ƒοΈ", // finally, part 1 is done, it wasn't that hard + "progress": "πŸ”Ή" // *cries in part 2* +} diff --git a/src/emojis.json b/src/presets/default.json similarity index 100% rename from src/emojis.json rename to src/presets/default.json diff --git a/src/presets/default.jsonc b/src/presets/default.jsonc new file mode 100644 index 0000000..f568050 --- /dev/null +++ b/src/presets/default.jsonc @@ -0,0 +1,56 @@ +{ + "fix": { + ".": "πŸ”§", // general fix + "typo": "✏️", // fixed typo in code, docs, ui, etc. + "bug": "πŸ›", // fixed a bug + "security": "πŸ”’" // fixed security issues + }, + "chore": { + ".": "πŸ—‘οΈ", // did some chores + "release": "πŸ”–", // new release commit (pairs well with [bumpp](https://github.com/antfu/bumpp)) + "cleanup": "🧹", // cleaned up code, removed logs and debug stuff, made everyting ready for production + "license": "πŸ“œ", // changed the license + "lint": "🧼", // fixed linting errors + "deps": "πŸ“¦", // changed dependencies + "readme": "πŸ“•,πŸ“—,πŸ“˜,πŸ“™" // update the README + }, + "release": "πŸ”–", + "cleanup": "🧹", + "lint": "🧼", + "deps": { + ".": "πŸ“¦", // added/removed/changed dependencies + "up": "⬆️", // updated dependencies + "down": "⬇️" // downgraded dependencies + }, + "up": "⬆️", + "down": "⬇️", + "build": { + ".": "🦺", // work regarding build processes + "deps": "πŸ“¦" // dependabot PRs (see the prefix in the [dependabot.yml](./.github/dependabot.yml) file on how to add an emoji to our friend's PRs) + }, + "docs": { + ".": "πŸ“", // documented something + "readme": "πŸ“•,πŸ“—,πŸ“˜,πŸ“™" + }, + "feat": { + ".": "✨", // introduced a new feature + "enhance": "πŸ’Ž" // made something a little better (but still include in release notes) + }, + "enhance": "πŸ’Ž", // made something a little better (omit from release notes) + "test": "πŸ§ͺ", // worked on tests + "refactor": "♻️", // refactored code, achieved the same with less + "init|initial": "πŸŽ‰", // started a new project! + "perf": "⚑", // improved performance, achieved the same faster + "breaking": "πŸ’₯", // *special type:* will be used if the commit contains an exclamation mark (`!`), indicates breaking changes + "ci": "🦾", // changed workflow files, CI stuff + "config": "βš™οΈ", // changed configuration files + "style": "🎨", // design changes, style changes + "ui": "πŸͺŸ", // worked on UI, UX or layout + "text": "πŸ’¬", // changed string literals, text content + "revert": "βͺ", // revert a commit + "i18n": "🌐", // translated something + "security": "πŸ”’", + "wip": "🚧", // wildcard type, works for anything + "add": "βž•", + "remove": "βž–" +} diff --git a/src/presets/minimal.jsonc b/src/presets/minimal.jsonc new file mode 100644 index 0000000..5de8ff2 --- /dev/null +++ b/src/presets/minimal.jsonc @@ -0,0 +1,32 @@ +{ + "fix": { + ".": "πŸ”§", // general fix + "typo": "✏️", // fixed typo in code, docs, ui, etc. + "bug": "πŸ›" // fixed a bug + }, + "chore": { + ".": "πŸ—‘οΈ", // did some chores + "release": "πŸ”–", // new release commit (pairs well with [bumpp](https://github.com/antfu/bumpp)) + "cleanup": "🧹", // cleaned up code, removed logs and debug stuff, made everyting ready for production + "license": "πŸ“œ", // changed the license + "deps": "πŸ“¦" // changed dependencies + }, + "feat": "✨", // introduced a new feature + "docs": "πŸ“", // documentation changes + "test": "πŸ§ͺ", // worked on tests + "refactor": "♻️", // refactored code, achieved the same with less + "deps": { + ".": "πŸ“¦", // added/removed/changed dependencies + "up": "⬆️", // updated dependencies + "down": "⬇️" // downgraded dependencies + }, + "build": { + ".": "🦺", // work regarding build processes + "deps": "πŸ“¦" // dependabot PRs (see the prefix in the [dependabot.yml](./.github/dependabot.yml) file on how to add an emoji to our friend's PRs) + }, + "init": "πŸŽ‰", // started a new project! + "perf": "⚑", // improved performance, achieved the same faster + "breaking": "πŸ’₯", // *special type:* will be used if the commit contains an exclamation mark (`!`), indicates breaking changes + "ci": "🦾", // changed workflow files, CI stuff + "revert": "βͺ" // revert a commit +} diff --git a/src/utils/utils.ts b/src/utils/utils.ts new file mode 100644 index 0000000..ebc9835 --- /dev/null +++ b/src/utils/utils.ts @@ -0,0 +1,5 @@ +import * as path from 'node:path' +import * as process from 'node:process' + +const cwd = process.env.INIT_CWD || process.cwd() +export const r = (file: string) => path.join(cwd, file)