Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ Migrate cli to ESM #926

Merged
merged 11 commits into from Sep 29, 2022
30 changes: 30 additions & 0 deletions babel.config.json
@@ -0,0 +1,30 @@
{
"presets": [
"@babel/preset-flow"
],
"plugins": [
[
"module-resolver",
{
"alias": {
"@utils": "./src/utils",
"@commands": "./src/commands",
"@constants": "./src/constants"
}
}
],
"@babel/plugin-syntax-import-assertions",
"module-extension-resolver"
],
"env": {
"test": {
"presets": [
"@babel/preset-env",
"@babel/preset-flow"
],
"plugins": [
"babel-plugin-transform-import-meta"
]
}
}
}
50 changes: 16 additions & 34 deletions package.json
@@ -1,9 +1,10 @@
{
"name": "gitmoji-cli",
"version": "6.3.0",
"type": "module",
"description": "A gitmoji client for using emojis on commit messages.",
"engines": {
"node": ">=14"
"node": ">=14.16"
},
"bin": {
"gitmoji": "lib/cli.js"
Expand Down Expand Up @@ -43,26 +44,29 @@
},
"homepage": "https://github.com/carloscuesta/gitmoji-cli#readme",
"dependencies": {
"chalk": "4.1.0",
"chalk": "^5.0.1",
"conf": "10.2.0",
"execa": "5.1.1",
"execa": "^6.1.0",
"fuse.js": "6.6.2",
"inquirer": "8.2.4",
"inquirer": "8.x",
"inquirer-autocomplete-prompt": "2.0.0",
"meow": "9.0.0",
"node-fetch": "2.6.7",
"ora": "5.4.1",
"path-exists": "4.0.0",
"meow": "^10.1.3",
"node-fetch": "^3.2.10",
"ora": "^6.1.2",
"path-exists": "^5.0.0",
"proxy-agent": "5.0.0",
"update-notifier": "5.1.0",
"update-notifier": "^6.0.2",
"validator": "^13.7.0"
},
"devDependencies": {
"@babel/cli": "7.18.10",
"@babel/core": "7.19.1",
"@babel/plugin-syntax-import-assertions": "^7.18.6",
"@babel/preset-env": "7.19.1",
"@babel/preset-flow": "7.18.6",
"babel-plugin-module-extension-resolver": "^1.0.0-rc.2",
"babel-plugin-module-resolver": "^4.1.0",
"babel-plugin-transform-import-meta": "^2.2.0",
"codecov": "3.8.3",
"flow-bin": "^0.187.0",
"husky": "8.0.1",
Expand All @@ -73,31 +77,6 @@
"pkg": "5.8.0",
"prettier": "2.7.1"
},
"babel": {
"presets": [
[
"@babel/preset-env",
{
"targets": {
"node": "12"
}
}
],
"@babel/preset-flow"
],
"plugins": [
[
"module-resolver",
{
"alias": {
"@utils": "./src/utils",
"@commands": "./src/commands",
"@constants": "./src/constants"
}
}
]
]
},
"jest": {
"coverageDirectory": "./coverage/",
"collectCoverage": true,
Expand All @@ -110,7 +89,10 @@
"setupFiles": [
"./test/setupTests.js"
],
"transformIgnorePatterns": [],
"moduleNameMapper": {
"^#ansi-styles$": "<rootDir>/node_modules/chalk/source/vendor/ansi-styles/index.js",
"^#supports-color$": "<rootDir>/node_modules/chalk/source/vendor/supports-color/index.js",
"@utils/(.*)$": "<rootDir>/src/utils/$1",
"@commands/(.*)$": "<rootDir>/src/commands/$1",
"@constants/(.*)$": "<rootDir>/src/constants/$1"
Expand Down
11 changes: 8 additions & 3 deletions src/cli.js
Expand Up @@ -2,13 +2,17 @@
// @flow
import meow from 'meow'
import updateNotifier from 'update-notifier'
import { readFileSync } from 'fs'

import pkg from '../package.json'
import commands from './commands'
import FLAGS from '@constants/flags'
import findGitmojiCommand from '@utils/findGitmojiCommand'
import commands from './commands'

const packageJson: Object = readFileSync(
new URL('../package.json', import.meta.url)
)

updateNotifier({ pkg }).notify({ isGlobal: true })
updateNotifier({ pkg: JSON.parse(packageJson) }).notify({ isGlobal: true })

const cli = meow(
`
Expand All @@ -28,6 +32,7 @@ const cli = meow(
$ gitmoji bug linter -s
`,
{
importMeta: { url: import.meta.url },
flags: {
[FLAGS.COMMIT]: { type: 'boolean', alias: 'c' },
[FLAGS.CONFIG]: { type: 'boolean', alias: 'g' },
Expand Down
5 changes: 3 additions & 2 deletions src/commands/commit/prompts.js
@@ -1,15 +1,16 @@
// @flow
import inquirer from 'inquirer'
import inquirerAutocompletePrompt from 'inquirer-autocomplete-prompt'

import configurationVault from '@utils/configurationVault'
import filterGitmojis from '@utils/filterGitmojis'
import getDefaultCommitContent from '@utils/getDefaultCommitContent'
import { type CommitOptions } from './index'
import { type CommitOptions } from '.'
import guard from './guard'

const TITLE_MAX_LENGTH_COUNT: number = 48

inquirer.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'))
inquirer.registerPrompt('autocomplete', inquirerAutocompletePrompt)

export type Gitmoji = {
code: string,
Expand Down
2 changes: 1 addition & 1 deletion src/commands/commit/withClient/index.js
@@ -1,5 +1,5 @@
// @flow
import execa from 'execa'
import { execa } from 'execa'
import fs from 'fs'
import chalk from 'chalk'

Expand Down
2 changes: 1 addition & 1 deletion src/commands/commit/withHook/index.js
@@ -1,5 +1,5 @@
// @flow
import execa from 'execa'
import { execa } from 'execa'
import fs from 'fs'

import { type Answers } from '../prompts'
Expand Down
2 changes: 1 addition & 1 deletion src/commands/config/guard.js
@@ -1,5 +1,5 @@
import chalk from 'chalk'
import isURL from 'validator/lib/isURL'
import isURL from 'validator/lib/isURL.js'

const errors = {
url: chalk.red('Enter a valid API URL')
Expand Down
19 changes: 14 additions & 5 deletions src/utils/configurationVault/getConfiguration.js
@@ -1,6 +1,7 @@
import Conf from 'conf'
import { cwd } from 'process'
import pathExists from 'path-exists'
import { readFileSync } from 'fs'
import { pathExistsSync } from 'path-exists'

import { CONFIG, EMOJI_COMMIT_FORMATS } from '@constants/configuration'

Expand All @@ -23,19 +24,27 @@ const LOCAL_CONFIGURATION: typeof Conf = new Conf({
}
})

const getFile = (path: string): Buffer | void => {
try {
return JSON.parse(readFileSync(path))
} catch (error) {
return
}
}

const getConfiguration = (): { get: Function, set: Function } => {
const loadConfig = (): {
[$Values<typeof CONFIG>]: string | boolean
} => {
const packageJson = `${cwd()}/package.json`
const configurationFile = `${cwd()}/.gitmojirc.json`

if (pathExists.sync(packageJson) && require(packageJson)?.gitmoji) {
return require(packageJson).gitmoji
if (pathExistsSync(packageJson) && getFile(packageJson)?.gitmoji) {
return getFile(packageJson)?.gitmoji
}

if (pathExists.sync(configurationFile) && require(configurationFile)) {
return require(configurationFile)
if (pathExistsSync(configurationFile) && getFile(configurationFile)) {
return getFile(configurationFile)
}

return LOCAL_CONFIGURATION.store
Expand Down
6 changes: 3 additions & 3 deletions src/utils/emojisCache.js
Expand Up @@ -2,7 +2,7 @@
import fs from 'fs'
import os from 'os'
import path from 'path'
import pathExists from 'path-exists'
import { pathExistsSync } from 'path-exists'

export const GITMOJI_CACHE: Object = {
FOLDER: '.gitmoji',
Expand All @@ -16,7 +16,7 @@ export const CACHE_PATH: string = path.join(
)

const createEmojis = (emojis: Array<Object>): void => {
if (!pathExists.sync(path.dirname(CACHE_PATH))) {
if (!pathExistsSync(path.dirname(CACHE_PATH))) {
fs.mkdirSync(path.dirname(CACHE_PATH))
}

Expand All @@ -31,7 +31,7 @@ const getEmojis = (): Array<Object> => {
}
}

const isAvailable = (): boolean => pathExists.sync(CACHE_PATH)
const isAvailable = (): boolean => pathExistsSync(CACHE_PATH)

export default {
createEmojis,
Expand Down
2 changes: 1 addition & 1 deletion src/utils/getAbsoluteHooksPath.js
@@ -1,5 +1,5 @@
// @flow
import execa from 'execa'
import { execa } from 'execa'
import path from 'path'

const getAbsoluteHooksPath = async (hookName: string): Promise<string> => {
Expand Down
2 changes: 1 addition & 1 deletion src/utils/getDefaultCommitContent.js
@@ -1,7 +1,7 @@
// @flow
import fs from 'fs'

import { type CommitOptions } from '@commands/commit/index'
import { type CommitOptions } from '@commands/commit'
import COMMIT_MODES from '@constants/commit'

const COMMIT_FILE_PATH_INDEX = 3
Expand Down
1 change: 1 addition & 0 deletions test/__snapshots__/cli.spec.js.snap
Expand Up @@ -58,6 +58,7 @@ exports[`cli should match meow with cli information 1`] = `
"type": "boolean",
},
},
"importMeta": "import.meta.url",
},
],
]
Expand Down
2 changes: 2 additions & 0 deletions test/cli.spec.js
Expand Up @@ -16,6 +16,8 @@ describe('cli', () => {
})

it('should match meow with cli information', () => {
meow.mock.calls[0][1].importMeta = 'import.meta.url'

expect(meow.mock.calls).toMatchSnapshot()
})

Expand Down
17 changes: 8 additions & 9 deletions test/commands/commit.spec.js
@@ -1,8 +1,8 @@
import inquirer from 'inquirer'
import execa from 'execa'
import { execa } from 'execa'
import fs from 'fs'
import chalk from 'chalk'
const mockProcess = require('jest-mock-process')
import { mockProcessExit } from 'jest-mock-process'

import configurationVault from '@utils/configurationVault'
import getDefaultCommitContent from '@utils/getDefaultCommitContent'
Expand Down Expand Up @@ -162,7 +162,7 @@ describe('commit command', () => {
Promise.resolve(stubs.clientCommitAnswers)
)
getEmojis.mockResolvedValue(stubs.gitmojis)
mockProcess.mockProcessExit()
mockProcessExit()
process.argv[3] = stubs.argv
process.argv[COMMIT_MESSAGE_SOURCE] = undefined
getDefaultCommitContent.mockReturnValueOnce(
Expand Down Expand Up @@ -192,7 +192,7 @@ describe('commit command', () => {
Promise.resolve(stubs.clientCommitAnswersWithScope)
)
getEmojis.mockResolvedValue(stubs.gitmojis)
mockProcess.mockProcessExit()
mockProcessExit()
process.argv[3] = stubs.argv
process.argv[COMMIT_MESSAGE_SOURCE] = stubs.commitSource
getDefaultCommitContent.mockReturnValueOnce(
Expand Down Expand Up @@ -223,7 +223,7 @@ describe('commit command', () => {
Simulation needed because if we just mock process exit, then the code execution resume in the test.
*/
process.argv[COMMIT_MESSAGE_SOURCE] = stubs.commitSource
mockProcess.mockProcessExit(new Error('ProcessExit0'))
mockProcessExit(new Error('ProcessExit0'))
execa.mockReturnValueOnce(Promise.resolve(stubs.gitAbsoluteDir))
// mock that we found one of the rebase trigger (file existence in .git)
fs.existsSync.mockReturnValueOnce(true)
Expand All @@ -245,7 +245,7 @@ describe('commit command', () => {
when the hook mode detect that the user is rebasing. (Simulated to not kill the tests)
Simulation needed because if we just mock process exit, then the code execution resume in the test.
*/
mockProcess.mockProcessExit(new Error('ProcessExit0'))
mockProcessExit(new Error('ProcessExit0'))
execa.mockReturnValueOnce(Promise.resolve(stubs.gitAbsoluteDir))
// mock that we are amending
process.argv[COMMIT_MESSAGE_SOURCE] = 'commit sha123'
Expand Down Expand Up @@ -282,7 +282,7 @@ describe('commit command', () => {
getEmojis.mockResolvedValue(stubs.gitmojis)

// Use an exception to suspend code execution to simulate process.exit
mockProcess.mockProcessExit(new Error('SIGINT'))
mockProcessExit(new Error('SIGINT'))
process.argv[3] = stubs.argv
process.argv[COMMIT_MESSAGE_SOURCE] = stubs.commitSource

Expand All @@ -303,7 +303,7 @@ describe('commit command', () => {

describe('with git auto merge trigger by git pull', () => {
it('should cancel the hook', async () => {
mockProcess.mockProcessExit(new Error('ProcessExit0'))
mockProcessExit(new Error('ProcessExit0'))
execa.mockReturnValueOnce(Promise.resolve(stubs.gitAbsoluteDir))
// mock that we are merging
process.argv[3] = '.git/MERGE_MSG'
Expand All @@ -318,7 +318,6 @@ describe('commit command', () => {
expect(process.exit).toHaveBeenCalledWith(0)
})
})

})

describe('guard', () => {
Expand Down
3 changes: 3 additions & 0 deletions test/setupTests.js
Expand Up @@ -3,6 +3,9 @@ import fetchMock from 'jest-fetch-mock'
jest.setMock('node-fetch', fetchMock)
jest.mock('path-exists')
jest.mock('fs')
jest
.requireMock('fs')
.readFileSync.mockImplementation(jest.requireActual('fs').readFileSync)
jest.mock('ora', () =>
jest.fn().mockReturnValue({
start: jest.fn(function () {
Expand Down