@filipebraida/adonis-function-points 0.3.0 → 0.5.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.
- package/CHANGELOG.md +113 -0
- package/README.md +17 -6
- package/build/commands/main.js +6 -6
- package/build/{fp_calibrate-iFAec0tA.js → fp_calibrate-DUbHiifm.js} +1 -1
- package/build/{fp_count-D21tQ_pv.js → fp_count-ChtblhZV.js} +1 -1
- package/build/{fp_diff-D0pHGMgi.js → fp_diff-Dt7J4IWu.js} +1 -1
- package/build/{fp_explain-BwFs-LW-.js → fp_explain-DZJ--0-S.js} +1 -1
- package/build/{fp_inventory-Bu6O1Nn0.js → fp_inventory-CPtmuuke.js} +1 -1
- package/build/{fp_metrics-MGDppfSa.js → fp_metrics-et8F1Wvt.js} +1 -1
- package/build/index.js +2 -2
- package/build/{pipeline-CIAydCcT.js → pipeline-CNTBhs6o.js} +442 -79
- package/build/{resolvers-CRB6lXoo.js → resolvers-PJwo2Z8R.js} +64 -1
- package/build/{runners-CmxNHuuq.js → runners-DIt1G85i.js} +19 -4
- package/build/src/albrecht/counter.d.ts +1 -1
- package/build/src/albrecht/transactional_functions.d.ts +9 -0
- package/build/src/cli.js +2 -2
- package/build/src/define_config.d.ts +26 -1
- package/build/src/inventory/graph/call_graph.d.ts +10 -0
- package/build/src/inventory/paths.d.ts +18 -0
- package/build/src/inventory/resolvers/index.d.ts +7 -0
- package/build/src/inventory/resolvers/index.js +2 -2
- package/build/src/inventory/resolvers/types.d.ts +19 -0
- package/build/src/inventory/source.d.ts +8 -1
- package/build/src/pipeline.js +1 -1
- package/build/src/types.d.ts +2 -0
- package/build/stubs/config.stub +7 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,119 @@ release moves the number for unchanged code, the rule set version moves with it
|
|
|
6
6
|
otherwise the difference would measure the tool's change rather than the work, and
|
|
7
7
|
that difference becomes an invoice.
|
|
8
8
|
|
|
9
|
+
## 0.5.0
|
|
10
|
+
|
|
11
|
+
**Rule set `afp@1.4.0`.** Two classification defects are fixed and both move numbers,
|
|
12
|
+
so a 0.4.0 baseline has to be recounted.
|
|
13
|
+
|
|
14
|
+
Found by auditing a production count function by function against the code, rather than
|
|
15
|
+
by reading the report's warnings — which is where the previous rounds had been looking.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Maintenance was decided per REQUEST instead of per store.** `behavior.writes`
|
|
20
|
+
decides EI against EO and was also read as "this store is maintained", so every store
|
|
21
|
+
a writing transaction touched became an ILF. A reference table merely READ by a route
|
|
22
|
+
that writes something else counted as maintained. On a production application this
|
|
23
|
+
left exactly one EIF in the whole count, which should have been the signal.
|
|
24
|
+
- **Seeders, tests and factories counted as maintenance.** The project-wide pass read a
|
|
25
|
+
seeder's inserts as the application maintaining a table, so reference data only the
|
|
26
|
+
seed populates came out as an ILF — which the CPM does not allow. The filter on scan
|
|
27
|
+
roots drops `tests/` and `database/` only at the ROOT, and a domain-module layout puts
|
|
28
|
+
both inside `app/`. It now applies at any depth.
|
|
29
|
+
- **The override warning counted floors that were already answered**, said "one schema"
|
|
30
|
+
whatever it was given, and therefore fired on a configuration that was complete.
|
|
31
|
+
- **`opaqueReviewed` matching nothing was silent.** `detFromSchema` already warns when
|
|
32
|
+
it names a schema that is not declared; a review naming a field that does not exist
|
|
33
|
+
reviewed nothing while the warning kept firing, which reads as the tool ignoring the
|
|
34
|
+
configuration.
|
|
35
|
+
- **A review was invisible in `fp:explain`.** Its reason appeared nowhere, which defeats
|
|
36
|
+
requiring one. Reviewed floors are now marked `(opaque, reviewed)` and the reason is
|
|
37
|
+
printed — without being counted in the "Declared by override" share, since a review
|
|
38
|
+
declares no number.
|
|
39
|
+
|
|
40
|
+
### Documented
|
|
41
|
+
|
|
42
|
+
- **In CI, prefer the standalone binary.** `node ace` validates `start/env.ts` before
|
|
43
|
+
running any command, so `node ace fp:count` fails on a missing environment variable
|
|
44
|
+
that has nothing to do with counting — measured on a production application, it
|
|
45
|
+
stopped at `Missing environment variable "AUTHZ_STORE"` and never reached the
|
|
46
|
+
command. The `fp:*` commands declare `startApp: false`, which is not enough. The
|
|
47
|
+
README said the two front-ends were interchangeable; for a pipeline that only checks
|
|
48
|
+
out code, they are not.
|
|
49
|
+
|
|
50
|
+
### New
|
|
51
|
+
|
|
52
|
+
- **`CallResolver.technicalWrite()`** declares that a write is not what the transaction
|
|
53
|
+
is for. §6.5.3 reads any write as an EI, which misreads a screen that records the
|
|
54
|
+
visit; the CPM asks about primary intent. The fact is declared about the CALL, so a
|
|
55
|
+
bookkeeping helper called from several screens is declared once. It does not hide the
|
|
56
|
+
write: the store stays an ILF and stays an FTR.
|
|
57
|
+
- **`boundary.business` says when it contradicts the code.** It accepted without comment
|
|
58
|
+
a table nothing in the application writes — which is how two read-only lookup tables
|
|
59
|
+
were declared as business data on the belief they had a CRUD, when the routes were
|
|
60
|
+
`.only(['index', 'show'])`. The declaration is still honoured; the fact is reported.
|
|
61
|
+
|
|
62
|
+
## 0.4.0
|
|
63
|
+
|
|
64
|
+
**Rule set `afp@1.3.0`.** Conditional validator groups now count, and a nested
|
|
65
|
+
schema is recognised however the formatter wrapped it — so a 0.3.0 baseline has to
|
|
66
|
+
be recounted.
|
|
67
|
+
|
|
68
|
+
Five items reported from real use of 0.3.0, three of them defects.
|
|
69
|
+
|
|
70
|
+
### Fixed
|
|
71
|
+
|
|
72
|
+
- **A newline decided whether a field counted.** The recogniser for a nested schema
|
|
73
|
+
was a regex over the property's source text (`/vine\.object/`), and Prettier breaks
|
|
74
|
+
a long chain across lines — `data: vine` then `.object({})` — so the regex missed
|
|
75
|
+
and the field was counted as one leaf instead of its nested ones, and never marked
|
|
76
|
+
opaque. Decided by structure now: is this literal the argument of a call named
|
|
77
|
+
`object`? The same applied to `.merge(…)` and `group.if(…)`, which had the same
|
|
78
|
+
kind of check. A count that depends on where the formatter put a newline is not a
|
|
79
|
+
measurement — the reason the implementation-scope hash strips whitespace before
|
|
80
|
+
hashing.
|
|
81
|
+
- **The list of unreadable DETs ignored the overrides that answered it.** It was
|
|
82
|
+
computed before `applyOverrides` ran, so a function whose floor `detFromSchema` had
|
|
83
|
+
already replaced still appeared under "this is a FLOOR", telling the reader to map
|
|
84
|
+
something already mapped. It caused a real misreading of a production report, by
|
|
85
|
+
the author of this code. It now runs after the overrides, is grouped by FUNCTION,
|
|
86
|
+
and states per function how many were replaced by an override, how many reviewed,
|
|
87
|
+
and how many are still unanswered — only the last being a request to do anything.
|
|
88
|
+
- **Emitted artefacts carried absolute paths.** `CountSource.app` is documented as
|
|
89
|
+
never being one, because that says where the machine keeps its files and travels
|
|
90
|
+
with every artefact sent anywhere — and the rule was applied to that one field. A
|
|
91
|
+
production count carried **858** absolute paths in its traces; an inventory
|
|
92
|
+
carried **2036** across ten fields, including the data-store `id`. Every path that
|
|
93
|
+
leaves is now relative to the application root, and the internal absolute form is
|
|
94
|
+
untouched because that is what ts-morph resolves against.
|
|
95
|
+
- **`vine.group` and `.merge()` were not read.**
|
|
96
|
+
`vine.object({}).merge(vine.group([vine.group.if(p, {…})]))` reported the whole
|
|
97
|
+
validator as an open input object: five fields counted as one, and the report said
|
|
98
|
+
they were data when they are in the code. The branches are mutually exclusive at
|
|
99
|
+
runtime and the transaction can carry any of them, so §7.2 counts their union — a
|
|
100
|
+
field two branches share counts once. The group usually lives in an unexported
|
|
101
|
+
constant beside the validator, so the reference is resolved in the validator's own
|
|
102
|
+
file rather than the caller's.
|
|
103
|
+
- **`fp:explain` matched by substring even when the exact name existed.** Asking
|
|
104
|
+
about `POST /orders/:param/submit` returned four functions, because
|
|
105
|
+
`/submit-ready` and `/submit-ready/return` contain it. An exact name now wins
|
|
106
|
+
outright; the substring search is the fallback.
|
|
107
|
+
|
|
108
|
+
### New
|
|
109
|
+
|
|
110
|
+
- **`detFromSchema` accepts a list**, unioned by leaf path. An ILF's DETs are the
|
|
111
|
+
fields the user recognises in the file, and an application with one schema per
|
|
112
|
+
template recognises all of them. Pointing at the largest and justifying it in
|
|
113
|
+
`reason` gives the same answer only while they land in the same band — reasoning
|
|
114
|
+
the configuration should not have to carry.
|
|
115
|
+
- **`overrides.<fn>.opaqueReviewed`** records that someone looked at an opaque DET
|
|
116
|
+
and decided 1 is right. 1 DET is a floor and `fp:count` says so on every run, but
|
|
117
|
+
some of those columns really are one field, and a warning that cannot be answered
|
|
118
|
+
is one the team learns to scroll past. It moves no number, it is not counted as a
|
|
119
|
+
declared override in the "Declared by override" share, and the volume reviewed is
|
|
120
|
+
still printed.
|
|
121
|
+
|
|
9
122
|
## 0.3.0
|
|
10
123
|
|
|
11
124
|
**Rule set `afp@1.2.0`.** Three counting fixes move the number for unchanged code,
|
package/README.md
CHANGED
|
@@ -13,7 +13,7 @@ node ace fp:count
|
|
|
13
13
|
|
|
14
14
|
```
|
|
15
15
|
Unadjusted count: 46 FP
|
|
16
|
-
Ruleset: afp@1.
|
|
16
|
+
Ruleset: afp@1.4.0
|
|
17
17
|
|
|
18
18
|
type n FP
|
|
19
19
|
ILF 2 14
|
|
@@ -63,11 +63,21 @@ For CI, or a one-off count on a project you do not want to touch:
|
|
|
63
63
|
npx @filipebraida/adonis-function-points count --root ./my-app
|
|
64
64
|
```
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
The engine itself boots nothing — it only reads files — and the standalone binary
|
|
67
|
+
needs no `.env`, no database, and no install inside the analysed project. The
|
|
68
|
+
`fp:*` commands declare `startApp: false` for the same reason.
|
|
69
|
+
|
|
70
|
+
**In CI, prefer the standalone binary.** Not for convenience: `node ace` validates
|
|
71
|
+
`start/env.ts` before it runs any command, so `node ace fp:count` fails on a
|
|
72
|
+
missing environment variable that has nothing to do with counting. Measured on a
|
|
73
|
+
production application, it stopped at `Missing environment variable "AUTHZ_STORE"`
|
|
74
|
+
and never reached the command. A pipeline that only checks out the code has no
|
|
75
|
+
secrets, and does not need them to count.
|
|
76
|
+
|
|
77
|
+
The standalone binary **does not replace installing**: a project that installs the
|
|
78
|
+
package keeps the `node ace fp:*` commands — which is the right front-end at a
|
|
79
|
+
developer's terminal, where the `.env` is already there — and both call the same
|
|
80
|
+
code, so they cannot disagree about a number.
|
|
71
81
|
|
|
72
82
|
```
|
|
73
83
|
adonis-function-points <command> [options]
|
|
@@ -75,6 +85,7 @@ adonis-function-points <command> [options]
|
|
|
75
85
|
count count the unadjusted function points
|
|
76
86
|
inventory the raw facts: stores, routes, tracing coverage
|
|
77
87
|
explain <name> why one function was counted that way
|
|
88
|
+
metrics density, coupling and conformance, from the same run
|
|
78
89
|
diff <previous.json> additions / modifications / deletions, and billable FP
|
|
79
90
|
calibrate <samples.csv> correction factors against a manual count
|
|
80
91
|
|
package/build/commands/main.js
CHANGED
|
@@ -14,27 +14,27 @@
|
|
|
14
14
|
const commands = [
|
|
15
15
|
{
|
|
16
16
|
commandName: "fp:inventory",
|
|
17
|
-
importer: () => import("../fp_inventory-
|
|
17
|
+
importer: () => import("../fp_inventory-CPtmuuke.js")
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
commandName: "fp:metrics",
|
|
21
|
-
importer: () => import("../fp_metrics-
|
|
21
|
+
importer: () => import("../fp_metrics-et8F1Wvt.js")
|
|
22
22
|
},
|
|
23
23
|
{
|
|
24
24
|
commandName: "fp:count",
|
|
25
|
-
importer: () => import("../fp_count-
|
|
25
|
+
importer: () => import("../fp_count-ChtblhZV.js")
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
28
|
commandName: "fp:explain",
|
|
29
|
-
importer: () => import("../fp_explain-
|
|
29
|
+
importer: () => import("../fp_explain-DZJ--0-S.js")
|
|
30
30
|
},
|
|
31
31
|
{
|
|
32
32
|
commandName: "fp:diff",
|
|
33
|
-
importer: () => import("../fp_diff-
|
|
33
|
+
importer: () => import("../fp_diff-Dt7J4IWu.js")
|
|
34
34
|
},
|
|
35
35
|
{
|
|
36
36
|
commandName: "fp:calibrate",
|
|
37
|
-
importer: () => import("../fp_calibrate-
|
|
37
|
+
importer: () => import("../fp_calibrate-DUbHiifm.js")
|
|
38
38
|
}
|
|
39
39
|
];
|
|
40
40
|
let cache = null;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { s as printResult, t as runCalibrate } from "./runners-
|
|
1
|
+
import { s as printResult, t as runCalibrate } from "./runners-DIt1G85i.js";
|
|
2
2
|
import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
|
|
3
3
|
import { BaseCommand, args } from "@adonisjs/core/ace";
|
|
4
4
|
//#region commands/fp_calibrate.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as runCount, s as printResult } from "./runners-
|
|
1
|
+
import { n as runCount, s as printResult } from "./runners-DIt1G85i.js";
|
|
2
2
|
import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
|
|
3
3
|
import { BaseCommand, flags } from "@adonisjs/core/ace";
|
|
4
4
|
//#region commands/fp_count.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as runDiff, s as printResult } from "./runners-
|
|
1
|
+
import { r as runDiff, s as printResult } from "./runners-DIt1G85i.js";
|
|
2
2
|
import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
|
|
3
3
|
import { BaseCommand, args } from "@adonisjs/core/ace";
|
|
4
4
|
//#region commands/fp_diff.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { i as runExplain, s as printResult } from "./runners-
|
|
1
|
+
import { i as runExplain, s as printResult } from "./runners-DIt1G85i.js";
|
|
2
2
|
import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
|
|
3
3
|
import { BaseCommand, args } from "@adonisjs/core/ace";
|
|
4
4
|
//#region commands/fp_explain.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as runInventory, s as printResult } from "./runners-
|
|
1
|
+
import { a as runInventory, s as printResult } from "./runners-DIt1G85i.js";
|
|
2
2
|
import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
|
|
3
3
|
import { BaseCommand, flags } from "@adonisjs/core/ace";
|
|
4
4
|
//#region commands/fp_inventory.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { o as runMetrics, s as printResult } from "./runners-
|
|
1
|
+
import { o as runMetrics, s as printResult } from "./runners-DIt1G85i.js";
|
|
2
2
|
import { n as printerFor, t as __decorate } from "./decorate-D6enDn9D.js";
|
|
3
3
|
import { BaseCommand, flags } from "@adonisjs/core/ace";
|
|
4
4
|
//#region commands/fp_metrics.ts
|
package/build/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { configure } from "./configure.js";
|
|
2
2
|
import { a as AEP_FACTORS, c as diffCounts, i as measureStructure, n as parseSamples, o as IncomparableRulesetsError, r as measureConformance, s as IncomparableSourcesError, t as calibrate, u as defineConfig } from "./calibration-8eV8CEix.js";
|
|
3
3
|
import "./src/types.js";
|
|
4
|
-
import { t as BUILTIN_CALL_RESOLVERS } from "./resolvers-
|
|
5
|
-
import { i as RULESET_VERSION, n as analyze, r as RULESET, t as CoverageTooLowError } from "./pipeline-
|
|
4
|
+
import { t as BUILTIN_CALL_RESOLVERS } from "./resolvers-PJwo2Z8R.js";
|
|
5
|
+
import { i as RULESET_VERSION, n as analyze, r as RULESET, t as CoverageTooLowError } from "./pipeline-CNTBhs6o.js";
|
|
6
6
|
export { AEP_FACTORS, BUILTIN_CALL_RESOLVERS, CoverageTooLowError, IncomparableRulesetsError, IncomparableSourcesError, RULESET, RULESET_VERSION, analyze, calibrate, configure, defineConfig, diffCounts, measureConformance, measureStructure, parseSamples };
|