@produtype/core 0.92.0 → 0.94.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.
@@ -161,18 +161,48 @@ function parsePyprojectSections(text, runtimeOnly) {
161
161
  * Everything after `src/main/java` is a package name, not a project layout.
162
162
  *
163
163
  * spring-petclinic lives in `org.springframework.samples.petclinic`, so every one of
164
- * its thirty Java files sits under a path segment called `samples` and the rule that
165
- * removes sample code removed the whole application. The report saw a project with no
166
- * Java in it at all: twelve files, an HTML front end, no backend, and a profile of
167
- * `client-app` at high confidence for a Spring Boot server.
164
+ * its thirty Java files sat under a path segment called `samples`, and the rule that
165
+ * removes sample code removed the whole application: twelve files, an HTML front end,
166
+ * no backend, and `client-app` at high confidence for a Spring Boot server.
168
167
  *
169
- * Maven and Gradle both fix that prefix, so the segments after it are the author's
170
- * package and mean nothing about the layout. A real sample directory sits beside
171
- * `src`, not inside its source rootktor-documentation keeps its under
172
- * `codeSnippets/snippets/`, which this still removes.
168
+ * It was not only `samples`. `spring-test/src/main/java/org/springframework/mock/`
169
+ * holds forty-four files `MockHttpServletRequest` and its neighbours, shipped in the
170
+ * jar and the whole point of that module and the rule that removes `mocks/` removed
171
+ * every one of them. A package can be called anything: `vendor`, `testing`, `fixtures`
172
+ * are all ordinary domain words.
173
+ *
174
+ * Maven and Gradle fix the `src/main/<language>` prefix, so directory rules are
175
+ * applied to the path *up to* it and never to the package below.
176
+ *
177
+ * Only `main` is named, and that is a statement of intent rather than a rule doing
178
+ * work: `src/test/java/...` stays excluded either way, because the boundary itself
179
+ * contains `test` and the directory rule matches it. Writing `main|test` here fails
180
+ * no test, which is worth saying instead of implying a protection that is not there.
181
+ */
182
+ const JVM_MAIN_SOURCE_ROOT = /(^|\/)src\/main\/(java|kotlin|scala|groovy)\//;
183
+ /** The part of the path that describes layout rather than package. */
184
+ function layoutPartOf(file) {
185
+ const root = JVM_MAIN_SOURCE_ROOT.exec(file);
186
+ return root ? file.slice(0, root.index + root[0].length) : file;
187
+ }
188
+ /**
189
+ * Go names its tests by file, never by directory.
190
+ *
191
+ * `_test.go` is the suffix the toolchain compiles separately; a directory called
192
+ * `mock`, `testing` or `fixtures` is just a package. testify's own `mock/mock.go` —
193
+ * half of what that library is for — was removed by the rule that drops `mocks/`, and
194
+ * the analyzer saw 38 of its Go files with the two biggest missing.
195
+ *
196
+ * One directory convention is left here, and it is the toolchain's: a directory whose
197
+ * name begins with `_` or `.` is skipped when building, which is why testify keeps
198
+ * `_codegen` and `_readme-gofmt` under those names.
199
+ *
200
+ * `vendor/` and `testdata/` are not repeated: the file scanner never hands them over
201
+ * in the first place. Both were written here and both survived being deleted in a
202
+ * mutation run, which is how the duplication came to light.
173
203
  */
174
- function isAPackageName(file) {
175
- return /(^|\/)src\/(main|test)\/(java|kotlin|scala|groovy)\//.test(file);
204
+ function isGoToolchainExclusion(file) {
205
+ return /(^|\/)[_.][^/]+\//.test(file);
176
206
  }
177
207
  function isTestOrExamplePath(file) {
178
208
  // `__mocks__` was missing, and a mock is the most misleading file in a repository:
@@ -181,7 +211,14 @@ function isTestOrExamplePath(file) {
181
211
  // `fixtures` was listed and `fixture` was not, so `extra/fixture/authsources.php`
182
212
  // made PHP one of the languages of an Elixir analytics product — and of cal.com,
183
213
  // which is TypeScript.
184
- return /(^|\/)(__tests__|__mocks__|mocks?|tests?|test-data|fixtures?|frontend-example)(\/|$)/i.test(file)
214
+ /**
215
+ * A Go file answers to Go's conventions and to none of the directory rules below:
216
+ * every one of those names is a package name there.
217
+ */
218
+ if (/\.go$/.test(file))
219
+ return isGoToolchainExclusion(file) || /_test\.go$/.test(file);
220
+ const layout = layoutPartOf(file);
221
+ return /(^|\/)(__tests__|__mocks__|mocks?|tests?|test-data|fixtures?|frontend-example)(\/|$)/i.test(layout)
185
222
  /**
186
223
  * The conventions other ecosystems use, which this list did not know.
187
224
  *
@@ -192,7 +229,7 @@ function isTestOrExamplePath(file) {
192
229
  * would have parsed the same files and reached the same wrong conclusion, which is
193
230
  * the argument for fixing what gets read before fixing how.
194
231
  */
195
- || /(^|\/)(spec|specs|e2e|integration-tests?|cypress|playwright|testing)(\/|$)/i.test(file)
232
+ || /(^|\/)(spec|specs|e2e|integration-tests?|cypress|playwright|testing)(\/|$)/i.test(layout)
196
233
  || /\.(e2e|e2e-spec|cy|stories)\.(ts|tsx|js|jsx|mjs|cjs)$/i.test(file)
197
234
  || /_spec\.rb$/i.test(file)
198
235
  || /_test\.(go|py|rb|java|cs|php)$/i.test(file)
@@ -236,7 +273,7 @@ function isTestOrExamplePath(file) {
236
273
  * spell it. A repository whose every source file is a sample now has no source
237
274
  * files, and says so — which is the honest answer for one.
238
275
  */
239
- || (/(^|\/)(samples?|snippets?|codesnippets)(\/|$)/i.test(file) && !isAPackageName(file))
276
+ || /(^|\/)(samples?|snippets?|codesnippets)(\/|$)/i.test(layout)
240
277
  /**
241
278
  * Somebody else's code, vendored in.
242
279
  *
@@ -245,7 +282,7 @@ function isTestOrExamplePath(file) {
245
282
  * crate copied in whole. A manifest under a vendor directory is a statement about
246
283
  * that library, not about this product.
247
284
  */
248
- || /(^|\/)(vendor|vendored|third[-_]?party|external[-_]crates)(\/|$)/i.test(file);
285
+ || /(^|\/)(vendor|vendored|third[-_]?party|external[-_]crates)(\/|$)/i.test(layout);
249
286
  }
250
287
  /**
251
288
  * Extensions the detectors can read.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.92.0",
3
+ "version": "0.94.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": {