Skip to content
This repository has been archived by the owner on Aug 31, 2019. It is now read-only.

Latest commit

 

History

History
141 lines (101 loc) · 4.84 KB

DESIGN.md

File metadata and controls

141 lines (101 loc) · 4.84 KB

Design

Goals

  • Correct
  • Fast
  • Simple
  • Versatile
  • Safe

Correct

  • Evaluate the exact diff to determine what changed.
  • Evaluates all the import paths of all the untouched packages to discover any package that would be transitively (indirectly affected by a change in an imported package. Evaluates the dependency chain recursively. Do the same for tests.
    • For example, if package ./foo is modified, ./bar depends on ./foo and ./tom depends on ./bar, all three packages will be tested.

Fast

  • Between hard to implement or slow, choose fast.
  • All checks are run concurrently.
  • Lookup for prerequisites presence is concurrent.
    • Checks that are Go builtin are executed right away, without waiting for prerequisities to be installed.
  • Checks are only run on the relevant code, not on the whole tree.
  • Checks are increasingly involved based on mode; pre-commit vs pre-push vs continuous-integration.

Simple

  • Commit hooks are installed automatically.
  • Prerequisites are installed automatically.
  • Running it just does the right thing depending on context. Switches automatically on CI mode when CI=true is set. When run directly, it diffs against upstream and runs checks on the local changes only. On pre-commit, it diffs the staged changes. On pre-push, it diffs the commits being pushed.
  • Easy to bypass the hook.
  • Sane defaults.

Versatile

  • Easy to configure.
  • Yet powerful extensibility.
  • Configuration file is simple and documented by structures. No need to check-in the configuration file if not desired.
  • Integrated support with popular hosted CI systems.

Safe

  • No check can modify any file.
  • If any modification to the checkout is needed, it is very carefull about what can be done.
    • Very careful when unstaged changes are present.
    • Bails out if any untracked file is present.
  • In the normal cases (git commit -a and git push where what is pushed is currently checked out), the checkout is not touched.

Behavior

Command installrun

pcg defaults to command installrun when executed without argument. This mode sense the current environment and switches to run-hook continuous-integration if the environment variable CI=true is set.

It reinstalls git hooks and checks for prerequisites in this mode. Both are checked concurrently, and checking for each prerequisite is done concurrently. Simultaneously, the list of checks for the current mode is gathered simultaneously, which is generated by running git commands. The git command used depend on the current mode and state of the git checkout.

All checks that do not require any prerequisites is started immediately, even before reinstalling git hooks is completed. Checks that require prerequisites are started as soon as prerequisites that checked for presence and installed if necessary.

Mode pre-commit

It does the following concurrently:

  • If any untracked file is found, the run is aborted with error.
  • It looks at the staging index and stash any unstaged change. No stashing is done if unnecessary, so git doesn't touch unnecessarily the files.
  • It gathers the list of files in the staging area.

After;

  • A Change object is created that contains only the staging area.
  • Runs all the checks defined as mode pre-commit.

Mode pre-push

It does the following concurrently:

  • If any untracked file is found, the run is aborted with error.
  • It reads stdin for pre-push pairs as and analyze each one. For each pair;
    • If a branch is being deleted, skip the checks.
    • It looks if the current checkout commit hash matches what needs to be tested, if not, it registers the previous commit&ref and checks out the right code.
    • It creates a Change based on the diff between what is pushed.
    • Runs all the checks defined as mode pre-push for this pair serially.

After;

  • Upon stdin close, restore the checkout only if it had been modified. By default, when push.default = simple, the checkout won't be touched since what is being pushed is what is currently checked out.

Mode continuous-integration

It does the following concurrently:

  • Enable verbose mode.
  • It installs prerequisites (but not hooks).
  • If any untracked file is found, the run is aborted with error.
  • It create a Change based on all the code.

After;

  • Runs all the checks defined as mode continous-integration

Mode is unspecified

When run without argument in a checkout, it defaults to installrun then mode pre-push. The Change is created from the diff between @{upstream} and HEAD, including untracked changes.