gcheck_core 0.4.2
gcheck_core: ^0.4.2 copied to clipboard
Checklist and reference document engine of the Duniter/Ğ1 ecosystem, with the official gcheck checklists and documents embedded.
gcheck_core #
Checklist and reference document engine of the Duniter/Ğ1 ecosystem, for Dart and Flutter applications such as Ğecko and Ginkgo.
It reads a gcheck checklist (YAML or JSON), resolves its options, selects the questions to ask and turns the answers into a verdict (pass, warning or fail). It also serves the reference documents — the Ğ1 licence and the smith and technical committee commitments — in markdown, as an HTML fragment and as a standalone HTML page, with a content hash and the earlier versions, so an application can tell whether the user accepted an outdated version and show what changed since.
Checklists and documents are embedded and come from the source of truth, g1_monetary_license: updating this dependency is enough to get the latest questions and texts. An application can also provide its own, which take precedence.
Same engine as the TypeScript, Rust and Python ports; the four share their business test cases, so they answer exactly the same thing, hash included.
Running a checklist #
import 'package:gcheck_core/gcheck_core.dart';
final engine = GcheckEngine();
final checklist = getChecklist(memberCertification, 'fr')!;
final quiz = engine.prepare(checklist.content);
for (final question in quiz.questions) {
print(question.text); // ask the user, then collect the answers
}
final verdict = engine.evaluate(quiz, {'ownKeys': true, 'meetsInPerson': false});
if (verdict.verdict == VerdictStatus.fail) {
for (final issue in verdict.issues) {
print('${issue.text} → ${issue.message}');
}
}
checklist.hash() is worth storing after a successful run: it tells you later whether the
checklist has changed and should be taken again.
Showing a reference document #
final document = getDocument(memberCommitment, 'fr')!;
document.markdown; // raw text
document.fragment; // HTML to insert in an existing page
document.page(); // standalone HTML page
document.hash; // store it once the user has accepted
// Later, with what the application kept of that acceptance
switch (document.state(Acceptance(acceptedHash))) {
case AcceptanceState.never: // never accepted
case AcceptanceState.outdated: // accepted in an earlier version
case AcceptanceState.current: // up to date
}
// What changed since, to show before asking for a new acceptance
final changes = document.changesSince(acceptedHash);
for (final block in changes?.blocks ?? const []) {
// EqualBlock: unchanged, ChangeBlock: removed/added, MovedBlock: moved elsewhere
}
changes.exact says whether the comparison starts from the very version the user accepted; when
that version is no longer shipped, it starts from the closest kept one before it — showing a little
more than what the user has not read yet, never less.
Within a rewritten line, compareWords(before, after) marks each piece as unchanged, changed or
simply moved, so an application can highlight without mistaking a move for a rewrite.
Application-provided content #
final catalog = Catalog.embedded()..addContent('my-checklist', yamlOrJson);
final checklist = catalog.get('my-checklist', 'fr');
// Or from files (needs dart:io, so not on the web)
import 'package:gcheck_core/gcheck_core_io.dart';
Catalog.embedded().addDir('/path/to/checklists');
Catalog() and DocumentCatalog() start empty, for an application that only uses its own content.
Licence #
AGPL-3.0-or-later, like the rest of gcheck.