@produtype/core 0.68.0 → 0.69.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.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The lines of a Python file that are a docstring rather than code.
3
+ *
4
+ * This analyzer has skipped comments since the day it read its own prose about Stripe
5
+ * as evidence that it takes payments. The rule looks for a line marker — `#`, `//`,
6
+ * `/*`, `<!--` — and Python's main way of writing prose has none: a docstring is a
7
+ * string, and its interior lines begin with whatever the author was saying.
8
+ *
9
+ * Measured across the corpus: 118 of 1587 citations from Python files land inside
10
+ * one. `/api/auth/... registrazione + JWT` was cited as evidence of an
11
+ * authentication route; `Chi arriva col link (?k=...) si vede posare un cookie` as
12
+ * evidence about cookies. Sentences describing the code, offered as the code.
13
+ *
14
+ * Only a block that stands on its own. `QUERY = """SELECT ..."""` is data assigned to
15
+ * a name and a hardcoded secret could live in one, so a triple-quoted string on the
16
+ * right of an assignment stays readable. A docstring is an expression statement and
17
+ * has nothing before it but indentation.
18
+ */
19
+ export declare function proseLines(file: string, text: string): Set<number>;
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.proseLines = proseLines;
4
+ /**
5
+ * The lines of a Python file that are a docstring rather than code.
6
+ *
7
+ * This analyzer has skipped comments since the day it read its own prose about Stripe
8
+ * as evidence that it takes payments. The rule looks for a line marker — `#`, `//`,
9
+ * `/*`, `<!--` — and Python's main way of writing prose has none: a docstring is a
10
+ * string, and its interior lines begin with whatever the author was saying.
11
+ *
12
+ * Measured across the corpus: 118 of 1587 citations from Python files land inside
13
+ * one. `/api/auth/... registrazione + JWT` was cited as evidence of an
14
+ * authentication route; `Chi arriva col link (?k=...) si vede posare un cookie` as
15
+ * evidence about cookies. Sentences describing the code, offered as the code.
16
+ *
17
+ * Only a block that stands on its own. `QUERY = """SELECT ..."""` is data assigned to
18
+ * a name and a hardcoded secret could live in one, so a triple-quoted string on the
19
+ * right of an assignment stays readable. A docstring is an expression statement and
20
+ * has nothing before it but indentation.
21
+ */
22
+ function proseLines(file, text) {
23
+ const prose = new Set();
24
+ if (!/\.py$/i.test(file))
25
+ return prose;
26
+ const lines = text.split(/\r?\n/);
27
+ let openQuote = null;
28
+ let openIsProse = false;
29
+ for (let i = 0; i < lines.length; i++) {
30
+ const line = lines[i];
31
+ if (openQuote) {
32
+ if (openIsProse)
33
+ prose.add(i + 1);
34
+ if (line.includes(openQuote)) {
35
+ openQuote = null;
36
+ openIsProse = false;
37
+ }
38
+ continue;
39
+ }
40
+ const match = /("""|''')/.exec(line);
41
+ if (!match)
42
+ continue;
43
+ const before = line.slice(0, match.index);
44
+ /** An expression statement: nothing before the quotes but whitespace. */
45
+ const standsAlone = /^\s*[rRbBuUfF]*$/.test(before);
46
+ const rest = line.slice(match.index + 3);
47
+ const closesOnThisLine = rest.includes(match[1]);
48
+ if (standsAlone)
49
+ prose.add(i + 1);
50
+ if (closesOnThisLine)
51
+ continue;
52
+ openQuote = match[1];
53
+ openIsProse = standsAlone;
54
+ }
55
+ return prose;
56
+ }
@@ -6,6 +6,7 @@ exports.searchInFiles = searchInFiles;
6
6
  exports.anyIncludes = anyIncludes;
7
7
  const readTextFileSafe_1 = require("./readTextFileSafe");
8
8
  const developmentOnly_1 = require("../analyzer/developmentOnly");
9
+ const proseLines_1 = require("../analyzer/proseLines");
9
10
  /**
10
11
  * A line that declares a pattern rather than doing anything.
11
12
  *
@@ -103,9 +104,11 @@ function matchLines(text, needles, file = '') {
103
104
  * fixture of a test asserting the wrong secret is rejected.
104
105
  */
105
106
  const testOnly = (0, developmentOnly_1.testOnlyLines)(file, text);
107
+ /** A Python docstring is prose with no line marker to recognise it by. */
108
+ const prose = (0, proseLines_1.proseLines)(file, text);
106
109
  for (let i = 0; i < lines.length; i++) {
107
110
  const line = lines[i];
108
- if (testOnly.has(i + 1))
111
+ if (testOnly.has(i + 1) || prose.has(i + 1))
109
112
  continue;
110
113
  if (line.length > MAX_CITABLE_LINE)
111
114
  continue;
@@ -135,9 +138,10 @@ async function searchInFiles(root, files, needles, limit = 25) {
135
138
  continue;
136
139
  const lines = text.split(/\r?\n/);
137
140
  const testOnly = (0, developmentOnly_1.testOnlyLines)(file, text);
141
+ const prose = (0, proseLines_1.proseLines)(file, text);
138
142
  for (let i = 0; i < lines.length; i++) {
139
143
  const line = lines[i];
140
- if (testOnly.has(i + 1))
144
+ if (testOnly.has(i + 1) || prose.has(i + 1))
141
145
  continue;
142
146
  if (line.length > MAX_CITABLE_LINE)
143
147
  continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@produtype/core",
3
- "version": "0.68.0",
3
+ "version": "0.69.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": {