From f9646d8cf36e3f88dcd5735c98df84c1a230873d Mon Sep 17 00:00:00 2001 From: legendecas Date: Thu, 8 Oct 2020 01:47:20 +0800 Subject: [PATCH] build: add incremental clang-format checks --- .clang-format | 111 +++++++++++++++++++++++++++++++++++ .github/workflows/linter.yml | 20 +++++++ package.json | 7 ++- scripts/clang-format.js | 42 +++++++++++++ 4 files changed, 178 insertions(+), 2 deletions(-) create mode 100644 .clang-format create mode 100644 .github/workflows/linter.yml create mode 100644 scripts/clang-format.js diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..4aad29c32 --- /dev/null +++ b/.clang-format @@ -0,0 +1,111 @@ +--- +Language: Cpp +# BasedOnStyle: Google +AccessModifierOffset: -1 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortIfStatementsOnASingleLine: true +AllowShortLoopsOnASingleLine: true +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^' + Priority: 2 + - Regex: '^<.*\.h>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '([-_](test|unittest))?$' +IndentCaseLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: false +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Auto +TabWidth: 8 +UseTab: Never diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml new file mode 100644 index 000000000..f772297b4 --- /dev/null +++ b/.github/workflows/linter.yml @@ -0,0 +1,20 @@ +name: Style Checks + +on: [push, pull_request] + +jobs: + build: + strategy: + matrix: + node-version: [14.x] + os: [ubuntu-latest] + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v2 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v1 + with: + node-version: ${{ matrix.node-version }} + - run: npm install + - run: npm run lint diff --git a/package.json b/package.json index 93f3fd81c..13c384d1f 100644 --- a/package.json +++ b/package.json @@ -264,8 +264,9 @@ "description": "Node.js API (N-API)", "devDependencies": { "benchmark": "^2.1.4", - "fs-extra": "^9.0.1", "bindings": "^1.5.0", + "clang-format": "^1.4.0", + "fs-extra": "^9.0.1", "safe-buffer": "^5.1.1" }, "directories": {}, @@ -300,7 +301,9 @@ "dev": "node test", "predev:incremental": "node-gyp configure build -C test --debug", "dev:incremental": "node test", - "doc": "doxygen doc/Doxyfile" + "doc": "doxygen doc/Doxyfile", + "lint": "node scripts/clang-format.js", + "lint:fix": "git-clang-format" }, "version": "3.0.2" } diff --git a/scripts/clang-format.js b/scripts/clang-format.js new file mode 100644 index 000000000..b44d47674 --- /dev/null +++ b/scripts/clang-format.js @@ -0,0 +1,42 @@ +#!/usr/bin/env node + +const spawn = require('child_process').spawnSync; +const path = require('path'); + +const filesToCheck = ['*.h', '*.cc']; +const CLANG_FORMAT_START = process.env.CLANG_FORMAT_START || 'master'; + +function main(args) { + let clangFormatPath = path.dirname(require.resolve('clang-format')); + const options = ['--binary=node_modules/.bin/clang-format', '--style=file']; + + const gitClangFormatPath = path.join(clangFormatPath, + 'bin/git-clang-format'); + const result = spawn('python', [ + gitClangFormatPath, + ...options, + '--diff', + CLANG_FORMAT_START, + 'HEAD', + ...filesToCheck + ], { encoding: 'utf-8' }); + + if (result.error) { + console.error('Error running git-clang-format:', result.error); + return 2; + } + + const clangFormatOutput = result.stdout.trim(); + if (clangFormatOutput !== ('no modified files to format') && + clangFormatOutput !== ('clang-format did not modify any files')) { + console.error(clangFormatOutput); + const fixCmd = '"npm run lint:fix"'; + console.error(` + ERROR: please run ${fixCmd} to format changes in your commit`); + return 1; + } +} + +if (require.main === module) { + process.exitCode = main(process.argv.slice(2)); +}