mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Chore: Convert changelog tool to TypeScript
This commit is contained in:
parent
bd4714037c
commit
ad51090cdb
@ -1740,6 +1740,9 @@ packages/tools/generate-database-types.js.map
|
|||||||
packages/tools/generate-images.d.ts
|
packages/tools/generate-images.d.ts
|
||||||
packages/tools/generate-images.js
|
packages/tools/generate-images.js
|
||||||
packages/tools/generate-images.js.map
|
packages/tools/generate-images.js.map
|
||||||
|
packages/tools/git-changelog.d.ts
|
||||||
|
packages/tools/git-changelog.js
|
||||||
|
packages/tools/git-changelog.js.map
|
||||||
packages/tools/lerna-add.d.ts
|
packages/tools/lerna-add.d.ts
|
||||||
packages/tools/lerna-add.js
|
packages/tools/lerna-add.js
|
||||||
packages/tools/lerna-add.js.map
|
packages/tools/lerna-add.js.map
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -1725,6 +1725,9 @@ packages/tools/generate-database-types.js.map
|
|||||||
packages/tools/generate-images.d.ts
|
packages/tools/generate-images.d.ts
|
||||||
packages/tools/generate-images.js
|
packages/tools/generate-images.js
|
||||||
packages/tools/generate-images.js.map
|
packages/tools/generate-images.js.map
|
||||||
|
packages/tools/git-changelog.d.ts
|
||||||
|
packages/tools/git-changelog.js
|
||||||
|
packages/tools/git-changelog.js.map
|
||||||
packages/tools/lerna-add.d.ts
|
packages/tools/lerna-add.d.ts
|
||||||
packages/tools/lerna-add.js
|
packages/tools/lerna-add.js
|
||||||
packages/tools/lerna-add.js.map
|
packages/tools/lerna-add.js.map
|
||||||
|
@ -1,25 +1,51 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
// Supported commit formats:
|
// Supported commit formats:
|
||||||
|
|
||||||
// (Desktop|Mobile|Android|iOS[CLI): (New|Improved|Fixed): Some message..... (#ISSUE)
|
// (Desktop|Mobile|Android|iOS[CLI): (New|Improved|Fixed): Some message..... (#ISSUE)
|
||||||
|
|
||||||
const { execCommand, githubUsername } = require('./tool-utils.js');
|
import { execCommand, githubUsername } from './tool-utils';
|
||||||
|
|
||||||
// From https://stackoverflow.com/a/6234804/561309
|
interface LogEntry {
|
||||||
function escapeHtml(unsafe) {
|
message: string;
|
||||||
// We only escape <> as this is enough for Markdown
|
commit: string;
|
||||||
return unsafe
|
author: Author;
|
||||||
// .replace(/&/g, '&')
|
|
||||||
.replace(/</g, '<')
|
|
||||||
.replace(/>/g, '>');
|
|
||||||
// .replace(/"/g, '"')
|
|
||||||
// .replace(/'/g, ''');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function gitLog(sinceTag) {
|
enum Platform {
|
||||||
let lines = await execCommand(`git log --pretty=format:"%H::::DIV::::%ae::::DIV::::%an::::DIV::::%s" ${sinceTag}..HEAD`);
|
Android = 'android',
|
||||||
lines = lines.split('\n');
|
Ios = 'ios',
|
||||||
|
Desktop = 'desktop',
|
||||||
|
Clipper = 'clipper',
|
||||||
|
Server = 'server',
|
||||||
|
Cli = 'cli',
|
||||||
|
PluginGenerator = 'plugin-generator',
|
||||||
|
}
|
||||||
|
|
||||||
|
enum PublishFormat {
|
||||||
|
Full = 'full',
|
||||||
|
Simple = 'simple',
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Options {
|
||||||
|
publishFormat: PublishFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Author {
|
||||||
|
email: string;
|
||||||
|
name: string;
|
||||||
|
login: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// From https://stackoverflow.com/a/6234804/561309
|
||||||
|
function escapeHtml(unsafe: string) {
|
||||||
|
// We only escape <> as this is enough for Markdown
|
||||||
|
return unsafe
|
||||||
|
.replace(/</g, '<')
|
||||||
|
.replace(/>/g, '>');
|
||||||
|
}
|
||||||
|
|
||||||
|
async function gitLog(sinceTag: string) {
|
||||||
|
const commandResult = await execCommand(`git log --pretty=format:"%H::::DIV::::%ae::::DIV::::%an::::DIV::::%s" ${sinceTag}..HEAD`);
|
||||||
|
const lines = commandResult.split('\n');
|
||||||
|
|
||||||
const output = [];
|
const output = [];
|
||||||
for (const line of lines) {
|
for (const line of lines) {
|
||||||
@ -46,31 +72,22 @@ async function gitLog(sinceTag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function gitTags() {
|
async function gitTags() {
|
||||||
const lines = await execCommand('git tag --sort=committerdate');
|
const lines: string = await execCommand('git tag --sort=committerdate');
|
||||||
return lines.split('\n').map(l => l.trim()).filter(l => !!l);
|
return lines.split('\n').map(l => l.trim()).filter(l => !!l);
|
||||||
}
|
}
|
||||||
|
|
||||||
function platformFromTag(tagName) {
|
function platformFromTag(tagName: string): Platform {
|
||||||
if (tagName.indexOf('v') === 0) return 'desktop';
|
if (tagName.indexOf('v') === 0) return Platform.Desktop;
|
||||||
if (tagName.indexOf('android') >= 0) return 'android';
|
if (tagName.indexOf('android') >= 0) return Platform.Android;
|
||||||
if (tagName.indexOf('ios') >= 0) return 'ios';
|
if (tagName.indexOf('ios') >= 0) return Platform.Ios;
|
||||||
if (tagName.indexOf('clipper') === 0) return 'clipper';
|
if (tagName.indexOf('clipper') === 0) return Platform.Clipper;
|
||||||
if (tagName.indexOf('cli') === 0) return 'cli';
|
if (tagName.indexOf('cli') === 0) return Platform.Cli;
|
||||||
if (tagName.indexOf('server') === 0) return 'server';
|
if (tagName.indexOf('server') === 0) return Platform.Server;
|
||||||
if (tagName.indexOf('plugin-generator') === 0) return 'plugin-generator';
|
if (tagName.indexOf('plugin-generator') === 0) return Platform.PluginGenerator;
|
||||||
throw new Error(`Could not determine platform from tag: "${tagName}"`);
|
throw new Error(`Could not determine platform from tag: "${tagName}"`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// function tagPrefixFromPlatform(platform) {
|
function filterLogs(logs: LogEntry[], platform: Platform) {
|
||||||
// if (platform === 'desktop') return '';
|
|
||||||
// if (platform === 'android') return 'android-';
|
|
||||||
// if (platform === 'ios') return 'ios-';
|
|
||||||
// if (platform === 'clipper') return 'clipper-';
|
|
||||||
// if (platform === 'cli') return 'cli-';
|
|
||||||
// throw new Error(`Could not determine tag prefix from platform: ${platform}`);
|
|
||||||
// }
|
|
||||||
|
|
||||||
function filterLogs(logs, platform) {
|
|
||||||
const output = [];
|
const output = [];
|
||||||
const revertedLogs = [];
|
const revertedLogs = [];
|
||||||
|
|
||||||
@ -124,7 +141,7 @@ function filterLogs(logs, platform) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatCommitMessage(commit, msg, author, options) {
|
function formatCommitMessage(commit: string, msg: string, author: Author, options: Options): string {
|
||||||
options = Object.assign({}, { publishFormat: 'full' }, options);
|
options = Object.assign({}, { publishFormat: 'full' }, options);
|
||||||
|
|
||||||
let output = '';
|
let output = '';
|
||||||
@ -133,8 +150,8 @@ function formatCommitMessage(commit, msg, author, options) {
|
|||||||
|
|
||||||
let subModule = '';
|
let subModule = '';
|
||||||
|
|
||||||
const isPlatformPrefix = prefix => {
|
const isPlatformPrefix = (prefixString: string) => {
|
||||||
prefix = prefix.split(',').map(p => p.trim().toLowerCase());
|
const prefix = prefixString.split(',').map(p => p.trim().toLowerCase());
|
||||||
for (const p of prefix) {
|
for (const p of prefix) {
|
||||||
if (['android', 'mobile', 'ios', 'desktop', 'cli', 'clipper', 'all', 'api', 'plugins', 'server'].indexOf(p) >= 0) return true;
|
if (['android', 'mobile', 'ios', 'desktop', 'cli', 'clipper', 'all', 'api', 'plugins', 'server'].indexOf(p) >= 0) return true;
|
||||||
}
|
}
|
||||||
@ -154,7 +171,7 @@ function formatCommitMessage(commit, msg, author, options) {
|
|||||||
|
|
||||||
output = output.split('\n')[0].trim();
|
output = output.split('\n')[0].trim();
|
||||||
|
|
||||||
const detectType = msg => {
|
const detectType = (msg: string) => {
|
||||||
msg = msg.trim().toLowerCase();
|
msg = msg.trim().toLowerCase();
|
||||||
|
|
||||||
if (msg.indexOf('fix') === 0) return 'fixed';
|
if (msg.indexOf('fix') === 0) return 'fixed';
|
||||||
@ -166,7 +183,7 @@ function formatCommitMessage(commit, msg, author, options) {
|
|||||||
return 'improved';
|
return 'improved';
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseCommitMessage = (msg, subModule) => {
|
const parseCommitMessage = (msg: string, subModule: string) => {
|
||||||
const parts = msg.split(':');
|
const parts = msg.split(':');
|
||||||
|
|
||||||
if (parts.length === 1) {
|
if (parts.length === 1) {
|
||||||
@ -202,20 +219,14 @@ function formatCommitMessage(commit, msg, author, options) {
|
|||||||
if (t.indexOf('improved') === 0) type = 'improved';
|
if (t.indexOf('improved') === 0) type = 'improved';
|
||||||
if (t.indexOf('security') === 0) type = 'security';
|
if (t.indexOf('security') === 0) type = 'security';
|
||||||
|
|
||||||
// if (t.indexOf('security') === 0) {
|
|
||||||
// type = 'security';
|
|
||||||
// parts.splice(0, 1);
|
|
||||||
// message = parts.join(':').trim();
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (!type) {
|
if (!type) {
|
||||||
type = detectType(message);
|
type = detectType(message);
|
||||||
if (originalType.toLowerCase() === 'tinymce') originalType = 'WYSIWYG';
|
if (originalType.toLowerCase() === 'tinymce') originalType = 'WYSIWYG';
|
||||||
message = `${originalType}: ${message}`;
|
message = `${originalType}: ${message}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
let issueNumber = output.match(/#(\d+)/);
|
const issueNumberMatch = output.match(/#(\d+)/);
|
||||||
issueNumber = issueNumber && issueNumber.length >= 2 ? issueNumber[1] : null;
|
const issueNumber = issueNumberMatch && issueNumberMatch.length >= 2 ? issueNumberMatch[1] : null;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
type: type,
|
type: type,
|
||||||
@ -271,7 +282,7 @@ function formatCommitMessage(commit, msg, author, options) {
|
|||||||
return escapeHtml(output);
|
return escapeHtml(output);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createChangeLog(logs, options) {
|
function createChangeLog(logs: LogEntry[], options: Options) {
|
||||||
const output = [];
|
const output = [];
|
||||||
|
|
||||||
for (const log of logs) {
|
for (const log of logs) {
|
||||||
@ -281,35 +292,13 @@ function createChangeLog(logs, options) {
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
function capitalizeFirstLetter(string) {
|
function capitalizeFirstLetter(string: string) {
|
||||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// function decreaseTagVersion(tag) {
|
|
||||||
// const s = tag.split('.');
|
|
||||||
|
|
||||||
// let updated = false;
|
|
||||||
|
|
||||||
// for (let tokenIndex = s.length - 1; tokenIndex >= 0; tokenIndex--) {
|
|
||||||
// const token = s[tokenIndex];
|
|
||||||
// const s2 = token.split('-');
|
|
||||||
// let num = Number(s2[0]);
|
|
||||||
// num--;
|
|
||||||
// if (num >= 0) {
|
|
||||||
// updated = true;
|
|
||||||
// s[tokenIndex] = num;
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!updated) throw new Error(`Cannot decrease tag version: ${tag}`);
|
|
||||||
|
|
||||||
// return s.join('.');
|
|
||||||
// }
|
|
||||||
|
|
||||||
// This function finds the first relevant tag starting from the given tag.
|
// This function finds the first relevant tag starting from the given tag.
|
||||||
// The first "relevant tag" is the one that exists, and from which there are changes.
|
// The first "relevant tag" is the one that exists, and from which there are changes.
|
||||||
async function findFirstRelevantTag(baseTag, platform, allTags) {
|
async function findFirstRelevantTag(baseTag: string, platform: Platform, allTags: string[]) {
|
||||||
let baseTagIndex = allTags.indexOf(baseTag);
|
let baseTagIndex = allTags.indexOf(baseTag);
|
||||||
if (baseTagIndex < 0) baseTagIndex = allTags.length;
|
if (baseTagIndex < 0) baseTagIndex = allTags.length;
|
||||||
|
|
||||||
@ -349,8 +338,8 @@ async function main() {
|
|||||||
|
|
||||||
const filteredLogs = filterLogs(logsSinceTags, platform);
|
const filteredLogs = filterLogs(logsSinceTags, platform);
|
||||||
|
|
||||||
let publishFormat = 'full';
|
let publishFormat: PublishFormat = PublishFormat.Full;
|
||||||
if (['android', 'ios'].indexOf(platform) >= 0) publishFormat = 'simple';
|
if (['android', 'ios'].indexOf(platform) >= 0) publishFormat = PublishFormat.Simple;
|
||||||
if (argv.publishFormat) publishFormat = argv.publishFormat;
|
if (argv.publishFormat) publishFormat = argv.publishFormat;
|
||||||
let changelog = createChangeLog(filteredLogs, { publishFormat: publishFormat });
|
let changelog = createChangeLog(filteredLogs, { publishFormat: publishFormat });
|
||||||
|
|
@ -109,7 +109,7 @@ async function saveGitHubUsernameCache(cache: any) {
|
|||||||
// Returns the project root dir
|
// Returns the project root dir
|
||||||
export const rootDir = require('path').dirname(require('path').dirname(__dirname));
|
export const rootDir = require('path').dirname(require('path').dirname(__dirname));
|
||||||
|
|
||||||
export function execCommand(command: string, options: any = null) {
|
export function execCommand(command: string, options: any = null): Promise<string> {
|
||||||
options = options || {};
|
options = options || {};
|
||||||
|
|
||||||
const exec = require('child_process').exec;
|
const exec = require('child_process').exec;
|
||||||
@ -322,6 +322,11 @@ export async function githubUsername(email: string, name: string) {
|
|||||||
|
|
||||||
const urlsToTry = [
|
const urlsToTry = [
|
||||||
`https://api.github.com/search/users?q=${encodeURI(email)}+in:email`,
|
`https://api.github.com/search/users?q=${encodeURI(email)}+in:email`,
|
||||||
|
|
||||||
|
// Note that this can fail if the email could not be found and the user
|
||||||
|
// shares a name with someone else. It's rare enough that we can leave
|
||||||
|
// it for now.
|
||||||
|
// https://github.com/laurent22/joplin/pull/5390
|
||||||
`https://api.github.com/search/users?q=user:${encodeURI(name)}`,
|
`https://api.github.com/search/users?q=user:${encodeURI(name)}`,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user