PowerShell / PowerShell/PSScriptAnalyzer

Improve settings format, allow JSON + custom settings formats

Đang mở
#1,552 3 bình luận 2 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

API Proposal Consider - 2.0 Issue - Discussion
Ngôn ngữ chính
C#
Star
2.2k
Fork
414
Merge trung bình
13 giờ 1 phút
Pull request đã merge (30 ngày)
2

Mô tả

Currently PSScriptAnalyzer settings suffer from the following drawbacks:

  • They are opaque and truly documented only by the parsing logic
  • Misconfiguration usually fails silently, or at best issues an unhelpful generic error
  • They must be specified in PSD format, forcing a PSD parser to be present
  • Configurable rules cannot easily specify arbitrary configurations to be read from settings
  • Setting properties on configurable rules can conflict with constructors (they are set after constructor and default value evaluation)
  • Settings (and Invoke-ScriptAnalyzer parameters) have ambiguous duplication like Rules, IncludeRules and ExcludeRules
  • The default Enable rule configuration is false...
  • Rule names vs namespaces aren't delineated, so it can't be known from settings where the namespace vs name of a rule begins/ends

Instead, PSScriptAnalyzer settings should:

  • Be self-documenting when possible
  • Issue useful errors about where and why settings parsing failed
  • Be specifiable in multiple convenient ways that don't require PowerShell (particularly in JSON), and allow extension to specify them in more ways
  • Allow arbitrary structured configuration for rules, to be defined by those rules, and read configurations in as objects for the rule to consume
  • Pass configurations to rules in the constructor call, to allow rules to apply the configurations at the correct time and with their own logic
  • Make settings simple and self-documenting, with no ambiguous concepts
  • Enable rules by default, while offering a way to disable them while preserving their configuration entry
  • Specify rules by name and namespace, separating them with a / character

As such, the proposed new settings will provide:

  • An extensible API to provide settings
  • A better way to provide settings in PSD format (and the same from a hashtable object)
  • A new way to provide settings as JSON

PSSA API structure

PSSA will provide an extensible API to provide configurations. This consists of a top level Script Analyzer configuration:

https://github.com/PowerShell/PSScriptAnalyzer/blob/9ee8c0f3110fda305314b050bf0c74766bfcce42/ScriptAnalyzer2/Configuration/IScriptAnalyzerConfiguration.cs#L22-L31

An individual rule configuration:

https://github.com/PowerShell/PSScriptAnalyzer/blob/9ee8c0f3110fda305314b050bf0c74766bfcce42/ScriptAnalyzer2/Configuration/IRuleConfiguration.cs#L9-L49

And the ability to implement a subclass/implementation of IRuleConfiguration and inject it into a rule's constructor by specifying a rule as generic:

https://github.com/PowerShell/PSScriptAnalyzer/blob/9ee8c0f3110fda305314b050bf0c74766bfcce42/ScriptAnalyzer2/Rules/Rule.cs#L84-L91

Script Analyzer is able to use this configuration type in the generic parameter to deserialise the rule configuration when it is contructed.

PSD settings

Implementing these APIs for PSD format, a typical PSD settings file will look like this:

@{
    BuiltinRules = "Default" # Or "None" | "Aggressive" (name changeable)
    RuleExecution = "Default" # Or "Sequential" | "Parallel", possibly others depending on executor implementations
    RulePaths = @(
        "C:\somewhere\rules.dll"
        "path/relative/to/host/configured/root/module.psm1"
        "/also/allow/directory/module/"
    )
    RuleConfiguration = @(
        @{ Rule = "PS/AvoidAliases"; Configuration = @{ Enable = $false } }
        @{
            Rule = "PS/UseCompatibleCommands"
            Configuration = @{
                TargetPlatforms = @(
                    @{ OS = "Linux" }
                    @{ OS = "MacOS" }
                )
            }
        }
       @{
            Rule = "PS/AnotherRule"
            Configuration = @{
                ModeEnum = "CustomMode"
                Numbers = @(1, 2, 3)
            }
        }
        @{ Rule = "PS/RuleWithoutConfiguration" }
        @{ Rule = "ExternalRules/ExternallyImplementedRule" }
    )
}

Setting fields that aren't provided will have sensible defaults, and explicit default options allowing for the same. When rule settings are deserialised for the first time, failures will be reported (I haven't gotten to this part yet, but I would like to make the settings tell users where the failure occurred, what was given and what was expected).

Hashtable settings

Settings provided by Hashtable object will follow exactly the same conventions as those given above for PSD format, except converting from an in-memory hashtable object. A PSD file and its hashtable result in PowerShell will convert to the same settings.

JSON settings

Similar to the PSD settings, the JSON settings will essentially offer a new syntax for rule settings:

{
    "BuiltinRules": "Default",
    "RuleExecution": "Default",
    "RulePaths": [
        "C:\\somewhere\\rules.dll",
        "path/relative/to/host/configured/root/module.psm1",
        "/also/allow/directory/module/",
    ],
    "RuleConfiguration": [
        { "Rule": "PS/AvoidAliases", "Configuration": { "Enable": false } },
        {
            "Rule": "PS/UseCompatibleCommands",
            "Configuration": {
                "TargetPlatforms": [
                    { "OS": "Linux" },
                    { "OS": "MacOS" }
                ]
            }
        },
        {
            "Rule": "PS/AnotherRule",
            "Configuration": {
                "ModeEnum": "CustomMode",
                "Numbers": [1, 2, 3]
            }
        },
        { "Rule": "PS/RuleWithoutConfiguration" },
        { "Rule": "ExternalRules/ExternallyImplementedRule" }
    ]
}

Deserialisation to objects

Settings in PSD and JSON form will be deserialised to the type requested by the rule they configure. For JSON, this will use Newtonsoft.Json deserialisation, so allowing all attributes it supports. In the case of PSD, those attributes will also be supported. For example:

https://github.com/PowerShell/PSScriptAnalyzer/blob/9ee8c0f3110fda305314b050bf0c74766bfcce42/Tests/ScriptAnalyzer2.Test/PsdTypedObjectConverterTests.cs#L92-L95

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách đọc các interface được liên kết trong ScriptAnalyzer2/Configuration/IScriptAnalyzerConfiguration.cs và IRuleConfiguration.cs, sau đó kiểm tra phần hỗ trợ rule tổng quát trong ScriptAnalyzer2/Rules/Rule.cs. Xem lại Tests/ScriptAnalyzer2.Test/PsdTypedObjectConverterTests.cs để kiểm tra phạm vi deserialization hiện có. Công việc được xem là hoàn tất khi các API cấu hình PSD, hashtable và JSON được đề xuất hỗ trợ các cài đặt có cấu trúc dành riêng cho từng rule cùng với các lỗi phân tích hữu ích.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
csharp, powershell
Lĩnh vực
tooling
Loại issue
Tính năng
Độ khó
5/5
Thời gian dự kiến
Hơn một tuần
Mức độ hoạt động
Đình trệ
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
25/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.