Skip to content

Commit d92aeb6

Browse files
CLOUDP-271995: Merge conflict
2 parents 1e88a54 + 356445e commit d92aeb6

File tree

7 files changed

+109
-37
lines changed

7 files changed

+109
-37
lines changed

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
"format-check": "npx prettier . --check",
88
"lint-js": "npx eslint **/*.js",
99
"gen-ipa-docs": "node tools/spectral/ipa/scripts/generateRulesetReadme.js",
10-
"ipa-validation": "spectral lint ./openapi/.raw/v2.yaml --ruleset=./tools/spectral/ipa/ipa-spectral.yaml",
10+
"ipa-validation": "spectral lint ./openapi/.raw/v2.yaml --ruleset=./tools/spectral/ipa/ipa-spectral.yaml",
11+
"ipa-filter-violations": "node tools/spectral/ipa/scripts/filter-ipa-violations.js",
1112
"spectral-validation": "spectral lint ./openapi/.raw/v2.yaml --ruleset=./tools/spectral/.spectral.yaml",
1213
"test": "jest",
1314
"precommit": "husky install"

tools/spectral/ipa/__tests__/exceptionExtensionFormat.test.js renamed to tools/spectral/ipa/__tests__/IPA105exceptionExtensionFormat.test.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,25 +51,25 @@ testRule('xgen-IPA-005-exception-extension-format', [
5151
errors: [
5252
{
5353
code: 'xgen-IPA-005-exception-extension-format',
54-
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa/5',
54+
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa-spectral#IPA-102',
5555
path: ['paths', '/path1', 'x-xgen-IPA-exception'],
5656
severity: DiagnosticSeverity.Warning,
5757
},
5858
{
5959
code: 'xgen-IPA-005-exception-extension-format',
60-
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa/5',
60+
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa-spectral#IPA-102',
6161
path: ['paths', '/path2', 'x-xgen-IPA-exception', 'xgen-IPA-100-rule-name'],
6262
severity: DiagnosticSeverity.Warning,
6363
},
6464
{
6565
code: 'xgen-IPA-005-exception-extension-format',
66-
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa/5',
66+
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa-spectral#IPA-102',
6767
path: ['paths', '/path3', 'x-xgen-IPA-exception', 'invalid-rule-name'],
6868
severity: DiagnosticSeverity.Warning,
6969
},
7070
{
7171
code: 'xgen-IPA-005-exception-extension-format',
72-
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa/5',
72+
message: 'IPA exceptions must have a valid rule name and a reason. http://go/ipa-spectral#IPA-102',
7373
path: ['paths', '/path4', 'x-xgen-IPA-exception', 'xgen-IPA-100-rule-name'],
7474
severity: DiagnosticSeverity.Warning,
7575
},

tools/spectral/ipa/rulesets/IPA-005.yaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,20 @@
22
# http://go/ipa/5
33

44
functions:
5-
- exceptionExtensionFormat
5+
- IPA105ExceptionExtensionFormat
66

77
rules:
88
xgen-IPA-005-exception-extension-format:
9-
description: 'IPA exception extensions must follow the correct format. http://go/ipa/5'
10-
message: '{{error}} http://go/ipa/5'
9+
description: |
10+
IPA exception extensions must follow the correct format. http://go/ipa/5
11+
12+
##### Implementation details
13+
Rule checks for the following conditions:
14+
- Exception rule names must start with 'xgen-IPA-' prefix
15+
- Each exception must include a non-empty reason as a string
16+
- This rule itself does not allow exceptions
17+
message: '{{error}} http://go/ipa-spectral#IPA-102'
1118
severity: error
1219
given: '$..x-xgen-IPA-exception'
1320
then:
14-
function: 'exceptionExtensionFormat'
21+
function: 'IPA105ExceptionExtensionFormat'

tools/spectral/ipa/rulesets/README.md

Lines changed: 6 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ Rule is based on [http://go/ipa/IPA-5](http://go/ipa/IPA-5).
1717
![error](https://img.shields.io/badge/error-red)
1818
IPA exception extensions must follow the correct format. http://go/ipa/5
1919

20+
##### Implementation details
21+
Rule checks for the following conditions:
22+
- Exception rule names must start with 'xgen-IPA-' prefix
23+
- Each exception must include a non-empty reason as a string
24+
- This rule itself does not allow exceptions
25+
2026

2127

2228
### IPA-102
@@ -27,7 +33,6 @@ Rule is based on [http://go/ipa/IPA-102](http://go/ipa/IPA-102).
2733

2834
![error](https://img.shields.io/badge/error-red)
2935
Paths should alternate between resource names and path params. http://go/ipa/102
30-
3136
#### xgen-IPA-102-collection-identifier-camelCase
3237

3338
![warn](https://img.shields.io/badge/warning-yellow)
@@ -44,14 +49,12 @@ Collection identifiers must be in camelCase.
4449
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
4550
- Double slashes (//) are not allowed in paths
4651

47-
4852
#### xgen-IPA-102-collection-identifier-pattern
4953

5054
![warn](https://img.shields.io/badge/warning-yellow)
5155
Collection identifiers must begin with a lowercase letter and contain only ASCII letters and numbers. http://go/ipa/102
5256

5357

54-
5558
### IPA-104
5659

5760
Rule is based on [http://go/ipa/IPA-104](http://go/ipa/IPA-104).
@@ -60,34 +63,28 @@ Rule is based on [http://go/ipa/IPA-104](http://go/ipa/IPA-104).
6063

6164
![warn](https://img.shields.io/badge/warning-yellow)
6265
APIs must provide a Get method for resources. http://go/ipa/104
63-
6466
#### xgen-IPA-104-get-method-returns-single-resource
6567

6668
![warn](https://img.shields.io/badge/warning-yellow)
6769
The purpose of the Get method is to return data from a single resource. http://go/ipa/104
68-
6970
#### xgen-IPA-104-get-method-response-code-is-200
7071

7172
![warn](https://img.shields.io/badge/warning-yellow)
7273
The Get method must return a 200 OK response. http://go/ipa/104
73-
7474
#### xgen-IPA-104-get-method-returns-response-suffixed-object
7575

7676
![warn](https://img.shields.io/badge/warning-yellow)
7777
The Get method of a resource should return a "Response" suffixed object. http://go/ipa/104
78-
7978
#### xgen-IPA-104-get-method-response-has-no-input-fields
8079

8180
![warn](https://img.shields.io/badge/warning-yellow)
8281
The Get method response object must not include writeOnly properties (fields that should be used only on creation or update, ie output fields). http://go/ipa/104
83-
8482
#### xgen-IPA-104-get-method-no-request-body
8583

8684
![warn](https://img.shields.io/badge/warning-yellow)
8785
The Get method request must not include a body. http://go/ipa/104
8886

8987

90-
9188
### IPA-105
9289

9390
Rule is based on [http://go/ipa/IPA-105](http://go/ipa/IPA-105).
@@ -96,19 +93,16 @@ Rule is based on [http://go/ipa/IPA-105](http://go/ipa/IPA-105).
9693

9794
![warn](https://img.shields.io/badge/warning-yellow)
9895
The List method must return a 200 OK response. http://go/ipa/105
99-
10096
#### xgen-IPA-105-list-method-no-request-body
10197

10298
![warn](https://img.shields.io/badge/warning-yellow)
10399
The List method request must not include a body. http://go/ipa/105
104-
105100
#### xgen-IPA-105-resource-has-list
106101

107102
![warn](https://img.shields.io/badge/warning-yellow)
108103
APIs must provide a List method for resources. http://go/ipa/105
109104

110105

111-
112106
### IPA-106
113107

114108
Rule is based on [http://go/ipa/IPA-106](http://go/ipa/IPA-106).
@@ -117,29 +111,24 @@ Rule is based on [http://go/ipa/IPA-106](http://go/ipa/IPA-106).
117111

118112
![warn](https://img.shields.io/badge/warning-yellow)
119113
The Create method request should be a Request suffixed object. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs.
120-
121114
#### xgen-IPA-106-create-method-should-not-have-query-parameters
122115

123116
![warn](https://img.shields.io/badge/warning-yellow)
124117
Create operations should not use query parameters. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs.
125-
126118
#### xgen-IPA-106-create-method-request-body-is-get-method-response
127119

128120
![warn](https://img.shields.io/badge/warning-yellow)
129121
Request body content of the Create method and response content of the Get method should refer to the same resource. http://go/ipa/106 readOnly/writeOnly properties will be ignored. This rule applies only to POST requests targeting resource collection URIs.
130-
131122
#### xgen-IPA-106-create-method-request-has-no-readonly-fields
132123

133124
![warn](https://img.shields.io/badge/warning-yellow)
134125
Create method Request object must not include fields with readOnly:true. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs.
135-
136126
#### xgen-IPA-106-create-method-response-code-is-201
137127

138128
![warn](https://img.shields.io/badge/warning-yellow)
139129
Create methods must return a 201 Created response code. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs.
140130

141131

142-
143132
### IPA-107
144133

145134
Rule is based on [http://go/ipa/IPA-107](http://go/ipa/IPA-107).
@@ -153,7 +142,6 @@ Validation checks the PUT method for single resource paths and singleton resourc
153142

154143
- Query parameters `envelope` and `pretty` are exempt from this rule
155144
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
156-
157145
#### xgen-IPA-107-patch-must-not-have-query-params
158146

159147
![warn](https://img.shields.io/badge/warning-yellow)
@@ -165,7 +153,6 @@ Validation checks the PATCH method for single resource paths and singleton resou
165153
- Operation objects with `x-xgen-IPA-exception` for this rule are excluded from validation
166154

167155

168-
169156
### IPA-108
170157

171158
Rule is based on [http://go/ipa/IPA-108](http://go/ipa/IPA-108).
@@ -174,24 +161,20 @@ Rule is based on [http://go/ipa/IPA-108](http://go/ipa/IPA-108).
174161

175162
![warn](https://img.shields.io/badge/warning-yellow)
176163
Delete method response should not have schema reference to object. http://go/ipa/108
177-
178164
#### xgen-IPA-108-delete-method-return-204-response
179165

180166
![warn](https://img.shields.io/badge/warning-yellow)
181167
DELETE method must return 204 No Content. http://go/ipa/108
182-
183168
#### xgen-IPA-108-delete-include-404-response
184169

185170
![warn](https://img.shields.io/badge/warning-yellow)
186171
DELETE method must include 404 response and return it when resource not found. http://go/ipa/108
187-
188172
#### xgen-IPA-108-delete-request-no-body
189173

190174
![warn](https://img.shields.io/badge/warning-yellow)
191175
DELETE method must not have request body. http://go/ipa/108
192176

193177

194-
195178
### IPA-109
196179

197180
Rule is based on [http://go/ipa/IPA-109](http://go/ipa/IPA-109).
@@ -200,14 +183,12 @@ Rule is based on [http://go/ipa/IPA-109](http://go/ipa/IPA-109).
200183

201184
![error](https://img.shields.io/badge/error-red)
202185
The HTTP method for custom methods must be GET or POST. http://go/ipa/109
203-
204186
#### xgen-IPA-109-custom-method-must-use-camel-case
205187

206188
![error](https://img.shields.io/badge/error-red)
207189
The custom method must use camelCase format. http://go/ipa/109
208190

209191

210-
211192
### IPA-113
212193

213194
Rule is based on [http://go/ipa/IPA-113](http://go/ipa/IPA-113).
@@ -218,7 +199,6 @@ Rule is based on [http://go/ipa/IPA-113](http://go/ipa/IPA-113).
218199
Singleton resources must not have a user-provided or system-generated ID. http://go/ipa/113
219200

220201

221-
222202
### IPA-123
223203

224204
Rule is based on [http://go/ipa/IPA-123](http://go/ipa/IPA-123).
@@ -230,4 +210,3 @@ Enum values must be UPPER_SNAKE_CASE. http://go/ipa/123
230210

231211

232212

233-
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import fs from 'node:fs/promises';
2+
import { execSync } from 'child_process';
3+
import path from 'path';
4+
5+
async function filterIpaViolations() {
6+
try {
7+
// Check if rule ID is provided
8+
const ruleId = process.argv[2];
9+
if (!ruleId) {
10+
console.error('Usage: node filter-ipa-violations.js <rule-id>');
11+
console.error('Example: node filter-ipa-violations.js xgen-IPA-102-collection-identifier-camelCase');
12+
process.exit(1);
13+
}
14+
15+
const outputFile = path.join(process.cwd(), `${ruleId}-violations.md`);
16+
17+
console.log(`Filtering violations for rule ID: ${ruleId}`);
18+
console.log('Running IPA validation...');
19+
20+
let validationOutput;
21+
try {
22+
// Run IPA validation and get output as JSON
23+
execSync(
24+
'spectral lint --format=json -o results.json ./openapi/.raw/v2.yaml --ruleset=./tools/spectral/ipa/ipa-spectral.yaml',
25+
{
26+
encoding: 'utf-8',
27+
timeout: 4000,
28+
maxBuffer: 10 * 1024 * 1024,
29+
}
30+
);
31+
} catch (error) {
32+
console.error('Error (expected):', error.message);
33+
}
34+
35+
// Read the JSON output
36+
validationOutput = await fs.readFile('results.json', 'utf-8');
37+
console.log('Filtering results...');
38+
39+
// Parse the JSON output
40+
const validationResults = JSON.parse(validationOutput);
41+
42+
// Filter results for the exact specified rule ID
43+
const filteredResults = validationResults.filter((violation) => violation.code === ruleId);
44+
45+
// Group by source file
46+
const groupedBySource = filteredResults.reduce((acc, violation) => {
47+
const source = violation.source;
48+
if (!acc[source]) {
49+
acc[source] = [];
50+
}
51+
acc[source].push({
52+
path: violation.path,
53+
message: violation.message,
54+
source: violation.source,
55+
});
56+
return acc;
57+
}, {});
58+
59+
// Generate markdown content
60+
let markdownContent = `# ${ruleId} Violations Checklist\n\n`;
61+
markdownContent += `Generated on: ${new Date().toLocaleString()}\n\n`;
62+
63+
Object.keys(groupedBySource).forEach((source) => {
64+
const violations = groupedBySource[source];
65+
66+
violations.forEach((violation) => {
67+
markdownContent += `## ${violation.source}\n\n`;
68+
markdownContent += `Path: \`${violation.path.join('/')}\`\n\n`;
69+
markdownContent += `- [ ] Fixed\n\n`;
70+
});
71+
});
72+
73+
// Write the markdown file
74+
await fs.writeFile(outputFile, markdownContent, 'utf-8');
75+
76+
const violationCount = filteredResults.length;
77+
console.log(`Results saved to ${outputFile}`);
78+
console.log(`Found ${violationCount} violations to fix`);
79+
} catch (error) {
80+
console.error('Error:', error.message);
81+
process.exit(1);
82+
}
83+
}
84+
85+
filterIpaViolations();

tools/spectral/ipa/scripts/generateRulesetReadme.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ function generateRulesetSections(rules) {
6060

6161
sortedRuleEntries.forEach((rule) => {
6262
const severityFormatted = formatSeverity(rule.severity);
63-
sections += `#### ${rule.name}\n\n ${severityFormatted} \n${rule.description}\n\n`;
63+
sections += `#### ${rule.name}\n\n ${severityFormatted} \n${rule.description}\n`;
6464
});
6565

6666
return sections;

0 commit comments

Comments
 (0)