Skip to content

Commit cb22393

Browse files
authored
Merge pull request #68 from rvermeulen/guideline-recategorization
Guideline recategorization support
2 parents 0291b4c + be60c7b commit cb22393

File tree

158 files changed

+8661
-1178
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

158 files changed

+8661
-1178
lines changed

.github/workflows/code-scanning-pack-gen.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ jobs:
8686
codeql query compile --search-path c --search-path cpp --threads 0 c
8787
8888
cd ..
89-
zip -r codeql-coding-standards/code-scanning-cpp-query-pack.zip codeql-coding-standards/c/ codeql-coding-standards/cpp/ codeql-coding-standards/.codeqlmanifest.json codeql-coding-standards/supported_codeql_configs.json codeql-coding-standards/scripts/deviations codeql-coding-standards/scripts/reports
89+
zip -r codeql-coding-standards/code-scanning-cpp-query-pack.zip codeql-coding-standards/c/ codeql-coding-standards/cpp/ codeql-coding-standards/.codeqlmanifest.json codeql-coding-standards/supported_codeql_configs.json codeql-coding-standards/scripts/configuration codeql-coding-standards/scripts/reports codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/guideline_recategorization codeql-coding-standards/scripts/shared codeql-coding-standards/scripts/schemas
9090
9191
- name: Upload GHAS Query Pack
9292
uses: actions/upload-artifact@v2
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
name: 🧰 Tooling unit tests
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- "rc/**"
8+
- next
9+
pull_request:
10+
branches:
11+
- main
12+
- "rc/**"
13+
- next
14+
15+
jobs:
16+
prepare-supported-codeql-env-matrix:
17+
name: Prepare supported CodeQL environment matrix
18+
runs-on: ubuntu-latest
19+
outputs:
20+
matrix: ${{ steps.export-supported-codeql-env-matrix.outputs.matrix }}
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@v2
24+
25+
- name: Export supported CodeQL environment matrix
26+
id: export-supported-codeql-env-matrix
27+
run: |
28+
echo "::set-output name=matrix::$(
29+
jq --compact-output '.supported_environment | {include: .}' supported_codeql_configs.json
30+
)"
31+
32+
analysis-report-tests:
33+
name: Run analysis report tests
34+
needs: prepare-supported-codeql-env-matrix
35+
runs-on: ubuntu-latest
36+
strategy:
37+
fail-fast: false
38+
matrix: ${{ fromJSON(needs.prepare-supported-codeql-env-matrix.outputs.matrix) }}
39+
steps:
40+
- name: Checkout
41+
uses: actions/checkout@v2
42+
43+
- name: Install Python
44+
uses: actions/setup-python@v4
45+
with:
46+
python-version: "3.9"
47+
48+
- name: Install Python dependencies
49+
run: pip install -r scripts/reports/requirements.txt
50+
51+
- name: Cache CodeQL
52+
id: cache-codeql
53+
uses: actions/[email protected]
54+
with:
55+
path: ${{ github.workspace }}/codeql_home
56+
key: codeql-home-${{ matrix.os }}-${{ matrix.codeql_cli }}-${{ matrix.codeql_standard_library }}
57+
58+
- name: Install CodeQL
59+
if: steps.cache-codeql.outputs.cache-hit != 'true'
60+
uses: ./.github/actions/install-codeql
61+
with:
62+
codeql-cli-version: ${{ matrix.codeql_cli }}
63+
codeql-stdlib-version: ${{ matrix.codeql_standard_library }}
64+
codeql-home: ${{ github.workspace }}/codeql_home
65+
add-to-path: false
66+
67+
- name: Run PyTest
68+
env:
69+
CODEQL_HOME: ${{ github.workspace }}/codeql_home
70+
run: |
71+
PATH=$PATH:$CODEQL_HOME/codeql
72+
pytest scripts/reports/analysis_report_test.py
73+
74+
recategorization-tests:
75+
name: Run Guideline Recategorization tests
76+
runs-on: ubuntu-latest
77+
steps:
78+
- name: Checkout
79+
uses: actions/checkout@v2
80+
81+
- name: Install Python
82+
uses: actions/setup-python@v4
83+
with:
84+
python-version: "3.9"
85+
86+
- name: Install Python dependencies
87+
run: pip install -r scripts/guideline_recategorization/requirements.txt
88+
89+
- name: Run PyTest
90+
run: |
91+
pytest scripts/guideline_recategorization/recategorize_test.py

.github/workflows/validate-coding-standards.yml

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,15 @@ jobs:
2828
with:
2929
python-version: "3.9"
3030

31+
- name: Install CodeQL
32+
run: |
33+
VERSION="v$( jq -r '.supported_environment | .[0] | .codeql_cli' supported_codeql_configs.json)"
34+
gh extensions install github/gh-codeql
35+
gh codeql set-version "$VERSION"
36+
gh codeql install-stub
37+
env:
38+
GITHUB_TOKEN: ${{ github.token }}
39+
3140
- name: Install generate_package_files.py dependencies
3241
run: pip install -r scripts/requirements.txt
3342

@@ -49,14 +58,14 @@ jobs:
4958
5059
- name: Validate Package Files (CPP)
5160
run: |
52-
find rule_packages/cpp -name \*.json -exec basename {} .json \; | xargs --max-procs "$XARGS_MAX_PROCS" --max-args 1 python scripts/generate_rules/generate_package_files.py cpp
61+
find rule_packages/cpp -name \*.json -exec basename {} .json \; | xargs python scripts/generate_rules/generate_package_files.py cpp
5362
git diff
5463
git diff --compact-summary
5564
git diff --quiet
5665
5766
- name: Validate Package Files (C)
5867
run: |
59-
find rule_packages/c -name \*.json -exec basename {} .json \; | xargs --max-procs "$XARGS_MAX_PROCS" --max-args 1 python scripts/generate_rules/generate_package_files.py c
68+
find rule_packages/c -name \*.json -exec basename {} .json \; | xargs python scripts/generate_rules/generate_package_files.py c
6069
git diff
6170
git diff --compact-summary
6271
git diff --quiet
@@ -68,25 +77,26 @@ jobs:
6877
- name: Checkout
6978
uses: actions/checkout@v2
7079

71-
- name: Fetch CodeQL
80+
- name: Install CodeQL
7281
run: |
73-
TAG="v$( jq -r '.supported_environment | .[0] | .codeql_cli' supported_codeql_configs.json)"
74-
gh release download $TAG --repo https://github.com/github/codeql-cli-binaries --pattern codeql-linux64.zip
75-
unzip -q codeql-linux64.zip
82+
VERSION="v$( jq -r '.supported_environment | .[0] | .codeql_cli' supported_codeql_configs.json)"
83+
gh extensions install github/gh-codeql
84+
gh codeql set-version "$VERSION"
85+
gh codeql install-stub
7686
env:
7787
GITHUB_TOKEN: ${{ github.token }}
7888

7989
- name: Validate CodeQL Format (CPP)
8090
run: |
81-
find cpp -name \*.ql -or -name \*.qll -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql/codeql query format --in-place
91+
find cpp -name \*.ql -or -name \*.qll -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql query format --in-place
8292
8393
git diff
8494
git diff --compact-summary
8595
git diff --quiet
8696
8797
- name: Validate CodeQL Format (C)
8898
run: |
89-
find c -name \*.ql -or -name \*.qll -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql/codeql query format --in-place
99+
find c -name \*.ql -or -name \*.qll -print0 | xargs -0 --max-procs "$XARGS_MAX_PROCS" codeql query format --in-place
90100
91101
git diff
92102
git diff --compact-summary
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- Add the Python scripts under `scripts/guideline_recategorization` and the JSON schemas under `schemas`.
2+
- Add the Python scripts under `scripts/shared` relied upon by the analysis report generation.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* A module for runtime configuration settings specified in a `conding-standards.yml` file.
3+
*/
4+
5+
import cpp
6+
import semmle.code.cpp.XML
7+
import codingstandards.cpp.exclusions.RuleMetadata
8+
import codingstandards.cpp.deviations.Deviations
9+
10+
/** A `coding-standards.xml` configuration file (usually generated from an YAML configuration file). */
11+
class CodingStandardsFile extends XMLFile {
12+
CodingStandardsFile() {
13+
this.getBaseName() = "coding-standards.xml" and
14+
// Must be within the users source code.
15+
exists(this.getRelativePath())
16+
}
17+
}
18+
19+
class CodingStandardsConfigSection extends XMLElement {
20+
CodingStandardsConfigSection() { getParent() instanceof CodingStandardsConfig }
21+
}
22+
23+
/** A "Coding Standards" configuration file */
24+
class CodingStandardsConfig extends XMLElement {
25+
CodingStandardsConfig() {
26+
any(CodingStandardsFile csf).getARootElement() = this and
27+
this.getName() = "codingstandards"
28+
}
29+
30+
/** Get a section in this configuration file. */
31+
CodingStandardsConfigSection getASection() { result.getParent() = this }
32+
}

cpp/common/src/codingstandards/cpp/Exclusions.qll

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,25 @@ predicate isExcluded(Element e) {
2525
}
2626

2727
bindingset[e, query]
28-
predicate isExcluded(Element e, Query query) {
29-
e instanceof ExcludedElement
28+
predicate isExcluded(Element e, Query query) { isExcluded(e, query, _) }
29+
30+
bindingset[e, query]
31+
predicate isExcluded(Element e, Query query, string reason) {
32+
e instanceof ExcludedElement and reason = "Element is an excluded element."
3033
or
31-
e.getFile() instanceof ExcludedFile
34+
e.getFile() instanceof ExcludedFile and reason = "Element is part of an excluded file."
3235
or
33-
not exists(e.getFile())
36+
not exists(e.getFile()) and reason = "Element is not part of the source repository."
3437
or
35-
// There exists a `DeviationRecord` that applies to this element and query
38+
// There exists a `DeviationRecord` that applies to this element and query, and the query's effective category permits deviation.
39+
query.getEffectiveCategory().permitsDeviation() and
3640
exists(DeviationRecord dr | applyDeviationsAtQueryLevel() |
3741
// The element is in a file which has a deviation for this query
3842
exists(string path |
3943
dr.isDeviated(query, path) and
4044
e.getFile().getRelativePath().prefix(path.length()) = path
41-
)
45+
) and
46+
reason = "Query has an associated deviation record for the element's file."
4247
or
4348
// The element is on the same line as a suppression comment
4449
exists(Comment c |
@@ -50,6 +55,13 @@ predicate isExcluded(Element e, Query query) {
5055
e.getLocation().hasLocationInfo(filepath, _, _, endLine, _) and
5156
c.getLocation().hasLocationInfo(filepath, endLine, _, _, _)
5257
)
53-
)
58+
) and
59+
reason =
60+
"Query has an associated deviation record with a code identifier that is applied to the element."
5461
)
62+
or
63+
// The effective category of the query is 'Disapplied'.
64+
// This can occur when a Guideline Recategorization Plan is applied.
65+
query.getEffectiveCategory().isDisapplied() and
66+
reason = "The query is disapplied."
5567
}

cpp/common/src/codingstandards/cpp/deviations/Deviations.qll

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import cpp
88
import semmle.code.cpp.XML
99
import codingstandards.cpp.exclusions.RuleMetadata
10+
import codingstandards.cpp.Config
1011

1112
predicate applyDeviationsAtQueryLevel() {
1213
not exists(CodingStandardsReportDeviatedAlerts reportDeviatedResults |
@@ -15,26 +16,6 @@ predicate applyDeviationsAtQueryLevel() {
1516
)
1617
}
1718

18-
/** A `coding-standards.xml` configuration file (usually generated from an YAML configuration file). */
19-
class CodingStandardsFile extends XMLFile {
20-
CodingStandardsFile() {
21-
this.getBaseName() = "coding-standards.xml" and
22-
// Must be within the users source code.
23-
exists(this.getRelativePath())
24-
}
25-
}
26-
27-
/** A "Coding Standards" configuration file */
28-
class CodingStandardsConfig extends XMLElement {
29-
CodingStandardsConfig() {
30-
any(CodingStandardsFile csf).getARootElement() = this and
31-
this.getName() = "codingstandards"
32-
}
33-
34-
/** Gets a deviation record for this configuration. */
35-
DeviationRecord getADeviationRecord() { result = getAChild().(DeviationRecords).getAChild() }
36-
}
37-
3819
/** An element which tells the analysis whether to report deviated results. */
3920
class CodingStandardsReportDeviatedAlerts extends XMLElement {
4021
CodingStandardsReportDeviatedAlerts() {
@@ -44,19 +25,13 @@ class CodingStandardsReportDeviatedAlerts extends XMLElement {
4425
}
4526

4627
/** A container of deviation records. */
47-
class DeviationRecords extends XMLElement {
48-
DeviationRecords() {
49-
getParent() instanceof CodingStandardsConfig and
50-
hasName("deviations")
51-
}
28+
class DeviationRecords extends CodingStandardsConfigSection {
29+
DeviationRecords() { hasName("deviations") }
5230
}
5331

5432
/** A container for the deviation permits records. */
55-
class DeviationPermits extends XMLElement {
56-
DeviationPermits() {
57-
getParent() instanceof CodingStandardsConfig and
58-
hasName("deviation-permits")
59-
}
33+
class DeviationPermits extends CodingStandardsConfigSection {
34+
DeviationPermits() { hasName("deviation-permits") }
6035
}
6136

6237
/** A deviation permit record, that is specified by a permit identifier */
@@ -357,6 +332,13 @@ class DeviationRecord extends XMLElement {
357332
hasPermitId() and
358333
not hasADeviationPermit() and
359334
result = "There is no deviation permit with id `" + getPermitId() + "`."
335+
or
336+
exists(Query q | q.getQueryId() = getQueryId() |
337+
not q.getEffectiveCategory().permitsDeviation() and
338+
result =
339+
"The deviation is applied to a query with the rule category '" +
340+
q.getEffectiveCategory().toString() + "' that does not permit a deviation."
341+
)
360342
}
361343

362344
/** Holds if the deviation record is valid */

0 commit comments

Comments
 (0)