Skip to content

Commit fe79f41

Browse files
authored
Fix false-positive blocklist filenames, better handling for unsupported source code (#82)
1 parent 667a161 commit fe79f41

File tree

14 files changed

+253
-23
lines changed

14 files changed

+253
-23
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,13 @@ Each analyzed file in your project ends up with:
112112

113113
To customise your analysis, use the following options, placed in a `codehawk.json` file in the root directory.
114114

115-
| Option | Description | Default |
116-
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
117-
| `enableFlow` | Enable Flow support | `false` |
118-
| `extensions` | File extensions that should be analyzed. The default is always used, but you can add more extensions. You can use the `exclude[...]` options to exclude specific files. | `['.js', '.jsx', '.ts', '.tsx']` |
119-
| `excludeFilenames` | Filename matches that should be excluded from analysis. The default is always used, but you can add more matches to be excluded. Note that the matching is exact. The exclude list is taken into consideration after the extension list. | `['.d.ts', '.min.js', '.bundle.js']` |
120-
| `excludeDirectories` | Directory matches that should be excluded from analysis. Relative to the root. E.g. `['/fixtures', '/test']` | `['/dist', '/bin', '/build']` |
121-
| `skipDirectories` | Directories that should be excluded completely. The defaults will always be skipped. | `['/node_modules', '/flow-typed', '/coverage']` |
115+
| Option | Description | Default |
116+
|----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------|
117+
| `enableFlow` | Enable Flow support | `false` |
118+
| `extensions` | File extensions that should be analyzed. The default is always used, but you can add more extensions. You can use the `exclude[...]` options to exclude specific files. | `['.js', '.jsx', '.ts', '.tsx']` |
119+
| `excludeFilenames` | Filename matches that should be excluded from static analysis (but still show in the data). The default is always used, but you can add more matches to be excluded. Note that the matching is exact. The exclude list is taken into consideration after the extension list. | `['.d.ts', '.min.js', '.bundle.js']` |
120+
| `excludeDirectories` | Directory matches that should be excluded from static analysis (but still show in the data). Relative to the root. E.g. `['/fixtures', '/test']` | `['/dist', '/bin', '/build']` |
121+
| `skipDirectories` | Directories that should be excluded completely, i.e. not visible in the resulting data at all. The defaults will always be skipped. | `['/node_modules', '/flow-typed', '/coverage']` |
122122

123123
## Badges
124124

generated/avg-maintainability.svg

Lines changed: 4 additions & 4 deletions
Loading

generated/worst-maintainability.svg

Lines changed: 4 additions & 4 deletions
Loading
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// This contains java code - it's intentional so that we can test handling un-transpile-able code
2+
3+
public class HelloWorld {
4+
5+
public static void main(String[] args) {
6+
// Prints "Hello, World" to the terminal window.
7+
System.out.println("Hello, World");
8+
}
9+
10+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
{
2+
"summary": {
3+
"average": 58.93321508519464,
4+
"median": 58.93321508519464,
5+
"worst": 58.93321508519464
6+
},
7+
"resultsList": [
8+
{
9+
"fullPath": "/samples/contains-some-bad-code/good-code.ts",
10+
"filename": "good-code.ts",
11+
"shouldAnalyze": true,
12+
"path": "/samples/contains-some-bad-code",
13+
"type": "file",
14+
"complexityReport": {
15+
"aggregate": {
16+
"cyclomatic": 11,
17+
"cyclomaticDensity": 37.931,
18+
"halstead": {
19+
"bugs": 0.217,
20+
"difficulty": 35.889,
21+
"effort": 23378.702,
22+
"length": 127,
23+
"time": 1298.817,
24+
"vocabulary": 35,
25+
"volume": 651.419,
26+
"operands": { "distinct": 18, "total": 76 },
27+
"operators": { "distinct": 17, "total": 51 }
28+
},
29+
"paramCount": 9,
30+
"sloc": { "logical": 29, "physical": 50 }
31+
},
32+
"dependencies": [],
33+
"errors": [],
34+
"lineEnd": 50,
35+
"lineStart": 1,
36+
"maintainability": 108.234,
37+
"codehawkScore": 58.93321508519464,
38+
"coverage": "0"
39+
},
40+
"timesDependedOn": 0
41+
}
42+
],
43+
"fullResultsTree": [
44+
{
45+
"fullPath": "/samples/contains-some-bad-code/bad-code.ts",
46+
"filename": "bad-code.ts",
47+
"shouldAnalyze": true,
48+
"path": "/samples/contains-some-bad-code",
49+
"type": "file",
50+
"complexityReport": null,
51+
"timesDependedOn": 0
52+
},
53+
{
54+
"fullPath": "/samples/contains-some-bad-code/expected.json",
55+
"filename": "expected.json",
56+
"shouldAnalyze": false,
57+
"path": "/samples/contains-some-bad-code",
58+
"type": "file",
59+
"complexityReport": null,
60+
"timesDependedOn": 0
61+
},
62+
{
63+
"fullPath": "/samples/contains-some-bad-code/good-code.ts",
64+
"filename": "good-code.ts",
65+
"shouldAnalyze": true,
66+
"path": "/samples/contains-some-bad-code",
67+
"type": "file",
68+
"complexityReport": {
69+
"aggregate": {
70+
"cyclomatic": 11,
71+
"cyclomaticDensity": 37.931,
72+
"halstead": {
73+
"bugs": 0.217,
74+
"difficulty": 35.889,
75+
"effort": 23378.702,
76+
"length": 127,
77+
"time": 1298.817,
78+
"vocabulary": 35,
79+
"volume": 651.419,
80+
"operands": { "distinct": 18, "total": 76 },
81+
"operators": { "distinct": 17, "total": 51 }
82+
},
83+
"paramCount": 9,
84+
"sloc": { "logical": 29, "physical": 50 }
85+
},
86+
"dependencies": [],
87+
"errors": [],
88+
"lineEnd": 50,
89+
"lineStart": 1,
90+
"maintainability": 108.234,
91+
"codehawkScore": 58.93321508519464,
92+
"coverage": "0"
93+
},
94+
"timesDependedOn": 0
95+
}
96+
]
97+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
export function swap(items, leftIndex, rightIndex) {
2+
var temp = items[leftIndex]
3+
items[leftIndex] = items[rightIndex]
4+
items[rightIndex] = temp
5+
}
6+
7+
export function partition(items, left, right) {
8+
var pivot = items[Math.floor((right + left) / 2)], //middle element
9+
i = left, //left pointer
10+
j = right //right pointer
11+
while (i <= j) {
12+
while (items[i] < pivot) {
13+
i++
14+
}
15+
while (items[j] > pivot) {
16+
j--
17+
}
18+
if (i <= j) {
19+
swap(items, i, j) //sawpping two elements
20+
i++
21+
j--
22+
}
23+
}
24+
return i
25+
}
26+
27+
export function quickSort(items, left, right) {
28+
var index
29+
if (items.length > 1) {
30+
index = partition(items, left, right) //index returned from partition
31+
if (left < index - 1) {
32+
//more elements on the left side of the pivot
33+
quickSort(items, left, index - 1)
34+
}
35+
if (index < right) {
36+
//more elements on the right side of the pivot
37+
quickSort(items, index, right)
38+
}
39+
}
40+
return items
41+
}

src/analyze.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@ export const analyzeFile = (
5555
file: FileWithContents,
5656
projectCoverage: CoverageMapping[]
5757
): CompleteCodehawkComplexityResult => {
58+
// Handle cases where a file was intended to be analyzed, but the source could not be parsed
59+
if (!file.rawSource) {
60+
return null
61+
}
62+
5863
let report = null
5964
const relativeFilePath = `${file.path}/${file.filename}`.replace(dirPath, '')
6065
const coverageData = projectCoverage.find((c) => c.path === relativeFilePath)
@@ -95,7 +100,9 @@ export const analyzeFile = (
95100
}
96101
}
97102
} catch (e) {
98-
console.error(`Unable to parse "${file.path}/${file.filename}", skipping`)
103+
console.error(
104+
`[codehawk-cli] Unable to analyze file "${file.path}/${file.filename}", skipping`
105+
)
99106
// if (NODE_ENV !== 'production') {
100107
// // Print out what is attempting to be evaluated
101108
// // Exposes bugs such as flow-remove-types not working correctly

src/codehawk.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ describe('codehawk-cli', () => {
9393
outputMatchesResult('samples/react-component-typescript')
9494
})
9595

96+
it('contains-some-bad-code', () => {
97+
outputMatchesResult('samples/contains-some-bad-code')
98+
})
99+
96100
it('sweetalert', () => {
97101
outputMatchesResult('samples/sweetalert')
98102
})

src/codehawk.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,25 @@ const analyzeProject = (rawPath: string, isCliContext?: boolean): Results => {
5757
const projectCoverage = getCoverage(dirPath)
5858

5959
const addComplexityToFile = (file: ParsedFile): AnalyzedFile => {
60+
let fileContents
61+
try {
62+
if (file.shouldAnalyze) {
63+
fileContents = getFileContents(file.fullPath, options.enableFlow)
64+
}
65+
} catch (error) {
66+
console.error(
67+
`[codehawk-cli] Unable to parse "${file.path}/${file.filename}", skipping`
68+
)
69+
}
70+
6071
const complexityReport = !file.shouldAnalyze
6172
? null
6273
: analyzeFile(
6374
dirPath,
6475
{
6576
path: file.path,
6677
filename: file.filename,
67-
rawSource: getFileContents(file.fullPath, options.enableFlow),
78+
rawSource: fileContents,
6879
},
6980
projectCoverage
7081
)

0 commit comments

Comments
 (0)