Skip to content

Commit ae8e86d

Browse files
jeeyojeeyoencX
authored
Add jscpd (#152)
* add jscpd report support * fix jscpd issues not reported * fix comment typo * fix test case * add multi-line comments support * remove octokit logging * go * fix styling * fix styling * remove local debugging * Apply suggestions from code review Co-authored-by: Plai <[email protected]> * apply suggestions to test --------- Co-authored-by: jeeyo <[email protected]> Co-authored-by: Plai <[email protected]>
1 parent 23909bc commit ae8e86d

26 files changed

+1050
-262
lines changed

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ So it can be integrated with any CI with ease.
2323
- DartLint
2424
- SwiftLint (0.49.1 or later)
2525

26+
#### Supported code duplication detectors.
27+
- jscpd
28+
2629
#### Supported source controls
2730
- GitHub
2831
- GitHub Enterprise

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"node": ">=14.0.0"
2727
},
2828
"devDependencies": {
29+
"@jscpd/finder": "^3.5.5",
2930
"@octokit/types": "^6.34.0",
3031
"@types/jest": "^26.0.18",
3132
"@types/js-yaml": "^4.0.0",
@@ -45,7 +46,7 @@
4546
"typescript": "^4.1.2"
4647
},
4748
"dependencies": {
48-
"@gitbeaker/node": "^35.7.0",
49+
"@gitbeaker/rest": "^39.10.2",
4950
"@octokit/core": "^3.2.4",
5051
"@octokit/rest": "^18.12.0",
5152
"rimraf": "^3.0.2",

sample/jscpd/jscpd-report.json

+337
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,337 @@
1+
{
2+
"statistics": {
3+
"detectionDate": "2023-07-21T10:00:47.817Z",
4+
"formats": {
5+
"csharp": {
6+
"sources": {
7+
"/Users/codecoach/myproject/src/WebApi/Startuping/ALoader.cs": {
8+
"lines": 10,
9+
"tokens": 68,
10+
"sources": 1,
11+
"clones": 0,
12+
"duplicatedLines": 0,
13+
"duplicatedTokens": 0,
14+
"percentage": 0,
15+
"percentageTokens": 0,
16+
"newDuplicatedLines": 0,
17+
"newClones": 0
18+
},
19+
"/Users/codecoach/myproject/src/WebApi/Services/BService.cs": {
20+
"lines": 58,
21+
"tokens": 450,
22+
"sources": 1,
23+
"clones": 0,
24+
"duplicatedLines": 0,
25+
"duplicatedTokens": 0,
26+
"percentage": 0,
27+
"percentageTokens": 0,
28+
"newDuplicatedLines": 0,
29+
"newClones": 0
30+
},
31+
"/Users/codecoach/myproject/src/WebApi/Services/CService.cs": {
32+
"lines": 27,
33+
"tokens": 252,
34+
"sources": 1,
35+
"clones": 0,
36+
"duplicatedLines": 0,
37+
"duplicatedTokens": 0,
38+
"percentage": 0,
39+
"percentageTokens": 0,
40+
"newDuplicatedLines": 0,
41+
"newClones": 0
42+
},
43+
"/Users/codecoach/myproject/src/WebApi/Services/DService.cs": {
44+
"lines": 35,
45+
"tokens": 342,
46+
"sources": 1,
47+
"clones": 0,
48+
"duplicatedLines": 0,
49+
"duplicatedTokens": 0,
50+
"percentage": 0,
51+
"percentageTokens": 0,
52+
"newDuplicatedLines": 0,
53+
"newClones": 0
54+
},
55+
"/Users/codecoach/myproject/src/WebApi/Services/EService.cs": {
56+
"lines": 84,
57+
"tokens": 742,
58+
"sources": 1,
59+
"clones": 0,
60+
"duplicatedLines": 0,
61+
"duplicatedTokens": 0,
62+
"percentage": 0,
63+
"percentageTokens": 0,
64+
"newDuplicatedLines": 0,
65+
"newClones": 0
66+
},
67+
"/Users/codecoach/myproject/src/WebApi/Services/FService.cs": {
68+
"lines": 35,
69+
"tokens": 342,
70+
"sources": 1,
71+
"clones": 0,
72+
"duplicatedLines": 0,
73+
"duplicatedTokens": 0,
74+
"percentage": 0,
75+
"percentageTokens": 0,
76+
"newDuplicatedLines": 0,
77+
"newClones": 0
78+
},
79+
"/Users/codecoach/myproject/src/WebApi/Controllers/GController.cs": {
80+
"lines": 46,
81+
"tokens": 391,
82+
"sources": 1,
83+
"clones": 2,
84+
"duplicatedLines": 20,
85+
"duplicatedTokens": 187,
86+
"percentage": 43.48,
87+
"percentageTokens": 47.83,
88+
"newDuplicatedLines": 0,
89+
"newClones": 0
90+
},
91+
"/Users/codecoach/myproject/src/WebApi/Controllers/HController.cs": {
92+
"lines": 40,
93+
"tokens": 342,
94+
"sources": 1,
95+
"clones": 1,
96+
"duplicatedLines": 10,
97+
"duplicatedTokens": 92,
98+
"percentage": 25,
99+
"percentageTokens": 26.9,
100+
"newDuplicatedLines": 0,
101+
"newClones": 0
102+
},
103+
"/Users/codecoach/myproject/src/WebApi/Controllers/IController.cs": {
104+
"lines": 77,
105+
"tokens": 730,
106+
"sources": 1,
107+
"clones": 0,
108+
"duplicatedLines": 0,
109+
"duplicatedTokens": 0,
110+
"percentage": 0,
111+
"percentageTokens": 0,
112+
"newDuplicatedLines": 0,
113+
"newClones": 0
114+
},
115+
"/Users/codecoach/myproject/src/WebApi/Controllers/JController.cs": {
116+
"lines": 26,
117+
"tokens": 217,
118+
"sources": 1,
119+
"clones": 0,
120+
"duplicatedLines": 0,
121+
"duplicatedTokens": 0,
122+
"percentage": 0,
123+
"percentageTokens": 0,
124+
"newDuplicatedLines": 0,
125+
"newClones": 0
126+
},
127+
"/Users/codecoach/myproject/src/WebApi/Controllers/KController.cs": {
128+
"lines": 34,
129+
"tokens": 288,
130+
"sources": 1,
131+
"clones": 0,
132+
"duplicatedLines": 0,
133+
"duplicatedTokens": 0,
134+
"percentage": 0,
135+
"percentageTokens": 0,
136+
"newDuplicatedLines": 0,
137+
"newClones": 0
138+
},
139+
"/Users/codecoach/myproject/src/WebApi/Controllers/LController.cs": {
140+
"lines": 38,
141+
"tokens": 294,
142+
"sources": 1,
143+
"clones": 0,
144+
"duplicatedLines": 0,
145+
"duplicatedTokens": 0,
146+
"percentage": 0,
147+
"percentageTokens": 0,
148+
"newDuplicatedLines": 0,
149+
"newClones": 0
150+
},
151+
"/Users/codecoach/myproject/src/WebApi/Controllers/MController.cs": {
152+
"lines": 44,
153+
"tokens": 394,
154+
"sources": 1,
155+
"clones": 2,
156+
"duplicatedLines": 17,
157+
"duplicatedTokens": 166,
158+
"percentage": 38.64,
159+
"percentageTokens": 42.13,
160+
"newDuplicatedLines": 0,
161+
"newClones": 0
162+
},
163+
"/Users/codecoach/myproject/src/WebApi/Controllers/NController.cs": {
164+
"lines": 51,
165+
"tokens": 445,
166+
"sources": 1,
167+
"clones": 1,
168+
"duplicatedLines": 7,
169+
"duplicatedTokens": 71,
170+
"percentage": 13.73,
171+
"percentageTokens": 15.96,
172+
"newDuplicatedLines": 0,
173+
"newClones": 0
174+
},
175+
"/Users/codecoach/myproject/src/WebApi/Controllers/OController.cs": {
176+
"lines": 26,
177+
"tokens": 230,
178+
"sources": 1,
179+
"clones": 0,
180+
"duplicatedLines": 0,
181+
"duplicatedTokens": 0,
182+
"percentage": 0,
183+
"percentageTokens": 0,
184+
"newDuplicatedLines": 0,
185+
"newClones": 0
186+
},
187+
"/Users/codecoach/myproject/src/WebApi/Program.cs": {
188+
"lines": 144,
189+
"tokens": 1338,
190+
"sources": 1,
191+
"clones": 0,
192+
"duplicatedLines": 0,
193+
"duplicatedTokens": 0,
194+
"percentage": 0,
195+
"percentageTokens": 0,
196+
"newDuplicatedLines": 0,
197+
"newClones": 0
198+
}
199+
},
200+
"total": {
201+
"lines": 775,
202+
"tokens": 6865,
203+
"sources": 16,
204+
"clones": 3,
205+
"duplicatedLines": 27,
206+
"duplicatedTokens": 258,
207+
"percentage": 3.48,
208+
"percentageTokens": 3.76,
209+
"newDuplicatedLines": 0,
210+
"newClones": 0
211+
}
212+
}
213+
},
214+
"total": {
215+
"lines": 775,
216+
"tokens": 6865,
217+
"sources": 16,
218+
"clones": 3,
219+
"duplicatedLines": 27,
220+
"duplicatedTokens": 258,
221+
"percentage": 3.48,
222+
"percentageTokens": 3.76,
223+
"newDuplicatedLines": 0,
224+
"newClones": 0
225+
}
226+
},
227+
"duplicates": [
228+
{
229+
"format": "csharp",
230+
"lines": 11,
231+
"fragment": "using System.Threading.Tasks;\r\nusing Core.Models;\r\nusing Core.Services;\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Nelibur.ObjectMapper;\r\nusing Swashbuckle.AspNetCore.Annotations;\r\n\r\nnamespace WebApi.Controllers;\r\n\r\n[",
232+
"tokens": 0,
233+
"firstFile": {
234+
"name": "src/WebApi/Controllers/HController.cs",
235+
"start": 1,
236+
"end": 11,
237+
"startLoc": {
238+
"line": 1,
239+
"column": 2,
240+
"position": 1
241+
},
242+
"endLoc": {
243+
"line": 11,
244+
"column": 2,
245+
"position": 93
246+
}
247+
},
248+
"secondFile": {
249+
"name": "src/WebApi/Controllers/GController.cs",
250+
"start": 1,
251+
"end": 11,
252+
"startLoc": {
253+
"line": 1,
254+
"column": 1,
255+
"position": 0
256+
},
257+
"endLoc": {
258+
"line": 11,
259+
"column": 14,
260+
"position": 92
261+
}
262+
}
263+
},
264+
{
265+
"format": "csharp",
266+
"lines": 11,
267+
"fragment": "using System.Threading.Tasks;\r\nusing Core.Models;\r\nusing Core.Services;\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Nelibur.ObjectMapper;\r\nusing Swashbuckle.AspNetCore.Annotations;\r\n\r\nnamespace WebApi.Controllers;\r\n\r\n[Route(\"gradletalaiot\"",
268+
"tokens": 0,
269+
"firstFile": {
270+
"name": "src/WebApi/Controllers/MController.cs",
271+
"start": 2,
272+
"end": 12,
273+
"startLoc": {
274+
"line": 2,
275+
"column": 1,
276+
"position": 6
277+
},
278+
"endLoc": {
279+
"line": 12,
280+
"column": 16,
281+
"position": 101
282+
}
283+
},
284+
"secondFile": {
285+
"name": "src/WebApi/Controllers/GController.cs",
286+
"start": 1,
287+
"end": 11,
288+
"startLoc": {
289+
"line": 1,
290+
"column": 1,
291+
"position": 0
292+
},
293+
"endLoc": {
294+
"line": 11,
295+
"column": 7,
296+
"position": 96
297+
}
298+
}
299+
},
300+
{
301+
"format": "csharp",
302+
"lines": 8,
303+
"fragment": ";\r\nusing System.Threading.Tasks;\r\nusing Core.Models;\r\nusing Core.Services;\r\nusing Microsoft.AspNetCore.Mvc;\r\nusing Nelibur.ObjectMapper;\r\nusing Serilog",
304+
"tokens": 0,
305+
"firstFile": {
306+
"name": "src/WebApi/Controllers/NController.cs",
307+
"start": 2,
308+
"end": 9,
309+
"startLoc": {
310+
"line": 2,
311+
"column": 5,
312+
"position": 15
313+
},
314+
"endLoc": {
315+
"line": 9,
316+
"column": 8,
317+
"position": 86
318+
}
319+
},
320+
"secondFile": {
321+
"name": "src/WebApi/Controllers/MController.cs",
322+
"start": 1,
323+
"end": 8,
324+
"startLoc": {
325+
"line": 1,
326+
"column": 7,
327+
"position": 3
328+
},
329+
"endLoc": {
330+
"line": 8,
331+
"column": 12,
332+
"position": 74
333+
}
334+
}
335+
}
336+
]
337+
}

src/AnalyzerBot/@types/CommentTypes.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
export interface Comment {
22
file: string;
33
line: number;
4+
nLines?: number;
45
text: string;
56
errors: number;
67
warnings: number;

src/AnalyzerBot/AnalyzerBot.spec.ts

+2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ describe('AnalyzerBot', () => {
3535
{
3636
file: mockTouchFile,
3737
line: file1TouchLine,
38+
nLines: 1,
3839
text:
3940
MessageUtil.createMessageWithEmoji(
4041
touchFileError.msg,
@@ -47,6 +48,7 @@ describe('AnalyzerBot', () => {
4748
{
4849
file: mockTouchFile,
4950
line: file2TouchLine,
51+
nLines: 2,
5052
text:
5153
MessageUtil.createMessageWithEmoji(
5254
touchFileWarning.msg,

0 commit comments

Comments
 (0)