diff --git a/.travis.yml b/.travis.yml index b2e8d24..751475a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,5 +13,6 @@ install: export DISPLAY=':99.0' /usr/bin/Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 & fi + - npm install script: - npm test diff --git a/CHANGELOG.md b/CHANGELOG.md index f040d9f..1e6905e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [2.0.0] - 2020-02-06 + +### Added + +- Add new types with helpful descriptions

Improving default types

+- Add new option to show description for types ([#de88ff6](https://github.com/nitayneeman/vscode-git-semantic-commit/commit/de88ff66cab1bc3788915aafc7b3756209f08dc2)) - thanks to [@balazsorban44](https://github.com/balazsorban44)

Showing Descriptions for Types

+ +## [1.1.0] - 2019-10-25 + +### Added + +- Add new option to change the scope template through a placeholder ([#610a3fc](https://github.com/nitayneeman/vscode-git-semantic-commit/commit/610a3fc9550b4a88fcea06741c3cd6602a2051d3)) - thanks to [@axelprox](https://github.com/axelprox)

Changing the Scope Template

+ ## [1.0.1] - 2019-10-22 ### Changed diff --git a/README.md b/README.md index 763cf80..b548524 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,8 @@ This Visual Studio Code extension enables to commit simply by the semantic messa Preview

+Notice that the default types are aligned with the Angular commit message [conventions](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#type). +
## 👨🏻‍🏫 How to Use @@ -62,17 +64,26 @@ The extension allows you to customize the following configuration settings: | --------------------------------- | ------------------------------------------------------------------------------------------------------------------ | | `gitSemanticCommit.commitOptions` | Specifies which [arguments](https://git-scm.com/docs/git-commit#_options) to be passed when the commit is executed | | `gitSemanticCommit.preserveScope` | Determines whether to preserve the last message scope that was inserted | +| `gitSemanticCommit.scopeTemplate` | Specifies scope template (`$scope` placeholder will be replaced with the passed scope) | | `gitSemanticCommit.stageAll` | Determines whether to stage all changes before the commit, in case the staging area (index) is empty | | `gitSemanticCommit.types` | Specifies the supported message types | ### Customize Your Types -Besides the fact you can add new message types, it's either possible to modify the existing values: +Besides the fact you can add new message types, it's also possible to modify the existing values and their descriptions:

Enriching types with Emojis

+### Customize Your Scope + +You can modify the scope template through a placeholder: + +

+ Changing the Scope Template +

+
## 💁🏻 Contributing diff --git a/images/examples/settings/scope-template.gif b/images/examples/settings/scope-template.gif new file mode 100644 index 0000000..b4188de Binary files /dev/null and b/images/examples/settings/scope-template.gif differ diff --git a/images/examples/settings/types-with-emojis.png b/images/examples/settings/types-with-emojis.png index 6841d62..47a7826 100644 Binary files a/images/examples/settings/types-with-emojis.png and b/images/examples/settings/types-with-emojis.png differ diff --git a/images/examples/usage/types-with-descriptions.png b/images/examples/usage/types-with-descriptions.png new file mode 100644 index 0000000..e72e742 Binary files /dev/null and b/images/examples/usage/types-with-descriptions.png differ diff --git a/package-lock.json b/package-lock.json index d2556a1..f994d49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "git-semantic-commit", - "version": "1.0.0", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -452,9 +452,9 @@ } }, "https-proxy-agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "dev": true, "requires": { "agent-base": "^4.3.0", @@ -561,9 +561,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "log-symbols": { @@ -986,9 +986,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", "dev": true }, "yargs": { diff --git a/package.json b/package.json index 5e161cb..2df1e2b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "git-semantic-commit", - "version": "1.0.1", + "version": "2.0.0", "license": "MIT", "author": "Nitay Neeman", "description": "💬 A Visual Studio Code extension which enables to commit simply by the semantic message conventions", @@ -55,6 +55,11 @@ "default": false, "markdownDescription": "Determines whether to preserve the last message scope that was inserted." }, + "gitSemanticCommit.scopeTemplate": { + "type": "string", + "default": "($scope)", + "markdownDescription": "Specifies scope template (`$scope` placeholder will be replaced with the passed scope). Check out [this](https://github.com/nitayneeman/vscode-git-semantic-commit#customize-your-scope) example." + }, "gitSemanticCommit.stageAll": { "type": "boolean", "default": true, @@ -63,20 +68,53 @@ "gitSemanticCommit.types": { "type": "array", "default": [ - "chore", - "docs", - "feat", - "fix", - "refactor", - "style", - "test" + { + "type": "build", + "description": "Development changes related to the build system" + }, + { + "type": "ci", + "description": "Development changes related to the continuous integration and deployment system" + }, + { + "type": "docs", + "description": "Documentation changes related to the project" + }, + { + "type": "feat", + "description": "Production changes related to new backward-compatible abilities or functionality" + }, + { + "type": "fix", + "description": "Production changes related to backward-compatible bug fixes" + }, + { + "type": "perf", + "description": "Production changes related to backward-compatible performance improvements" + }, + { + "type": "refactor", + "description": "Development changes related to modifying the codebase" + }, + { + "type": "style", + "description": "Development changes related to styling the codebase" + }, + { + "type": "test", + "description": "Development changes related to tests" + } ], "items": { - "type": "string" + "type": [ + "string", + "object" + ], + "description": "Can be either a string, or an object. If an object, use type for the commit type, and description to give a short description for the particular commit type." }, "minItems": 1, "uniqueItems": true, - "markdownDescription": "Specifies the supported message types." + "markdownDescription": "Specifies the supported message types. Check out [this](https://github.com/nitayneeman/vscode-git-semantic-commit#customize-your-types) example." } } }, @@ -116,7 +154,7 @@ "vscode:prepublish": "npm run compile", "compile": "tsc -p ./", "watch": "tsc -watch -p ./", - "pretest": "npm run compile && ./scripts/pretest.sh", + "pretest": "npm run compile && git init test-temp --quiet", "test": "node ./out/test/runTest.js" }, "devDependencies": { diff --git a/scripts/pretest.sh b/scripts/pretest.sh deleted file mode 100755 index fd07655..0000000 --- a/scripts/pretest.sh +++ /dev/null @@ -1,5 +0,0 @@ -mkdir test-temp - -cd test-temp - -git init --quiet \ No newline at end of file diff --git a/src/commands/semantic-commit.ts b/src/commands/semantic-commit.ts index fdb0d49..45ee6f9 100644 --- a/src/commands/semantic-commit.ts +++ b/src/commands/semantic-commit.ts @@ -2,7 +2,7 @@ import { window, workspace, ExtensionContext, QuickPickItem } from 'vscode'; import { getConfiguration, ConfigurationProperties } from '../config'; import { Git } from '../git'; -import { workspaceStorageKey } from '../constants'; +import { workspaceStorageKey, scopeTemplatePlaceholder } from '../constants'; import { Command } from './common'; const enum ActionType { @@ -17,7 +17,7 @@ export class SemanticCommitCommand extends Command { context: ExtensionContext; scope: string; - types: string[]; + types: (string | {type: string, description: string})[]; constructor(context: ExtensionContext) { super(); @@ -75,6 +75,11 @@ export class SemanticCommitCommand extends Command { return getConfiguration()[ConfigurationProperties.stageAll]; } + private get scopeTemplate() { + const template = getConfiguration()[ConfigurationProperties.scopeTemplate]; + return template.length ? template : scopeTemplatePlaceholder; + } + private hasScope() { return this.scope.length > 0; } @@ -105,13 +110,17 @@ export class SemanticCommitCommand extends Command { private createQuickPickItems(): QuickPickItem[] { const hasScope = this.hasScope(); - const typeItems = this.types.map(type => ({ - label: `$(git-commit) Commit with "${type}" type`, - alwaysShow: true, - actionType: ActionType.subject, - type, - description: '' - })); + const typeItems = this.types.map(item => { + const description = typeof item === "string" ? "" : item.description + const type = typeof item === "string" ? item : item.type + return ({ + label: `$(git-commit) Commit with "${type}" type`, + alwaysShow: true, + actionType: ActionType.subject, + type, + description + }) + }); return [ { @@ -129,7 +138,10 @@ export class SemanticCommitCommand extends Command { private async performCommit(type: string, subject: string) { if (subject.length > 0) { - const message = `${type}${this.hasScope() ? `(${this.scope})` : ''}: ${subject}`; + const scope = this.hasScope() + ? this.scopeTemplate.replace(scopeTemplatePlaceholder, this.scope) + : ''; + const message = `${type}${scope}: ${subject}`; if (this.isStageAllEnabled()) { try { diff --git a/src/config.ts b/src/config.ts index fbdbac3..fd9b719 100644 --- a/src/config.ts +++ b/src/config.ts @@ -8,6 +8,7 @@ enum ConfigurationProperties { commitOptions = 'commitOptions', preserveScope = 'preserveScope', stageAll = 'stageAll', + scopeTemplate = 'scopeTemplate', types = 'types' } diff --git a/src/constants.ts b/src/constants.ts index 8ae7f0d..2bf3a4b 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -2,4 +2,6 @@ const extensionIdentifier = 'gitSemanticCommit'; const workspaceStorageKey = 'gitSemanticCommit'; -export { extensionIdentifier, workspaceStorageKey }; +const scopeTemplatePlaceholder = '$scope'; + +export { extensionIdentifier, workspaceStorageKey, scopeTemplatePlaceholder }; diff --git a/src/test/runTest.ts b/src/test/runTest.ts index b317851..01bfac7 100644 --- a/src/test/runTest.ts +++ b/src/test/runTest.ts @@ -5,7 +5,7 @@ async function main() { try { const extensionDevelopmentPath = path.resolve(__dirname, '../../'); const extensionTestsPath = path.resolve(__dirname, './suite/index'); - const testWorkspace = path.resolve(__dirname, './test-temp'); + const testWorkspace = path.resolve(__dirname, '../../test-temp'); await runTests({ extensionDevelopmentPath, diff --git a/src/test/suite/extension.test.ts b/src/test/suite/extension.test.ts index 80cb566..25da345 100644 --- a/src/test/suite/extension.test.ts +++ b/src/test/suite/extension.test.ts @@ -1,44 +1,54 @@ -import * as assert from 'assert'; -import * as vscode from 'vscode'; +import * as assert from "assert"; +import * as vscode from "vscode"; -import { createFile, clearDirectory, getLastMessage } from './common'; +import { createFile, clearDirectory, getLastMessage } from "./common"; -suite('Extension Test Suite', () => { +suite("Extension Test Suite", () => { const { workspaceFolders } = vscode.workspace; - const directoryPath = workspaceFolders ? workspaceFolders[0].uri.fsPath : ''; + const directoryPath = workspaceFolders ? workspaceFolders[0].uri.fsPath : ""; suiteTeardown(() => clearDirectory(directoryPath)); - test('should commit with "chore" type', async () => { - const sampleSubject = 'add new file'; - const expectedMessage = `chore: ${sampleSubject}`; + test('should commit with "build" type', async () => { + const sampleSubject = "add new file"; + const expectedMessage = `build: ${sampleSubject}`; - await createFile(directoryPath, 'Hello World'); + await createFile(directoryPath, "Hello World"); await vscode.env.clipboard.writeText(sampleSubject); - await vscode.commands.executeCommand('gitSemanticCommit.semanticCommit'); - await vscode.commands.executeCommand('editor.action.clipboardPasteAction'); - await vscode.commands.executeCommand('workbench.action.quickOpenSelectNext'); - await vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); + await vscode.commands.executeCommand("gitSemanticCommit.semanticCommit"); + await vscode.commands.executeCommand("editor.action.clipboardPasteAction"); + await vscode.commands.executeCommand( + "workbench.action.quickOpenSelectNext" + ); + await vscode.commands.executeCommand( + "workbench.action.acceptSelectedQuickOpenItem" + ); await new Promise(resolve => setTimeout(resolve, 3000)); const { stdout: message } = await getLastMessage(directoryPath); assert.equal(message.includes(expectedMessage), true); }); - test('should commit with a scope and "chore" type', async () => { - const sampleScope = 'scope'; - const sampleSubject = 'add new file'; - const expectedMessage = `chore(${sampleScope}): ${sampleSubject}`; + test('should commit with a scope and "build" type', async () => { + const sampleScope = "scope"; + const sampleSubject = "add new file"; + const expectedMessage = `build(${sampleScope}): ${sampleSubject}`; - await createFile(directoryPath, 'Hello World'); + await createFile(directoryPath, "Hello World"); await vscode.env.clipboard.writeText(sampleScope); - await vscode.commands.executeCommand('gitSemanticCommit.semanticCommit'); - await vscode.commands.executeCommand('editor.action.clipboardPasteAction'); - await vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); + await vscode.commands.executeCommand("gitSemanticCommit.semanticCommit"); + await vscode.commands.executeCommand("editor.action.clipboardPasteAction"); + await vscode.commands.executeCommand( + "workbench.action.acceptSelectedQuickOpenItem" + ); await vscode.env.clipboard.writeText(sampleSubject); - await vscode.commands.executeCommand('editor.action.clipboardPasteAction'); - await vscode.commands.executeCommand('workbench.action.quickOpenSelectNext'); - await vscode.commands.executeCommand('workbench.action.acceptSelectedQuickOpenItem'); + await vscode.commands.executeCommand("editor.action.clipboardPasteAction"); + await vscode.commands.executeCommand( + "workbench.action.quickOpenSelectNext" + ); + await vscode.commands.executeCommand( + "workbench.action.acceptSelectedQuickOpenItem" + ); await new Promise(resolve => setTimeout(resolve, 3000)); const { stdout: message } = await getLastMessage(directoryPath);