git-gamble 1.1.0-beta.2

blend TCR + TDD to make sure to develop the right thing, babystep by babystep
git-gamble-1.1.0-beta.2 is not a library.
Visit the last successful build: git-gamble-2.11.0

Git-Gamble

Crate available on Crates.io AppImage available on Bintray Debian package available on Bintray pipeline status AppVeyor for Homebrew status License ISC Contributor Covenant

Blend TCR (test && commit || revert) + TDD (Test Driven Development) to make sure to develop the right thing, babystep by babystep

Original idea by Xavier Detant

[[TOC]]

Theory

TCR

TCR (test && commit || revert) is cool! It encourages doing baby steps, reducing the waste when we are wrong

But it doesn't allow us to see the tests failing

So:

  • Maybe we test nothing (assert forgotten)

    def test_should_be_Buzz_given_5():
        input = 5
        actual = fizz_buzz(input)
        # Oops! Assert has been forgotten
    
  • Maybe we are testing something that is not the thing we should be testing

    it("should be Fizz given 3", () => {
      const input = 3;
      const actual = fizzBuzz(input);
      expect(input).toBe("Fizz");
      // Oops! Asserts on the input value instead of the actual value
    });
    

TDD

TDD (Test Driven Development) is cool! It makes sure we develop the right thing, step by step

TCRDD

TCRDD = TCR + TDD

TCRDD blends the constraints of the two methods to benefit from their advantages

Therefore, TCRDD makes sure we develop the right thing, step by step, and we are encouraged to do so by baby steps, reducing the waste when we are wrong

@startuml
skinparam ArrowColor black

start
repeat
	partition "red" #Coral {
		repeat
			:Write a test]
			:Gamble that the tests fail/
			if (Actually run tests) then (Fail)
				-[#Red]->
				:Commit;
				break
			else (Pass)
				-[#Green]->
				:Revert;
			endif
		repeat while (Write another test)
	}
	partition "green" #Lime {
		repeat
			:Write the minimum code]
			:Gamble that the tests pass/
			if (Actually run tests) then (Pass)
				-[#Green]->
				:Commit;
				break
			else (Fail)
				-[#Red]->
				:Revert;
			endif
		repeat while (Try something else)
	}
	partition "refactor" #668cff {
		repeat
			repeat
				:Write code
				without changing the behavior]
				:Gamble that the tests pass/
				if (Actually run tests) then (Pass)
					-[#Green]->
					:Commit;
					break
				else (Fail)
					-[#Tomato]->
					:Revert;
				endif
			repeat while (Change something else)
		repeat while (Another things to refactor ?)
	}
repeat while (Another feature to add ?)
stop
@enduml

git-gamble is a tool that helps to use the TCRDD method

How to install

Requirements

git-gamble doesn't repackage git, it use the one installed on your system

Install git

Be sure to make it available in your $PATH, you can check with this command

git --help

AppImage

  1. Download the latest version

    curl --location "https://dl.bintray.com/pinage404/git-gamble-AppImage/git-gamble-v1.0.0-x86_64.AppImage" --output git-gamble.AppImage
    
  2. Make it executable

    chmod +x git-gamble.AppImage
    
  3. Put it your $PATH

    # for example
    mkdir -p ~/.local/bin
    mv git-gamble.AppImage ~/.local/bin/git-gamble
    export PATH+=":~/.local/bin"
    

Debian

As root

  1. Install dependencies that seems needed to be able to add a new repository

    apt update
    apt install \
    	ca-certificates \
    	gnupg
    
  2. Add the git-gamble's GPG key (currently, it's Bintray GPG key)

    apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 379CE192D401AB61
    
  3. Add git-gamble repository

    echo "deb https://dl.bintray.com/pinage404/git-gamble-debian bullseye main" | tee -a /etc/apt/sources.list
    apt update
    
  4. Install git-gamble

    apt install git-gamble
    

Mac OS X / Homebrew

Install Homebrew

brew tap pinage404/git-gamble https://gitlab.com/pinage404/git-gamble.git
brew install --HEAD git-gamble

Windows / Chocolatey

Install Chocolatey

choco source add --name=git-gamble-repository --source="https://api.bintray.com/nuget/pinage404/git-gamble-chocolatey/"
choco install git-gamble

Cargo

Install Cargo

cargo install git-gamble

Add ~/.cargo/bin to your $PATH

Fish:

set --export --append PATH ~/.cargo/bin

Bash / ZSH:

export PATH=$PATH:~/.cargo/bin

Check the installation

Check if all have been well settled

git gamble

If it has been well settled, it should output this :

error: The following required arguments were not provided:
    <test-command>...
    <--pass|--fail>

USAGE:
    git-gamble --repository-path <repository-path> <--pass|--fail>

For more information try --help

If it has been badly settled, it should output this :

git : 'gamble' is not a git command. See 'git --help'.

How to use

To see all available flags and options

git-gamble --help # dash is only needed for --help
  1. Write a failing test in your codebase, then :

    git gamble --fail -- $YOUR_TEST_COMMAND
    
  2. Write the minimum code to make tests pass, then :

    git gamble --pass -- $YOUR_TEST_COMMAND
    
  3. Refactor your code, then :

    git gamble --pass -- $YOUR_TEST_COMMAND
    

It's a bit tedious to always repeat the test command

So you can set an environment variable with the test command to avoid repeating it all the time

export GAMBLE_TEST_COMMAND="sh -c 'cargo fix --allow-dirty ; cargo clippy --all-targets ; cargo check --all-targets ; cargo fmt ; cargo test'"
git gamble --pass

Test command must exit with a 0 status when there are 0 failing tests, anything else is considered as a failure

Backlog

@startmindmap "backlog"
* Backlog
left side
	* Done
		* MVP
			* base
				* run tests
				* `git commit`
				* `git revert`
				* test it
			* TCR
				* option --pass
			* TRC
				* option --fail
		* give path in option
		* improve test command
			* test command with arguments
			* script
		* dry run flag
		* help option
			* -h
			* --help
		* exclusive flag
		* required flag
		* option colors
			* -g
			* --green
			* -r
			* --red
		* merge commits
			* `git update-ref`
			* `git commit --amend`
		* should fail without test command
		* test command from environement variable
		* display when committed or reverted
		* how to use
		* test in isolated and reproductible environement
			* container
			* CI
			* [[https://doc.rust-lang.org/cargo/guide/continuous-integration.html Cargo's Documentation about CI]]
		* complete metadata
		* rename project?
			* simpler to say and understand and remember when not familiar with `TCR` or `TDD`
			* from `git-tcrdd` to `git-...`?
				* [[https://www.wordreference.com/fren/jouer jouer?]]
				* [[https://www.wordreference.com/fren/parier parier?]]
				* [[https://www.wordreference.com/enfr/bet bet?]]
				* [[https://www.wordreference.com/enfr/expect expect?]]
				* [[https://www.wordreference.com/enfr/gamble gamble?]]
				* [[https://www.wordreference.com/enfr/should should?]]
				* Quick save development (qsd)
		* TDD's option `--refactor` == `--pass`
		* message option
			* -m
			* --message
			* amend should keep message
				* `"--reuse-message=@",`
		* shell completion
			* shells
				* [x] Fish
				* [x] Bash
				* [x] Zsh
			* package
				* [x] Debian
				* [x] Homebrew
	* WIP
right side
	* TODO
		* `--edit` OR `--edit-message` option to open `$EDITOR` on commit like `git commit --edit`
			* how to test it ?
		* when revert `git clean`
		* `git workspace` support
			* `git update-ref` should contain an unique identifier to the workspace
				* branche name ?
				* folder path ?
		* gamble hooks
			* branch based developement
				* `git commit --fixup`
				* `git rebase --autosquash`
			* trunk based developement
				* `git pull`
				* `git push`
		* like git, flags & options & arguments should be retrieved from CLI or environment variable or config's file
			* re-use `git config` to store in file ?
			* repository level config using direnv and environment variable ?
		* [[https://rachelcarmena.github.io/2018/11/13/test-driven-programming-workflows.html#my-proposal-of-tcr-variant stash instead of revert ?]]
		* `--help` should link to the repository
		* shell completion
			* in the package ?
				* [ ] Cargo
				* [ ] AppImage
				* [ ] Chocolatey
			* in sub command ?
@endmindmap

Distribution / publishing backlog

CheckList

  • package in local
  • package in CI
  • upload
  • make public available
  • complete how to install
  • manual test
  • update backlog

Technical improvement opportunities

  • find why rustc warns about dead_code on identifier that are really used elsewhere
  • licence check
    • cargo license
    • cargo deny
  • code coverage
    • tarpaulin
    • kcov
  • smaller binary
    • cargo bloat
    • cargo deps

Reinvent the wheel

Why reinvent the wheel?

This script already works well

Because i would like to learn Rust ¯\_(ツ)_/¯

Contributing

Contributor Covenant

Any contributions (feedback, bug report, merge request ...) are welcome

Respect the code of conduct

Follow Keep a Changelog

Merge request

To contribute with merge request, install this crates

Deployment