UNPKG

changelog-guru

Version:
153 lines (152 loc) 8.85 kB
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { if (kind === "m") throw new TypeError("Private method is not writable"); if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _Builder_config, _Builder_package, _Builder_state; import { promises as fs } from 'fs'; import { Package } from 'package-json-helper'; import { Dependencies, Restriction } from 'package-json-helper/types/package'; import path from 'path'; import TaskTree from 'tasktree-cli'; import md from '../utils/markdown.js'; import { findSame } from '../utils/text.js'; import { GitServiceProvider } from './Config.js'; import Commit from './entities/Commit.js'; import Message from './entities/Message.js'; import Section from './entities/Section.js'; import GitHubProvider from './providers/GitHubProvider.js'; import GitLabProvider from './providers/GitLabProvider.js'; import State from './State.js'; class Builder { constructor(config) { _Builder_config.set(this, void 0); _Builder_package.set(this, void 0); _Builder_state.set(this, void 0); __classPrivateFieldSet(this, _Builder_config, config, "f"); __classPrivateFieldSet(this, _Builder_package, new Package(), "f"); } async build() { await __classPrivateFieldGet(this, _Builder_config, "f").init(); await __classPrivateFieldGet(this, _Builder_package, "f").read(); if (__classPrivateFieldGet(this, _Builder_package, "f").repository?.url) { const provider = new { [GitServiceProvider.GitHub]: GitHubProvider, [GitServiceProvider.GitLab]: GitLabProvider, }[__classPrivateFieldGet(this, _Builder_config, "f").provider](__classPrivateFieldGet(this, _Builder_package, "f").repository.url, __classPrivateFieldGet(this, _Builder_config, "f").branch); await this.read(provider); await this.write(provider); } else { TaskTree.fail('Package repository url is not defined!'); } } async bumpPackage(provider) { if (__classPrivateFieldGet(this, _Builder_config, "f").bump && __classPrivateFieldGet(this, _Builder_package, "f").version && __classPrivateFieldGet(this, _Builder_state, "f")) { const task = TaskTree.add('Updating package version'); const date = await provider.getLastChangeDate(true); const { version: prevVersion } = await provider.getCurrentPackage(date); const { version } = __classPrivateFieldGet(this, _Builder_package, "f"); if (prevVersion && prevVersion !== version) { task.skip(`Package version is already changed from {bold ${prevVersion}(${provider.branch.dev})} to {bold ${version}}`); } else { const [major, minor, patch] = __classPrivateFieldGet(this, _Builder_state, "f").changesLevels; if (major || minor || patch) { __classPrivateFieldGet(this, _Builder_package, "f").bump({ major, minor, patch }); await __classPrivateFieldGet(this, _Builder_package, "f").save(); task.complete(`Package version updated to {bold ${__classPrivateFieldGet(this, _Builder_package, "f").version}}`); } else { task.skip('Package version does not change'); } } task.clear(); } } async read(provider) { const stage = TaskTree.add('Loading repository changes...'); try { const date = await provider.getLastChangeDate(); const commits = await provider.getCommits(date); const previousPackage = await provider.getPreviousPackage(date); if (__classPrivateFieldGet(this, _Builder_package, "f").license) { const state = new State(__classPrivateFieldGet(this, _Builder_package, "f").license, previousPackage.license); [...Object.values(Dependencies), ...Object.values(Restriction)].forEach(name => { state.addChanges(name, __classPrivateFieldGet(this, _Builder_package, "f").getChanges(name, previousPackage)); }); commits.forEach(commit => state.addCommit(commit)); __classPrivateFieldSet(this, _Builder_state, state, "f"); stage.clear(); stage.log(`Branch {bold ${__classPrivateFieldGet(this, _Builder_config, "f").branch}} last changes at: {bold ${date.toLocaleString()}}`); stage.log(`{bold ${commits.length}} commits loaded`); stage.complete('Release information:'); } else { stage.fail('Package license is not defined'); } } catch (error) { stage.error(error, true); } } renderCommits(commits) { const groups = new Map(); commits.forEach(commit => { const subject = findSame(commit.subject, [...groups.keys()]) ?? commit.subject; const { accents, links } = groups.get(subject) ?? { subject, accents: new Set(), links: [] }; commit.accents.forEach(accent => accents.add(accent)); links.push(md.commit(commit.shortName, commit.url)); groups.set(commit.subject, { subject, accents, links }); }); return [ ...[...groups.values()].map(({ subject, accents, links }) => md.list([ accents.size ? md.strong(`[${[...accents.values()].map(md.capitalize).join(', ')}]`) : '', md.capitalize(subject), ...links, ] .filter(Boolean) .join(' '))), '', ]; } renderSection(section, level = 1) { const sections = section.sections.filter(Section.filter); const commits = section.commits.filter(Commit.filter); const messages = section.messages.filter(Message.filter); const output = section.isDetails ? [md.summary(section.title)] : [md.title(section.title, level)]; if (messages.length) output.push(...messages.map(message => message.text), ''); if (sections.length) output.push(...sections.map(subsection => this.renderSection(subsection, level + 1))); if (sections.length && commits.length) output.push(md.title('Others', level + 1)); if (commits.length) output.push(...this.renderCommits(commits)); return section.isDetails ? md.details(output.join('\n')) : output.join('\n'); } async write(provider) { if (__classPrivateFieldGet(this, _Builder_state, "f")) { const task = TaskTree.add('Generate changelog...'); __classPrivateFieldGet(this, _Builder_state, "f").updateCommitsChangeLevel(__classPrivateFieldGet(this, _Builder_config, "f").types); __classPrivateFieldGet(this, _Builder_state, "f").ignore(__classPrivateFieldGet(this, _Builder_config, "f").exclusions); await __classPrivateFieldGet(this, _Builder_state, "f").modify(__classPrivateFieldGet(this, _Builder_config, "f").rules); const data = __classPrivateFieldGet(this, _Builder_state, "f").sections.map(subsection => this.renderSection(subsection)); const filePath = path.resolve(process.cwd(), __classPrivateFieldGet(this, _Builder_config, "f").filePath); if (__classPrivateFieldGet(this, _Builder_state, "f").authors) { data.push(md.contributors(__classPrivateFieldGet(this, _Builder_state, "f").authors.map(({ name, avatar, url }) => md.image(name, avatar, url))), ''); } await fs.writeFile(filePath, data.join('\n')); await this.bumpPackage(provider); task.complete('Changelog generated!'); } } } _Builder_config = new WeakMap(), _Builder_package = new WeakMap(), _Builder_state = new WeakMap(); export default Builder;