From 3140d341463d7293f4d1638cb0c76f32ca8053bc Mon Sep 17 00:00:00 2001 From: Federico Grandi Date: Sun, 29 Nov 2020 17:51:26 +0100 Subject: [PATCH] chore: add prettier --- .eslintrc | 64 -------- .eslintrc.js | 38 +++++ .prettierrc | 7 + package-lock.json | 45 ++++++ package.json | 4 + scripts/all-contributors-badge.ts | 16 +- scripts/changelog.ts | 19 ++- src/main.ts | 251 +++++++++++++++++++++--------- 8 files changed, 290 insertions(+), 154 deletions(-) delete mode 100644 .eslintrc create mode 100644 .eslintrc.js create mode 100644 .prettierrc diff --git a/.eslintrc b/.eslintrc deleted file mode 100644 index 6904920..0000000 --- a/.eslintrc +++ /dev/null @@ -1,64 +0,0 @@ -{ - "env": { - "node": true, - "browser": true, - "amd": true, - "es6": true - }, - "root": true, - "extends": [ - "eslint:recommended" - ], - "plugins": [ - "@typescript-eslint" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module", - "ecmaFeatures": { - "jsx": true - } - }, - "rules": { - "no-cond-assign": [ - 2, - "except-parens" - ], - "no-use-before-define": [ - 2, - { - "functions": false, - "classes": false, - "variables": false - } - ], - "new-cap": 0, - "no-caller": 2, - "no-undef": 2, - "no-unused-vars": 0, - "@typescript-eslint/no-unused-vars": "warn", - "no-empty": [ - "error", - { - "allowEmptyCatch": true - } - ], - "no-console": "off", - "prefer-const": [ - "warn", - { - "destructuring": "all" - } - ], - "quotes": [ - "warn", - "single" - ], - "semi": [ - "warn", - "never" - ], - "spaced-comment": "warn" - } -} diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..9c70afe --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,38 @@ +module.exports = { + env: { + commonjs: true, + es6: true, + node: true + }, + extends: [ + 'eslint:recommended', + 'prettier/@typescript-eslint', + 'plugin:prettier/recommended' + ], + globals: {}, + parser: '@typescript-eslint/parser', + parserOptions: { + ecmaVersion: 6, + sourceType: 'module' + }, + plugins: ['@typescript-eslint'], + rules: { + 'prettier/prettier': 'warn', + 'no-cond-assign': [2, 'except-parens'], + 'no-unused-vars': 0, + '@typescript-eslint/no-unused-vars': 1, + 'no-empty': [ + 'error', + { + allowEmptyCatch: true + } + ], + 'prefer-const': [ + 'warn', + { + destructuring: 'all' + } + ], + 'spaced-comment': 'warn' + } +} diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..6449b38 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "semi": false, + "singleQuote": true, + "tabWidth": 2, + "useTabs": false, + "trailingComma": "none" +} diff --git a/package-lock.json b/package-lock.json index dd0fc65..4b4bdb3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -602,6 +602,24 @@ } } }, + "eslint-config-prettier": { + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.15.0.tgz", + "integrity": "sha512-a1+kOYLR8wMGustcgAjdydMsQ2A/2ipRPwRKUmfYaSxc9ZPcrku080Ctl6zrZzZNs/U82MjSv+qKREkoq3bJaw==", + "dev": true, + "requires": { + "get-stdin": "^6.0.0" + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, "eslint-scope": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", @@ -691,6 +709,12 @@ "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", "dev": true }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -780,6 +804,12 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, "glob": { "version": "7.1.6", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", @@ -1387,6 +1417,21 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.2.1.tgz", + "integrity": "sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", diff --git a/package.json b/package.json index 5666d7e..8e12558 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "scripts": { "build": "ncc build src/main.ts --minify --out lib", "watch": "ncc build src/main.ts --watch --out lib", + "lint:fix": "eslint --ext .ts --fix src", "all-contributors-badge": "ts-node scripts/all-contributors-badge", "changelog": "ts-node scripts/changelog.ts", "test": "echo \"Error: no test specified\" && exit 1" @@ -45,7 +46,10 @@ "@vercel/ncc": "^0.25.1", "all-contributors-cli": "^6.19.0", "eslint": "^6.8.0", + "eslint-config-prettier": "^6.15.0", + "eslint-plugin-prettier": "^3.1.4", "husky": "^4.3.0", + "prettier": "^2.2.1", "ts-node": "^9.0.0", "typescript": "^4.1.2", "yamljs": "^0.3.0" diff --git a/scripts/all-contributors-badge.ts b/scripts/all-contributors-badge.ts index d35dc99..6036728 100644 --- a/scripts/all-contributors-badge.ts +++ b/scripts/all-contributors-badge.ts @@ -6,15 +6,19 @@ function path(...segments: string[]) { } const README = fs.readFileSync(path('README.md'), { encoding: 'utf8' }), - { contributors } = JSON.parse(fs.readFileSync(path('.all-contributorsrc'), { encoding: 'utf8' })) + { contributors } = JSON.parse( + fs.readFileSync(path('.all-contributorsrc'), { encoding: 'utf8' }) + ) if (!(contributors instanceof Array)) throw new Error('Invalid config file') -const updatedREADME = README - .split('\n') - .map(line => - line.startsWith('[![All Contributors](https://img.shields.io/badge/all_contributors-') +const updatedREADME = README.split('\n') + .map((line) => + line.startsWith( + '[![All Contributors](https://img.shields.io/badge/all_contributors-' + ) ? `[![All Contributors](https://img.shields.io/badge/all_contributors-${contributors.length}-orange.svg?style=flat)](#contributors-)` : line - ).join('\n') + ) + .join('\n') fs.writeFileSync(path('README.md'), updatedREADME) diff --git a/scripts/changelog.ts b/scripts/changelog.ts index 97b4fc1..7e93e38 100644 --- a/scripts/changelog.ts +++ b/scripts/changelog.ts @@ -2,7 +2,7 @@ import fs from 'fs' import path from 'path' const currentVersion = require('../package.json').version -if (!currentVersion) throw new Error('Cant\'t detect library version.') +if (!currentVersion) throw new Error("Cant't detect library version.") const changelogPath = path.resolve(__dirname, '../CHANGELOG.md') const changelog = fs.readFileSync(changelogPath, { encoding: 'utf-8' }) @@ -12,7 +12,8 @@ let futureChangelog = '' // Add version section let arr = changelog.split('## [Unreleased]') -arr[1] = ` +arr[1] = + ` ## [${currentVersion}] - ${new Date().toISOString().slice(0, 10)} ### Removed: @@ -28,13 +29,15 @@ futureChangelog = arr.join('## [Unreleased]') // Update footer arr = futureChangelog .split('\n') - .map(line => line.startsWith('[Unreleased]') - ? `[Unreleased]: https://github.com/EndBug/add-and-commit/compare/v${currentVersion}...HEAD` - : line) + .map((line) => + line.startsWith('[Unreleased]') + ? `[Unreleased]: https://github.com/EndBug/add-and-commit/compare/v${currentVersion}...HEAD` + : line + ) -// eslint-disable-next-line no-useless-escape -const lastVersion = ([...arr].reverse()[1]?.match(/\[([^\][]*)]/) || [])[0].replace(/[\[\]']+/g, '') -if (!lastVersion) throw new Error('Can\'t find last version in changelog.') +const lastVersion = ([...arr].reverse()[1]?.match(/\[([^\][]*)]/) || + [])[0].replace(/[\[\]']+/g, '') // eslint-disable-line no-useless-escape +if (!lastVersion) throw new Error("Can't find last version in changelog.") const lastLine = `[${currentVersion}]: https://github.com/EndBug/add-and-commit/compare/v${lastVersion}...v${currentVersion}` if (arr[arr.length - 1] === '') arr[arr.length - 1] = lastLine diff --git a/src/main.ts b/src/main.ts index c3654f6..2f84cef 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,15 +1,34 @@ -import { info, setFailed, getInput as getInputCore, warning, debug, startGroup, endGroup, error } from '@actions/core' +import { + info, + setFailed, + getInput as getInputCore, + warning, + debug, + startGroup, + endGroup, + error +} from '@actions/core' import axios from 'axios' import path from 'path' import simpleGit, { Response } from 'simple-git' -type Input = 'add' | 'author_name' | 'author_email' | 'branch' | 'cwd' | 'message' | 'pull_strategy' | 'push' | 'remove' | 'signoff' | 'tag' +type Input = + | 'add' + | 'author_name' + | 'author_email' + | 'branch' + | 'cwd' + | 'message' + | 'pull_strategy' + | 'push' + | 'remove' + | 'signoff' + | 'tag' const baseDir = path.join(process.cwd(), getInput('cwd') || '') const git = simpleGit({ baseDir }) -console.log(`Running in ${baseDir}`); - -(async () => { +console.log(`Running in ${baseDir}`) +;(async () => { await checkInputs().catch(setFailed) startGroup('Internal logs') @@ -33,7 +52,10 @@ console.log(`Running in ${baseDir}`); await git .addConfig('user.email', getInput('author_email'), undefined, log) .addConfig('user.name', getInput('author_name'), undefined, log) - debug('> Current git config\n' + JSON.stringify((await git.listConfig()).all, null, 2)) + debug( + '> Current git config\n' + + JSON.stringify((await git.listConfig()).all, null, 2) + ) await git.fetch(['--tags', '--force'], log) @@ -43,23 +65,35 @@ console.log(`Running in ${baseDir}`); .catch(() => git.checkoutLocalBranch(getInput('branch'), log)) info('> Pulling from remote...') - await git - .fetch(undefined, log) - .pull(undefined, undefined, { + await git.fetch(undefined, log).pull( + undefined, + undefined, + { [getInput('pull_strategy')]: null - }, log) + }, + log + ) info('> Re-staging files...') if (getInput('add')) await add({ ignoreErrors: true }) if (getInput('remove')) await remove({ ignoreErrors: true }) info('> Creating commit...') - await git.commit(getInput('message'), undefined, { - '--author': `"${getInput('author_name')} <${getInput('author_email')}>"`, - ...(getInput('signoff') ? { - '--signoff': null - } : {}) - }, log) + await git.commit( + getInput('message'), + undefined, + { + '--author': `"${getInput('author_name')} <${getInput( + 'author_email' + )}>"`, + ...(getInput('signoff') + ? { + '--signoff': null + } + : {}) + }, + log + ) if (getInput('tag')) { info('> Tagging commit...') @@ -68,19 +102,34 @@ console.log(`Running in ${baseDir}`); if (getInput('push')) { info('> Pushing commit to repo...') - await git.push('origin', getInput('branch'), { '--set-upstream': null }, log) + await git.push( + 'origin', + getInput('branch'), + { '--set-upstream': null }, + log + ) if (getInput('tag')) { info('> Pushing tags to repo...') - await git.pushTags('origin', (e, d?) => log(undefined, e || d)).catch(() => { - info('> Tag push failed: deleting remote tag and re-pushing...') - return git.push(undefined, undefined, { - '--delete': null, - 'origin': null, - [getInput('tag').split(' ').filter(w => !w.startsWith('-'))[0]]: null - }, log) - .pushTags('origin', log) - }) + await git + .pushTags('origin', (e, d?) => log(undefined, e || d)) + .catch(() => { + info('> Tag push failed: deleting remote tag and re-pushing...') + return git + .push( + undefined, + undefined, + { + '--delete': null, + origin: null, + [getInput('tag') + .split(' ') + .filter((w) => !w.startsWith('-'))[0]]: null + }, + log + ) + .pushTags('origin', log) + }) } else info('> No tags to push.') } else info('> Not pushing anything.') @@ -90,14 +139,14 @@ console.log(`Running in ${baseDir}`); endGroup() info('> Working tree clean. Nothing to commit.') } -})().catch(e => { +})().catch((e) => { endGroup() setFailed(e) }) async function checkInputs() { function setInput(input: Input, value: string | undefined) { - if (value) return process.env[`INPUT_${input.toUpperCase()}`] = value + if (value) return (process.env[`INPUT_${input.toUpperCase()}`] = value) else return delete process.env[`INPUT_${input.toUpperCase()}`] } function setDefault(input: Input, value: string) { @@ -111,34 +160,45 @@ async function checkInputs() { isPR = process.env.GITHUB_EVENT_NAME?.includes('pull_request'), sha = (event?.pull_request?.head?.sha || process.env.GITHUB_SHA) as string, defaultBranch = isPR - ? event?.pull_request?.head?.ref as string + ? (event?.pull_request?.head?.ref as string) : process.env.GITHUB_REF?.substring(11) // #region GITHUB_TOKEN - if (!token) warning('The GITHUB_TOKEN env variable is missing: the action may not work as expected.') + if (!token) + warning( + 'The GITHUB_TOKEN env variable is missing: the action may not work as expected.' + ) // #endregion // #region add, remove if (!getInput('add') && !getInput('remove')) - throw new Error('Both \'add\' and \'remove\' are empty, the action has nothing to do.') + throw new Error( + "Both 'add' and 'remove' are empty, the action has nothing to do." + ) // #endregion // #region author_name, author_email let author = event?.head_commit?.author if (sha && !author) { - info('> Unable to get commit from workflow event: trying with the GitHub API...') + info( + '> Unable to get commit from workflow event: trying with the GitHub API...' + ) // https://docs.github.com/en/rest/reference/repos#get-a-commit--code-samples const url = `https://api.github.com/repos/${process.env.GITHUB_REPOSITORY}/commits/${sha}`, - headers = token ? { - Authorization: `Bearer ${token}` - } : undefined, - commit = (await axios.get(url, { headers }).catch(err => { - startGroup('Request error:') - info(`> Request URL: ${url}\b${err}`) - endGroup() - return undefined - }))?.data + headers = token + ? { + Authorization: `Bearer ${token}` + } + : undefined, + commit = ( + await axios.get(url, { headers }).catch((err) => { + startGroup('Request error:') + info(`> Request URL: ${url}\b${err}`) + endGroup() + return undefined + }) + )?.data author = commit?.commit?.author } @@ -152,22 +212,29 @@ async function checkInputs() { const reason = !eventPath ? 'event path' : isPR - ? sha - ? 'fetch commit' - : 'find commit sha' - : !event?.head_commit - ? 'find commit' - : 'find commit author' + ? sha + ? 'fetch commit' + : 'find commit sha' + : !event?.head_commit + ? 'find commit' + : 'find commit author' warning(`Unable to fetch author info: couldn't ${reason}.`) setDefault('author_name', 'Add & Commit Action') setDefault('author_email', 'actions@github.com') } - info(`> Using '${getInput('author_name')} <${getInput('author_email')}>' as author.`) + info( + `> Using '${getInput('author_name')} <${getInput( + 'author_email' + )}>' as author.` + ) // #endregion // #region message - setDefault('message', `Commit from GitHub Actions (${process.env.GITHUB_WORKFLOW})`) + setDefault( + 'message', + `Commit from GitHub Actions (${process.env.GITHUB_WORKFLOW})` + ) info(`> Using "${getInput('message')}" as commit message.`) // #endregion @@ -181,28 +248,41 @@ async function checkInputs() { const parsed = parseBool(getInput('signoff')) if (parsed === undefined) - throw new Error(`"${getInput('signoff')}" is not a valid value for the 'signoff' input: only "true" and "false" are allowed.`) + throw new Error( + `"${getInput( + 'signoff' + )}" is not a valid value for the 'signoff' input: only "true" and "false" are allowed.` + ) - if (!parsed) - setInput('signoff', undefined) + if (!parsed) setInput('signoff', undefined) - debug(`Current signoff option: ${getInput('signoff')} (${typeof getInput('signoff')})`) + debug( + `Current signoff option: ${getInput('signoff')} (${typeof getInput( + 'signoff' + )})` + ) } - // #endregion + // #endregion // #region push setDefault('push', 'true') - if (getInput('push')) { // It's just to scope the parsed constant + if (getInput('push')) { + // It's just to scope the parsed constant const parsed = parseBool(getInput('push')) if (parsed === undefined) - throw new Error(`"${getInput('push')}" is not a valid value for the 'push' input: only "true" and "false" are allowed.`) + throw new Error( + `"${getInput( + 'push' + )}" is not a valid value for the 'push' input: only "true" and "false" are allowed.` + ) - if (!parsed) - setInput('push', undefined) + if (!parsed) setInput('push', undefined) - debug(`Current push option: ${getInput('push')} (${typeof getInput('push')})`) + debug( + `Current push option: ${getInput('push')} (${typeof getInput('push')})` + ) } // #endregion } @@ -214,9 +294,8 @@ function getInput(name: Input) { function parseBool(value: any) { try { const parsed = JSON.parse(value) - if (typeof parsed == 'boolean') - return parsed - } catch { } + if (typeof parsed == 'boolean') return parsed + } catch {} } function log(err: any | Error, data?: any) { @@ -224,22 +303,42 @@ function log(err: any | Error, data?: any) { if (err) error(err) } -function add({ logWarning = true, ignoreErrors = false } = {}): Promise> | void { +function add({ + logWarning = true, + ignoreErrors = false +} = {}): Promise> | void { if (getInput('add')) - return git.add(getInput('add').split(' '), (e: any, d?: any) => log(ignoreErrors ? null : e, d)).catch((e: Error) => { - if (ignoreErrors) return - if (e.message.includes('fatal: pathspec') && e.message.includes('did not match any files')) - logWarning && warning('Add command did not match any file.') - else throw e - }) + return git + .add(getInput('add').split(' '), (e: any, d?: any) => + log(ignoreErrors ? null : e, d) + ) + .catch((e: Error) => { + if (ignoreErrors) return + if ( + e.message.includes('fatal: pathspec') && + e.message.includes('did not match any files') + ) + logWarning && warning('Add command did not match any file.') + else throw e + }) } -function remove({ logWarning = true, ignoreErrors = false } = {}): Promise> | void { +function remove({ + logWarning = true, + ignoreErrors = false +} = {}): Promise> | void { if (getInput('remove')) - return git.rm(getInput('remove').split(' '), (e: any, d?: any) => log(ignoreErrors ? null : e, d)).catch((e: Error) => { - if (ignoreErrors) return - if (e.message.includes('fatal: pathspec') && e.message.includes('did not match any files')) - logWarning && warning('Remove command did not match any file.') - else throw e - }) + return git + .rm(getInput('remove').split(' '), (e: any, d?: any) => + log(ignoreErrors ? null : e, d) + ) + .catch((e: Error) => { + if (ignoreErrors) return + if ( + e.message.includes('fatal: pathspec') && + e.message.includes('did not match any files') + ) + logWarning && warning('Remove command did not match any file.') + else throw e + }) }