Skip to content

Commit c77fdac

Browse files
committed
code gen for sdk
Signed-off-by: Bikash Roshan <Bikash.Roshan@ibm.com>
1 parent 3dcb5c8 commit c77fdac

23 files changed

Lines changed: 2062 additions & 288 deletions

codegen/.gitignore

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Generated files (if using safe mode)
2+
generated/
3+
4+
# Node modules
5+
node_modules/
6+
7+
# Build output
8+
dist/
9+
build/
10+
11+
# Logs
12+
*.log
13+
npm-debug.log*
14+
15+
# Made with Bob

codegen/check-generated.ts

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/**
2+
* This program and the accompanying materials are made available under the terms of the
3+
* Eclipse Public License v2.0 which accompanies this distribution, and is available at
4+
* https://www.eclipse.org/legal/epl-v20.html
5+
*
6+
* SPDX-License-Identifier: EPL-2.0
7+
*
8+
* Copyright Contributors to the Zowe Project.
9+
*
10+
*/
11+
12+
import * as path from "path";
13+
import { execSync } from "child_process";
14+
15+
/**
16+
* CI Check Script: Verifies that running the generator does not change tracked files.
17+
*
18+
* This script:
19+
* 1. Runs the generator against the repository
20+
* 2. Uses git to detect whether tracked files changed
21+
* 3. Fails if generation leaves the working tree dirty
22+
*
23+
* Usage: npm run check:generated
24+
*/
25+
26+
class GeneratedFileChecker {
27+
/**
28+
* Main check function
29+
*/
30+
public async check(): Promise<boolean> {
31+
console.log("🔍 Checking that generated files are up to date...\n");
32+
33+
this.generateInRepo();
34+
return this.reportResults();
35+
}
36+
37+
/**
38+
* Run generator against the repository
39+
*/
40+
private generateInRepo(): void {
41+
console.log("📦 Running generator against repository...");
42+
43+
try {
44+
execSync("npm run generate", {
45+
cwd: __dirname,
46+
stdio: "inherit",
47+
});
48+
console.log("✅ Generation completed\n");
49+
} catch (error) {
50+
console.error("❌ Failed to generate files:", error);
51+
throw error;
52+
}
53+
}
54+
55+
/**
56+
* Report git diff results
57+
*/
58+
private reportResults(): boolean {
59+
const changedFilesOutput = execSync("git diff --name-only -- packages/sdk", {
60+
cwd: path.join(__dirname, ".."),
61+
encoding: "utf-8",
62+
}).trim();
63+
64+
if (changedFilesOutput.length > 0) {
65+
const changedFiles = changedFilesOutput.split("\n").filter(Boolean);
66+
67+
console.log("❌ Generated files are not up to date.\n");
68+
console.log("Changed files:");
69+
for (const file of changedFiles) {
70+
console.log(` • ${file}`);
71+
}
72+
73+
console.log("\n💡 To fix this:");
74+
console.log(" 1. Run: cd codegen && npm run generate");
75+
console.log(" 2. Review the changes");
76+
console.log(" 3. Commit the regenerated files\n");
77+
return false;
78+
}
79+
80+
console.log("✅ No tracked files changed after generation.\n");
81+
return true;
82+
}
83+
}
84+
85+
// Main execution
86+
if (require.main === module) {
87+
const checker = new GeneratedFileChecker();
88+
checker.check().then(success => {
89+
process.exit(success ? 0 : 1);
90+
}).catch(error => {
91+
console.error("❌ Check failed with error:", error);
92+
process.exit(1);
93+
});
94+
}

codegen/docs/codegen.md

Lines changed: 280 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,280 @@
1+
# CICS SDK Code Generation
2+
3+
## Quick Start
4+
5+
1. Install dependencies: `npm install`
6+
2. Generate code: `npm run generate`
7+
3. Verify changes: `npm run check-generated`
8+
9+
The generator reads `resourceSpecification.json` and produces SDK files, utility files, and test files using Handlebars templates.
10+
11+
---
12+
13+
## Prerequisites
14+
15+
- **Node.js**: Version 18 or higher
16+
- **npm**: For package management
17+
- **TypeScript**: Knowledge helpful for understanding generated code
18+
- **Git**: For version control and CI integration
19+
20+
---
21+
22+
## What is the Use of Codegen?
23+
24+
The code generation system automates the creation of CICS SDK code from a single source of truth specification. It generates:
25+
26+
- **SDK Resource Files**: TypeScript classes for CICS resources (LocalFile, Program, Transaction, etc.)
27+
- **Utility Files**: Helper functions and constants for resource actions
28+
- **Test Files**: Unit tests for SDK resource classes
29+
- **Type Definitions**: Interfaces and type definitions for parameters
30+
31+
This eliminates manual coding errors, ensures consistency across resources, and makes it easy to add new resources or actions.
32+
33+
---
34+
35+
## Why Use Codegen?
36+
37+
### Benefits
38+
39+
1. **Single Source of Truth**: All resource definitions, actions, and options are defined once in `resourceSpecification.json`
40+
2. **Consistency**: Generated code follows the same patterns and conventions across all resources
41+
3. **Reduced Duplication**: Shared actions and options are defined once and referenced by multiple resources
42+
4. **Maintainability**: Changes to resource behavior only require updating the specification and regenerating
43+
5. **Error Prevention**: Automated generation eliminates manual coding mistakes
44+
6. **Scalability**: Adding new resources or actions is straightforward
45+
7. **Documentation**: The specification serves as documentation for available resources and actions
46+
47+
### Resource-Focused Architecture
48+
49+
The specification is organized by resources rather than actions, which:
50+
51+
- Reduces specification size by 79% (from 323 lines to 68 lines)
52+
- Eliminates duplication of resource information across action groups
53+
- Makes it easier to understand what actions are available for each resource
54+
- Allows sharing of common actions and options across resources
55+
56+
---
57+
58+
## How to Use Codegen
59+
60+
### Basic Workflow
61+
62+
1. **Modify Specification**: Edit `resourceSpecification.json` to add/modify resources, actions, or options
63+
2. **Validate**: The JSON schema automatically validates your changes
64+
3. **Generate Code**: Run `npm run generate` to create SDK files
65+
4. **Review Changes**: Check the generated files in `packages/sdk/src/` and `packages/sdk/__tests__/`
66+
5. **Test**: Run tests to ensure generated code works correctly
67+
6. **Commit**: Commit both specification and generated files together
68+
69+
### Generation Modes
70+
71+
#### Direct Mode (Default)
72+
Generates all files directly into the SDK package:
73+
- SDK resource files in `packages/sdk/src/`
74+
- Utility files in `packages/sdk/src/utils/`
75+
- Test files in `packages/sdk/__tests__/__unit__/`
76+
77+
Use this mode during active development when making changes to resources.
78+
79+
#### Tests-Only Mode
80+
Generates only test files without modifying SDK source files. Useful for:
81+
- Updating tests after manual SDK changes
82+
- Regenerating tests when templates change
83+
- Verifying test coverage
84+
85+
Enable with: `npm run generate -- --tests-only`
86+
87+
### Adding a New Resource
88+
89+
1. Add resource definition to `resourceSpecification.json` under `resources` section
90+
2. Specify resource identifier (name, aliases, primary key, etc.)
91+
3. List actions for the resource (can reference shared actions or define inline)
92+
4. Run `npm run generate`
93+
5. Generated files appear automatically in the SDK package
94+
95+
### Adding a New Action
96+
97+
1. Define action in `actions` section of `resourceSpecification.json`
98+
2. Specify action identifier (name, aliases, description, verbs)
99+
3. List options for the action (can reference shared options or define inline)
100+
4. Reference the action in relevant resources
101+
5. Run `npm run generate`
102+
103+
### Modifying Options
104+
105+
1. Update option definition in `options` section
106+
2. Changes automatically apply to all actions using that option
107+
3. Run `npm run generate`
108+
109+
---
110+
111+
## Architecture of Codegen
112+
113+
### Components
114+
115+
#### 1. Specification File (`resourceSpecification.json`)
116+
The single source of truth containing:
117+
- **Resources**: CICS resource types (LocalFile, Program, Transaction, etc.)
118+
- **Actions**: Operations that can be performed (ENABLE, DISABLE, OPEN, CLOSE, etc.)
119+
- **Options**: Parameters for actions (busy, force, etc.)
120+
121+
#### 2. Schema File (`resourceSpecification.schema.json`)
122+
JSON schema that validates the specification structure and ensures:
123+
- Required fields are present
124+
- Data types are correct
125+
- References to shared actions/options are valid
126+
- Naming conventions are followed
127+
128+
#### 3. Generator (`generate.ts`)
129+
TypeScript program that:
130+
- Reads and validates the specification
131+
- Derives properties (constants, interface names, function names)
132+
- Processes Handlebars templates
133+
- Writes generated files to the SDK package
134+
- Handles both direct and tests-only generation modes
135+
136+
#### 4. Templates (`templates/`)
137+
Handlebars templates that define the structure of generated files:
138+
- `sdk/resource.file.hbs`: SDK resource class template
139+
- `sdk/resource.index.hbs`: SDK index file template
140+
- `sdk/utils.resourceactions.hbs`: Utility functions template
141+
- `sdk/utils.index.hbs`: Utility index file template
142+
- `tests/sdk.resource.unit.test.hbs`: Unit test template
143+
144+
### Data Flow
145+
146+
1. **Input**: `resourceSpecification.json` defines resources, actions, and options
147+
2. **Validation**: JSON schema validates the specification structure
148+
3. **Processing**: Generator reads specification and derives additional properties
149+
4. **Template Rendering**: Handlebars templates are populated with resource data
150+
5. **Output**: Generated TypeScript files are written to SDK package
151+
152+
### Derived Properties
153+
154+
The generator automatically creates properties that don't need to be stored in the specification:
155+
156+
- **SDK Resource Type**: Constant name like `CICS_CMCI_LOCALFILE`
157+
- **Parameters Interface**: Interface name like `ILocalFileParms`
158+
- **Criteria Field**: Primary key field name in lowercase
159+
- **Function Names**: Action function names like `openLocalFile`
160+
- **File Names**: SDK file names like `LocalFile.ts`
161+
162+
This reduces specification size and eliminates manual maintenance of derived values.
163+
164+
### Shared Definitions
165+
166+
Actions and options can be defined once and referenced by multiple resources:
167+
168+
- **Shared Actions**: Common actions like ENABLE and DISABLE are defined in the `actions` section
169+
- **Shared Options**: Common options like BUSY are defined in the `options` section
170+
- **References**: Resources reference shared definitions by name
171+
- **Inline Definitions**: Resources can also define actions/options inline for resource-specific behavior
172+
173+
---
174+
175+
## CI Integration
176+
177+
### Automated Checks
178+
179+
The CI pipeline includes a check to ensure generated files are up-to-date:
180+
181+
1. CI runs `npm run check-generated`
182+
2. Script regenerates all files in a temporary directory
183+
3. Compares generated files with committed files
184+
4. Fails if differences are detected
185+
186+
This prevents:
187+
- Manual modifications to generated files
188+
- Forgetting to regenerate after specification changes
189+
- Inconsistencies between specification and code
190+
191+
### Git Workflow
192+
193+
1. **Modify Specification**: Make changes to `resourceSpecification.json`
194+
2. **Generate Code**: Run `npm run generate` locally
195+
3. **Review Changes**: Check generated files with `git diff`
196+
4. **Commit Together**: Commit specification and generated files in the same commit
197+
5. **Push**: CI automatically verifies generated files match specification
198+
199+
### Best Practices
200+
201+
- Always regenerate after modifying the specification
202+
- Never manually edit generated files (they will be overwritten)
203+
- Commit specification and generated files together
204+
- Use meaningful commit messages describing specification changes
205+
- Run `npm run check-generated` before pushing to catch issues early
206+
207+
---
208+
209+
## Troubleshooting
210+
211+
### Common Issues
212+
213+
#### Generated Files Don't Match Specification
214+
215+
**Problem**: After running `npm run generate`, the generated files don't reflect your specification changes.
216+
217+
**Solutions**:
218+
- Ensure you saved `resourceSpecification.json` before generating
219+
- Check for JSON syntax errors in the specification
220+
- Verify the schema validation passes
221+
- Clear any cached files and regenerate
222+
223+
#### Schema Validation Errors
224+
225+
**Problem**: The generator reports schema validation errors.
226+
227+
**Solutions**:
228+
- Check that all required fields are present in your resource definitions
229+
- Verify action and option references exist in their respective sections
230+
- Ensure data types match the schema (strings, arrays, objects)
231+
- Review the error message for specific field issues
232+
233+
#### CI Check Fails
234+
235+
**Problem**: The `check-generated` CI check fails even though you regenerated locally.
236+
237+
**Solutions**:
238+
- Ensure you committed the generated files along with the specification
239+
- Verify you're using the same Node.js version as CI
240+
- Run `npm run check-generated` locally to reproduce the issue
241+
- Check for platform-specific line ending differences (CRLF vs LF)
242+
243+
#### Template Rendering Errors
244+
245+
**Problem**: Handlebars template errors during generation.
246+
247+
**Solutions**:
248+
- Check that all template variables are defined in the specification
249+
- Verify template syntax is correct
250+
- Ensure derived properties are being generated correctly
251+
- Review the generator code for property derivation logic
252+
253+
#### Missing Generated Files
254+
255+
**Problem**: Some expected files are not generated.
256+
257+
**Solutions**:
258+
- Verify the resource is properly defined in the specification
259+
- Check that the resource has at least one action
260+
- Ensure templates exist for the file types you expect
261+
- Review generator output for error messages
262+
263+
#### Incorrect Action Order
264+
265+
**Problem**: Actions appear in the wrong order in generated files.
266+
267+
**Solutions**:
268+
- The generator sorts actions with CLOSE first, then alphabetically
269+
- This is intentional for consistency
270+
- If you need a different order, modify the generator's sorting logic
271+
272+
### Getting Help
273+
274+
If you encounter issues not covered here:
275+
276+
1. Check the specification schema for validation rules
277+
2. Review the generator code for processing logic
278+
3. Examine template files for expected data structure
279+
4. Run the generator with verbose logging if available
280+
5. Consult the team or create an issue with details about the problem

0 commit comments

Comments
 (0)