Родитель
f647c586bd
Коммит
7f89e52f79
|
@ -30,5 +30,8 @@
|
|||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
// Turn off tsc task auto detection since we have the necessary tasks as npm scripts
|
||||
"typescript.tsc.autoDetect": "off"
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"cSpell.words": [
|
||||
"pwsh"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -13,10 +13,14 @@ Continue reading to see the changes included in the latest version.
|
|||
|
||||
## Unreleased
|
||||
|
||||
- New features:
|
||||
- Added `PSRule: Run analysis` quick task to call `Assert-PSRule` for the current workspace. [#226](https://github.com/microsoft/PSRule-vscode/issues/226)
|
||||
- To configure set `path`, `inputPath`, `baseline`, `module`, and `outcome` per task.
|
||||
- The default task will run analysis in the current workspace using rules in `.ps-rule/`.
|
||||
- General improvements:
|
||||
- Preview channel will notify that a stable version is available. [#235](https://github.com/microsoft/PSRule-vscode/issues/235)
|
||||
- Engineering:
|
||||
- Bump vscode engine to v1.55.0. [#241](https://github.com/microsoft/PSRule-vscode/pull/241)
|
||||
- Bump vscode engine to v1.56.0. [#241](https://github.com/microsoft/PSRule-vscode/pull/241)
|
||||
|
||||
## v1.0.0
|
||||
|
||||
|
|
28
README.md
28
README.md
|
@ -3,7 +3,7 @@
|
|||
Validate infrastructure as code (IaC) and DevOps repositories using the PSRule PowerShell module.
|
||||
PSRule is powerful, feature rich, and highly customizable to meet your needs.
|
||||
|
||||
![ext-stable-version-badge] ![ext-stable-installs-badge] ![module-version-badge]
|
||||
![module-version-badge]
|
||||
|
||||
This extension is available in two release channels:
|
||||
|
||||
|
@ -39,10 +39,33 @@ Channel | Description | Version/ downloads
|
|||
</p>
|
||||
|
||||
- Adds snippets for creating markdown documentation.
|
||||
- **Quick documentation** — create rule documentation to provide rule recommendations and examples.
|
||||
- **Quick documentation** — create rule documentation to provide rule recommendations and examples.
|
||||
- Trigger IntelliSense by typing `rule` in a `.md` file.
|
||||
IntelliSense can also be triggered by using the shortcut `Ctrl+Space`.
|
||||
|
||||
### Quick tasks
|
||||
|
||||
<p align="center">
|
||||
<img src="./docs/images/tasks-provider.png" alt="Built-in tasks shown in task list" />
|
||||
</p>
|
||||
|
||||
- Adds quick tasks for analysis directly from Visual Studio Code.
|
||||
- **Run analysis** — Runs rules against files in the current workspace.
|
||||
- _Input path_, _Baseline_, _Modules_, and _Outcome_ options can be configured per task.
|
||||
- _Output as_, and showing a _Not processed warning_ options can be configured by workspace or user.
|
||||
- Rule stored in `.ps-rule/` are automatically used by default.
|
||||
|
||||
## Configuration
|
||||
|
||||
In addition to configuring the [ps-rule.yaml] options file, the following settings are available.
|
||||
|
||||
Name | Description
|
||||
---- | -----------
|
||||
`PSRule.execution.notProcessedWarning` | Warn when objects are not processed by any rule.
|
||||
`PSRule.experimental.enabled` | Enables experimental features in the PSRule extension.
|
||||
`PSRule.notifications.showChannelUpgrade` | Specifies if a notification to switch to the stable channel is shown on start up.
|
||||
`PSRule.output.as` | Configures the output of analysis tasks, either summary or detailed.
|
||||
|
||||
## Support
|
||||
|
||||
This project uses GitHub Issues to track bugs and feature requests.
|
||||
|
@ -110,3 +133,4 @@ This project is [licensed under the MIT License][license].
|
|||
[license]: https://github.com/Microsoft/PSRule-vscode/blob/main/LICENSE
|
||||
[chat]: https://gitter.im/PSRule/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||
[chat-badge]: https://img.shields.io/static/v1.svg?label=chat&message=on%20gitter&color=informational&logo=gitter
|
||||
[ps-rule.yaml]: https://microsoft.github.io/PSRule/concepts/PSRule/en-US/about_PSRule_Options.html
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 23 KiB |
|
@ -135,9 +135,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "15.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz",
|
||||
"integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==",
|
||||
"version": "15.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.1.tgz",
|
||||
"integrity": "sha512-weaeiP4UF4XgF++3rpQhpIJWsCTS4QJw5gvBhQu6cFIxTwyxWIe3xbnrY/o2lTCQ0lsdb8YIUDUvLR4Vuz5rbw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/vscode": {
|
||||
|
@ -147,142 +147,71 @@
|
|||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.23.0.tgz",
|
||||
"integrity": "sha512-tGK1y3KIvdsQEEgq6xNn1DjiFJtl+wn8JJQiETtCbdQxw1vzjXyAaIkEmO2l6Nq24iy3uZBMFQjZ6ECf1QdgGw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.24.0.tgz",
|
||||
"integrity": "sha512-qbCgkPM7DWTsYQGjx9RTuQGswi+bEt0isqDBeo+CKV0953zqI0Tp7CZ7Fi9ipgFA6mcQqF4NOVNwS/f2r6xShw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/experimental-utils": "4.23.0",
|
||||
"@typescript-eslint/scope-manager": "4.23.0",
|
||||
"@typescript-eslint/experimental-utils": "4.24.0",
|
||||
"@typescript-eslint/scope-manager": "4.24.0",
|
||||
"debug": "^4.1.1",
|
||||
"functional-red-black-tree": "^1.0.1",
|
||||
"lodash": "^4.17.15",
|
||||
"regexpp": "^3.0.0",
|
||||
"semver": "^7.3.2",
|
||||
"tsutils": "^3.17.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz",
|
||||
"integrity": "sha512-ZZ21PCFxPhI3n0wuqEJK9omkw51wi2bmeKJvlRZPH5YFkcawKOuRMQMnI8mH6Vo0/DoHSeZJnHiIx84LmVQY+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/visitor-keys": "4.23.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.23.0.tgz",
|
||||
"integrity": "sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz",
|
||||
"integrity": "sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/experimental-utils": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.23.0.tgz",
|
||||
"integrity": "sha512-WAFNiTDnQfrF3Z2fQ05nmCgPsO5o790vOhmWKXbbYQTO9erE1/YsFot5/LnOUizLzU2eeuz6+U/81KV5/hFTGA==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.24.0.tgz",
|
||||
"integrity": "sha512-IwTT2VNDKH1h8RZseMH4CcYBz6lTvRoOLDuuqNZZoThvfHEhOiZPQCow+5El3PtyxJ1iDr6UXZwYtE3yZQjhcw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/json-schema": "^7.0.3",
|
||||
"@typescript-eslint/scope-manager": "4.23.0",
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/typescript-estree": "4.23.0",
|
||||
"@typescript-eslint/scope-manager": "4.24.0",
|
||||
"@typescript-eslint/types": "4.24.0",
|
||||
"@typescript-eslint/typescript-estree": "4.24.0",
|
||||
"eslint-scope": "^5.0.0",
|
||||
"eslint-utils": "^2.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz",
|
||||
"integrity": "sha512-ZZ21PCFxPhI3n0wuqEJK9omkw51wi2bmeKJvlRZPH5YFkcawKOuRMQMnI8mH6Vo0/DoHSeZJnHiIx84LmVQY+w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/visitor-keys": "4.23.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.23.0.tgz",
|
||||
"integrity": "sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz",
|
||||
"integrity": "sha512-5Sty6zPEVZF5fbvrZczfmLCOcby3sfrSPu30qKoY1U3mca5/jvU5cwsPb/CO6Q3ByRjixTMIVsDkqwIxCf/dMw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/visitor-keys": "4.23.0",
|
||||
"debug": "^4.1.1",
|
||||
"globby": "^11.0.1",
|
||||
"is-glob": "^4.0.1",
|
||||
"semver": "^7.3.2",
|
||||
"tsutils": "^3.17.1"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz",
|
||||
"integrity": "sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/parser": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.23.0.tgz",
|
||||
"integrity": "sha512-wsvjksHBMOqySy/Pi2Q6UuIuHYbgAMwLczRl4YanEPKW5KVxI9ZzDYh3B5DtcZPQTGRWFJrfcbJ6L01Leybwug==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.24.0.tgz",
|
||||
"integrity": "sha512-dj1ZIh/4QKeECLb2f/QjRwMmDArcwc2WorWPRlB8UNTZlY1KpTVsbX7e3ZZdphfRw29aTFUSNuGB8w9X5sS97w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/scope-manager": "4.23.0",
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/typescript-estree": "4.23.0",
|
||||
"@typescript-eslint/scope-manager": "4.24.0",
|
||||
"@typescript-eslint/types": "4.24.0",
|
||||
"@typescript-eslint/typescript-estree": "4.24.0",
|
||||
"debug": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/scope-manager": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.23.0.tgz",
|
||||
"integrity": "sha512-ZZ21PCFxPhI3n0wuqEJK9omkw51wi2bmeKJvlRZPH5YFkcawKOuRMQMnI8mH6Vo0/DoHSeZJnHiIx84LmVQY+w==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz",
|
||||
"integrity": "sha512-9+WYJGDnuC9VtYLqBhcSuM7du75fyCS/ypC8c5g7Sdw7pGL4NDTbeH38eJPfzIydCHZDoOgjloxSAA3+4l/zsA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/visitor-keys": "4.23.0"
|
||||
"@typescript-eslint/types": "4.24.0",
|
||||
"@typescript-eslint/visitor-keys": "4.24.0"
|
||||
}
|
||||
},
|
||||
"@typescript-eslint/types": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.23.0.tgz",
|
||||
"integrity": "sha512-oqkNWyG2SLS7uTWLZf6Sr7Dm02gA5yxiz1RP87tvsmDsguVATdpVguHr4HoGOcFOpCvx9vtCSCyQUGfzq28YCw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.24.0.tgz",
|
||||
"integrity": "sha512-tkZUBgDQKdvfs8L47LaqxojKDE+mIUmOzdz7r+u+U54l3GDkTpEbQ1Jp3cNqqAU9vMUCBA1fitsIhm7yN0vx9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"@typescript-eslint/typescript-estree": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.23.0.tgz",
|
||||
"integrity": "sha512-5Sty6zPEVZF5fbvrZczfmLCOcby3sfrSPu30qKoY1U3mca5/jvU5cwsPb/CO6Q3ByRjixTMIVsDkqwIxCf/dMw==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.24.0.tgz",
|
||||
"integrity": "sha512-kBDitL/by/HK7g8CYLT7aKpAwlR8doshfWz8d71j97n5kUa5caHWvY0RvEUEanL/EqBJoANev8Xc/mQ6LLwXGA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/visitor-keys": "4.23.0",
|
||||
"@typescript-eslint/types": "4.24.0",
|
||||
"@typescript-eslint/visitor-keys": "4.24.0",
|
||||
"debug": "^4.1.1",
|
||||
"globby": "^11.0.1",
|
||||
"is-glob": "^4.0.1",
|
||||
|
@ -291,12 +220,12 @@
|
|||
}
|
||||
},
|
||||
"@typescript-eslint/visitor-keys": {
|
||||
"version": "4.23.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.23.0.tgz",
|
||||
"integrity": "sha512-5PNe5cmX9pSifit0H+nPoQBXdbNzi5tOEec+3riK+ku4e3er37pKxMKDH5Ct5Y4fhWxcD4spnlYjxi9vXbSpwg==",
|
||||
"version": "4.24.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.24.0.tgz",
|
||||
"integrity": "sha512-4ox1sjmGHIxjEDBnMCtWFFhErXtKA1Ec0sBpuz0fqf3P+g3JFGyTxxbF06byw0FRsPnnbq44cKivH7Ks1/0s6g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@typescript-eslint/types": "4.23.0",
|
||||
"@typescript-eslint/types": "4.24.0",
|
||||
"eslint-visitor-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
|
@ -770,9 +699,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.11.23",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.11.23.tgz",
|
||||
"integrity": "sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==",
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.1.tgz",
|
||||
"integrity": "sha512-WfQ00MKm/Y4ysz1u9PCUAsV66k5lbrcEvS6aG9jhBIavpB94FBdaWeBkaZXxCZB4w+oqh+j4ozJFWnnFprOXbg==",
|
||||
"dev": true
|
||||
},
|
||||
"escalade": {
|
||||
|
|
80
package.json
80
package.json
|
@ -35,19 +35,84 @@
|
|||
"preview": true,
|
||||
"activationEvents": [
|
||||
"onLanguage:powershell",
|
||||
"workspaceContains:/ps-rule.yaml"
|
||||
"workspaceContains:/ps-rule.yaml",
|
||||
"workspaceContains:**/*.Rule.yaml",
|
||||
"workspaceContains:**/*.Rule.ps1",
|
||||
"onCommand:workbench.action.tasks.runTask"
|
||||
],
|
||||
"main": "./out/dist/extension.js",
|
||||
"main": "./out/dist/main.js",
|
||||
"contributes": {
|
||||
"configuration": [
|
||||
{
|
||||
"title": "PSRule",
|
||||
"properties": {
|
||||
"PSRule.execution.notProcessedWarning": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Warn when objects are not processed by any rule.",
|
||||
"scope": "window"
|
||||
},
|
||||
"PSRule.experimental.enabled": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "Enables experimental features in the PSRule extension.",
|
||||
"scope": "application"
|
||||
},
|
||||
"PSRule.notifications.showChannelUpgrade": {
|
||||
"type": "boolean",
|
||||
"default": true,
|
||||
"description": "Specifies if a notification to switch to the stable channel is shown on start up.",
|
||||
"scope": "application"
|
||||
},
|
||||
"PSRule.output.as": {
|
||||
"type": "string",
|
||||
"default": "Summary",
|
||||
"description": "Configures the output of analysis tasks, either summary or detailed.",
|
||||
"enum": [
|
||||
"Detail",
|
||||
"Summary"
|
||||
],
|
||||
"scope": "window"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"taskDefinitions": [
|
||||
{
|
||||
"type": "PSRule",
|
||||
"required": [],
|
||||
"properties": {
|
||||
"path": {
|
||||
"type": "string",
|
||||
"description": "The path containing rules.",
|
||||
"default": "./.ps-rule/"
|
||||
},
|
||||
"inputPath": {
|
||||
"type": "string",
|
||||
"description": "The path PSRule will look for input files. Defaults to workspace root.",
|
||||
"default": "."
|
||||
},
|
||||
"baseline": {
|
||||
"type": "string",
|
||||
"description": "The name of a PSRule baseline to use. Baselines can be used from modules or specified in a separate file."
|
||||
},
|
||||
"modules": {
|
||||
"type": "array",
|
||||
"description": "The name of one or more modules to use."
|
||||
},
|
||||
"outcome": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"enum": [
|
||||
"Pass",
|
||||
"Fail",
|
||||
"Error"
|
||||
]
|
||||
},
|
||||
"default": [
|
||||
"Fail",
|
||||
"Error"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -128,7 +193,7 @@
|
|||
"pretest": "npm run compile",
|
||||
"test": "node ./out/dist/test/runTest.js",
|
||||
"vscode:prepublish": "npm run -S esbuild-base -- --minify",
|
||||
"esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=out/dist/extension.js --external:vscode --format=cjs --platform=node",
|
||||
"esbuild-base": "esbuild ./src/main.ts --bundle --outfile=out/dist/main.js --external:vscode --format=cjs --platform=node",
|
||||
"esbuild": "npm run -S esbuild-base -- --sourcemap",
|
||||
"esbuild-watch": "npm run -S esbuild-base -- --sourcemap --watch"
|
||||
},
|
||||
|
@ -137,16 +202,17 @@
|
|||
},
|
||||
"extensionDependencies": [
|
||||
"vscode.powershell",
|
||||
"ms-vscode.powershell",
|
||||
"redhat.vscode-yaml"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@types/glob": "^7.1.3",
|
||||
"@types/mocha": "^8.2.2",
|
||||
"@types/node": "~15.3.0",
|
||||
"@types/node": "^15.3.1",
|
||||
"@types/vscode": "1.56.0",
|
||||
"@typescript-eslint/eslint-plugin": "^4.23.0",
|
||||
"@typescript-eslint/parser": "^4.23.0",
|
||||
"esbuild": "^0.11.23",
|
||||
"@typescript-eslint/eslint-plugin": "^4.24.0",
|
||||
"@typescript-eslint/parser": "^4.24.0",
|
||||
"esbuild": "^0.12.1",
|
||||
"eslint": "^7.26.0",
|
||||
"glob": "^7.1.7",
|
||||
"lodash": ">=4.17.21",
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
'use strict';
|
||||
|
||||
import { ConfigurationChangeEvent, ExtensionContext, workspace } from 'vscode';
|
||||
import { configurationItemPrefix } from './consts';
|
||||
|
||||
/**
|
||||
* The output of analysis tasks.
|
||||
*/
|
||||
export enum OutputAs {
|
||||
Detail = 0,
|
||||
Summary = 1,
|
||||
}
|
||||
|
||||
/**
|
||||
* PSRule extension settings.
|
||||
*/
|
||||
export interface ISetting {
|
||||
executionNotProcessedWarning: boolean;
|
||||
outputAs: OutputAs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default configuration for PSRule extension settings.
|
||||
*/
|
||||
const globalDefaults: ISetting = {
|
||||
executionNotProcessedWarning: false,
|
||||
outputAs: OutputAs.Summary,
|
||||
};
|
||||
|
||||
/**
|
||||
* A configuration manager class for PSRule.
|
||||
*/
|
||||
export class ConfigurationManager {
|
||||
private current: ISetting;
|
||||
private readonly default: ISetting;
|
||||
|
||||
/**
|
||||
* A flag for when setting require reload.
|
||||
*/
|
||||
private pendingLoad: boolean = true;
|
||||
|
||||
constructor(setting?: ISetting) {
|
||||
this.default = setting ?? globalDefaults;
|
||||
this.current = this.default;
|
||||
this.loadSettings();
|
||||
}
|
||||
|
||||
static configure(context: ExtensionContext) {
|
||||
if (context) {
|
||||
context.subscriptions.push(
|
||||
workspace.onDidChangeConfiguration(
|
||||
configuration.onConfigurationChanged,
|
||||
configuration
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public get(): ISetting {
|
||||
if (this.pendingLoad) {
|
||||
this.loadSettings();
|
||||
}
|
||||
return this.current;
|
||||
}
|
||||
|
||||
private onConfigurationChanged(e: ConfigurationChangeEvent) {
|
||||
if (!e.affectsConfiguration(configurationItemPrefix)) {
|
||||
return;
|
||||
}
|
||||
this.pendingLoad = true;
|
||||
}
|
||||
|
||||
private loadSettings(): void {
|
||||
const config = workspace.getConfiguration(configurationItemPrefix);
|
||||
|
||||
// Read settings
|
||||
this.current.executionNotProcessedWarning =
|
||||
config.get<boolean>('execution.notProcessedWarning') ??
|
||||
this.default.executionNotProcessedWarning;
|
||||
|
||||
this.current.outputAs = config.get<OutputAs>('output.as') ?? this.default.outputAs;
|
||||
|
||||
// Clear dirty settings flag
|
||||
this.pendingLoad = false;
|
||||
}
|
||||
}
|
||||
|
||||
export const configuration = new ConfigurationManager();
|
212
src/extension.ts
212
src/extension.ts
|
@ -6,91 +6,139 @@
|
|||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { logger } from './logger';
|
||||
import { PSRuleTaskProvider } from './tasks';
|
||||
import { ConfigurationManager } from './configuration';
|
||||
import { pwsh } from './powershell';
|
||||
|
||||
/**
|
||||
* Activate PSRule extension.
|
||||
* @param context An extension context.
|
||||
*/
|
||||
export function activate(context: vscode.ExtensionContext): void {
|
||||
// Check the extension
|
||||
checkExtension(context);
|
||||
export let taskManager: PSRuleTaskProvider | undefined;
|
||||
|
||||
export interface ExtensionInfo {
|
||||
id: string;
|
||||
version: string;
|
||||
channel: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate PSRule extension.
|
||||
*/
|
||||
export function deactivate(): void {
|
||||
if (logger) {
|
||||
logger.dispose();
|
||||
export class ExtensionManager implements vscode.Disposable {
|
||||
private _info!: ExtensionInfo;
|
||||
|
||||
constructor() {}
|
||||
|
||||
public get info(): Promise<ExtensionInfo> {
|
||||
const parent = this;
|
||||
return new Promise<ExtensionInfo>((resolve, reject) => {
|
||||
if (parent._info) {
|
||||
resolve(parent._info);
|
||||
} else {
|
||||
setTimeout(function (): void {
|
||||
if (parent._info) {
|
||||
resolve(parent._info);
|
||||
} else {
|
||||
reject('Failed to get info.');
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public activate(context: vscode.ExtensionContext) {
|
||||
this._info = this.checkExtension(context);
|
||||
|
||||
ConfigurationManager.configure(context);
|
||||
|
||||
pwsh.configure(this._info);
|
||||
|
||||
taskManager = new PSRuleTaskProvider(logger, context);
|
||||
taskManager.register();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (taskManager) {
|
||||
taskManager.dispose();
|
||||
}
|
||||
if (pwsh) {
|
||||
pwsh.dispose();
|
||||
}
|
||||
if (logger) {
|
||||
logger.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check channel and version of the extension activated.
|
||||
* @param context An extension context.
|
||||
*/
|
||||
private checkExtension(context: vscode.ExtensionContext): ExtensionInfo {
|
||||
const extensionVersionKey = 'ps-rule-extension-version';
|
||||
|
||||
// Get channel
|
||||
let extensionId = 'bewhite.psrule-vscode';
|
||||
let extensionChannel = 'stable';
|
||||
if (path.basename(context.globalStorageUri.fsPath) === 'bewhite.psrule-vscode-preview') {
|
||||
extensionId = 'bewhite.psrule-vscode-preview';
|
||||
extensionChannel = 'preview';
|
||||
}
|
||||
if (path.basename(context.globalStorageUri.fsPath) === 'bewhite.psrule-vscode-dev') {
|
||||
extensionId = 'bewhite.psrule-vscode-dev';
|
||||
extensionChannel = 'dev';
|
||||
}
|
||||
logger.verbose(`Running extension channel: ${extensionChannel}`);
|
||||
|
||||
// Get current version
|
||||
const extension = vscode.extensions.getExtension(extensionId)!;
|
||||
const extensionVersion: string = extension.packageJSON.version;
|
||||
logger.verbose(`Running extension version: ${extensionVersion}`);
|
||||
|
||||
// Get last version
|
||||
const lastVersion = context.globalState.get(extensionVersionKey);
|
||||
|
||||
// Save the extension version
|
||||
context.globalState.update(extensionVersionKey, extensionVersion);
|
||||
|
||||
// Determine if the channel upgrade message is shown
|
||||
const showChannelUpgrade: boolean = vscode.workspace
|
||||
.getConfiguration('PSRule.notifications')
|
||||
.get('showChannelUpgrade', true);
|
||||
|
||||
if ((extensionChannel === 'preview' || extensionChannel === 'dev') && showChannelUpgrade) {
|
||||
const showReleaseNotes = 'Show Release Notes';
|
||||
const showExtension = 'Show Extension';
|
||||
const alwaysIgnore = 'Always Ignore';
|
||||
|
||||
vscode.window
|
||||
.showInformationMessage(
|
||||
`You are running the ${extensionChannel} version of PSRule. A stable version is available.`,
|
||||
showReleaseNotes,
|
||||
showExtension,
|
||||
alwaysIgnore
|
||||
)
|
||||
.then((choice) => {
|
||||
if (choice === showReleaseNotes) {
|
||||
vscode.commands.executeCommand(
|
||||
'markdown.showPreview',
|
||||
vscode.Uri.file(path.resolve(__dirname, '../../CHANGELOG.md'))
|
||||
);
|
||||
}
|
||||
if (choice === showExtension) {
|
||||
vscode.commands.executeCommand(
|
||||
'workbench.extensions.search',
|
||||
'bewhite.psrule-vscode'
|
||||
);
|
||||
}
|
||||
if (choice === alwaysIgnore) {
|
||||
vscode.workspace
|
||||
.getConfiguration('PSRule.notifications')
|
||||
.update('showChannelUpgrade', false, vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
const result: ExtensionInfo = {
|
||||
id: extensionId,
|
||||
version: extensionVersion,
|
||||
channel: extensionChannel,
|
||||
};
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check channel and version of the extension activated.
|
||||
* @param context An extension context.
|
||||
*/
|
||||
function checkExtension(context: vscode.ExtensionContext): void {
|
||||
const extensionVersionKey = 'ps-rule-extension-version';
|
||||
|
||||
// Get channel
|
||||
let extensionId = 'bewhite.psrule-vscode';
|
||||
let extensionChannel = 'stable';
|
||||
if (path.basename(context.globalStorageUri.fsPath) === 'bewhite.psrule-vscode-preview') {
|
||||
extensionId = 'bewhite.psrule-vscode-preview';
|
||||
extensionChannel = 'preview';
|
||||
}
|
||||
if (path.basename(context.globalStorageUri.fsPath) === 'bewhite.psrule-vscode-dev') {
|
||||
extensionId = 'bewhite.psrule-vscode-dev';
|
||||
extensionChannel = 'dev';
|
||||
}
|
||||
logger.verbose(`Running extension channel: ${extensionChannel}`);
|
||||
|
||||
// Get current version
|
||||
const extension = vscode.extensions.getExtension(extensionId)!;
|
||||
const extensionVersion: string = extension.packageJSON.version;
|
||||
logger.verbose(`Running extension version: ${extensionVersion}`);
|
||||
|
||||
// Get last version
|
||||
const lastVersion = context.globalState.get(extensionVersionKey);
|
||||
|
||||
// Save the extension version
|
||||
context.globalState.update(extensionVersionKey, extensionVersion);
|
||||
|
||||
// Determine if the channel upgrade message is shown
|
||||
const showChannelUpgrade: boolean = vscode.workspace
|
||||
.getConfiguration('PSRule.notifications')
|
||||
.get('showChannelUpgrade', true);
|
||||
|
||||
if ((extensionChannel === 'preview' || extensionChannel === 'dev') && showChannelUpgrade) {
|
||||
const showReleaseNotes = 'Show Release Notes';
|
||||
const showExtension = 'Show Extension';
|
||||
const alwaysIgnore = 'Always Ignore';
|
||||
|
||||
vscode.window
|
||||
.showInformationMessage(
|
||||
`You are running the ${extensionChannel} version of PSRule. A stable version is available.`,
|
||||
showReleaseNotes,
|
||||
showExtension,
|
||||
alwaysIgnore
|
||||
)
|
||||
.then((choice) => {
|
||||
if (choice === showReleaseNotes) {
|
||||
vscode.commands.executeCommand(
|
||||
'markdown.showPreview',
|
||||
vscode.Uri.file(path.resolve(__dirname, '../../CHANGELOG.md'))
|
||||
);
|
||||
}
|
||||
if (choice === showExtension) {
|
||||
vscode.commands.executeCommand(
|
||||
'workbench.extensions.search',
|
||||
'bewhite.psrule-vscode'
|
||||
);
|
||||
}
|
||||
if (choice === alwaysIgnore) {
|
||||
vscode.workspace
|
||||
.getConfiguration('PSRule.notifications')
|
||||
.update('showChannelUpgrade', false, vscode.ConfigurationTarget.Global);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
export const ext: ExtensionManager = new ExtensionManager();
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ext } from './extension';
|
||||
|
||||
/**
|
||||
* Activate PSRule extension.
|
||||
* @param context An extension context.
|
||||
*/
|
||||
export function activate(context: vscode.ExtensionContext): void {
|
||||
ext.activate(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deactivate PSRule extension.
|
||||
*/
|
||||
export function deactivate(): void {
|
||||
if (ext) {
|
||||
ext.dispose();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as vscode from 'vscode';
|
||||
import { ExtensionInfo } from './extension';
|
||||
import { logger } from './logger';
|
||||
|
||||
/**
|
||||
* External interface from PowerShell extension.
|
||||
*/
|
||||
interface IExternalPowerShellDetails {
|
||||
exePath: string;
|
||||
version: string;
|
||||
displayName: string;
|
||||
architecture: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* External interface from PowerShell extension.
|
||||
*/
|
||||
interface IPowerShellExtensionClient {
|
||||
registerExternalExtension(id: string, apiVersion?: string): string;
|
||||
unregisterExternalExtension(uuid: string): boolean;
|
||||
getPowerShellVersionDetails(uuid: string): Promise<IExternalPowerShellDetails>;
|
||||
}
|
||||
|
||||
export class PowerShellExtension implements vscode.Disposable {
|
||||
private readonly extension: vscode.Extension<IPowerShellExtensionClient> | undefined;
|
||||
|
||||
private _version!: string;
|
||||
private _path!: string;
|
||||
private uuid!: string;
|
||||
|
||||
constructor() {
|
||||
this.extension = this.getExtension();
|
||||
if (this.extension !== undefined && !this.extension.isActive) {
|
||||
this.extension.activate();
|
||||
}
|
||||
}
|
||||
|
||||
public get path(): string {
|
||||
return this._path;
|
||||
}
|
||||
|
||||
public configure(info: ExtensionInfo): void {
|
||||
const powerShellExtensionClient = this.extension!.exports as IPowerShellExtensionClient;
|
||||
this.uuid = powerShellExtensionClient.registerExternalExtension(info.id, 'v1');
|
||||
powerShellExtensionClient
|
||||
.getPowerShellVersionDetails(this.uuid)
|
||||
.then((v) => this.handlePowerShell(v));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this.extension && this.uuid !== undefined) {
|
||||
const powerShellExtensionClient = this.extension!.exports as IPowerShellExtensionClient;
|
||||
powerShellExtensionClient.unregisterExternalExtension(this.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private handlePowerShell(value: IExternalPowerShellDetails): void {
|
||||
this._version = value.version;
|
||||
this._path = value.exePath;
|
||||
|
||||
logger.verbose(`Using PowerShell ${this._version} from ${this._path}`);
|
||||
}
|
||||
|
||||
private getExtension(): vscode.Extension<IPowerShellExtensionClient> | undefined {
|
||||
return (
|
||||
vscode.extensions.getExtension<IPowerShellExtensionClient>(
|
||||
'ms-vscode.powershell-preview'
|
||||
) ?? vscode.extensions.getExtension<IPowerShellExtensionClient>('ms-vscode.powershell')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export const pwsh = new PowerShellExtension();
|
|
@ -0,0 +1,288 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { defaultOptionsFile } from './consts';
|
||||
import { ILogger } from './logger';
|
||||
import { configuration } from './configuration';
|
||||
import { pwsh } from './powershell';
|
||||
|
||||
const emptyTasks: vscode.Task[] = [];
|
||||
|
||||
interface IContext {
|
||||
readonly logger: ILogger;
|
||||
readonly extensionContext: vscode.ExtensionContext;
|
||||
}
|
||||
|
||||
interface PSRuleTaskDefinition extends vscode.TaskDefinition {
|
||||
/**
|
||||
* The a path to rules to use for analysis.
|
||||
*/
|
||||
path?: string;
|
||||
|
||||
/**
|
||||
* The input path to run.
|
||||
*/
|
||||
inputPath?: string;
|
||||
|
||||
/**
|
||||
* An optional baseline to use.
|
||||
*/
|
||||
baseline?: string;
|
||||
|
||||
/**
|
||||
* Rule modules to use for analysis.
|
||||
*/
|
||||
modules?: string[];
|
||||
|
||||
outcome?: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A task provider for PSRule.
|
||||
*/
|
||||
export class PSRuleTaskProvider implements vscode.TaskProvider {
|
||||
// Fields
|
||||
private readonly context: IContext;
|
||||
|
||||
private static taskType: string = 'PSRule';
|
||||
private tasks: vscode.Task[] | undefined;
|
||||
|
||||
// We use a CustomExecution task when state needs to be shared across runs of the task or when
|
||||
// the task requires use of some VS Code API to run.
|
||||
// If you don't need to share state between runs and if you don't need to execute VS Code API in your task,
|
||||
// then a simple ShellExecution or ProcessExecution should be enough.
|
||||
// Since our build has this shared state, the CustomExecution is used below.
|
||||
private sharedState: string | undefined;
|
||||
private providerRegistration!: vscode.Disposable;
|
||||
|
||||
constructor(logger: ILogger, extensionContext: vscode.ExtensionContext) {
|
||||
this.context = { logger, extensionContext };
|
||||
}
|
||||
|
||||
public dispose() {
|
||||
// Do nothing yet
|
||||
if (this.providerRegistration) {
|
||||
this.providerRegistration.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
public register(): void {
|
||||
// Register a task provider
|
||||
this.providerRegistration = vscode.tasks.registerTaskProvider(
|
||||
PSRuleTaskProvider.taskType,
|
||||
this
|
||||
);
|
||||
this.context.logger.verbose('Registered task provider');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get tasks for Visual Studio Code API.
|
||||
* @returns Returns a list of tasks.
|
||||
*/
|
||||
public async provideTasks(): Promise<vscode.Task[]> {
|
||||
return this.getTasks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Complete a task object for Visual Studio Code.
|
||||
* @param _task A task object that might need completing.
|
||||
* @returns A completed Visual Studio Code task.
|
||||
*/
|
||||
public resolveTask(_task: vscode.Task): vscode.Task | undefined {
|
||||
const definition: PSRuleTaskDefinition = <any>_task.definition;
|
||||
const scope = _task.scope as vscode.WorkspaceFolder;
|
||||
return this.createTask(
|
||||
'Run analysis',
|
||||
scope,
|
||||
definition.path,
|
||||
definition.inputPath,
|
||||
definition.baseline,
|
||||
definition.modules,
|
||||
definition.outcome,
|
||||
undefined,
|
||||
definition
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of PSRule tasks for each Visual Studio Code workspace.
|
||||
* @returns A list of tasks.
|
||||
*/
|
||||
private async getTasks(): Promise<vscode.Task[]> {
|
||||
const folders = vscode.workspace.workspaceFolders;
|
||||
if (!folders) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
const result: vscode.Task[] = [];
|
||||
for (let i = 0, len = folders.length; i < len; i++) {
|
||||
if (this.isEnabled(folders[i])) {
|
||||
const tasks = await this.getWorkspaceTasks(folders[i]);
|
||||
result.push(...tasks);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private isEnabled(folder: vscode.WorkspaceFolder): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
private async exists(file: string): Promise<boolean> {
|
||||
return new Promise<boolean>((resolve) => {
|
||||
fs.exists(file, (value) => {
|
||||
resolve(value);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async readFile(file: string): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
fs.readFile(file, (err, data) => {
|
||||
if (err) {
|
||||
reject(err);
|
||||
}
|
||||
resolve(data.toString());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private async getWorkspaceTasks(folder: vscode.WorkspaceFolder): Promise<vscode.Task[]> {
|
||||
if (folder.uri.scheme !== 'file') {
|
||||
return emptyTasks;
|
||||
}
|
||||
|
||||
const rootPath = folder.uri.fsPath;
|
||||
const optionFilePath = path.join(rootPath, defaultOptionsFile);
|
||||
|
||||
if (!(await this.exists(optionFilePath))) {
|
||||
return emptyTasks;
|
||||
}
|
||||
|
||||
try {
|
||||
const result: vscode.Task[] = [];
|
||||
let t = this.createTask(
|
||||
'Run analysis',
|
||||
folder,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined,
|
||||
undefined
|
||||
);
|
||||
result.push(t);
|
||||
|
||||
return result;
|
||||
} catch (e) {
|
||||
return emptyTasks;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a task.
|
||||
* @param name The name of the task.
|
||||
* @param path The root of the workspace.
|
||||
* @param baseline An optional baseline.
|
||||
* @param matcher A task filter.
|
||||
*/
|
||||
private createTask(
|
||||
name: string,
|
||||
folder: vscode.WorkspaceFolder | undefined,
|
||||
path?: string,
|
||||
inputPath?: string,
|
||||
baseline?: string,
|
||||
modules?: string[],
|
||||
outcome?: string[],
|
||||
matcher?: any,
|
||||
definition?: PSRuleTaskDefinition
|
||||
): vscode.Task {
|
||||
if (definition === undefined) {
|
||||
definition = {
|
||||
type: PSRuleTaskProvider.taskType,
|
||||
};
|
||||
}
|
||||
|
||||
function getTaskName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
function getCmd(): string {
|
||||
let params = '';
|
||||
|
||||
// Path
|
||||
if (path !== undefined && path !== '') {
|
||||
params += ` -Path '${path}'`;
|
||||
} else {
|
||||
params += " -Path './.ps-rule/'";
|
||||
}
|
||||
|
||||
if (inputPath !== undefined && inputPath !== '') {
|
||||
params += ` -InputPath '${inputPath}'`;
|
||||
} else {
|
||||
params += ` -InputPath .`;
|
||||
}
|
||||
|
||||
// Baseline
|
||||
if (baseline !== undefined && baseline !== '') {
|
||||
params += ` -Baseline '${baseline}'`;
|
||||
}
|
||||
|
||||
// Modules
|
||||
if (modules !== undefined && modules.length > 0) {
|
||||
for (let i = 0; i < modules.length; i++) {
|
||||
if (i > 0) {
|
||||
params += `, ${modules[i]}`;
|
||||
} else {
|
||||
params += ` -Module ${modules[i]}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Outcome
|
||||
if (outcome !== undefined && outcome.length > 0) {
|
||||
for (let i = 0; i < outcome.length; i++) {
|
||||
if (i > 0) {
|
||||
params += `, ${outcome[i]}`;
|
||||
} else {
|
||||
params += ` -Outcome ${outcome[i]}`;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
params += ' -Outcome Fail, Error';
|
||||
}
|
||||
|
||||
return `Assert-PSRule -Format File${params};`;
|
||||
}
|
||||
|
||||
const taskName = getTaskName();
|
||||
const executionNotProcessedWarning = configuration.get().executionNotProcessedWarning;
|
||||
const outputAs = configuration.get().outputAs;
|
||||
|
||||
// Return the task instance
|
||||
return new vscode.Task(
|
||||
definition,
|
||||
folder ?? vscode.TaskScope.Workspace,
|
||||
taskName,
|
||||
PSRuleTaskProvider.taskType,
|
||||
new vscode.ShellExecution(getCmd(), {
|
||||
executable: pwsh.path,
|
||||
shellArgs: ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command'],
|
||||
env: {
|
||||
PSRULE_OUTPUT_STYLE: 'Client',
|
||||
PSRULE_OUTPUT_AS: outputAs.toString(),
|
||||
PSRULE_OUTPUT_CULTURE: vscode.env.language,
|
||||
PSRULE_OUTPUT_BANNER: 'Minimal',
|
||||
PSRULE_EXECUTION_NOTPROCESSEDWARNING: executionNotProcessedWarning
|
||||
? 'true'
|
||||
: 'false',
|
||||
},
|
||||
}),
|
||||
matcher
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { configuration, OutputAs } from '../../configuration';
|
||||
|
||||
suite('ConfigurationManager tests', () => {
|
||||
test('Defaults', () => {
|
||||
assert.strictEqual(configuration.get().executionNotProcessedWarning, false);
|
||||
assert.strictEqual(configuration.get().outputAs, OutputAs.Summary);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as Extension from '../../extension';
|
||||
|
||||
suite('Extension tests', () => {
|
||||
test('Get extension info', () => {
|
||||
Extension.ext.info
|
||||
.then((info) => {
|
||||
assert.strictEqual('dev', info.channel);
|
||||
assert.strictEqual('0.0.1', info.version);
|
||||
assert.strictEqual('bewhite.psrule-vscode-dev', info.id);
|
||||
})
|
||||
.catch((reason) => {
|
||||
assert.fail(`Failed to get extension info. ${reason}`);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,18 @@
|
|||
// Copyright (c) Microsoft Corporation.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as Extension from '../../extension';
|
||||
|
||||
suite('PSRuleTaskProvider tests', () => {
|
||||
test('Call taskManager', () => {
|
||||
Extension.taskManager
|
||||
?.provideTasks()
|
||||
.then((t) => {
|
||||
assert.strictEqual(1, t.length);
|
||||
})
|
||||
.catch((reason) => {
|
||||
assert.fail(`Failed to get tasks. ${reason}`);
|
||||
});
|
||||
});
|
||||
});
|
Загрузка…
Ссылка в новой задаче