Skip to content

murex/TCR

Repository files navigation

Go Go lint NPM build and test sonarcloud Coveralls goreleaser Add contributors

TCR - Test && Commit || Revert

A Go implementation of TCR, for practicing baby-steps development, and much more!

What is this?

TCR is a programming workflow, standing for Test && Commit || Revert.

Kent Beck, Oddmund Strømme, Lars Barlindhaug and Ole Johannessen came up with this concept as described in this post.

Since then several people experimented with this idea.

This repository provides a tool allowing people to use the TCR workflow.

Why TCR?

Although probably a bit challenging to use on real production code, we found TCR to be quite beneficial when used as a learning and practicing tool on the katas that we use when doing software craftsmanship coaching.

TCR enforces developing in baby steps, with a strong focus on always keeping the green light on tests. Having a TCR tool feels a bit like having a coaching assistant constantly enforcing such practices!

We initially came up with a small shell script implementing this workflow, and decided to embed it in each of our katas so that people can use it if they like. This was a way for us to quickly provide a usable TCR solution. However, shell scripts are not the best in class when it comes to maintainability and changeability.

For This reason we decided to work on a new implementation of TCR, written in Go this time.

Who is this for?

If you are a developer willing to practice TCR workflow and baby-step development either alone, in pair or in a mob, just download and run this tool with the piece of code on which you want to practice. You can also use it on real production code if you feel like it!

If you are a technical coach, you can advise participants to your coaching sessions to use it during the sessions.

Where to start?

Prerequisites

  1. Have git or Perforce client installed on your machine
  2. Have a clone of the git repository or a client view of the Perforce depot containing the code you intend to work on
  3. TCR can run on macOS, Linux and Windows. Refer to TCR releases page for a complete list of supported platforms/architectures

Languages and toolchains

TCR can potentially work with any programming language. The only things it needs to know for a language are the following:

  • Where to find, and how to recognize source files
  • Where to find, and how to recognize test files
  • How to build the code
  • How to run the tests

The 2 first points are defined through a language setting

The 2 other points are defined through a toolchain setting

TCR comes with a few built-in languages and toolchains.

You can customize these built-in settings if needed. You can also add your own languages and toolchains if they are not provided as built-in.

Built-in languages and toolchains

Language Default Toolchain Compatible Toolchains
cpp cmake cmake bazel make
csharp dotnet dotnet bazel make
elixir mix mix
go go-tools go-tools gotestsum bazel make
haskell stack stack
java gradle-wrapper gradle gradle-wrapper maven maven-wrapper bazel make
javascript yarn yarn bazel make
kotlin gradle-wrapper gradle gradle-wrapper maven maven-wrapper bazel make
php phpunit phpunit
python pytest pytest bazel make
rust cargo cargo nextest
scala sbt sbt
typescript yarn yarn bazel make

TCR Variants

TCR tool can run several variants of the TCR workflow, inspired by this blog post by Thomas Deniffel.

Some are great as pedagogic tools, some are better for day-to-day use.

The default variant is "The Relaxed". You can refer to this page for further details on available variants.

Base directory

In order to know which files and directories to watch, TCR needs to know on which part of the filesystem it should work. This is what we call the base directory.

  • The base directory can be specified when starting TCR using the -b (or --base-dir) command line option.
  • When the base directory is not provided, TCR assumes that the current directory is the base directory.

Work directory

TCR work directory is the directory from which build and test commands are launched. In most cases using the same value as the base directory is sufficient.

In some situations (for instance on multi-component projects), it might be necessary to run build and test tools from a different directory than the one where source and test files are located.

  • The work directory can be specified when starting TCR using the -w (or --work-dir) command line option.
  • When the work directory is not provided, TCR assumes that the current directory is the work directory.

Configuration directory

If you want to save non-default TCR configuration options, customize a built-in language or toolchain, or add your own language/toolchain, TCR needs to know where it should save them. This is the purpose of the configuration directory.

  • The configuration directory can be specified when starting TCR using the -c (or --config-dir) command line option.
  • When the configuration directory is not provided, TCR assumes that the current directory is the configuration directory.
Configuration directory layout
<configuration directory>/
└── .tcr/
    ├── config.yml             - contains all TCR configuration settings
    ├── language/              - subdirectory containing all language configurations
    │   ├── cpp.yml            - configuration for C++ language
    │   ├── java.yml           - configuration for java language
    │   └── etc.
    └── toolchain/             - subdirectory containing all toolchain configurations
        ├── cmake.yml          - configuration for cmake toolchain
        ├── gradle.yml         - configuration for gradle toolchain
        ├── gradle-wrapper.yml - configuration for gradle wrapper toolchain
        └── etc.

Examples

Refer to the examples directory on how to set up and run TCR for various language/toolchain combinations.

Running TCR

Operating Systems

On MacOS
  1. Download the latest version of TCR for Darwin from here

  2. Extract TCR executable (replace with the appropriate version and architecture)

    tar zxf tcr_1.4.0_Darwin_x86_64.tar.gz
  3. Launch TCR

    ./tcr -b <base-directory> -w <work-directory> -l <language> -t <toolchain>
On Linux
  1. Download the latest version of TCR for Linux from here

  2. Extract TCR executable (replace with the appropriate version and architecture)

    tar zxf tcr_1.4.0_Linux_x86_64.tar.gz
  3. Launch TCR

    ./tcr -b <base-directory> -w <work-directory> -l <language> -t <toolchain>
On Windows
  1. Download the latest version of TCR for Windows from here

  2. Extract TCR executable (replace with the appropriate version and architecture)

    tar zxf tcr_1.4.0_Windows_x86_64.tar.gz
  3. Launch TCR

    ./tcr.exe -b <base-directory> -w <work-directory> -l <language> -t <toolchain>

Version Control Systems

Git

TCR uses git by default. There is no need to specify anything particular to use git.

Note: TCR and git commits signing

Some users prefer to set up their git configuration so that each of their commits is signed and verified through a GPG passphrase as described here.

TCR automatically performs a significant number of commits. It would become unusable if the user had to enter a passphrase at each commit.

For this reason, TCR commits are deliberately not signed.

If signing every commit is important to you, you can still do it when you're done working with TCR, when reworking git history and squashing TCR commits into meaningful ones.

Perforce

Before running TCR with Perforce, make sure that the P4 Client is properly configured.

To use TCR with Perforce, you'll need to add the --vcs=p4 to the command line (you can also set this up in the .tcr/config.yml, see the Configuration Directory section below).

Ignoring intermediate files

As TCR automatically submits everything that changed since last submit, you might end up with binary and/or build files in the depot.

To prevent this from happening, you can set up Perforce to ignore them.

In practice, we found that you can use the same setting as with git:

p4 set P4IGNORE=.gitignore
IDE configuration when using TCR with Perforce

In order to use TCR with Perforce, make sure to setup your IDE so that it automatically marks files for edit on modify. Without this you will still be able to use TCR, but you will have to repeatedly mark files for edit after every commit.

  • With VS-Code, look for available Perforce extensions to enable it
  • With JetBrains IDEs, Perforce Helix Core plugin allows to enable it
Perforce limitations

At the moment, TCR over Perforce is still in the experimentation phase. It does not yet support all the options available with git. Here are the main limitations:

  • Option --auto-push or -p has no meaning with Perforce and is ignored
  • Sub-command log is not supported
  • Sub-command stats is not supported

Using TCR configuration

TCR runs by default without any local configuration, using either built-in settings or settings defined through command line options.

If you prefer to use your own custom settings, you have the possibility to save them locally without the need to provide them every time you run TCR. This can be achieved through the tcr config subcommand.

All configuration settings are saved in YAML format. Thus you can edit them later using a text editor.

Expand for usage examples
  • To save TCR configuration in your HOME directory (using the default settings):

    ./tcr config save -c $HOME
  • To save TCR configuration in the current directory, setting the timer duration to 10m, the language to java and the toolchain to maven:

    ./tcr config save -d 10m -l java -t maven
  • To show the current TCR configuration settings (previously saved in the current directory)

    ./tcr config show
  • To reset TCR configuration settings to their default values (in the current directory)

    ./tcr config reset

Adding a new language and toolchain

New languages and toolchains can be added through adding related configuration files in the configuration directory.

Expand for details

We're assuming in this example that the configuration directory is your HOME directory. Replace $HOME in the examples below if you prefer to use a different location.

Suppose you want to run TCR with Javascript language and yarn toolchain. Here is what you would do:

  1. Create the TCR configuration directory structure (you can skip this step if you saved TCR configuration before)

    tcr config save -c $HOME
  2. Create yarn.yml toolchain configuration file from an existing toolchain configuration

    cd $HOME/.tcr/toolchain
    cp gradle.yml yarn.yml
  3. Adjust yarn.yml contents

    Edit yarn.yml with your favorite editor and adjust the contents as follows.

    We're assuming here that yarn is installed and that yarn build and yarn test are set up so that they run respectively the build and test.

    build:
    - os: [darwin, linux, windows]
      arch: ["386", amd64, arm64]
      command: yarn
      arguments: [build]
    test:
    - os: [darwin, linux, windows]
      arch: ["386", amd64, arm64]
      command: yarn
      arguments: [test]
  4. Create javascript.yml language configuration file from an existing language configuration

    cd $HOME/.tcr/language
    cp java.yml javascript.yml
  5. Adjust javascript.yml contents

    Edit javascript.yml with your favorite editor and adjust the contents as follows:

    We're assuming here that all source files are under src subdirectory and are named *.js, and that all test files are under test subdirectory and are named *.test.js.

    toolchains:
      default: yarn
      compatible-with: [yarn]
    source-files:
      directories: [src]
      patterns: ['(?i)^.*\.js$']
    test-files:
      directories: [test]
      patterns: ['(?i)^.*\.test\.js$']

    Regex on filenames

    TCR complies with RE2 for pattern matching on filenames.

  6. Check TCR settings with the newly configured language and toolchain

    TCR's check subcommand performs a number of checks on configuration, parameters and local environment without triggering the TCR cycle. It helps you quickly tune your configuration and command line parameters. Make sure that there is no error checkpoint in the trace displayed before proceeding any further.

    cd <base-directory>
    tcr check -c $HOME -l javascript -t yarn
  7. Try running TCR with the newly configured language and toolchain

    TCR's one-shot subcommand runs one single TCR cycle then exits. Through checking its return code you can quickly verify that everything works as expected.

    cd <base-directory>
    tcr one-shot -c $HOME -l javascript -t yarn
    echo $?

    Language's Default Toolchain

    Each language has a default toolchain, which is the one that will be used with this language if no toolchain is specified on the command line. In the above example, -t yarn could actually be skipped.

Using TCR's embedded web interface experimental

Since version 1.0.0, TCR comes with an embedded web interface that can be used to monitor the TCR cycle, control driver and navigator roles, and show the countdown timer when the driver mode active.

To use it, start TCR using the web subcommand:

./tcr web

Once TCR is running, you can open the web interface in your browser by typing the O shortcut in the terminal.

TCR runs its internal web server on port 8483 by default. You can change the port through using the -P (or --port-number) command line option.

Command line help (all platforms)

Refer to here for TCR command line help and additional options.

Building, testing and releasing TCR

Refer to TCR development documentation for details.

How to Contribute?

TCR tool is still at an early stage of development, and there are still plenty of features that we would like to add in the future, such as additional languages and toolchains, collaboration utilities, etc.

Refer to CONTRIBUTING.md for general contribution agreement and guidelines.

License

The TCR application and the accompanying materials are made available under the terms of the MIT License which accompanies this distribution, and is available at the Open Source site.

Contributors

Damien
Damien Menanteau
Philippe
Philippe Bourgau
Ahmad
Ahmad Atwi
Yifang
Yifang DONG
rwilsonmurex/
rwilsonmurex