Skip to content

Measuring what is there

Two subcommands report what the analyzer found. Neither decides anything. The exit status is zero whatever the counts say, since gating is what the analyzer and a baseline are for.

Command Unit Answers
declscope survey [packages] package Which package do I open first?
declscope inspect <package> namespace, crossing What shape is this package in?
$ declscope survey -config .declscope-strict.yaml ./internal/measure/...
## Checks in force

| check      | value                                                                  | packages |
| ---------- | ---------------------------------------------------------------------- | -------: |
| config     | `.declscope-strict.yaml`                                               |        1 |
| rules      | boundary on, qualify ondemand, exported, surplus strict, unused strict |        1 |
| type check | 1 package ok, 0 failed                                                 |          |

## Findings

| rule        | found | ignored | baselined | reported |
| ----------- | ----: | ------: | --------: | -------: |
| `boundary`  |     0 |       0 |         0 |        0 |
| `qualify`   |     0 |       0 |         0 |        0 |
| `surplus`   |     0 |       0 |         0 |        0 |
| `unused`    |     0 |       0 |         - |        0 |
| `directive` |     0 |       0 |         - |        0 |
| `filter`    |     0 |       0 |         - |        0 |

## Packages — boundary

| package                                      | reported | baselined | declared | largest crossing                 |
| -------------------------------------------- | -------: | --------: | -------: | -------------------------------- |
| `github.com/mpyw/declscope/internal/measure` |        0 |         0 |       30 | markdown → cell (7 declarations) |

## Packages — qualify

| package                                      | reported | baselined | exempt | worst namespace |
| -------------------------------------------- | -------: | --------: | -----: | --------------- |
| `github.com/mpyw/declscope/internal/measure` |        0 |         0 |      0 | -               |

That is one package of this repository. A codebase adopting declscope has numbers in the first two columns, and a row per package.

  • The state of the checks comes first, because a count means nothing without it. A zero from a rule that was off, a package that did not compile, or a baseline that absorbed everything looks like a zero from clean code.
  • A rule prints - rather than 0 where it was not asked. It may be switched off, or it may stand itself down, as surplus does for a package with a file it cannot read.
  • A package that does not type-check stops the run, and so does a package that imports one, directly or not. -allow-errors continues: type check counts the failures, and a list under the Checks table names each package with its first error. For a package whose dependency failed, the list names that dependency and its error.
  • So does a run whose patterns match no package. A pattern that matches nothing beside others that do gets a warning. inspect does the same.
  • Rows are ordered by how much is outstanding: undecided, reported and baselined together. largest crossing names where it is concentrated.

Tip

Look for the row with nothing reported, much baselined and nothing declared. Nothing was decided there, everything was deferred, and the analyzer alone calls it clean.

inspect prints several sections. The excerpt below is its Crossings section, in full: a Mermaid diagram, then the same crossings as a table, folded under it. The other sections list the namespaces, rank the most-reached declarations outside the core, and give the naming rule per namespace.

$ declscope inspect -config .declscope-strict.yaml ./internal/measure
## Crossings

```mermaid
graph LR
  n0["markdown"]
  n1["cell"]
  n2["sink"]
  n3["golden"]
  n4["(core)"]
  n5["json"]
  n6["summary"]
  n7["crossing"]
  n8["format"]
  n9["reach"]
  n10["qualify"]
  n0 -.->|7| n1
  n0 -.->|5| n2
  n3 -.->|4| n4
  n5 -.->|3| n6
  n0 -.->|3| n6
  n0 -.->|2| n7
  n1 -.->|2| n0
  n8 -.->|2| n5
  n8 -.->|2| n0
  n0 -.->|2| n9
  n6 -.->|2| n7
  n7 -.->|1| n4
  n3 -.->|1| n0
  n3 -.->|1| n9
  n1 -.->|1| n6
  n3 -.->|1| n7
  n3 -.->|1| n8
  n1 -.->|1| n4
  n1 -.->|1| n5
  n8 -.->|1| n4
  n3 -.->|1| n5
  n5 -.->|1| n7
  n0 -.->|1| n10
  n10 -.->|1| n4
  n6 -.->|1| n5
  n6 -.->|1| n0
  n6 -.->|1| n10
```

<details>
<summary>Table: 27 crossings</summary>

| crossing            | mutual | declared | baselined | reported | clears |  reached | uses |
| ------------------- | ------ | -------: | --------: | -------: | -----: | -------: | ---: |
| markdown → cell     | yes    |        7 |         0 |        0 |      0 |  7 of 18 |   18 |
| markdown → sink     |        |        5 |         0 |        0 |      0 |  5 of 18 |   36 |
| golden → (core)     |        |        4 |         0 |        0 |      0 |  4 of 79 |    9 |
| json → summary      | yes    |        3 |         0 |        0 |      0 |  3 of 27 |    9 |
| markdown → summary  | yes    |        3 |         0 |        0 |      0 |  3 of 27 |    7 |
| markdown → crossing |        |        2 |         0 |        0 |      0 |  2 of 20 |    6 |
| cell → markdown     | yes    |        2 |         0 |        0 |      0 |  2 of 10 |    3 |
| format → json       |        |        2 |         0 |        0 |      0 | 2 of 107 |    2 |
| format → markdown   |        |        2 |         0 |        0 |      0 |  2 of 10 |    2 |
| markdown → reach    |        |        2 |         0 |        0 |      0 |   2 of 9 |    2 |
| summary → crossing  |        |        2 |         0 |        0 |      0 |  2 of 20 |    2 |
| crossing → (core)   |        |        1 |         0 |        0 |      0 |  1 of 79 |    3 |
| golden → markdown   |        |        1 |         0 |        0 |      0 |  1 of 10 |    3 |
| golden → reach      |        |        1 |         0 |        0 |      0 |   1 of 9 |    3 |
| cell → summary      |        |        1 |         0 |        0 |      0 |  1 of 27 |    2 |
| golden → crossing   |        |        1 |         0 |        0 |      0 |  1 of 20 |    2 |
| golden → format     |        |        1 |         0 |        0 |      0 |   1 of 9 |    2 |
| cell → (core)       |        |        1 |         0 |        0 |      0 |  1 of 79 |    1 |
| cell → json         |        |        1 |         0 |        0 |      0 | 1 of 107 |    1 |
| format → (core)     |        |        1 |         0 |        0 |      0 |  1 of 79 |    1 |
| golden → json       |        |        1 |         0 |        0 |      0 | 1 of 107 |    1 |
| json → crossing     |        |        1 |         0 |        0 |      0 |  1 of 20 |    1 |
| markdown → qualify  |        |        1 |         0 |        0 |      0 |  1 of 15 |    1 |
| qualify → (core)    |        |        1 |         0 |        0 |      0 |  1 of 79 |    1 |
| summary → json      | yes    |        1 |         0 |        0 |      0 | 1 of 107 |    1 |
| summary → markdown  | yes    |        1 |         0 |        0 |      0 |  1 of 10 |    1 |
| summary → qualify   |        |        1 |         0 |        0 |      0 |  1 of 15 |    1 |

</details>

109 declarations are further: open, shared by default rather than by decision, so left out of the table and of the diagram.

Declarations crossed: 0 reported, 0 baselined, 30 declared. The columns above count within a pair, so they sum to more: a declaration reached from two namespaces is two rows and one finding.

One row per directed edge, so a mutual pair is two rows. clears is the number the decision turns on: how many findings would go away if the two namespaces became one.

Both commands take -test=false. On a large package it changes the picture. In net/http the heaviest crossing is export_test.go reaching the transport internals, which is what that file is for.

The other columns, and the formats
Column What it says
clears Findings that would go away if these two namespaces merged. A declaration a third namespace also reaches survives the merge, so a heavy crossing can clear much less than it reaches
reached Declarations of the reached namespace this edge touches, over every declaration it holds. 12 of 19 says the second namespace holds the working parts of the first. Open crossings are counted under the table, not in the rows
declared / baselined / reported Declarations on this edge, by what became of each. A declaration reached from two namespaces is two rows and one finding, so these sum to more than the rule found. The line under the table gives the rule's own count, which is the survey's
saturation, in the Qualify table How much of a namespace the naming rule is unsatisfied by. Near the top, the namespace name is usually what is wrong
-format For
markdown (default) A terminal and an issue or pull request. Cells are padded, so the output aligns in both. inspect adds a Mermaid diagram and folds the table under it
json An agent, and anything scripted

The JSON carries four arrays.

Array Holds
edges, names One flat row each
crossings The fold the crossing table prints, clears included
namespaces The denominators every ratio divides by

findings carries the same asked flag the tables print a dash for. Markdown is a rendering of the same data.