Standalone COBOL processor following the markdown-processor.ts pattern: - No LanguageProvider modification — COBOL uses regex, not tree-sitter - No SupportedLanguages enum change — standalone processor pattern New files: - cobol-processor.ts — orchestrator (processCobol, isCobolFile, isJclFile) - cobol/cobol-preprocessor.ts — regex state machine extraction (~888 LOC) - cobol/cobol-copy-expander.ts — COPY statement expansion with circular detection - cobol/jcl-parser.ts — JCL job/step/DD extraction - cobol/jcl-processor.ts — JCL graph node creation Extraction produces: - Module nodes (PROGRAM-ID) - Function nodes (paragraphs) - Namespace nodes (sections) - Property nodes (data items) - CALLS edges (PERFORM intra-file, CALL cross-program) - IMPORTS edges (COPY statements) - CONTAINS edges (section → paragraph hierarchy) Pipeline integration: single processCobol() call in Phase 2.6 54 new tests (33 COBOL + 21 JCL), all 3889 tests pass.
4.4 KiB
COBOL File Detection
GitNexus detects COBOL files through two mechanisms: extension-based mapping and directory-based override for extensionless files. This document covers both, plus the copybook/program classification logic.
Extension Mapping
Program Extensions
| Extension | Type |
|---|---|
.cbl |
COBOL program |
.cob |
COBOL program |
.cobol |
COBOL program |
Copybook Extensions
| Extension | Type | Notes |
|---|---|---|
.cpy |
Copybook | Standard |
.copy |
Copybook | Standard |
.gnm / .GNM |
Copybook | Enterprise (GnuCOBOL naming) |
.fd / .FD |
Copybook | File Description fragment |
.wrk / .WRK |
Copybook | Working-Storage fragment |
.sel / .SEL |
Copybook | SELECT clause fragment |
.open / .OPEN |
Copybook | File OPEN fragment |
.close / .CLOSE |
Copybook | File CLOSE fragment |
.ini / .INI |
Copybook | Initialization fragment |
.def / .DEF |
Copybook | Definition fragment |
All extension matching is case-sensitive in getLanguageFromFilename (the extensions above are matched as written, including uppercase variants like .GNM).
Extensionless File Detection: GITNEXUS_COBOL_DIRS
Many enterprise COBOL repositories use extensionless files -- the filename alone identifies the program (e.g., s/BGTABFL is the source for program BGTABFL). GitNexus handles this via the GITNEXUS_COBOL_DIRS environment variable.
Configuration
Set GITNEXUS_COBOL_DIRS to a comma-separated list of directory names:
# Files in s/, c/, and wfproc/ directories (at any depth) are treated as COBOL
export GITNEXUS_COBOL_DIRS=s,c,wfproc
The matching is case-insensitive and checks all path segments:
/repo/s/BGTABFL-- matches segments-- COBOL/repo/src/c/CPSESP-- matches segmentc-- COBOL/repo/wfproc/WF001-- matches segmentwfproc-- COBOL/repo/docs/README-- no matching segment -- skipped
Decision Tree
flowchart TD
A[getLanguageFromPath] --> B[getLanguageFromFilename]
B --> C{Known extension?}
C -->|Yes .cbl/.cob/.cobol/.cpy/...| D[Return COBOL]
C -->|Yes .ts/.py/.java/...| E[Return other language]
C -->|No match| F{Has extension?}
F -->|"Has dot in basename"| G[Return null]
F -->|"No dot = extensionless"| H{GITNEXUS_COBOL_DIRS set?}
H -->|No| G
H -->|Yes| I{Any path segment<br/>matches a configured dir?}
I -->|Yes| D
I -->|No| G
style D fill:#e8f5e9,stroke:#2e7d32
style G fill:#ffebee,stroke:#c62828
Implementation Detail
The GITNEXUS_COBOL_DIRS value is parsed once (on first call) and cached in a Set<string>:
// From gitnexus/src/core/ingestion/utils.ts
const getCobolDirs = (): Set<string> => {
if (_cobolDirs) return _cobolDirs;
const raw = process.env.GITNEXUS_COBOL_DIRS;
_cobolDirs = raw
? new Set(raw.split(',').map(d => d.trim().toLowerCase()))
: new Set();
return _cobolDirs;
};
The path segment check splits the full path on / and tests each segment against the cached set.
Copybook vs Program Classification
After a file is identified as COBOL, it must be classified as either a program (to be parsed for symbols) or a copybook (to be loaded into the copybook map for COPY expansion).
Classification Rules
A COBOL file is classified as a copybook if ANY of these conditions is true:
- It has a recognized copybook extension (
.cpy,.copy,.gnm,.fd,.wrk,.sel,.open,.close,.ini,.def) - It is an extensionless file whose path contains a directory segment matching one of:
c,copy,copybooks,copylib,cpy
A file is classified as a program if:
- It has a program extension (
.cbl,.cob,.cobol), OR - It is extensionless and does NOT match any copybook directory pattern
Copybook Name Resolution
Copybook names are derived from the filename:
- Strip the extension (if any)
- Convert to uppercase
Examples:
c/CPSESP-- name:CPSESPcopy/workgrid.cpy-- name:WORKGRIDc/ANAZI.GNM-- name:ANAZI
This name is used to resolve COPY CPSESP. statements during expansion.
Source Files
gitnexus/src/core/ingestion/utils.ts--getLanguageFromPath(),getLanguageFromFilename(),getCobolDirs()gitnexus/src/core/ingestion/pipeline.ts--isCobolCopybook(),getCopybookName(),COPYBOOK_EXTENSIONS,COBOL_PROGRAM_EXTENSIONS