@produtype/core 0.25.1 → 0.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -596,7 +596,7 @@ async function analyzeProject(projectPath) {
|
|
|
596
596
|
|| w.packageManager !== 'unknown');
|
|
597
597
|
const ctx = {
|
|
598
598
|
root,
|
|
599
|
-
files: { all: allFiles, source: sourceFiles, config: configFiles },
|
|
599
|
+
files: { all: allFiles, source: sourceFiles, config: configFiles, unreadable: unreadableLanguages(allFiles) },
|
|
600
600
|
packageJson,
|
|
601
601
|
pythonDeps,
|
|
602
602
|
phpDeps: unique(phpDeps),
|
|
@@ -704,6 +704,7 @@ async function analyzeProject(projectPath) {
|
|
|
704
704
|
pythonDeps,
|
|
705
705
|
workspaceStacks,
|
|
706
706
|
files: {
|
|
707
|
+
unreadable: unreadableLanguages(allFiles),
|
|
707
708
|
all: allFiles,
|
|
708
709
|
source: sourceFiles,
|
|
709
710
|
config: configFiles,
|
package/dist/analyzer/types.d.ts
CHANGED
|
@@ -86,6 +86,19 @@ export interface ProjectFiles {
|
|
|
86
86
|
source: string[];
|
|
87
87
|
/** Config files. */
|
|
88
88
|
config: string[];
|
|
89
|
+
/**
|
|
90
|
+
* Files in languages nothing here can read, counted by language.
|
|
91
|
+
*
|
|
92
|
+
* The warning built from this has existed for a while and said the right thing —
|
|
93
|
+
* "1257 Elixir files were not analysed: this reading covers only part of the
|
|
94
|
+
* repository" — while the same report named a profile with high confidence and scored
|
|
95
|
+
* it 85. Exposing the count rather than only the sentence lets the reading take its
|
|
96
|
+
* own warning into account instead of printing it beside a verdict that ignores it.
|
|
97
|
+
*/
|
|
98
|
+
unreadable: Array<{
|
|
99
|
+
language: string;
|
|
100
|
+
files: number;
|
|
101
|
+
}>;
|
|
89
102
|
}
|
|
90
103
|
export interface PackageJson {
|
|
91
104
|
name?: string;
|
|
@@ -169,7 +169,26 @@ function buildReport(analysis, options) {
|
|
|
169
169
|
*/
|
|
170
170
|
const tooLittleAssessed = requestedProfile !== 'observed-only'
|
|
171
171
|
&& assessedChecks < score_1.MIN_ASSESSED_FOR_A_READING;
|
|
172
|
-
|
|
172
|
+
/**
|
|
173
|
+
* The report reads its own warning.
|
|
174
|
+
*
|
|
175
|
+
* Plausible is a Phoenix application: 1257 Elixir files and 215 of JavaScript around
|
|
176
|
+
* them. The analyzer said so — "1257 Elixir files were not analysed: this reading
|
|
177
|
+
* covers only part of the repository" — and in the same report called it a client
|
|
178
|
+
* application, with high confidence, scored 85 and not inconclusive. A warning printed
|
|
179
|
+
* beside a verdict that ignores it is not a warning.
|
|
180
|
+
*
|
|
181
|
+
* The test is which part is bigger. Where the languages nothing here can read
|
|
182
|
+
* outnumber the files it did read, the reading rests on a minority of the repository
|
|
183
|
+
* and cannot characterise it — whatever those remaining files happen to look like. A
|
|
184
|
+
* game with a handful of C++ files beside its TypeScript is unaffected, which is the
|
|
185
|
+
* shape this must not break: not one of the seventy-eight repositories on the machine
|
|
186
|
+
* this was written on crosses the line, and the first public repository that did was
|
|
187
|
+
* the sixth one tried.
|
|
188
|
+
*/
|
|
189
|
+
const unreadableFiles = analysis.files.unreadable.reduce((total, entry) => total + entry.files, 0);
|
|
190
|
+
const mostlyUnreadable = unreadableFiles > analysis.files.source.length;
|
|
191
|
+
const inconclusive = nothingIdentified || tooLittleAssessed || mostlyUnreadable;
|
|
173
192
|
// Each reason says which of the two it was, because they call for different things:
|
|
174
193
|
// one is a repository this analyzer cannot read, the other is one there is barely
|
|
175
194
|
// anything to read.
|
|
@@ -181,6 +200,10 @@ function buildReport(analysis, options) {
|
|
|
181
200
|
inconclusiveReasons.push('No recognizable source files were found.');
|
|
182
201
|
}
|
|
183
202
|
}
|
|
203
|
+
if (mostlyUnreadable) {
|
|
204
|
+
const [largest] = [...analysis.files.unreadable].sort((left, right) => right.files - left.files);
|
|
205
|
+
inconclusiveReasons.push(`Most of this repository is written in ${largest.language}, which this analyzer does not read: ${unreadableFiles} of its files were skipped and ${analysis.files.source.length} were read.`);
|
|
206
|
+
}
|
|
184
207
|
if (tooLittleAssessed) {
|
|
185
208
|
inconclusiveReasons.push(`Only ${assessedChecks} check${assessedChecks === 1 ? '' : 's'} reached a verdict, which is too few to characterise this project.`);
|
|
186
209
|
}
|
|
@@ -261,6 +284,7 @@ function buildReport(analysis, options) {
|
|
|
261
284
|
observedScore,
|
|
262
285
|
overallScore,
|
|
263
286
|
inconclusive,
|
|
287
|
+
inconclusiveReasons,
|
|
264
288
|
});
|
|
265
289
|
const expectationMode = determineExpectationMode(requestedProfile, productProfile, expectationScore);
|
|
266
290
|
const diagnostics = {
|
|
@@ -23,4 +23,6 @@ export declare function buildExecutiveSummary(args: {
|
|
|
23
23
|
observedScore: number;
|
|
24
24
|
overallScore: number;
|
|
25
25
|
inconclusive: boolean;
|
|
26
|
+
/** Why, when the report could not form a reading. Named in the verdict. */
|
|
27
|
+
inconclusiveReasons?: string[];
|
|
26
28
|
}): ExecutiveSummary;
|
|
@@ -109,8 +109,19 @@ function estimateEffort(findings, profile) {
|
|
|
109
109
|
}
|
|
110
110
|
function buildVerdict(args) {
|
|
111
111
|
if (args.inconclusive) {
|
|
112
|
+
/**
|
|
113
|
+
* The reason, where there is one worth giving.
|
|
114
|
+
*
|
|
115
|
+
* "Check that the path points at application source" is right for a directory with
|
|
116
|
+
* nothing in it and wrong for a Phoenix application: the path was fine, the language
|
|
117
|
+
* is one this analyzer does not read, and telling its author to check their path
|
|
118
|
+
* sends them looking for a mistake they did not make.
|
|
119
|
+
*/
|
|
120
|
+
const [reason] = args.inconclusiveReasons;
|
|
112
121
|
return {
|
|
113
|
-
verdict:
|
|
122
|
+
verdict: reason
|
|
123
|
+
? `ProdKit could not judge this project. ${reason}`
|
|
124
|
+
: 'ProdKit could not recognise this project well enough to judge it. Check that the path points at application source.',
|
|
114
125
|
launchReady: false,
|
|
115
126
|
};
|
|
116
127
|
}
|
|
@@ -172,6 +183,7 @@ function buildExecutiveSummary(args) {
|
|
|
172
183
|
profile: args.profile,
|
|
173
184
|
maturity: args.maturity,
|
|
174
185
|
inconclusive: args.inconclusive,
|
|
186
|
+
inconclusiveReasons: args.inconclusiveReasons ?? [],
|
|
175
187
|
});
|
|
176
188
|
const topRisks = (0, categoryScores_1.weakestCategories)(args.categoryScores).map((entry) => {
|
|
177
189
|
const label = CATEGORY_LABEL[entry.category];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@produtype/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.26.0",
|
|
4
4
|
"description": "Deterministic CLI and library that analyzes a web application repository and reports how far it is from production-ready for the kind of product it is meant to be.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"bin": {
|