Skip to content

Conversation

@parloti
Copy link
Contributor

@parloti parloti commented Jun 16, 2023

Description

Add an emoji in the title of the questions referring to the type of commit

Motivation and Context

Although emojis are already configured in config-conventional they are not used in cz-commitlint

TODO emoji + title

Usage examples

No need for configuration

How Has This Been Tested?

Tested in private repository

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Add an emoji in the title of the questions referring to the type of commit
@escapedcat
Copy link
Member

@parloti thanks! Any chance you can add a test for this?
@curly210102 what do you think about this PR?

@parloti
Copy link
Contributor Author

parloti commented Jun 17, 2023

@parloti thanks! Any chance you can add a test for this? @curly210102 what do you think about this PR?

Hi!
I'll add the tests, to cover the changes.

const enumDescription = enumDescriptions[enumName]?.description;
if (enumDescription) {
const emoji = enumDescriptions[enumName]?.emoji;
const prefix = emoji ? emoji + ' ' : '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Due to the different number of characters in the composition of Emoji, it is necessary to determine the longest one and perform space alignment processing.

image

@escapedcat escapedcat marked this pull request as draft October 20, 2023 14:16
@ZeliosAriex
Copy link

will this be implemented in a near future :) ?

@escapedcat
Copy link
Member

Please re-open when this continues

@escapedcat escapedcat closed this Jan 16, 2025
@phsd0

This comment was marked as off-topic.

@parloti
Copy link
Contributor Author

parloti commented Aug 16, 2025

Sorry guys, after some research, I gave up on finishing this.

Emojis have random, fractional sizes, and there's no easy way to find the pixel width in non-browser environments. And even if we had the width, we wouldn't be able to add a fraction of a white space to force alignment.

The best solution I could find was to add a tab between the emoji and the message.

image

But I'm not sure if this should be set in the service or if the emoji itself should have its own alignment characters.

@escapedcat if you find this solution viable I can write the tests.

@parloti parloti mentioned this pull request Aug 20, 2025
4 tasks
@ViniDevBR
Copy link

hey guys lets talk about this?
this is beautiful and good for community

@escapedcat
Copy link
Member

@parloti might be better than nothing. Would you mind adjusting the docs how to use this?

@ViniDevBR
Copy link

ViniDevBR commented Aug 20, 2025

@parloti might be better than nothing. Would you mind adjusting the docs how to use this?

I created an issue with everything.

Docs and examples

@ViniDevBR
Copy link

you can see here

#4534 (comment)

@escapedcat
Copy link
Member

Yeah, should be added to this PR

@ViniDevBR
Copy link

Expected Behavior

Please add this

cz-commitlint -> lib -> services -> getRuleQuestionConfig.js : 30

enumList = enumRuleList
                .sort((a, b) => enumNames.indexOf(a) - enumNames.indexOf(b))
                .map((enumName) => {
                    const enumDescription = enumDescriptions[enumName]?.description;
                    const emoji = enumDescriptions[enumName]?.emoji ? enumDescriptions[enumName].emoji : '';

                    if (enumDescription) {
                        return {
                            name: `${emoji} ${enumName}:`.padEnd(longest + 8) + enumDescription,
                            value: enumName,
                            short: enumName,
                            emoji: emoji || null
                        };
                    }
                    else {
                        return enumName;
                    }
                }
            );

cz-commitlint -> lib -> SectionHeader.js

export function getEmojis() {
    const headerRuleQuestionConfig = getRuleQuestionConfig("header");

    if (!headerRuleQuestionConfig) {
        return [];
    }

    const emojis = headerRuleQuestionConfig?.enumList?.map(item => {
        if (typeof item === 'object') {
            return { value: item.value, emoji: item.emoji || '' };
        }

        return { value: item, emoji: null };
    })

   return emojis || [];
}

export function combineCommitMessage(answers) {
    const { type = "", scope = "", subject = "" } = answers;

    const questions = getQuestions();

    const emoji = questions
        .find(item => item.type === 'list' && item.name === 'type')?.choices
        ?.find(choice => choice.value === type)?.emoji;

    const prefix = `${emoji?.trim()} ${type}${scope ? `(${scope})` : ""}`;
    if (subject) {
        return ((prefix ? prefix + ": " : "") + subject).trim();
    }
    else {
        return prefix.trim();
    }
}

Config for gitmoji

import { UserConfig } from "@commitlint/types";
import gitmoji from 'commitlint-config-gitmoji'

/**
 * @type {import('@commitlint/types').UserConfig}
 */
module.exports = {
  extends: ['@commitlint/config-conventional'],
  prompt: {
    questions: {
      type: {
        description: "Select the type of change that you're committing",
        enum: {
          feat: {
            description: "A new feature",
            title: "Features",
            emoji: "✨",
          },
          fix: {
            description: "A bug fix",
            title: "Bug Fixes",
            emoji: "🐛",
          },
          docs: {
            description: "Documentation only changes",
            title: "Documentation",
            emoji: "📚",
          },
          style: {
            description:
              "Changes that do not affect the meaning of the code (linters)",
            title: "Styles",
            emoji: "🎨",
          },
          refactor: {
            description:
              "A code change that neither fixes a bug nor adds a feature",
            title: "Code Refactoring",
            emoji: "📦",
          },
          perf: {
            description: "A code change that improves performance",
            title: "Performance Improvements",
            emoji: "🚀",
          },
          test: {
            description: "Adding missing tests or correcting existing tests",
            title: "Tests",
            emoji: "🚨",
          },
          build: {
            description:
              "Changes that affect the build system or external dependencies (yarn)",
            title: "Builds",
            emoji: "🏗️ ",
          },
          ci: {
            description:
              "Changes to our CI configuration files and scripts (GitActions)",
            title: "Continuous Integrations",
            emoji: "⚙️ ",
          },
          chore: {
            description: "Other changes that don't modify src or test files",
            title: "Chores",
            emoji: "♻️ ",
          },
          revert: {
            description: "Reverts a previous commit",
            title: "Reverts",
            emoji: "⏪",
          },
        },
      },
    },
  },
  parserPreset: {
    parserOpts: gitmoji.parserPreset.parserOpts,
    plugins: [gitmoji.parserPreset.plugins],
  },
  ...gitmoji.rules,
  ...gitmoji.plugins
} as UserConfig

.czrc

{
  "path": "@commitlint/cz-commitlint",
  "useGitmojis": true
}

@ViniDevBR
Copy link

I just added the git moji just for parse the emojis in the regex. But if this will be default, we can create our parse.
or remove the icon when make the parse... and add later.

Or just show this in the options with CZ and return separated { emoji: '✅', message: '...' }, to add later parser

@ViniDevBR
Copy link

ViniDevBR commented Aug 21, 2025

Hey guys... anything more about this?
Lets continue this

@parloti
@escapedcat
@curly210102

@ViniDevBR
Copy link

ViniDevBR commented Aug 21, 2025

Sorry guys, after some research, I gave up on finishing this.

Emojis have random, fractional sizes, and there's no easy way to find the pixel width in non-browser environments. And even if we had the width, we wouldn't be able to add a fraction of a white space to force alignment.

The best solution I could find was to add a tab between the emoji and the message.

image But I'm not sure if this should be set in the service or if the emoji itself should have its own alignment characters.

@escapedcat if you find this solution viable I can write the tests.

about this... we can create 2 options

ci: {
            description:
              "Changes to our CI configuration files and scripts (GitActions)",
            title: "Continuous Integrations",
            emoji: "⚙️ ",
          },

add some space in the emoji...
or

ci: {
            description:
              "Changes to our CI configuration files and scripts (GitActions)",
            title: "Continuous Integrations",
            emoji: "⚙️",
            emojiBlankArea: true
          },

with this boolean option we can do a condition for space or in the function to make the space.

and need to make a parser of this. I used from gitmoji. but we can reuse the gitmoji parser and sum with the ours

@parloti
Copy link
Contributor Author

parloti commented Aug 21, 2025

Working on it!

@ViniDevBR
Copy link

another solution

#!/usr/bin/env ts-node
import fs from "fs"

// get commit msg file from git
const commitMsgFile = process.argv[2]
const msg = fs.readFileSync(commitMsgFile, "utf8")
const lines = msg.split("\n")
const firstLine = lines[0]

// import commitlint.config.ts
import commitlintConfig  from "../../commitlint.config.js"

const types = commitlintConfig.prompt?.questions?.type?.enum ?? {}

// Regex to get type with scope or no scope
const match = firstLine.match(/^([a-z]+)(?:\([^)]+\))?:/)
const type = match ? match[1] : null

if (type && types[type]) {
  const emoji = types[type].emoji
  if (emoji && !firstLine.includes(emoji)) {
    // Add emoji
    const newFirstLine = `${emoji} ${firstLine}`
    const newMsg = [newFirstLine, ...lines.slice(1)].join("\n")

    fs.writeFileSync(commitMsgFile, newMsg, "utf8")
  }
}

later commitlint

node ./.husky/scripts/add-emoji.js "$1"

Its working good

and you can test creating a commit.txt
ci: test

and run

node ./.husky/scripts/add-emoji.js commit.txt

but the problem with space keep. and i just added a space.

the commitlint.config.js is here
#3618 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

6 participants