From ef9e790f846a08223ef45faba67cd8424709fe1a Mon Sep 17 00:00:00 2001 From: vers-one <12114169+vers-one@users.noreply.github.com> Date: Wed, 8 May 2024 01:49:55 -0400 Subject: [PATCH] Tag filter support (#11) --- .gitignore | 1 + .vscode/launch.json | 20 ++ LICENSE | 2 +- README.md | 94 ++++++--- package.json | 2 +- src/index.ts | 7 +- src/plugins/assemblyinfo-cpp-plugin.ts | 17 +- src/plugins/assemblyinfo-cs-plugin.ts | 17 +- src/plugins/assemblyinfo-fs-plugin.ts | 17 +- src/plugins/assemblyinfo-vb-plugin.ts | 17 +- src/plugins/csproj-plugin.ts | 23 ++- src/plugins/fsproj-plugin.ts | 23 ++- src/plugins/nuspec-plugin.ts | 14 +- src/plugins/plugin.ts | 57 ++++-- src/plugins/props-plugin.ts | 23 ++- src/plugins/rc-plugin.ts | 23 ++- src/plugins/vbproj-plugin.ts | 23 ++- src/test.ts | 4 + src/tests/filter-utils-tests.ts | 192 ++++++++++++++++++ .../assemblyinfo-cpp-plugin-test.ts | 24 +++ .../assemblyinfo-cs-plugin-test.ts | 24 +++ .../assemblyinfo-fs-plugin-test.ts | 24 +++ .../assemblyinfo-vb-plugin-test.ts | 24 +++ src/tests/plugins-tests/csproj-plugin-test.ts | 44 ++++ src/tests/plugins-tests/fsproj-plugin-test.ts | 44 ++++ src/tests/plugins-tests/nuspec-plugin-test.ts | 20 ++ src/tests/plugins-tests/plugin-test.ts | 15 ++ src/tests/plugins-tests/plugins-tests.ts | 52 +++++ src/tests/plugins-tests/props-plugin-test.ts | 44 ++++ src/tests/plugins-tests/rc-plugin-test.ts | 38 ++++ src/tests/plugins-tests/vbproj-plugin-test.ts | 44 ++++ src/tests/updater-tests.ts | 184 +++++++++++++++-- src/tests/version-utils-tests.ts | 3 +- src/types/filter-types.ts | 12 ++ src/types/version-types.ts | 43 ++++ src/updater.ts | 68 ++++++- src/utils/filter-utils.ts | 88 ++++++++ src/utils/version-utils.ts | 50 +---- .../expected-results/Test.cpp | 0 .../expected-results/Test.cs | 0 .../expected-results/Test.csproj | 0 .../expected-results/Test.fs | 2 +- .../expected-results/Test.fsproj | 0 .../expected-results/Test.nuspec | 0 .../expected-results/Test.props | 2 + .../expected-results/Test.rc | 0 .../expected-results/Test.vb | 0 .../expected-results/Test.vbproj | 0 .../{ => all-files-test}/input/Test.cpp | 0 test-files/{ => all-files-test}/input/Test.cs | 0 .../{ => all-files-test}/input/Test.csproj | 0 test-files/{ => all-files-test}/input/Test.fs | 2 +- .../{ => all-files-test}/input/Test.fsproj | 0 .../{ => all-files-test}/input/Test.nuspec | 0 test-files/all-files-test/input/Test.props | 8 + test-files/{ => all-files-test}/input/Test.rc | 0 test-files/{ => all-files-test}/input/Test.vb | 0 .../{ => all-files-test}/input/Test.vbproj | 0 .../expected-results/Test.cpp | 4 + .../expected-results/Test.cs | 4 + .../expected-results/Test.fs | 5 + .../expected-results/Test.vb | 4 + .../files-with-comments-test/input/Test.cpp | 4 + .../files-with-comments-test/input/Test.cs | 4 + .../files-with-comments-test/input/Test.fs | 5 + .../files-with-comments-test/input/Test.vb | 4 + .../no-matching-files-test/input/Test.cs | 2 + .../no-matching-files-test/input/Test.csproj | 8 + test-files/single-file-test/input/Test.cs | 2 + test-files/single-file-test/input/Test.csproj | 8 + .../expected-results/Skip.props} | 0 .../tag-filter-test/expected-results/Test.cs | 2 + .../expected-results/Test.csproj | 8 + test-files/tag-filter-test/input/Skip.props | 6 + test-files/tag-filter-test/input/Test.cs | 2 + test-files/tag-filter-test/input/Test.csproj | 8 + .../input/Test.txt | 0 tsconfig.json | 3 +- 78 files changed, 1335 insertions(+), 183 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 src/tests/filter-utils-tests.ts create mode 100644 src/tests/plugins-tests/assemblyinfo-cpp-plugin-test.ts create mode 100644 src/tests/plugins-tests/assemblyinfo-cs-plugin-test.ts create mode 100644 src/tests/plugins-tests/assemblyinfo-fs-plugin-test.ts create mode 100644 src/tests/plugins-tests/assemblyinfo-vb-plugin-test.ts create mode 100644 src/tests/plugins-tests/csproj-plugin-test.ts create mode 100644 src/tests/plugins-tests/fsproj-plugin-test.ts create mode 100644 src/tests/plugins-tests/nuspec-plugin-test.ts create mode 100644 src/tests/plugins-tests/plugin-test.ts create mode 100644 src/tests/plugins-tests/plugins-tests.ts create mode 100644 src/tests/plugins-tests/props-plugin-test.ts create mode 100644 src/tests/plugins-tests/rc-plugin-test.ts create mode 100644 src/tests/plugins-tests/vbproj-plugin-test.ts create mode 100644 src/types/filter-types.ts create mode 100644 src/types/version-types.ts create mode 100644 src/utils/filter-utils.ts rename test-files/{ => all-files-test}/expected-results/Test.cpp (100%) rename test-files/{ => all-files-test}/expected-results/Test.cs (100%) rename test-files/{ => all-files-test}/expected-results/Test.csproj (100%) rename test-files/{ => all-files-test}/expected-results/Test.fs (94%) rename test-files/{ => all-files-test}/expected-results/Test.fsproj (100%) rename test-files/{ => all-files-test}/expected-results/Test.nuspec (100%) rename test-files/{ => all-files-test}/expected-results/Test.props (60%) rename test-files/{ => all-files-test}/expected-results/Test.rc (100%) rename test-files/{ => all-files-test}/expected-results/Test.vb (100%) rename test-files/{ => all-files-test}/expected-results/Test.vbproj (100%) rename test-files/{ => all-files-test}/input/Test.cpp (100%) rename test-files/{ => all-files-test}/input/Test.cs (100%) rename test-files/{ => all-files-test}/input/Test.csproj (100%) rename test-files/{ => all-files-test}/input/Test.fs (94%) rename test-files/{ => all-files-test}/input/Test.fsproj (100%) rename test-files/{ => all-files-test}/input/Test.nuspec (100%) create mode 100644 test-files/all-files-test/input/Test.props rename test-files/{ => all-files-test}/input/Test.rc (100%) rename test-files/{ => all-files-test}/input/Test.vb (100%) rename test-files/{ => all-files-test}/input/Test.vbproj (100%) create mode 100644 test-files/files-with-comments-test/expected-results/Test.cpp create mode 100644 test-files/files-with-comments-test/expected-results/Test.cs create mode 100644 test-files/files-with-comments-test/expected-results/Test.fs create mode 100644 test-files/files-with-comments-test/expected-results/Test.vb create mode 100644 test-files/files-with-comments-test/input/Test.cpp create mode 100644 test-files/files-with-comments-test/input/Test.cs create mode 100644 test-files/files-with-comments-test/input/Test.fs create mode 100644 test-files/files-with-comments-test/input/Test.vb create mode 100644 test-files/no-matching-files-test/input/Test.cs create mode 100644 test-files/no-matching-files-test/input/Test.csproj create mode 100644 test-files/single-file-test/input/Test.cs create mode 100644 test-files/single-file-test/input/Test.csproj rename test-files/{input/Test.props => tag-filter-test/expected-results/Skip.props} (100%) create mode 100644 test-files/tag-filter-test/expected-results/Test.cs create mode 100644 test-files/tag-filter-test/expected-results/Test.csproj create mode 100644 test-files/tag-filter-test/input/Skip.props create mode 100644 test-files/tag-filter-test/input/Test.cs create mode 100644 test-files/tag-filter-test/input/Test.csproj rename test-files/{ => unsupported-file-type-test}/input/Test.txt (100%) diff --git a/.gitignore b/.gitignore index 491fc35..faee05e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules lib +test-files/*/actual-results diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..f40affa --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Run tests", + "program": "${workspaceFolder}/node_modules/ava/entrypoints/cli.mjs", + "args": [ + "--serial", + "lib/test.js" + ], + "outputCapture": "std", + "console": "integratedTerminal", + "skipFiles": [ + "/**/*.js" + ] + } + ] +} diff --git a/LICENSE b/LICENSE index 5879c1d..4e8de47 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 vers-one +Copyright (c) 2022-2024 vers-one Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index c4e4401..e156bbb 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,67 @@ Examples: |1.1 |`*.*.*.*` |1.1.0.0 |Sets the missing build and revision parts to zero, leaves the major and the minor parts unchanged | |1.1 |`?.?.?.?` |1.1 |Leaves all parts unchanged | +### `tags` (optional) + +Comma-separated list of version tags to process. + +Allows to refine the `file` / `files` filter to exclude the unwanted version declarations found in the matching files. The values in the list are not case-sensitive, extra spaces between the values are trimmed. + +**Default**: `*` + +Supported tags: + +|Tag |Description | +|--------------------------------------|------------------------------------------------------------------------------| +|`*` |Process all supported version declarations in all supported file types | +|`csproj.*` |Process all supported version declarations in *.csproj* files | +|`csproj.Version` |Process `...` item in *.csproj* files | +|`csproj.VersionPrefix` |Process `...` item in *.csproj* files | +|`csproj.AssemblyVersion` |Process `...` item in *.csproj* files | +|`csproj.FileVersion` |Process `...` item in *.csproj* files | +|`vbproj.*` |Process all supported version declarations in *.vbproj* files | +|`vbproj.Version` |Process `...` item in *.vbproj* files | +|`vbproj.VersionPrefix` |Process `...` item in *.vbproj* files | +|`vbproj.AssemblyVersion` |Process `...` item in *.vbproj* files | +|`vbproj.FileVersion` |Process `...` item in *.vbproj* files | +|`fsproj.*` |Process all supported version declarations in *.fsproj* files | +|`fsproj.Version` |Process `...` item in *.fsproj* files | +|`fsproj.VersionPrefix` |Process `...` item in *.fsproj* files | +|`fsproj.AssemblyVersion` |Process `...` item in *.fsproj* files | +|`fsproj.FileVersion` |Process `...` item in *.fsproj* files | +|`props.*` |Process all supported version declarations in *.props* files | +|`props.Version` |Process `...` item in *.props* files | +|`props.VersionPrefix` |Process `...` item in *.props* files | +|`props.AssemblyVersion` |Process `...` item in *.props* files | +|`props.FileVersion` |Process `...` item in *.props* files | +|`nuspec.*` |Process all supported version declarations in *.nuspec* files | +|`nuspec.Version` |Process `...` item in *.nuspec* files | +|`AssemblyInfo-cs.*` |Process all supported version declarations in *.cs* files | +|`AssemblyInfo-cs.AssemblyVersion` |Process `[assembly: AssemblyVersion("...")]` item in *.cs* files | +|`AssemblyInfo-cs.AssemblyFileVersion` |Process `[assembly: AssemblyFileVersion("...")]` item in *.cs* files | +|`AssemblyInfo-vb.*` |Process all supported version declarations in *.vb* files | +|`AssemblyInfo-vb.AssemblyVersion` |Process `` item in *.vb* files | +|`AssemblyInfo-vb.AssemblyFileVersion` |Process `` item in *.vb* files | +|`AssemblyInfo-fs.*` |Process all supported version declarations in *.fs* files | +|`AssemblyInfo-fs.AssemblyVersion` |Process `[]` item in *.fs* files | +|`AssemblyInfo-fs.AssemblyFileVersion` |Process `[]` item in *.fs* files | +|`AssemblyInfo-cpp.*` |Process all supported version declarations in *.cpp* files | +|`AssemblyInfo-cpp.AssemblyVersion` |Process `[assembly:AssemblyVersionAttribute(L"...")]` item in *.cpp* files | +|`AssemblyInfo-cpp.AssemblyFileVersion`|Process `[assembly:AssemblyFileVersionAttribute(L"...")]` item in *.cpp* files| +|`rc.*` |Process all supported version declarations in *.rc* files | +|`rc.FileVersion-param` |Process `FILEVERSION x,x,x,x` item in *.rc* files | +|`rc.ProductVersion-param` |Process `PRODUCTVERSION x,x,x,x` item in *.rc* files | +|`rc.FileVersion-string` |Process `VALUE "FileVersion", "..."` item in *.rc* files | +|`rc.ProductVersion-string` |Process `VALUE "ProductVersion", "..."` item in *.rc* files | + +Examples: + +|`tags` input |Explanation | +|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +|`AssemblyInfo-cs.AssemblyVersion` |Process only *.cs* files and only `[assembly: AssemblyVersion("...")]` items in those files | +|`csproj.Version, csproj.AssemblyVersion` |Process only *.csproj* files and only `...` and `...` items in those files | +|`csproj.Version, AssemblyInfo-cs.AssemblyVersion, nuspec.*`|Process only `...` items in *.csproj* files, `[assembly: AssemblyVersion("...")]` items in *.cs* files, and all supported version declarations in `.nuspec` files, and skip everything else| + ## Outputs ### `oldVersion` @@ -123,7 +184,7 @@ jobs: - name: Set MyProject.csproj version id: update - uses: vers-one/dotnet-project-version-updater@v1.5 + uses: vers-one/dotnet-project-version-updater@v1.6 with: file: "src/MyProject.csproj" version: ${{ github.event.inputs.version }} @@ -159,7 +220,7 @@ jobs: - name: Set project versions id: update - uses: vers-one/dotnet-project-version-updater@v1.5 + uses: vers-one/dotnet-project-version-updater@v1.6 with: file: | "**/*.csproj", "**/*.nuspec", "**/AssemblyInfo.cs" @@ -203,7 +264,7 @@ jobs: - name: Bump build version id: bump - uses: vers-one/dotnet-project-version-updater@v1.5 + uses: vers-one/dotnet-project-version-updater@v1.6 with: file: "src/MyProject.csproj" version: bump-build @@ -218,31 +279,6 @@ jobs: ## Additional notes -* This action searches for the following version declarations: - * for .csproj, .vbproj, .fsproj, and .props files: - * `...`; - * `...`; - * `...`; - * `...`; - * for .nuspec files: - * `...`; - * for .cs files: - * `[assembly: AssemblyVersion("...")]`; - * `[assembly: AssemblyFileVersion("...")]`; - * for .vb files: - * ``; - * ``; - * for .fs files: - * `[]`; - * `[]`; - * for .cpp files: - * `[assembly:AssemblyVersionAttribute(L"...")]`; - * `[assembly:AssemblyFileVersionAttribute(L"...")]`; - * for .rc files: - * `FILEVERSION x,x,x,x`; - * `PRODUCTVERSION x,x,x,x`; - * `VALUE "FileVersion", "..."` - * `VALUE "ProductVersion", "..."`. -* If you set the new version explicitly, you can use any string as a version number (e.g. `1.2.3`, `1.0.0-beta5`, `Vista`, `blah-blah`, etc). However if you use one of the bump commands or a bump pattern, the existing version must by in the following format: *major[.minor[.build[.revision]]]*. +* If you set the new version explicitly, you can use any string as a version number (e.g. `1.2.3`, `1.0.0-beta5`, `Vista`, `blah-blah`, etc). However, if you use one of the bump commands or a bump pattern, the existing version must by in the following format: *major[.minor[.build[.revision]]]*. * Keep in mind that .NET Framework assembly versions [must be](https://docs.microsoft.com/en-us/dotnet/api/system.version#remarks) in the following format: *major.minor[.build[.revision]]*. Any other versions formats like `1.0.0-beta5` will cause a compilation failure. * C++ resource files [require](https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource#parameters) `FILEVERSION` and `PRODUCTVERSION` resource parameters to have all four version components (*major.minor.build.revision*). diff --git a/package.json b/package.json index be97a1c..2152c0b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dotnet-project-version-updater", - "version": "1.5.0", + "version": "1.6.0", "description": "A GitHub action to update or bump project versions. Supports .csproj, .props, .nuspec, and many other .NET file types.", "main": "lib/index.js", "scripts": { diff --git a/src/index.ts b/src/index.ts index c3fdac4..e9fb106 100644 --- a/src/index.ts +++ b/src/index.ts @@ -11,9 +11,14 @@ async function run(): Promise filePathPattern = Core.getInput("files"); } const newVersion: string = Core.getInput("version"); + const pluginTagFilter: string = Core.getInput("tags"); console.log(`File path pattern: ${filePathPattern}`); console.log(`New version: ${newVersion}`); - const updaterResults: UpdaterResult[] = await Updater.update(filePathPattern, newVersion); + if (pluginTagFilter !== "") + { + console.log(`Tag filter: ${pluginTagFilter}`); + } + const updaterResults: UpdaterResult[] = await Updater.update(filePathPattern, newVersion, pluginTagFilter); let oldVersionString: string = ""; let newVersionString: string = ""; for (const updaterResult of updaterResults) diff --git a/src/plugins/assemblyinfo-cpp-plugin.ts b/src/plugins/assemblyinfo-cpp-plugin.ts index 2e5e77c..a63777e 100644 --- a/src/plugins/assemblyinfo-cpp-plugin.ts +++ b/src/plugins/assemblyinfo-cpp-plugin.ts @@ -1,26 +1,33 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /\[assembly:\s*AssemblyVersionAttribute\(\s*L"(.*)"\s*\)]/i; -const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /\[assembly:\s*AssemblyFileVersionAttribute\(\s*L"(.*)"\s*\)]/i; +const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*\[assembly:\s*AssemblyVersionAttribute\(\s*L"(.*)"\s*\)]/; +const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*\[assembly:\s*AssemblyFileVersionAttribute\(\s*L"(.*)"\s*\)]/; export default class AssemblyInfoCppPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyVersion attribute" }, { + tagName: "assemblyfileversion", regex: ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyFileVersion attribute" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "assemblyinfo-cpp"; } get fileTypeName(): string diff --git a/src/plugins/assemblyinfo-cs-plugin.ts b/src/plugins/assemblyinfo-cs-plugin.ts index fac2b9d..983fc15 100644 --- a/src/plugins/assemblyinfo-cs-plugin.ts +++ b/src/plugins/assemblyinfo-cs-plugin.ts @@ -1,26 +1,33 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /\[assembly:\s*AssemblyVersion\(\s*"(.*)"\s*\)]/i; -const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /\[assembly:\s*AssemblyFileVersion\(\s*"(.*)"\s*\)]/i; +const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*\[assembly:\s*AssemblyVersion\(\s*"(.*)"\s*\)]/; +const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*\[assembly:\s*AssemblyFileVersion\(\s*"(.*)"\s*\)]/; export default class AssemblyInfoCsPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyVersion attribute" }, { + tagName: "assemblyfileversion", regex: ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyFileVersion attribute" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "assemblyinfo-cs"; } get fileTypeName(): string diff --git a/src/plugins/assemblyinfo-fs-plugin.ts b/src/plugins/assemblyinfo-fs-plugin.ts index ae960b9..86d6e6a 100644 --- a/src/plugins/assemblyinfo-fs-plugin.ts +++ b/src/plugins/assemblyinfo-fs-plugin.ts @@ -1,26 +1,33 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /\[]/i; -const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /\[]/i; +const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*\[]/; +const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*\[]/; export default class AssemblyInfoFsPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyVersion attribute" }, { + tagName: "assemblyfileversion", regex: ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyFileVersion attribute" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "assemblyinfo-fs"; } get fileTypeName(): string diff --git a/src/plugins/assemblyinfo-vb-plugin.ts b/src/plugins/assemblyinfo-vb-plugin.ts index c242220..68c4060 100644 --- a/src/plugins/assemblyinfo-vb-plugin.ts +++ b/src/plugins/assemblyinfo-vb-plugin.ts @@ -1,26 +1,33 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = //i; -const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = //i; +const ASSEMBLY_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*/; +const ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX: RegExp = /^\s*/; export default class AssemblyInfoVbPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyVersion attribute" }, { + tagName: "assemblyfileversion", regex: ASSEMBLY_FILE_VERSION_ATTRIBUTE_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "AssemblyFileVersion attribute" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "assemblyinfo-vb"; } get fileTypeName(): string diff --git a/src/plugins/csproj-plugin.ts b/src/plugins/csproj-plugin.ts index e789a45..f7c7367 100644 --- a/src/plugins/csproj-plugin.ts +++ b/src/plugins/csproj-plugin.ts @@ -1,38 +1,47 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/i; -const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/i; -const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/i; -const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/i; +const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/; +const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/; +const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/; +const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/; export default class CsProjPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "version", regex: VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "versionprefix", regex: VERSION_PREFIX_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "fileversion", regex: FILE_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "csproj"; } get fileTypeName(): string diff --git a/src/plugins/fsproj-plugin.ts b/src/plugins/fsproj-plugin.ts index 366ce4a..db058b7 100644 --- a/src/plugins/fsproj-plugin.ts +++ b/src/plugins/fsproj-plugin.ts @@ -1,38 +1,47 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/i; -const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/i; -const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/i; -const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/i; +const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/; +const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/; +const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/; +const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/; export default class FsProjPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "version", regex: VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "versionprefix", regex: VERSION_PREFIX_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "fileversion", regex: FILE_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "fsproj"; } get fileTypeName(): string diff --git a/src/plugins/nuspec-plugin.ts b/src/plugins/nuspec-plugin.ts index 19fd5fe..032d934 100644 --- a/src/plugins/nuspec-plugin.ts +++ b/src/plugins/nuspec-plugin.ts @@ -1,20 +1,26 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/i; +const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/; export default class NuspecPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "version", regex: VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "nuspec"; } get fileTypeName(): string diff --git a/src/plugins/plugin.ts b/src/plugins/plugin.ts index 7e87d0b..c7180d5 100644 --- a/src/plugins/plugin.ts +++ b/src/plugins/plugin.ts @@ -1,4 +1,6 @@ -import VersionUtils, { Version, VersionUpdateRule } from "../utils/version-utils"; +import type { TagFilter } from "../types/filter-types"; +import type { Version, VersionUpdateRule } from "../types/version-types"; +import VersionUtils from "../utils/version-utils"; export interface VersionUpdateResult { @@ -19,53 +21,76 @@ export enum VersionPartDelimiter COMMA } -export interface PluginVersionRegex +export interface PluginTag { + tagName: string; regex: RegExp; versionPartDelimiter: VersionPartDelimiter; versionType: string; } export default abstract class Plugin { - private versionRegexes: PluginVersionRegex[]; + #tags: PluginTag[]; - constructor(versionRegexes: PluginVersionRegex[]) + constructor(tags: PluginTag[]) { - this.versionRegexes = versionRegexes; + this.#tags = tags; } + abstract get pluginName(): string; abstract get fileTypeName(): string; abstract isFileTypeSupported(filePath: string): boolean; - updateFile(fileContent: string, versionUpdateRule: VersionUpdateRule): FileUpdateResult | null + get tags(): PluginTag[] + { + return this.#tags; + } + + updateFile(filePath: string, fileContent: string, versionUpdateRule: VersionUpdateRule, tagFilters: TagFilter[]): FileUpdateResult | null { const updatedVersions: VersionUpdateResult[] = []; - for (const versionRegex of this.versionRegexes) + const isMatchAllTagsFilter = tagFilters.length === 1 && tagFilters[0].tagName === "*"; + for (const tag of this.#tags) { - const matches: RegExpExecArray | null = versionRegex.regex.exec(fileContent); - if (matches && matches.length == 2) + if (!isMatchAllTagsFilter && tagFilters.find(tagFilter => tagFilter.tagName === tag.tagName) === undefined) + { + continue; + } + const regex: RegExp = new RegExp(tag.regex, "gim"); + const matches: RegExpExecArray | null = regex.exec(fileContent); + if (matches) { + if (matches.length < 2) + { + throw new Error(`Expected to find 2 matches for regular expression "${regex}" but found only ${matches.length}.`); + } + if (regex.exec(fileContent) !== null) + { + throw new Error(`Too many occurrences of the ${tag.versionType} found in the file: ${filePath}`); + } const oldVersionPatternMatch: string = matches[0]; const oldVersionString: string = matches[1].trim(); let newVersionString: string; - switch (versionRegex.versionPartDelimiter) + switch (tag.versionPartDelimiter) { case VersionPartDelimiter.DOT: - newVersionString = - VersionUtils.updateNonParsedVersion(oldVersionString, versionUpdateRule, VersionUtils.VERSION_NUMBER_WITH_DOT_DELIMITER_REGEX, "."); + newVersionString = VersionUtils.updateNonParsedVersion(oldVersionString, versionUpdateRule, + VersionUtils.VERSION_NUMBER_WITH_DOT_DELIMITER_REGEX, "."); break; case VersionPartDelimiter.COMMA: - const parsedOldVersion: Version = VersionUtils.parseVersion(oldVersionString, VersionUtils.VERSION_NUMBER_WITH_COMMA_DELIMITER_REGEX); + const parsedOldVersion: Version = VersionUtils.parseVersion(oldVersionString, + VersionUtils.VERSION_NUMBER_WITH_COMMA_DELIMITER_REGEX); const newVersion: Version = VersionUtils.updateParsedVersion(parsedOldVersion, versionUpdateRule); newVersionString = VersionUtils.formatVersion(newVersion, ",", true); break; default: - throw new Error(`Unexpected version part delimiter: ${versionRegex.versionPartDelimiter}.`); + throw new Error(`Unexpected version part delimiter: ${tag.versionPartDelimiter}.`); } const oldVersionPatternMatchReplacement: string = oldVersionPatternMatch.replace(oldVersionString, newVersionString); - fileContent = fileContent.replace(oldVersionPatternMatch, oldVersionPatternMatchReplacement); + fileContent = fileContent.substring(0, matches.index) + oldVersionPatternMatchReplacement + + fileContent.substring(matches.index + oldVersionPatternMatch.length); updatedVersions.push({ - versionType: versionRegex.versionType, + versionType: tag.versionType, oldVersion: oldVersionString, newVersion: newVersionString }); diff --git a/src/plugins/props-plugin.ts b/src/plugins/props-plugin.ts index 76322d2..f58a925 100644 --- a/src/plugins/props-plugin.ts +++ b/src/plugins/props-plugin.ts @@ -1,38 +1,47 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/i; -const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/i; -const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/i; -const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/i; +const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/; +const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/; +const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/; +const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/; export default class PropsPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "version", regex: VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "versionprefix", regex: VERSION_PREFIX_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "fileversion", regex: FILE_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "props"; } get fileTypeName(): string diff --git a/src/plugins/rc-plugin.ts b/src/plugins/rc-plugin.ts index ae9ea4c..0ddef6d 100644 --- a/src/plugins/rc-plugin.ts +++ b/src/plugins/rc-plugin.ts @@ -1,38 +1,47 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const FILEVERSION_REGEX: RegExp = /FILEVERSION\s*(.*)/i; -const FILEVERSION_STRING_REGEX: RegExp = /VALUE\s*"FileVersion",\s*"(.*)"/i; -const PRODUCTVERSION_REGEX: RegExp = /PRODUCTVERSION\s*(.*)/i; -const PRODUCTVERSION_STRING_REGEX: RegExp = /VALUE\s*"ProductVersion",\s*"(.*)"/i; +const FILEVERSION_REGEX: RegExp = /FILEVERSION\s+(\d+,\d+,\d+,\d+)/; +const FILEVERSION_STRING_REGEX: RegExp = /VALUE\s*"FileVersion",\s*"(.*)"/; +const PRODUCTVERSION_REGEX: RegExp = /PRODUCTVERSION\s+(\d+,\d+,\d+,\d+)/; +const PRODUCTVERSION_STRING_REGEX: RegExp = /VALUE\s*"ProductVersion",\s*"(.*)"/; export default class RcPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "fileversion-param", regex: FILEVERSION_REGEX, versionPartDelimiter: VersionPartDelimiter.COMMA, versionType: "FILEVERSION parameter" }, { + tagName: "fileversion-string", regex: FILEVERSION_STRING_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "FileVersion string" }, { + tagName: "productversion-param", regex: PRODUCTVERSION_REGEX, versionPartDelimiter: VersionPartDelimiter.COMMA, versionType: "PRODUCTVERSION parameter" }, { + tagName: "productversion-string", regex: PRODUCTVERSION_STRING_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: "ProductVersion string" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "rc"; } get fileTypeName(): string diff --git a/src/plugins/vbproj-plugin.ts b/src/plugins/vbproj-plugin.ts index 5fd7925..48b02f8 100644 --- a/src/plugins/vbproj-plugin.ts +++ b/src/plugins/vbproj-plugin.ts @@ -1,38 +1,47 @@ -import Plugin, { PluginVersionRegex, VersionPartDelimiter } from "./plugin"; +import Plugin, { PluginTag, VersionPartDelimiter } from "./plugin"; -const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/i; -const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/i; -const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/i; -const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/i; +const VERSION_TAG_REGEX: RegExp = /(.*)<\/Version>/; +const VERSION_PREFIX_TAG_REGEX: RegExp = /(.*)<\/VersionPrefix>/; +const ASSEMBLY_VERSION_TAG_REGEX: RegExp = /(.*)<\/AssemblyVersion>/; +const FILE_VERSION_TAG_REGEX: RegExp = /(.*)<\/FileVersion>/; export default class VbProjPlugin extends Plugin { constructor() { - const versionRegexes: PluginVersionRegex[] = + const tags: PluginTag[] = [ { + tagName: "version", regex: VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "versionprefix", regex: VERSION_PREFIX_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "assemblyversion", regex: ASSEMBLY_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" }, { + tagName: "fileversion", regex: FILE_VERSION_TAG_REGEX, versionPartDelimiter: VersionPartDelimiter.DOT, versionType: " tag" } ]; - super(versionRegexes); + super(tags); + } + + get pluginName(): string + { + return "vbproj"; } get fileTypeName(): string diff --git a/src/test.ts b/src/test.ts index 59ab7f9..7c7dfb4 100644 --- a/src/test.ts +++ b/src/test.ts @@ -1,5 +1,9 @@ import UpdaterTests from "./tests/updater-tests"; import VersionUtilsTests from "./tests/version-utils-tests"; +import FilterUtilsTests from "./tests/filter-utils-tests"; +import PluginsTests from "./tests/plugins-tests/plugins-tests"; UpdaterTests.runTests(); VersionUtilsTests.runTests(); +FilterUtilsTests.runTests(); +PluginsTests.runTests(); diff --git a/src/tests/filter-utils-tests.ts b/src/tests/filter-utils-tests.ts new file mode 100644 index 0000000..7988246 --- /dev/null +++ b/src/tests/filter-utils-tests.ts @@ -0,0 +1,192 @@ +import test, { ExecutionContext } from "ava"; +import type { PluginFilter, TagFilter } from "../types/filter-types"; +import FilterUtils from "../utils/filter-utils"; + +function createPluginFilter(pluginName: string, originalPluginName: string, tagFilters: TagFilter[]): PluginFilter +{ + const result: PluginFilter = + { + pluginName, + originalPluginName, + tagFilters + }; + return result; +} + +function createTagFilters(...params: string[]): TagFilter[] +{ + const result: TagFilter[] = []; + if (params.length % 2 !== 0) + { + throw new Error("Number of createTagFilters parameters must be even.") + } + for (let i = 0; i < params.length; i += 2) + { + result.push({ + tagName: params[i], + originalTagName: params[i+1] + }); + } + return result; +} + +function runParsePluginTagFilterStringTests() +{ + const parsePluginTagFilterStringTest = test.macro({ + exec(t: ExecutionContext, pluginTagFilterString: string | undefined, expectedResult: PluginFilter[]) + { + const actualResult = FilterUtils.parsePluginTagFilterString(pluginTagFilterString); + t.is(actualResult.length, expectedResult.length); + for (let pluginIndex = 0; pluginIndex < actualResult.length; pluginIndex++) + { + t.is(actualResult[pluginIndex].pluginName, expectedResult[pluginIndex].pluginName, "pluginName doesn't match"); + t.is(actualResult[pluginIndex].originalPluginName, expectedResult[pluginIndex].originalPluginName, "originalPluginName doesn't match"); + t.is(actualResult[pluginIndex].tagFilters.length, expectedResult[pluginIndex].tagFilters.length, "tagFilters.length doesn't match"); + for (let tagIndex = 0; tagIndex < actualResult[pluginIndex].tagFilters.length; tagIndex++) + { + t.is(actualResult[pluginIndex].tagFilters[tagIndex].tagName, expectedResult[pluginIndex].tagFilters[tagIndex].tagName, + "tagName doesn't match"); + t.is(actualResult[pluginIndex].tagFilters[tagIndex].originalTagName, + expectedResult[pluginIndex].tagFilters[tagIndex].originalTagName, "originalTagName doesn't match"); + } + } + }, + title(providedTitle: string | undefined, pluginTagFilterString: string | undefined, _: PluginFilter[]) + { + let result = "parsePluginTagFilterStringTest: "; + if (providedTitle !== undefined) + { + result += `(${providedTitle}) `; + } + result += pluginTagFilterString; + return result; + } + }); + + test("* without whitespaces", parsePluginTagFilterStringTest, "*", [ createPluginFilter("*", "*", createTagFilters("*", "")) ]); + test("* with whitespaces", parsePluginTagFilterStringTest, " * ", [ createPluginFilter("*", "*", createTagFilters("*", "")) ]); + test("empty string without whitespaces", parsePluginTagFilterStringTest, "", [ createPluginFilter("*", "", createTagFilters("*", "")) ]); + test("empty string with whitespaces", parsePluginTagFilterStringTest, " ", [ createPluginFilter("*", "", createTagFilters("*", "")) ]); + test(parsePluginTagFilterStringTest, undefined, [ createPluginFilter("*", "", createTagFilters("*", "")) ]); + test(parsePluginTagFilterStringTest, "csproj", [ createPluginFilter("csproj", "csproj", createTagFilters("*", "*")) ]); + test(parsePluginTagFilterStringTest, "csproj.*", [ createPluginFilter("csproj", "csproj", createTagFilters("*", "*")) ]); + test(parsePluginTagFilterStringTest, "CsProj.*", [ createPluginFilter("csproj", "CsProj", createTagFilters("*", "*")) ]); + test(parsePluginTagFilterStringTest, "csproj.assemblyversion", + [ createPluginFilter("csproj", "csproj", createTagFilters("assemblyversion", "assemblyversion")) ]); + test(parsePluginTagFilterStringTest, "CsProj.AssemblyVersion", + [ createPluginFilter("csproj", "CsProj", createTagFilters("assemblyversion", "AssemblyVersion")) ]); + test("two filters without whitespaces", parsePluginTagFilterStringTest, "csproj.Version,csproj.AssemblyVersion", + [ createPluginFilter("csproj", "csproj", createTagFilters("version", "Version", "assemblyversion", "AssemblyVersion")) ]); + test("two filters with a single whitespace", parsePluginTagFilterStringTest, "csproj.Version, csproj.AssemblyVersion", + [ createPluginFilter("csproj", "csproj", createTagFilters("version", "Version", "assemblyversion", "AssemblyVersion")) ]); + test("two filters with two whitespaces", parsePluginTagFilterStringTest, "csproj.Version, csproj.AssemblyVersion", + [ createPluginFilter("csproj", "csproj", createTagFilters("version", "Version", "assemblyversion", "AssemblyVersion")) ]); + test(parsePluginTagFilterStringTest, "csproj.Version, props.Version", + [ createPluginFilter("csproj", "csproj", createTagFilters("version", "Version")), + createPluginFilter("props", "props", createTagFilters("version", "Version")) ]); + test(parsePluginTagFilterStringTest, "AssemblyInfo-cs.Version, AssemblyInfo-cpp.AssemblyFileVersion", + [ createPluginFilter("assemblyinfo-cs", "AssemblyInfo-cs", createTagFilters("version", "Version")), + createPluginFilter("assemblyinfo-cpp", "AssemblyInfo-cpp", createTagFilters("assemblyfileversion", "AssemblyFileVersion")) ]); +} + +function runPluginWildcardFilterWithOtherFiltersTest() +{ + test("Plugin wildcard filter along with other filters test", t => + { + const error = t.throws(() => + { + FilterUtils.parsePluginTagFilterString("csproj,*") + }); + t.is(error?.message, "'*' must be the only element in the tag filter list: 'csproj,*'."); + }) +} + +function runTagWildcardFilterWithOtherFiltersTest() +{ + const tagWildcardFilterWithOtherFiltersTest = test.macro({ + exec(t: ExecutionContext, filter: string, pluginName: string, filterStringPart: string) + { + const error = t.throws(() => + { + FilterUtils.parsePluginTagFilterString(filter); + }); + t.is(error?.message, `'${filterStringPart}' must be the only filter for the '${pluginName}' file type ` + + `in the tag filter list: '${filter}'.`); + }, + title(_ = "", filter: string) + { + return `tagWildcardFilterWithOtherFiltersTest: ${filter}`; + } + }); + + test(tagWildcardFilterWithOtherFiltersTest, "csproj.version,csproj.*", "csproj", "csproj.*"); + test(tagWildcardFilterWithOtherFiltersTest, "csproj.*,csproj.version", "csproj", "csproj.*"); + test(tagWildcardFilterWithOtherFiltersTest, "nuspec.*,csproj.version,csproj.*", "csproj", "csproj.*"); + test(tagWildcardFilterWithOtherFiltersTest, "CsProj.Version,csproj.*", "csproj", "csproj.*"); + test(tagWildcardFilterWithOtherFiltersTest, "csproj.*,CsProj.Version", "csproj", "csproj.*"); + test(tagWildcardFilterWithOtherFiltersTest, "csproj.version,CsProj.*", "CsProj", "CsProj.*"); + test(tagWildcardFilterWithOtherFiltersTest, "CsProj.*,csproj.version", "CsProj", "CsProj.*"); +} + +function runInvalidFiltersTest() +{ + const invalidFiltersTest = test.macro({ + exec(t: ExecutionContext, filter: string) + { + const filterStringWithCsProjFilter = "csproj," + filter; + const error = t.throws(() => + { + FilterUtils.parsePluginTagFilterString(filterStringWithCsProjFilter); + }); + t.is(error?.message, `'${filter}' is not a valid filter in the tag filter list: '${filterStringWithCsProjFilter}'.`); + }, + title(_ = "", filter: string) + { + return `invalidFiltersTest: ${filter}`; + } + }); + + test(invalidFiltersTest, "nuspec."); + test(invalidFiltersTest, ".version"); + test(invalidFiltersTest, "."); +} + +function runDuplicateFilterPartsTest() +{ + const duplicateFilterPartsTest = test.macro({ + exec(t: ExecutionContext, filter: string, duplicateFilterPart: string) + { + const error = t.throws(() => + { + FilterUtils.parsePluginTagFilterString(filter); + }); + t.is(error?.message, `Duplicate filter: '${duplicateFilterPart}' in the tag filter list: '${filter}'.`); + }, + title(_ = "", filter: string) + { + return `duplicateFilterPartsTest: ${filter}`; + } + }); + + test(duplicateFilterPartsTest, "csproj.version,csproj.version", "csproj.version"); + test(duplicateFilterPartsTest, "CsProj.Version,csproj.version", "csproj.version"); + test(duplicateFilterPartsTest, "nuspec.version,csproj.version,csproj.version", "csproj.version"); + test(duplicateFilterPartsTest, "csproj.version,nuspec.version,csproj.version", "csproj.version"); + test(duplicateFilterPartsTest, "csproj,nuspec,csproj", "csproj"); + test(duplicateFilterPartsTest, "csproj,nuspec,csproj.*", "csproj.*"); + test(duplicateFilterPartsTest, "csproj.*,nuspec,csproj", "csproj"); +} + +function runTests() +{ + runParsePluginTagFilterStringTests(); + runPluginWildcardFilterWithOtherFiltersTest(); + runTagWildcardFilterWithOtherFiltersTest(); + runInvalidFiltersTest(); + runDuplicateFilterPartsTest(); +} + +export default +{ + runTests +}; diff --git a/src/tests/plugins-tests/assemblyinfo-cpp-plugin-test.ts b/src/tests/plugins-tests/assemblyinfo-cpp-plugin-test.ts new file mode 100644 index 0000000..72a153b --- /dev/null +++ b/src/tests/plugins-tests/assemblyinfo-cpp-plugin-test.ts @@ -0,0 +1,24 @@ +import type { PluginTest } from "./plugin-test"; +import AssemblyInfoCppPlugin from "../../plugins/assemblyinfo-cpp-plugin"; + +const assemblyInfoCppPluginTest: PluginTest = +{ + plugin: new AssemblyInfoCppPlugin(), + input: `[assembly:AssemblyVersionAttribute(L"1.2.3")];\n[assembly:AssemblyFileVersionAttribute(L"1.2.3")]`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `[assembly:AssemblyVersionAttribute(L"4.5.6")];\n[assembly:AssemblyFileVersionAttribute(L"4.5.6")]` + }, + { + tag: "assemblyversion", + expectedResult: `[assembly:AssemblyVersionAttribute(L"4.5.6")];\n[assembly:AssemblyFileVersionAttribute(L"1.2.3")]` + }, + { + tag: "assemblyfileversion", + expectedResult: `[assembly:AssemblyVersionAttribute(L"1.2.3")];\n[assembly:AssemblyFileVersionAttribute(L"4.5.6")]` + }] +}; + +export default assemblyInfoCppPluginTest; diff --git a/src/tests/plugins-tests/assemblyinfo-cs-plugin-test.ts b/src/tests/plugins-tests/assemblyinfo-cs-plugin-test.ts new file mode 100644 index 0000000..79d56ec --- /dev/null +++ b/src/tests/plugins-tests/assemblyinfo-cs-plugin-test.ts @@ -0,0 +1,24 @@ +import type { PluginTest } from "./plugin-test"; +import AssemblyInfoCsPlugin from "../../plugins/assemblyinfo-cs-plugin"; + +const assemblyInfoCsPluginTest: PluginTest = +{ + plugin: new AssemblyInfoCsPlugin(), + input: `[assembly: AssemblyVersion("1.2.3")]\n[assembly: AssemblyFileVersion("1.2.3")]`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `[assembly: AssemblyVersion("4.5.6")]\n[assembly: AssemblyFileVersion("4.5.6")]` + }, + { + tag: "assemblyversion", + expectedResult: `[assembly: AssemblyVersion("4.5.6")]\n[assembly: AssemblyFileVersion("1.2.3")]` + }, + { + tag: "assemblyfileversion", + expectedResult: `[assembly: AssemblyVersion("1.2.3")]\n[assembly: AssemblyFileVersion("4.5.6")]` + }] +}; + +export default assemblyInfoCsPluginTest; diff --git a/src/tests/plugins-tests/assemblyinfo-fs-plugin-test.ts b/src/tests/plugins-tests/assemblyinfo-fs-plugin-test.ts new file mode 100644 index 0000000..8a181cc --- /dev/null +++ b/src/tests/plugins-tests/assemblyinfo-fs-plugin-test.ts @@ -0,0 +1,24 @@ +import type { PluginTest } from "./plugin-test"; +import AssemblyInfoFsPlugin from "../../plugins/assemblyinfo-fs-plugin"; + +const assemblyInfoFsPluginTest: PluginTest = +{ + plugin: new AssemblyInfoFsPlugin(), + input: `[]\n[]\ndo()`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `[]\n[]\ndo()` + }, + { + tag: "assemblyversion", + expectedResult: `[]\n[]\ndo()` + }, + { + tag: "assemblyfileversion", + expectedResult: `[]\n[]\ndo()` + }] +}; + +export default assemblyInfoFsPluginTest; diff --git a/src/tests/plugins-tests/assemblyinfo-vb-plugin-test.ts b/src/tests/plugins-tests/assemblyinfo-vb-plugin-test.ts new file mode 100644 index 0000000..1196ab1 --- /dev/null +++ b/src/tests/plugins-tests/assemblyinfo-vb-plugin-test.ts @@ -0,0 +1,24 @@ +import type { PluginTest } from "./plugin-test"; +import AssemblyInfoVbPlugin from "../../plugins/assemblyinfo-vb-plugin"; + +const assemblyInfoVbPluginTest: PluginTest = +{ + plugin: new AssemblyInfoVbPlugin(), + input: `\n`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `\n` + }, + { + tag: "assemblyversion", + expectedResult: `\n` + }, + { + tag: "assemblyfileversion", + expectedResult: `\n` + }] +}; + +export default assemblyInfoVbPluginTest; diff --git a/src/tests/plugins-tests/csproj-plugin-test.ts b/src/tests/plugins-tests/csproj-plugin-test.ts new file mode 100644 index 0000000..2193df8 --- /dev/null +++ b/src/tests/plugins-tests/csproj-plugin-test.ts @@ -0,0 +1,44 @@ +import type { PluginTest } from "./plugin-test"; +import CsProjPlugin from "../../plugins/csproj-plugin"; + +const csProjPluginTest: PluginTest = +{ + plugin: new CsProjPlugin(), + input: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n1.2.3\n` + + `\n`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `\n\n` + + `4.5.6\n4.5.6\n4.5.6\n4.5.6\n` + + `\n` + }, + { + tag: "version", + expectedResult: `\n\n` + + `4.5.6\n1.2.3\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "versionprefix", + expectedResult: `\n\n` + + `1.2.3\n4.5.6\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "assemblyversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n4.5.6\n1.2.3\n` + + `\n` + }, + { + tag: "fileversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n4.5.6\n` + + `\n` + }] +}; + +export default csProjPluginTest; diff --git a/src/tests/plugins-tests/fsproj-plugin-test.ts b/src/tests/plugins-tests/fsproj-plugin-test.ts new file mode 100644 index 0000000..4d5f592 --- /dev/null +++ b/src/tests/plugins-tests/fsproj-plugin-test.ts @@ -0,0 +1,44 @@ +import type { PluginTest } from "./plugin-test"; +import FsProjPlugin from "../../plugins/fsproj-plugin"; + +const fsProjPluginTest: PluginTest = +{ + plugin: new FsProjPlugin(), + input: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n1.2.3\n` + + `\n`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `\n\n` + + `4.5.6\n4.5.6\n4.5.6\n4.5.6\n` + + `\n` + }, + { + tag: "version", + expectedResult: `\n\n` + + `4.5.6\n1.2.3\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "versionprefix", + expectedResult: `\n\n` + + `1.2.3\n4.5.6\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "assemblyversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n4.5.6\n1.2.3\n` + + `\n` + }, + { + tag: "fileversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n4.5.6\n` + + `\n` + }] +}; + +export default fsProjPluginTest; diff --git a/src/tests/plugins-tests/nuspec-plugin-test.ts b/src/tests/plugins-tests/nuspec-plugin-test.ts new file mode 100644 index 0000000..4b9b9be --- /dev/null +++ b/src/tests/plugins-tests/nuspec-plugin-test.ts @@ -0,0 +1,20 @@ +import type { PluginTest } from "./plugin-test"; +import NuspecPlugin from "../../plugins/nuspec-plugin"; + +const nuspecPluginTest: PluginTest = +{ + plugin: new NuspecPlugin(), + input: `\n\n\n1.2.3\n\n`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `\n\n\n4.5.6\n\n` + }, + { + tag: "version", + expectedResult: `\n\n\n4.5.6\n\n` + }] +}; + +export default nuspecPluginTest; diff --git a/src/tests/plugins-tests/plugin-test.ts b/src/tests/plugins-tests/plugin-test.ts new file mode 100644 index 0000000..c9c0b65 --- /dev/null +++ b/src/tests/plugins-tests/plugin-test.ts @@ -0,0 +1,15 @@ +import type Plugin from "../../plugins/plugin"; + +export interface PluginTest +{ + plugin: Plugin; + input: string; + newVersion: string; + tagTests: TagTest[]; +} + +export interface TagTest +{ + tag: string; + expectedResult: string; +} diff --git a/src/tests/plugins-tests/plugins-tests.ts b/src/tests/plugins-tests/plugins-tests.ts new file mode 100644 index 0000000..dbe796c --- /dev/null +++ b/src/tests/plugins-tests/plugins-tests.ts @@ -0,0 +1,52 @@ +import test from "ava"; +import type { PluginTest } from "./plugin-test"; +import type { TagFilter } from "../../types/filter-types"; +import type { VersionUpdateRule } from "../../types/version-types"; +import VersionUtils from "../../utils/version-utils"; +import assemblyInfoCppPluginTest from "./assemblyinfo-cpp-plugin-test" +import assemblyInfoCsPluginTest from "./assemblyinfo-cs-plugin-test" +import assemblyInfoFsPluginTest from "./assemblyinfo-fs-plugin-test" +import assemblyInfoVbPluginTest from "./assemblyinfo-vb-plugin-test" +import csProjPluginTest from "./csproj-plugin-test" +import fsProjPluginTest from "./fsproj-plugin-test" +import vbProjPluginTest from "./vbproj-plugin-test" +import nuspecPluginTest from "./nuspec-plugin-test" +import propsPluginTest from "./props-plugin-test" +import rcPluginTest from "./rc-plugin-test" + +function runPluginTest(pluginTest: PluginTest) +{ + const versionUpdateRule: VersionUpdateRule = VersionUtils.parseVersionUpdateRule(pluginTest.newVersion); + for (const tagTest of pluginTest.tagTests) + { + test(`Plugin test: plugin = ${pluginTest.plugin.pluginName}, tag = ${tagTest.tag}`, t => + { + const tagFilter: TagFilter = + { + tagName: tagTest.tag, + originalTagName: tagTest.tag + }; + const fileUpdateResult = pluginTest.plugin.updateFile("testfile", pluginTest.input, versionUpdateRule, [ tagFilter ]); + t.is(fileUpdateResult?.newFileContent, tagTest.expectedResult); + }); + } +} + +function runTests() +{ + runPluginTest(assemblyInfoCppPluginTest); + runPluginTest(assemblyInfoCsPluginTest); + runPluginTest(assemblyInfoFsPluginTest); + runPluginTest(assemblyInfoVbPluginTest); + runPluginTest(csProjPluginTest); + runPluginTest(fsProjPluginTest); + runPluginTest(vbProjPluginTest); + runPluginTest(nuspecPluginTest); + runPluginTest(propsPluginTest); + runPluginTest(rcPluginTest); +} + +export default +{ + runTests +}; diff --git a/src/tests/plugins-tests/props-plugin-test.ts b/src/tests/plugins-tests/props-plugin-test.ts new file mode 100644 index 0000000..9c3d47f --- /dev/null +++ b/src/tests/plugins-tests/props-plugin-test.ts @@ -0,0 +1,44 @@ +import type { PluginTest } from "./plugin-test"; +import PropsPlugin from "../../plugins/props-plugin"; + +const propsPluginTest: PluginTest = +{ + plugin: new PropsPlugin(), + input: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n1.2.3\n` + + `\n`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `\n\n` + + `4.5.6\n4.5.6\n4.5.6\n4.5.6\n` + + `\n` + }, + { + tag: "version", + expectedResult: `\n\n` + + `4.5.6\n1.2.3\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "versionprefix", + expectedResult: `\n\n` + + `1.2.3\n4.5.6\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "assemblyversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n4.5.6\n1.2.3\n` + + `\n` + }, + { + tag: "fileversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n4.5.6\n` + + `\n` + }] +}; + +export default propsPluginTest; diff --git a/src/tests/plugins-tests/rc-plugin-test.ts b/src/tests/plugins-tests/rc-plugin-test.ts new file mode 100644 index 0000000..4e7ad8a --- /dev/null +++ b/src/tests/plugins-tests/rc-plugin-test.ts @@ -0,0 +1,38 @@ +import type { PluginTest } from "./plugin-test"; +import RcPlugin from "../../plugins/rc-plugin"; + +const rcPluginTest: PluginTest = +{ + plugin: new RcPlugin(), + input: `VS_VERSION_INFO VERSIONINFO\nFILEVERSION 1,2,3,0\nPRODUCTVERSION 1,2,3,0\nBEGIN\nBLOCK "StringFileInfo"\nBEGIN\nBLOCK "040904b0"\n` + + `BEGIN\nVALUE "FileVersion", "1.2.3"\nVALUE "ProductVersion", "1.2.3"\nEND\nEND\nEND`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `VS_VERSION_INFO VERSIONINFO\nFILEVERSION 4,5,6,0\nPRODUCTVERSION 4,5,6,0\nBEGIN\nBLOCK "StringFileInfo"\nBEGIN\nBLOCK "040904b0"\n` + + `BEGIN\nVALUE "FileVersion", "4.5.6"\nVALUE "ProductVersion", "4.5.6"\nEND\nEND\nEND` + }, + { + tag: "fileversion-param", + expectedResult: `VS_VERSION_INFO VERSIONINFO\nFILEVERSION 4,5,6,0\nPRODUCTVERSION 1,2,3,0\nBEGIN\nBLOCK "StringFileInfo"\nBEGIN\nBLOCK "040904b0"\n` + + `BEGIN\nVALUE "FileVersion", "1.2.3"\nVALUE "ProductVersion", "1.2.3"\nEND\nEND\nEND` + }, + { + tag: "fileversion-string", + expectedResult: `VS_VERSION_INFO VERSIONINFO\nFILEVERSION 1,2,3,0\nPRODUCTVERSION 1,2,3,0\nBEGIN\nBLOCK "StringFileInfo"\nBEGIN\nBLOCK "040904b0"\n` + + `BEGIN\nVALUE "FileVersion", "4.5.6"\nVALUE "ProductVersion", "1.2.3"\nEND\nEND\nEND` + }, + { + tag: "productversion-param", + expectedResult: `VS_VERSION_INFO VERSIONINFO\nFILEVERSION 1,2,3,0\nPRODUCTVERSION 4,5,6,0\nBEGIN\nBLOCK "StringFileInfo"\nBEGIN\nBLOCK "040904b0"\n` + + `BEGIN\nVALUE "FileVersion", "1.2.3"\nVALUE "ProductVersion", "1.2.3"\nEND\nEND\nEND` + }, + { + tag: "productversion-string", + expectedResult: `VS_VERSION_INFO VERSIONINFO\nFILEVERSION 1,2,3,0\nPRODUCTVERSION 1,2,3,0\nBEGIN\nBLOCK "StringFileInfo"\nBEGIN\nBLOCK "040904b0"\n` + + `BEGIN\nVALUE "FileVersion", "1.2.3"\nVALUE "ProductVersion", "4.5.6"\nEND\nEND\nEND` + }] +}; + +export default rcPluginTest; diff --git a/src/tests/plugins-tests/vbproj-plugin-test.ts b/src/tests/plugins-tests/vbproj-plugin-test.ts new file mode 100644 index 0000000..cf98792 --- /dev/null +++ b/src/tests/plugins-tests/vbproj-plugin-test.ts @@ -0,0 +1,44 @@ +import type { PluginTest } from "./plugin-test"; +import VbProjPlugin from "../../plugins/vbproj-plugin"; + +const vbProjPluginTest: PluginTest = +{ + plugin: new VbProjPlugin(), + input: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n1.2.3\n` + + `\n`, + newVersion: "4.5.6", + tagTests: + [{ + tag: "*", + expectedResult: `\n\n` + + `4.5.6\n4.5.6\n4.5.6\n4.5.6\n` + + `\n` + }, + { + tag: "version", + expectedResult: `\n\n` + + `4.5.6\n1.2.3\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "versionprefix", + expectedResult: `\n\n` + + `1.2.3\n4.5.6\n1.2.3\n1.2.3\n` + + `\n` + }, + { + tag: "assemblyversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n4.5.6\n1.2.3\n` + + `\n` + }, + { + tag: "fileversion", + expectedResult: `\n\n` + + `1.2.3\n1.2.3\n1.2.3\n4.5.6\n` + + `\n` + }] +}; + +export default vbProjPluginTest; diff --git a/src/tests/updater-tests.ts b/src/tests/updater-tests.ts index f5e875f..d81832a 100644 --- a/src/tests/updater-tests.ts +++ b/src/tests/updater-tests.ts @@ -1,56 +1,145 @@ import test, { ExecutionContext } from "ava"; import { promises as fs } from "fs"; +import path from "path"; import Updater, { UpdaterResult } from "../updater"; +const TEST_FILES_DIRECTORY_PATH = "test-files"; +const ALL_FILES_TEST_DIRECTORY_NAME = "all-files-test"; +const SINGLE_FILE_TEST_DIRECTORY_NAME = "single-file-test"; +const TAG_FILTER_TEST_DIRECTORY_NAME = "tag-filter-test"; +const NO_MATCHING_FILES_TEST_DIRECTORY_NAME = "no-matching-files-test"; +const UNSUPPORTED_FILE_TYPE_TEST_DIRECTORY_NAME = "unsupported-file-type-test"; +const FILES_WITH_COMMENTS_TEST_DIRECTORY_NAME = "files-with-comments-test"; +const INPUT_DIRECTORY_NAME = "input"; +const EXPECTED_RESULTS_DIRECTORY_NAME = "expected-results"; +const ACTUAL_RESULTS_DIRECTORY_NAME = "actual-results"; + +function joinPaths(...paths: string[]): string +{ + return path.join(...paths).split(path.sep).join("/"); +} + +function getTestDirectoryPath(testDirectoryName: string) +{ + return joinPaths(TEST_FILES_DIRECTORY_PATH, testDirectoryName); +} + +function getInputDirectoryPath(testDirectoryName: string) +{ + return joinPaths(getTestDirectoryPath(testDirectoryName), INPUT_DIRECTORY_NAME); +} + +function getExpectedResultsDirectoryPath(testDirectoryName: string) +{ + return joinPaths(getTestDirectoryPath(testDirectoryName), EXPECTED_RESULTS_DIRECTORY_NAME); +} + +function getActualResultsDirectoryPath(testDirectoryName: string) +{ + return joinPaths(getTestDirectoryPath(testDirectoryName), ACTUAL_RESULTS_DIRECTORY_NAME); +} + async function getFileContent(filePath: string): Promise { return await fs.readFile(filePath, "utf-8"); } +async function copyInputTestFiles(testDirectoryName: string) +{ + const inputPath = getInputDirectoryPath(testDirectoryName); + const actualResultsPath = getActualResultsDirectoryPath(testDirectoryName); + await fs.mkdir(actualResultsPath, { recursive: true }); + for (const inputFileName of await fs.readdir(inputPath)) + { + await fs.copyFile(joinPaths(inputPath, inputFileName), joinPaths(actualResultsPath, inputFileName)); + } +} + function runUpdateAllFilesTest() { - test.serial("Update all files test", async t => + test("Update all files test", async t => { - const updaterResults: UpdaterResult[] = await Updater.update("\"test-files/input/*\", \"!test-files/input/*.txt\"", "4.5.6"); - const expectedFiles: string[] = await fs.readdir("test-files/expected-results"); + await copyInputTestFiles(ALL_FILES_TEST_DIRECTORY_NAME); + const expectedResultsDirectoryPath = getExpectedResultsDirectoryPath(ALL_FILES_TEST_DIRECTORY_NAME); + const actualResultsDirectoryPath = getActualResultsDirectoryPath(ALL_FILES_TEST_DIRECTORY_NAME); + const updaterResults: UpdaterResult[] = + await Updater.update(`"${joinPaths(actualResultsDirectoryPath, "*")}", "!${joinPaths(actualResultsDirectoryPath, "*.txt")}"`, "4.5.6"); + const expectedFiles: string[] = await fs.readdir(expectedResultsDirectoryPath); t.is(updaterResults.length, expectedFiles.length); - for (const expectedFile of expectedFiles) + for (const expectedFileName of expectedFiles) { - const inputFilePath = "test-files/input/" + expectedFile; - const expectedFilePath = "test-files/expected-results/" + expectedFile; - const updaterResult: UpdaterResult | undefined = updaterResults.find(updateResult => updateResult.filePath === inputFilePath); + const expectedFilePath = joinPaths(expectedResultsDirectoryPath, expectedFileName); + const actualFilePath = joinPaths(actualResultsDirectoryPath, expectedFileName); + const updaterResult: UpdaterResult | undefined = updaterResults.find(updateResult => updateResult.filePath === actualFilePath); t.assert(updaterResult !== undefined); t.true(updaterResult!.updatedVersions.length > 0); for (const updatedVersion of updaterResult!.updatedVersions) { - if (expectedFile === "Test.rc" && (updatedVersion.versionType === "FILEVERSION parameter" || updatedVersion.versionType === "PRODUCTVERSION parameter")) + if (expectedFileName === "Test.rc" && + (updatedVersion.versionType === "FILEVERSION parameter" || updatedVersion.versionType === "PRODUCTVERSION parameter")) { - t.is(updatedVersion.oldVersion, "1,2,3,0"); - t.is(updatedVersion.newVersion, "4,5,6,0"); + t.is(updatedVersion.oldVersion, "1,2,3,0", `Actual old version doesn't match the expected old version for file ${expectedFileName}.`); + t.is(updatedVersion.newVersion, "4,5,6,0", `Actual new version doesn't match the expected new version for file ${expectedFileName}.`); } else { - t.is(updatedVersion.oldVersion, "1.2.3"); - t.is(updatedVersion.newVersion, "4.5.6"); + t.is(updatedVersion.oldVersion, "1.2.3", `Actual old version doesn't match the expected old version for file ${expectedFileName}.`); + t.is(updatedVersion.newVersion, "4.5.6", `Actual new version doesn't match the expected new version for file ${expectedFileName}.`); } } - t.is(await getFileContent(inputFilePath), await getFileContent(expectedFilePath)); + t.is(await getFileContent(actualFilePath), await getFileContent(expectedFilePath), + `Content of the actual file: '${actualFilePath}' doesn't match the content of the expected file: '${expectedFilePath}'.`); } }); } function runUpdateSingleFileTest() { - test.serial("Update single file test", async t => + test("Update single file test", async t => { - const updaterResults: UpdaterResult[] = await Updater.update("test-files/input/Test.csproj", "7.8.9"); + await copyInputTestFiles(SINGLE_FILE_TEST_DIRECTORY_NAME); + const actualResultsDirectoryPath = getActualResultsDirectoryPath(SINGLE_FILE_TEST_DIRECTORY_NAME); + const testFilePath = joinPaths(actualResultsDirectoryPath, "Test.csproj"); + const updaterResults: UpdaterResult[] = await Updater.update(testFilePath, "7.8.9"); t.is(updaterResults.length, 1); - t.is(updaterResults[0].filePath, "test-files/input/Test.csproj"); + t.is(updaterResults[0].filePath, testFilePath); t.is(updaterResults[0].updatedVersions[0].oldVersion, "4.5.6"); t.is(updaterResults[0].updatedVersions[0].newVersion, "7.8.9"); }); } +function runUpdateAllFilesWithTagFilterTest() +{ + test("Update all files with tag filter test", async t => + { + await copyInputTestFiles(TAG_FILTER_TEST_DIRECTORY_NAME); + const expectedResultsDirectoryPath = getExpectedResultsDirectoryPath(TAG_FILTER_TEST_DIRECTORY_NAME); + const actualResultsDirectoryPath = getActualResultsDirectoryPath(TAG_FILTER_TEST_DIRECTORY_NAME); + const updaterResults: UpdaterResult[] = + await Updater.update(`"${joinPaths(actualResultsDirectoryPath, "*")}"`, "4.5.6", "AssemblyInfo-cs,CsProj.Version,CsProj.AssemblyVersion"); + t.is(updaterResults.length, 2); + const expectedFiles: string[] = await fs.readdir(expectedResultsDirectoryPath); + for (const expectedFileName of expectedFiles) + { + const expectedFilePath = joinPaths(expectedResultsDirectoryPath, expectedFileName); + const actualFilePath = joinPaths(actualResultsDirectoryPath, expectedFileName); + if (expectedFileName !== "Skip.props") + { + const updaterResult: UpdaterResult | undefined = updaterResults.find(updateResult => updateResult.filePath === actualFilePath); + t.assert(updaterResult !== undefined); + t.true(updaterResult!.updatedVersions.length > 0); + for (const updatedVersion of updaterResult!.updatedVersions) + { + t.is(updatedVersion.oldVersion, "1.2.3", `Actual old version doesn't match the expected old version for file ${expectedFileName}.`); + t.is(updatedVersion.newVersion, "4.5.6", `Actual new version doesn't match the expected new version for file ${expectedFileName}.`); + } + } + t.is(await getFileContent(actualFilePath), await getFileContent(expectedFilePath), + `Content of the actual file: '${actualFilePath}' doesn't match the content of the expected file: '${expectedFilePath}'.`); + } + }); +} + function runEmptyFilePathPatternTests() { const emptyFilePathPatternTest = test.macro({ @@ -102,6 +191,7 @@ function runNoMatchingFilesTests() const noMatchingFilesTest = test.macro({ async exec(t: ExecutionContext, filePathPattern: string) { + await copyInputTestFiles(NO_MATCHING_FILES_TEST_DIRECTORY_NAME); const error = await t.throwsAsync(async () => { await Updater.update(filePathPattern, "1.2.3"); @@ -114,8 +204,9 @@ function runNoMatchingFilesTests() } }); - test(noMatchingFilesTest, "test-files/input/MissingFile.csproj"); - test(noMatchingFilesTest, "test-files/input/*.sln"); + const actualResultsDirectoryPath = getActualResultsDirectoryPath(NO_MATCHING_FILES_TEST_DIRECTORY_NAME); + test.serial(noMatchingFilesTest, joinPaths(actualResultsDirectoryPath, "MissingFile.csproj")); + test.serial(noMatchingFilesTest, joinPaths(actualResultsDirectoryPath, "*.props")); } function runUnsupportedFileTypeTests() @@ -123,6 +214,7 @@ function runUnsupportedFileTypeTests() const unsupportedFileTypeTest = test.macro({ async exec(t: ExecutionContext, filePathPattern: string) { + await copyInputTestFiles(UNSUPPORTED_FILE_TYPE_TEST_DIRECTORY_NAME); const error = await t.throwsAsync(async () => { await Updater.update(filePathPattern, "1.2.3"); @@ -134,18 +226,70 @@ function runUnsupportedFileTypeTests() return `unsupportedFileTypeTest: ${filePathPattern}`; } }); - - test(unsupportedFileTypeTest, "test-files/input/Test.txt"); + + const actualResultsDirectoryPath = getActualResultsDirectoryPath(UNSUPPORTED_FILE_TYPE_TEST_DIRECTORY_NAME); + test(unsupportedFileTypeTest, joinPaths(actualResultsDirectoryPath, "Test.txt")); +} + +function runInvalidTagFiltersTest() +{ + test("Invalid plugin name in the tag filter test", async t => + { + const error = await t.throwsAsync(async () => + { + await Updater.update("*", "1.2.3", "UnknownPlugin"); + }); + t.is(error?.message, "Unknown file type: 'UnknownPlugin' in the tag filter list: 'UnknownPlugin'."); + }); + test("Invalid tag name in the tag filter test", async t => + { + const error = await t.throwsAsync(async () => + { + await Updater.update("*", "1.2.3", "CsProj.UnknownTag"); + }); + t.is(error?.message, "Unknown tag: 'UnknownTag' for the file type: 'CsProj' in the tag filter list: 'CsProj.UnknownTag'."); + }); +} + +function runUpdateFilesWithCommentsTest() +{ + test("Update files with comments test", async t => + { + await copyInputTestFiles(FILES_WITH_COMMENTS_TEST_DIRECTORY_NAME); + const expectedResultsDirectoryPath = getExpectedResultsDirectoryPath(FILES_WITH_COMMENTS_TEST_DIRECTORY_NAME); + const actualResultsDirectoryPath = getActualResultsDirectoryPath(FILES_WITH_COMMENTS_TEST_DIRECTORY_NAME); + const updaterResults: UpdaterResult[] = await Updater.update(`"${joinPaths(actualResultsDirectoryPath, "*")}"`, "4.5.6"); + const expectedFiles: string[] = await fs.readdir(expectedResultsDirectoryPath); + t.is(updaterResults.length, expectedFiles.length); + for (const expectedFileName of expectedFiles) + { + const expectedFilePath = joinPaths(expectedResultsDirectoryPath, expectedFileName); + const actualFilePath = joinPaths(actualResultsDirectoryPath, expectedFileName); + const updaterResult: UpdaterResult | undefined = updaterResults.find(updateResult => updateResult.filePath === actualFilePath); + t.assert(updaterResult !== undefined); + t.true(updaterResult!.updatedVersions.length > 0); + for (const updatedVersion of updaterResult!.updatedVersions) + { + t.is(updatedVersion.oldVersion, "1.2.3", `Actual old version doesn't match the expected old version for file ${expectedFileName}.`); + t.is(updatedVersion.newVersion, "4.5.6", `Actual new version doesn't match the expected new version for file ${expectedFileName}.`); + } + t.is(await getFileContent(actualFilePath), await getFileContent(expectedFilePath), + `Content of the actual file: '${actualFilePath}' doesn't match the content of the expected file: '${expectedFilePath}'.`); + } + }); } function runTests() { runUpdateAllFilesTest(); runUpdateSingleFileTest(); + runUpdateAllFilesWithTagFilterTest(); runEmptyFilePathPatternTests(); runInvalidFilePatternTests(); runNoMatchingFilesTests(); runUnsupportedFileTypeTests(); + runInvalidTagFiltersTest(); + runUpdateFilesWithCommentsTest(); } export default diff --git a/src/tests/version-utils-tests.ts b/src/tests/version-utils-tests.ts index 4150eeb..16b2cf3 100644 --- a/src/tests/version-utils-tests.ts +++ b/src/tests/version-utils-tests.ts @@ -1,5 +1,6 @@ import test, { ExecutionContext } from "ava"; -import VersionUtils, { Version, VersionUpdateRule } from "../utils/version-utils"; +import type { Version, VersionUpdateRule } from "../types/version-types"; +import VersionUtils from "../utils/version-utils"; function createVersion(major: number, minor: number | null = null, build: number | null = null, revision: number | null = null): Version { diff --git a/src/types/filter-types.ts b/src/types/filter-types.ts new file mode 100644 index 0000000..a2ddd82 --- /dev/null +++ b/src/types/filter-types.ts @@ -0,0 +1,12 @@ +export interface PluginFilter +{ + pluginName: string; + originalPluginName: string; + tagFilters: TagFilter[]; +} + +export interface TagFilter +{ + tagName: string; + originalTagName: string; +} diff --git a/src/types/version-types.ts b/src/types/version-types.ts new file mode 100644 index 0000000..e9e7fda --- /dev/null +++ b/src/types/version-types.ts @@ -0,0 +1,43 @@ +export interface VersionUpdateRule +{ + updateMode: VersionUpdateMode; + explicitVersion: string | null; + updatePattern: VersionUpdatePattern | null; +} + +export enum VersionUpdateMode +{ + SET_EXPLICIT_VERSION, + USE_PATTERN +} + +export interface VersionUpdatePattern +{ + build: VersionPartUpdateRule; + major: VersionPartUpdateRule; + minor: VersionPartUpdateRule; + revision: VersionPartUpdateRule; +} + +export interface VersionPartUpdateRule +{ + updateMode: VersionPartUpdateMode; + overwriteTo: number | null; +} + +export enum VersionPartUpdateMode +{ + LEAVE_UNCHANGED, + LEAVE_UNCHANGED_SET_MISSING_TO_ZERO, + BUMP, + OVERWRITE, + REMOVE +} + +export interface Version +{ + major: number; + minor: number | null; + build: number | null; + revision: number | null; +} diff --git a/src/updater.ts b/src/updater.ts index 6126a4d..482f3ba 100644 --- a/src/updater.ts +++ b/src/updater.ts @@ -1,8 +1,12 @@ import { promises as fs } from "fs"; import fastGlob from "fast-glob"; import { FileUpdateResult, VersionUpdateResult } from "./plugins/plugin"; +import type Plugin from "./plugins/plugin"; import Plugins from "./plugins/plugins"; -import VersionUtils, { VersionUpdateRule } from "./utils/version-utils"; +import type { VersionUpdateRule } from "./types/version-types"; +import VersionUtils from "./utils/version-utils"; +import type { PluginFilter, TagFilter } from "./types/filter-types"; +import FilterUtils from "./utils/filter-utils"; export interface UpdaterResult { @@ -11,7 +15,7 @@ export interface UpdaterResult updatedVersions: VersionUpdateResult[]; } -async function update(filePathPattern: string, newVersion: string): Promise +async function update(filePathPattern: string, newVersion: string, pluginTagFilterString?: string): Promise { const trimmedFilePathPattern = filePathPattern.trim(); if (trimmedFilePathPattern.length === 0 || trimmedFilePathPattern === "\"\"") @@ -21,7 +25,8 @@ async function update(filePathPattern: string, newVersion: string): Promise +async function updateFile(filePath: string, versionUpdateRule: VersionUpdateRule, pluginFilters: PluginFilter[]): Promise { + const isMatchAllFilter = pluginFilters.length === 1 && pluginFilters[0].pluginName === "*"; for (const plugin of Plugins) { if (plugin.isFileTypeSupported(filePath)) { + let tagFilters: TagFilter[]; + if (isMatchAllFilter) + { + tagFilters = pluginFilters[0].tagFilters; + } + else + { + const pluginFilter = pluginFilters.find(pluginFilter => pluginFilter.pluginName === plugin.pluginName); + if (pluginFilter === undefined) + { + return null; + } + tagFilters = pluginFilter.tagFilters; + } const fileContent: string = await fs.readFile(filePath, "utf-8"); - const fileUpdateResult: FileUpdateResult | null = plugin.updateFile(fileContent, versionUpdateRule); + const fileUpdateResult: FileUpdateResult | null = plugin.updateFile(filePath, fileContent, versionUpdateRule, tagFilters); if (fileUpdateResult === null) { - throw new Error(`No version information found in ${filePath}`); + return null; } await fs.writeFile(filePath, fileUpdateResult.newFileContent, "utf-8"); const result: UpdaterResult = @@ -75,6 +101,34 @@ async function updateFile(filePath: string, versionUpdateRule: VersionUpdateRule throw new Error(`Unsupported file type for file: ${filePath}`); } +function validateFilters(filters: PluginFilter[], pluginTagFilterString: string): void +{ + for (const pluginFilter of filters) + { + if (pluginFilter.pluginName === "*") + { + continue; + } + const plugin: Plugin | undefined = Plugins.find(plugin => plugin.pluginName === pluginFilter.pluginName); + if (plugin === undefined) + { + throw new Error(`Unknown file type: '${pluginFilter.originalPluginName}' in the tag filter list: '${pluginTagFilterString}'.`); + } + for (const tagFilter of pluginFilter.tagFilters) + { + if (tagFilter.tagName === "*") + { + continue; + } + if (plugin.tags.find(tag => tag.tagName === tagFilter.tagName) === undefined) + { + throw new Error(`Unknown tag: '${tagFilter.originalTagName}' for the file type: '${pluginFilter.originalPluginName}' `+ + `in the tag filter list: '${pluginTagFilterString}'.`); + } + } + } +} + export default { update diff --git a/src/utils/filter-utils.ts b/src/utils/filter-utils.ts new file mode 100644 index 0000000..b4ba43d --- /dev/null +++ b/src/utils/filter-utils.ts @@ -0,0 +1,88 @@ +import type { PluginFilter } from "../types/filter-types"; + +function parsePluginTagFilterString(pluginTagFilterString: string | undefined): PluginFilter[] +{ + const result: PluginFilter[] = []; + pluginTagFilterString = pluginTagFilterString?.trim(); + if (pluginTagFilterString === undefined || pluginTagFilterString === "*" || pluginTagFilterString === "") + { + result.push({ + pluginName: "*", + originalPluginName: pluginTagFilterString ?? "", + tagFilters: + [{ + tagName: "*", + originalTagName: "" + }] + }); + } + else + { + const filterStringParts = pluginTagFilterString.split(','); + for (let filterStringPart of filterStringParts) + { + filterStringPart = filterStringPart.trim(); + if (filterStringPart === "*") + { + throw new Error(`'*' must be the only element in the tag filter list: '${pluginTagFilterString}'.`); + } + let pluginName; + let pluginTag; + const dotPosition = filterStringPart.indexOf('.'); + if (dotPosition !== -1) + { + if (dotPosition === 0 || dotPosition === filterStringPart.length - 1) + { + throw new Error(`'${filterStringPart}' is not a valid filter in the tag filter list: '${pluginTagFilterString}'.`) + } + pluginName = filterStringPart.substring(0, dotPosition); + pluginTag = filterStringPart.substring(dotPosition + 1); + } + else + { + pluginName = filterStringPart; + pluginTag = "*"; + } + const pluginNameLowerCase = pluginName.toLowerCase(); + const pluginTagLowerCase = pluginTag.toLowerCase(); + let resultPluginFilter = result.find(pluginFilter => pluginFilter.pluginName === pluginNameLowerCase); + if (resultPluginFilter === undefined) + { + resultPluginFilter = + { + pluginName: pluginNameLowerCase, + originalPluginName: pluginName, + tagFilters: [] + }; + result.push(resultPluginFilter); + } + if (resultPluginFilter.tagFilters.find(pluginTagFilter => pluginTagFilter.tagName === pluginTagLowerCase)) + { + throw new Error(`Duplicate filter: '${filterStringPart}' in the tag filter list: '${pluginTagFilterString}'.`) + } + else if (resultPluginFilter.tagFilters.length > 0) + { + if (pluginTagLowerCase === "*") + { + throw new Error(`'${filterStringPart}' must be the only filter for the '${pluginName}' file type ` + + `in the tag filter list: '${pluginTagFilterString}'.`); + } + else if (resultPluginFilter.tagFilters[0].tagName === "*") + { + throw new Error(`'${resultPluginFilter.originalPluginName}.*' must be the only filter ` + + `for the '${resultPluginFilter.originalPluginName}' file type in the tag filter list: '${pluginTagFilterString}'.`); + } + } + resultPluginFilter.tagFilters.push({ + tagName: pluginTagLowerCase, + originalTagName: pluginTag + }); + } + } + return result; +} + +export default +{ + parsePluginTagFilterString +}; diff --git a/src/utils/version-utils.ts b/src/utils/version-utils.ts index 8fa28c6..40e8058 100644 --- a/src/utils/version-utils.ts +++ b/src/utils/version-utils.ts @@ -1,3 +1,6 @@ +import type { Version, VersionPartUpdateRule, VersionUpdatePattern, VersionUpdateRule } from "../types/version-types"; +import { VersionPartUpdateMode, VersionUpdateMode } from "../types/version-types"; + const BUMP_MAJOR_COMMAND = "bump-major"; const BUMP_MINOR_COMMAND = "bump-minor"; const BUMP_BUILD_COMMAND = "bump-build"; @@ -6,50 +9,6 @@ const VERSION_UPDATE_RULE_REGEX: RegExp = /(\?|\*|\^|\d+)\.?(\?|\*|\^|\d+)?\.?(\ const VERSION_NUMBER_WITH_DOT_DELIMITER_REGEX: RegExp = /(\d+)\.?(\d+)?\.?(\d+)?\.?(\d+)?/; const VERSION_NUMBER_WITH_COMMA_DELIMITER_REGEX: RegExp = /(\d+)\,?(\d+)?\,?(\d+)?\,?(\d+)?/; -export interface VersionUpdateRule -{ - updateMode: VersionUpdateMode; - explicitVersion: string | null; - updatePattern: VersionUpdatePattern | null; -} - -enum VersionUpdateMode -{ - SET_EXPLICIT_VERSION, - USE_PATTERN -} - -interface VersionUpdatePattern -{ - build: VersionPartUpdateRule; - major: VersionPartUpdateRule; - minor: VersionPartUpdateRule; - revision: VersionPartUpdateRule; -} - -interface VersionPartUpdateRule -{ - updateMode: VersionPartUpdateMode; - overwriteTo: number | null; -} - -enum VersionPartUpdateMode -{ - LEAVE_UNCHANGED, - LEAVE_UNCHANGED_SET_MISSING_TO_ZERO, - BUMP, - OVERWRITE, - REMOVE -} - -export interface Version -{ - major: number; - minor: number | null; - build: number | null; - revision: number | null; -} - function parseVersionUpdateRule(input: string): VersionUpdateRule { input = input.trim(); @@ -114,7 +73,8 @@ function parseVersionUpdateRule(input: string): VersionUpdateRule return result; } -function updateNonParsedVersion(currentVersion: string, versionUpdateRule: VersionUpdateRule, versionNumberRegex: RegExp, versionPartDelimiter: string): string +function updateNonParsedVersion(currentVersion: string, versionUpdateRule: VersionUpdateRule, versionNumberRegex: RegExp, + versionPartDelimiter: string): string { if (versionUpdateRule.updateMode === VersionUpdateMode.SET_EXPLICIT_VERSION) { diff --git a/test-files/expected-results/Test.cpp b/test-files/all-files-test/expected-results/Test.cpp similarity index 100% rename from test-files/expected-results/Test.cpp rename to test-files/all-files-test/expected-results/Test.cpp diff --git a/test-files/expected-results/Test.cs b/test-files/all-files-test/expected-results/Test.cs similarity index 100% rename from test-files/expected-results/Test.cs rename to test-files/all-files-test/expected-results/Test.cs diff --git a/test-files/expected-results/Test.csproj b/test-files/all-files-test/expected-results/Test.csproj similarity index 100% rename from test-files/expected-results/Test.csproj rename to test-files/all-files-test/expected-results/Test.csproj diff --git a/test-files/expected-results/Test.fs b/test-files/all-files-test/expected-results/Test.fs similarity index 94% rename from test-files/expected-results/Test.fs rename to test-files/all-files-test/expected-results/Test.fs index f8ad5d0..b4820ea 100644 --- a/test-files/expected-results/Test.fs +++ b/test-files/all-files-test/expected-results/Test.fs @@ -1,3 +1,3 @@ [] [] -do() \ No newline at end of file +do() diff --git a/test-files/expected-results/Test.fsproj b/test-files/all-files-test/expected-results/Test.fsproj similarity index 100% rename from test-files/expected-results/Test.fsproj rename to test-files/all-files-test/expected-results/Test.fsproj diff --git a/test-files/expected-results/Test.nuspec b/test-files/all-files-test/expected-results/Test.nuspec similarity index 100% rename from test-files/expected-results/Test.nuspec rename to test-files/all-files-test/expected-results/Test.nuspec diff --git a/test-files/expected-results/Test.props b/test-files/all-files-test/expected-results/Test.props similarity index 60% rename from test-files/expected-results/Test.props rename to test-files/all-files-test/expected-results/Test.props index 5277b40..02fdd00 100644 --- a/test-files/expected-results/Test.props +++ b/test-files/all-files-test/expected-results/Test.props @@ -2,5 +2,7 @@ 4.5.6 4.5.6 + 4.5.6 + 4.5.6 diff --git a/test-files/expected-results/Test.rc b/test-files/all-files-test/expected-results/Test.rc similarity index 100% rename from test-files/expected-results/Test.rc rename to test-files/all-files-test/expected-results/Test.rc diff --git a/test-files/expected-results/Test.vb b/test-files/all-files-test/expected-results/Test.vb similarity index 100% rename from test-files/expected-results/Test.vb rename to test-files/all-files-test/expected-results/Test.vb diff --git a/test-files/expected-results/Test.vbproj b/test-files/all-files-test/expected-results/Test.vbproj similarity index 100% rename from test-files/expected-results/Test.vbproj rename to test-files/all-files-test/expected-results/Test.vbproj diff --git a/test-files/input/Test.cpp b/test-files/all-files-test/input/Test.cpp similarity index 100% rename from test-files/input/Test.cpp rename to test-files/all-files-test/input/Test.cpp diff --git a/test-files/input/Test.cs b/test-files/all-files-test/input/Test.cs similarity index 100% rename from test-files/input/Test.cs rename to test-files/all-files-test/input/Test.cs diff --git a/test-files/input/Test.csproj b/test-files/all-files-test/input/Test.csproj similarity index 100% rename from test-files/input/Test.csproj rename to test-files/all-files-test/input/Test.csproj diff --git a/test-files/input/Test.fs b/test-files/all-files-test/input/Test.fs similarity index 94% rename from test-files/input/Test.fs rename to test-files/all-files-test/input/Test.fs index 01b4533..caf3e31 100644 --- a/test-files/input/Test.fs +++ b/test-files/all-files-test/input/Test.fs @@ -1,3 +1,3 @@ [] [] -do() \ No newline at end of file +do() diff --git a/test-files/input/Test.fsproj b/test-files/all-files-test/input/Test.fsproj similarity index 100% rename from test-files/input/Test.fsproj rename to test-files/all-files-test/input/Test.fsproj diff --git a/test-files/input/Test.nuspec b/test-files/all-files-test/input/Test.nuspec similarity index 100% rename from test-files/input/Test.nuspec rename to test-files/all-files-test/input/Test.nuspec diff --git a/test-files/all-files-test/input/Test.props b/test-files/all-files-test/input/Test.props new file mode 100644 index 0000000..60e213f --- /dev/null +++ b/test-files/all-files-test/input/Test.props @@ -0,0 +1,8 @@ + + + 1.2.3 + 1.2.3 + 1.2.3 + 1.2.3 + + diff --git a/test-files/input/Test.rc b/test-files/all-files-test/input/Test.rc similarity index 100% rename from test-files/input/Test.rc rename to test-files/all-files-test/input/Test.rc diff --git a/test-files/input/Test.vb b/test-files/all-files-test/input/Test.vb similarity index 100% rename from test-files/input/Test.vb rename to test-files/all-files-test/input/Test.vb diff --git a/test-files/input/Test.vbproj b/test-files/all-files-test/input/Test.vbproj similarity index 100% rename from test-files/input/Test.vbproj rename to test-files/all-files-test/input/Test.vbproj diff --git a/test-files/files-with-comments-test/expected-results/Test.cpp b/test-files/files-with-comments-test/expected-results/Test.cpp new file mode 100644 index 0000000..ca5b56f --- /dev/null +++ b/test-files/files-with-comments-test/expected-results/Test.cpp @@ -0,0 +1,4 @@ +// [assembly:AssemblyVersionAttribute(L"1.2.3")]; +// [assembly:AssemblyFileVersionAttribute(L"1.2.3")] +[assembly:AssemblyVersionAttribute(L"4.5.6")]; +[assembly:AssemblyFileVersionAttribute(L"4.5.6")] diff --git a/test-files/files-with-comments-test/expected-results/Test.cs b/test-files/files-with-comments-test/expected-results/Test.cs new file mode 100644 index 0000000..33ade41 --- /dev/null +++ b/test-files/files-with-comments-test/expected-results/Test.cs @@ -0,0 +1,4 @@ +// [assembly: AssemblyVersion("1.2.3")] +// [assembly: AssemblyFileVersion("1.2.3")] +[assembly: AssemblyVersion("4.5.6")] +[assembly: AssemblyFileVersion("4.5.6")] diff --git a/test-files/files-with-comments-test/expected-results/Test.fs b/test-files/files-with-comments-test/expected-results/Test.fs new file mode 100644 index 0000000..0eb9cad --- /dev/null +++ b/test-files/files-with-comments-test/expected-results/Test.fs @@ -0,0 +1,5 @@ +// [] +// [] +[] +[] +do() diff --git a/test-files/files-with-comments-test/expected-results/Test.vb b/test-files/files-with-comments-test/expected-results/Test.vb new file mode 100644 index 0000000..e2c24fe --- /dev/null +++ b/test-files/files-with-comments-test/expected-results/Test.vb @@ -0,0 +1,4 @@ +' +' + + diff --git a/test-files/files-with-comments-test/input/Test.cpp b/test-files/files-with-comments-test/input/Test.cpp new file mode 100644 index 0000000..52f5f2f --- /dev/null +++ b/test-files/files-with-comments-test/input/Test.cpp @@ -0,0 +1,4 @@ +// [assembly:AssemblyVersionAttribute(L"1.2.3")]; +// [assembly:AssemblyFileVersionAttribute(L"1.2.3")] +[assembly:AssemblyVersionAttribute(L"1.2.3")]; +[assembly:AssemblyFileVersionAttribute(L"1.2.3")] diff --git a/test-files/files-with-comments-test/input/Test.cs b/test-files/files-with-comments-test/input/Test.cs new file mode 100644 index 0000000..214485d --- /dev/null +++ b/test-files/files-with-comments-test/input/Test.cs @@ -0,0 +1,4 @@ +// [assembly: AssemblyVersion("1.2.3")] +// [assembly: AssemblyFileVersion("1.2.3")] +[assembly: AssemblyVersion("1.2.3")] +[assembly: AssemblyFileVersion("1.2.3")] diff --git a/test-files/files-with-comments-test/input/Test.fs b/test-files/files-with-comments-test/input/Test.fs new file mode 100644 index 0000000..3d34231 --- /dev/null +++ b/test-files/files-with-comments-test/input/Test.fs @@ -0,0 +1,5 @@ +// [] +// [] +[] +[] +do() diff --git a/test-files/files-with-comments-test/input/Test.vb b/test-files/files-with-comments-test/input/Test.vb new file mode 100644 index 0000000..8190349 --- /dev/null +++ b/test-files/files-with-comments-test/input/Test.vb @@ -0,0 +1,4 @@ +' +' + + diff --git a/test-files/no-matching-files-test/input/Test.cs b/test-files/no-matching-files-test/input/Test.cs new file mode 100644 index 0000000..d4a1011 --- /dev/null +++ b/test-files/no-matching-files-test/input/Test.cs @@ -0,0 +1,2 @@ +[assembly: AssemblyVersion("1.2.3")] +[assembly: AssemblyFileVersion("1.2.3")] diff --git a/test-files/no-matching-files-test/input/Test.csproj b/test-files/no-matching-files-test/input/Test.csproj new file mode 100644 index 0000000..7aabc72 --- /dev/null +++ b/test-files/no-matching-files-test/input/Test.csproj @@ -0,0 +1,8 @@ + + + 1.2.3 + 1.2.3 + 1.2.3 + 1.2.3 + + diff --git a/test-files/single-file-test/input/Test.cs b/test-files/single-file-test/input/Test.cs new file mode 100644 index 0000000..a2bf27d --- /dev/null +++ b/test-files/single-file-test/input/Test.cs @@ -0,0 +1,2 @@ +[assembly: AssemblyVersion("4.5.6")] +[assembly: AssemblyFileVersion("4.5.6")] diff --git a/test-files/single-file-test/input/Test.csproj b/test-files/single-file-test/input/Test.csproj new file mode 100644 index 0000000..e468c88 --- /dev/null +++ b/test-files/single-file-test/input/Test.csproj @@ -0,0 +1,8 @@ + + + 4.5.6 + 4.5.6 + 4.5.6 + 4.5.6 + + diff --git a/test-files/input/Test.props b/test-files/tag-filter-test/expected-results/Skip.props similarity index 100% rename from test-files/input/Test.props rename to test-files/tag-filter-test/expected-results/Skip.props diff --git a/test-files/tag-filter-test/expected-results/Test.cs b/test-files/tag-filter-test/expected-results/Test.cs new file mode 100644 index 0000000..a2bf27d --- /dev/null +++ b/test-files/tag-filter-test/expected-results/Test.cs @@ -0,0 +1,2 @@ +[assembly: AssemblyVersion("4.5.6")] +[assembly: AssemblyFileVersion("4.5.6")] diff --git a/test-files/tag-filter-test/expected-results/Test.csproj b/test-files/tag-filter-test/expected-results/Test.csproj new file mode 100644 index 0000000..82d94fa --- /dev/null +++ b/test-files/tag-filter-test/expected-results/Test.csproj @@ -0,0 +1,8 @@ + + + 4.5.6 + 1.2.3 + 4.5.6 + 1.2.3 + + diff --git a/test-files/tag-filter-test/input/Skip.props b/test-files/tag-filter-test/input/Skip.props new file mode 100644 index 0000000..ecaca05 --- /dev/null +++ b/test-files/tag-filter-test/input/Skip.props @@ -0,0 +1,6 @@ + + + 1.2.3 + 1.2.3 + + diff --git a/test-files/tag-filter-test/input/Test.cs b/test-files/tag-filter-test/input/Test.cs new file mode 100644 index 0000000..d4a1011 --- /dev/null +++ b/test-files/tag-filter-test/input/Test.cs @@ -0,0 +1,2 @@ +[assembly: AssemblyVersion("1.2.3")] +[assembly: AssemblyFileVersion("1.2.3")] diff --git a/test-files/tag-filter-test/input/Test.csproj b/test-files/tag-filter-test/input/Test.csproj new file mode 100644 index 0000000..7aabc72 --- /dev/null +++ b/test-files/tag-filter-test/input/Test.csproj @@ -0,0 +1,8 @@ + + + 1.2.3 + 1.2.3 + 1.2.3 + 1.2.3 + + diff --git a/test-files/input/Test.txt b/test-files/unsupported-file-type-test/input/Test.txt similarity index 100% rename from test-files/input/Test.txt rename to test-files/unsupported-file-type-test/input/Test.txt diff --git a/tsconfig.json b/tsconfig.json index dbb5b7b..f420985 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "rootDir": "./src", "strict": true, "noImplicitAny": true, - "esModuleInterop": true + "esModuleInterop": true, + "sourceMap": true }, "exclude": [ "node_modules"