Skip to content

Commit

Permalink
feat: ✨ add Gitlab issues support
Browse files Browse the repository at this point in the history
  • Loading branch information
thierrymichel committed Jul 18, 2023
1 parent 54857b1 commit 77cb008
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 28 deletions.
65 changes: 65 additions & 0 deletions src/gitlab.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { execSync } from 'child_process'
import fetch from 'node-fetch'

function getApiInfos() {
const { GITLAB_API_PRIVATE_TOKEN: token, GITLAB_API_ENDPOINT: api } =
process.env

if (!token) {
throw new Error('Gitlab TOKEN is not defined')
}

if (!api) {
throw new Error('Gitlab API is not defined')
}

return { token, api }
}

function getProjectPath() {
const projectRemote = execSync('git remote get-url origin').toString()
const projectPath = encodeURIComponent(
projectRemote.trim().replace(/^git@git\.epic\.net:(.*)\.git+$/, '$1')
)

return projectPath
}

async function getIssues() {
try {
// ? manage pagination?
const page = 1
const { api, token } = getApiInfos()
const projectPath = getProjectPath()
const url = `${api}/projects/${projectPath}/issues`
const res = await fetch(`${url}?state=opened&per_page=5&page=${page}`, {
headers: {
'PRIVATE-TOKEN': token,
},
})

if (!res.ok) {
console.error(
`Error fetching issues [${url}]`,
res.status,
res.statusText
)

return []
}

const data = await res.json()
const issues = data.map(issue => ({
name: `#${issue.iid} - ${issue.title}`,
value: issue.iid,
}))

return issues
} catch (error) {
console.error(error.message)

return []
}
}

export { getIssues }
83 changes: 55 additions & 28 deletions src/index.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import rightPad from 'right-pad'
import wrap from 'wrap-ansi'

import { getEmojis } from './gitmojis.mjs'
import { getIssues } from './gitlab.mjs'

// https://www.stefanjudis.com/snippets/how-to-import-json-files-in-es-modules-node-js/
import { createRequire } from 'module'
Expand All @@ -34,11 +35,12 @@ const defaultConfig = {
additionalEmojis: [],
useScopes: true,
useLernaScopes: false,
useBranchScopes: false,
useFolderScopes: false,
useBranchScopes: true,
useFolderScopes: true,
folderRoot: '.',
folderIgnore: [],
additionalScopes: [],
useGitlab: true,
// You can use yours
// types: {},
// emojis: [],
Expand Down Expand Up @@ -185,9 +187,39 @@ async function loadOptions(config) {
options.scopes = [...scopes, ...config.additionalScopes]
}

if (config.useGitlab) {
let issues = [
{
name: '[none]',
value: '',
},
]

const gitlabIssues = await getIssues()
issues = issues.concat(gitlabIssues)

options.issues = issues
}

return options
}

function getSource(data) {
return function render(_answersSoFar, input) {
const query = input || ''

return new Promise(resolve => {
const result = fuzzy.filter(query, data, {
extract: el => el.name,
})

setTimeout(() => {
resolve(result.map(el => el.original))
}, 100)
})
}
}

/**
* Fill prompt for questions
* 1. Type
Expand All @@ -202,27 +234,14 @@ async function loadOptions(config) {
* @return {array} list of questions
*/
function fillPrompt(options) {
const { types, scopes, emojis } = options
const { types, scopes, emojis, issues } = options
const prompts = [
{
type: 'autocomplete',
name: 'type',
// eslint-disable-next-line quotes
message: "Select the type of change you're committing:",

source: (_answersSoFar, input) => {
const query = input || ''

return new Promise(resolve => {
const result = fuzzy.filter(query, types, {
extract: el => el.name,
})

setTimeout(() => {
resolve(result.map(el => el.original))
}, 100)
})
},
source: getSource(types),
},
{
type: scopes ? 'list' : 'input',
Expand Down Expand Up @@ -251,6 +270,12 @@ function fillPrompt(options) {
name: 'body',
message: 'Provide a longer description:\n',
},
{
type: issues ? 'autocomplete' : 'input',
name: 'issues',
message: 'Pick related issue:',
source: getSource(issues),
},
{
type: 'confirm',
name: 'isBreaking',
Expand All @@ -263,11 +288,6 @@ function fillPrompt(options) {
message: 'Describe the breaking changes:\n',
when: answers => answers.isBreaking,
},
{
type: 'input',
name: 'issues',
message: 'List any issue closed (#1, ...):',
},
]

if (options.useBranchScopes) {
Expand Down Expand Up @@ -332,7 +352,18 @@ function format(answers) {
const scope = answers.scope ? answers.scope.trim() : ''
const branch = answers.branch ? answers.branch.trim() : ''

const formatedScope = scope === '' ? branch : `(${scope}${branch})`
let formatedScope

if (scope !== '' && branch !== '') {
formatedScope = `${scope}:${branch}`
} else {
formatedScope = scope || branch
}

if (formatedScope !== '') {
formatedScope = `(${formatedScope})`
}

// Optional subject with emoji
const subject = answers.emoji ? `${answers.emoji} ${answers.subject}` : ''

Expand All @@ -345,12 +376,8 @@ function format(answers) {
const breaking = answers.breaking
? wrap(`BREAKING CHANGE: ${answers.breaking.trim()}`, 120)
: ''
const footer = (answers.issues.match(/#\d+/g) || [])
// .map(issue => `Closes ${issue}`)
.map(issue => `[#${issue}]`)
.join('\n')

return [head, body, breaking, footer]
return [head, body, breaking]
.filter(part => part.length > 0)
.join('\n\n')
.trim()
Expand Down

0 comments on commit 77cb008

Please sign in to comment.