36 releases (10 stable)
2.5.0 | Jul 3, 2022 |
---|---|
2.3.0 | Oct 23, 2021 |
1.3.0 | Mar 12, 2021 |
1.1.0 | May 25, 2020 |
0.4.0 | Mar 31, 2020 |
#70 in Testing
113 downloads per month
45KB
418 lines
Git-Gamble
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
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
If the above diagram is missing, you can see it on GitLab
git-gamble
is a tool that helps to use the TCRDD method
How to install
Requirements
git-gamble
doesn't repackage git
, it uses the one installed on your system
You have to install git
manually if you install git-gamble
using :
- AppImage
- Debian
- Cargo
Other installation methods include git
as a dependency
Make sure it is available in your $PATH
, you can check it with this command
git --help
Installation methods
Installations are currently not really convenient, contributions are welcome, feel free to add package to your prefered packages repository
AppImage
-
Download the latest version
curl --location "https://gitlab.com/api/v4/projects/pinage404%2Fgit-gamble/packages/generic/git-gamble-AppImage/2.5.0/git-gamble-v2.5.0-x86_64.AppImage" --output git-gamble-v2.5.0-x86_64.AppImage
-
Make it executable
chmod +x git-gamble-v2.5.0-x86_64.AppImage
-
Put it your
$PATH
# for example mkdir -p ~/.local/bin ln git-gamble-v2.5.0-x86_64.AppImage ~/.local/bin/git-gamble export PATH+=":~/.local/bin"
Debian
-
Go to the latest version of
git-gamble-debian
-
Download the latest version
git-gamble_2.5.0_amd64.deb
-
Install package
As root
dpkg --install git-gamble*.deb
This is not really convenient but a better way will come when GitLab Debian Package Manager MVC will be available
Mac OS X / Homebrew
brew tap pinage404/git-gamble https://gitlab.com/pinage404/git-gamble.git
brew install --HEAD git-gamble
Upgrade
git-gamble
has not yet been packaged by Homebrew
To upgrade git-gamble
, run this command
brew reinstall git-gamble
Windows / Chocolatey
-
Go to the latest version of
git-gamble.portable
-
Download the latest version
git-gamble.portable.2.5.0.nupkg
-
Install package
Follow GitLab's documentation and Chocolatey's documentation
choco install ./git-gamble.portable.2.5.0.nupkg
Nix / NixOS
Installation can be done at different levels, see below
It can be done with nix flake
or with legacy way, in this case you will have to run command several times to change the sha256
and cargoSha256
by the given one by Nix
Nix 2.4 or higher is required
Nix Flake
Use without installing
nix run gitlab:pinage404/git-gamble -- --help
To install it, see usage example
Project level
In shell.nix
{ pkgs ? import <nixpkgs> {} }:
let
git-gamble-derivation = pkgs.fetchurl {
url = "https://gitlab.com/pinage404/git-gamble/-/raw/main/packaging/nix/git-gamble/default.nix";
sha256 = "0000000000000000000000000000000000000000000000000000";
};
git-gamble = pkgs.callPackage git-gamble-derivation {
version = "2.5.0";
sha256 = "1111111111111111111111111111111111111111111111111111";
cargoSha256 = "0000000000000000000000000000000000000000000000000000";
};
in
pkgs.mkShell {
buildInputs = [
git-gamble
# others dependencies here
pkgs.nodejs
];
}
Then run this command
nix-shell
DirEnv
To automate the setup of the environment it's recommanded to install DirEnv
Add in .envrc
use nix
Then run this command
direnv allow
Home-Manager / user level
Install Home Manager
In ~/.config/nixpkgs/home.nix
{ pkgs, ... }:
let
git-gamble-derivation = pkgs.fetchurl {
url = "https://gitlab.com/pinage404/git-gamble/-/raw/main/packaging/nix/git-gamble/default.nix";
sha256 = "0000000000000000000000000000000000000000000000000000";
};
git-gamble = pkgs.callPackage git-gamble-derivation {
version = "2.5.0";
sha256 = "1111111111111111111111111111111111111111111111111111";
cargoSha256 = "0000000000000000000000000000000000000000000000000000";
};
in
{
home.packages = [
git-gamble
# others dependencies here
pkgs.gitAndTools.git-absorb
];
}
Then run this command
home-manager switch
NixOS / system level
In /etc/nixos/configuration.nix
{ pkgs, ... }:
let
git-gamble-derivation = pkgs.fetchurl {
url = "https://gitlab.com/pinage404/git-gamble/-/raw/main/packaging/nix/git-gamble/default.nix";
sha256 = "0000000000000000000000000000000000000000000000000000";
};
git-gamble = pkgs.callPackage git-gamble-derivation {
version = "2.5.0";
sha256 = "1111111111111111111111111111111111111111111111111111";
cargoSha256 = "0000000000000000000000000000000000000000000000000000";
};
in
{
environment.systemPackages = [
git-gamble
# others dependencies here
pkgs.bat
];
# This value determines the NixOS release with which your system is to be compatible, in order to avoid breaking some software such as database servers
# You should change this only after NixOS release notes say you should
system.stateVersion = "20.09";
}
Then run this command
nixos-rebuild switch
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
Download the binary
Only for Linux and Windows x86_64
- Download the binary on the release page
- Put it in your
$PATH
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:
<--pass|--fail>
<TEST_COMMAND>...
USAGE:
git-gamble [OPTIONS] <--pass|--fail> [--] <TEST_COMMAND>...
git-gamble [OPTIONS] <SUBCOMMAND>
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 between `git` and `gamble` is only needed for --help
-
Write a failing test in your codebase, then :
git gamble --fail -- $YOUR_TEST_COMMAND
-
Write the minimum code to make tests pass, then :
git gamble --pass -- $YOUR_TEST_COMMAND
-
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="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
For more detailed example, this the demo
Usage
git-gamble --help
git-gamble 2.5.0
Blend TCR (`test && commit || revert`) + TDD (Test Driven Development) to make sure to develop
the right thing, babystep by babystep
USAGE:
git-gamble [OPTIONS] <--pass|--fail> [--] <TEST_COMMAND>...
git-gamble [OPTIONS] <SUBCOMMAND>
ARGS:
<TEST_COMMAND>... The command to execute to know the result [env: GAMBLE_TEST_COMMAND=]
OPTIONS:
-g, --pass
Gamble that tests should pass [aliases: green, refactor]
-r, --fail
Gamble that tests should fail [aliases: red]
-C, --repository-path <REPOSITORY_PATH>
Repository path [default: .]
-e, --edit
Open editor to edit commit's message
--fixup <FIXUP>
Fixes up commit
-h, --help
Print help information
-m, --message <MESSAGE>
Commit's message [default: ]
-n, --dry-run
Do not make any changes
--no-verify
Do not run git hooks
--squash <SQUASH>
Construct a commit message for use with `rebase --autosquash`
-V, --version
Print version information
SUBCOMMANDS:
generate-shell-completions
help Print this message or the help of the given subcommand(s)
Any contributions (feedback, bug report, merge request ...) are welcome
https://gitlab.com/pinage404/git-gamble
Shells completions
To manually generate shell completions you can use this command
git gamble generate-shell-completions --help
git-gamble-generate-shell-completions
USAGE:
git-gamble generate-shell-completions <SHELL>
ARGS:
<SHELL>
Put generated file here :
* Fish https://fishshell.com/docs/current/completions.html#where-to-put-completions
* Others shells ; Don't know, MR are welcome
[possible values: bash, elvish, fish, powershell, zsh]
OPTIONS:
-h, --help
Print help information
Hooks
git-gamble
provides his own custom hooks :
pre-gamble <GAMBLED>
pre-gamble
hook is executed with one argument<GAMBLED>
post-gamble <GAMBLED> <ACTUAL>
post-gamble
hook is executed with two arguments<GAMBLED>
and<ACTUAL>
Where :
<GAMBLED>
ispass
orfail
<ACTUAL>
ispass
orfail
Custom hooks of git-gamble
are like any other client-side hooks :
- a hook is a file
- a hook must be in the
$GIT_DIR/hooks/
folder- or in the folder configured by
git config core.hooksPath
- or in the folder configured by
- a hook must be executable (
chmod +x .git/hooks/*-gamble
) - will not be executed if any of these options are used:
--no-verify
--dry-run
Check the hooks
' folder for examples of use
post-gamble.sample
is specially adapted to near real-time collaborationpost-gamble
is a simple assistant that displays tips based on the result of the gamble
The following diagram shows when custom hooks are executed in relation to normal git hooks
flowchart LR
subgraph git-gamble's hooks' lifecyle
direction TB
git-gamble([git-gamble\n--pass OR --fail])
--> pre-gamble[pre-gamble\npass OR fail]:::gitGambleHookStyle
--> GAMBLE_TEST_COMMAND([exec $GAMBLE_TEST_COMMAND]):::gitGambleInternalStyle
--> gamble{Result ?}:::gitGambleInternalStyle
gamble -->|Success| Success
subgraph Success
direction TB
git_add([git add --all]):::gitGambleInternalStyle
--> git_commit([git commit]):::gitGambleInternalStyle
--> pre-commit:::gitHookStyle
--> prepare-commit-msg[prepare-commit-msg\n$GIT_DIR/COMMIT_EDITMSG\nmessage]:::gitHookStyle
--> commit-msg[commit-msg\n$GIT_DIR/COMMIT_EDITMSG]:::gitHookStyle
--> post-commit:::gitHookStyle
post-commit --> rewritten?
rewritten?{{"Last commit rewritten ?\nWhen gambling fail\nafter another gamble fail"}}:::gitGambleInternalStyle
rewritten? -->|Yes| post-rewrite[post-rewrite\namend]:::gitHookStyle --> post-gamble-success
rewritten? -->|No| post-gamble-success
post-gamble-success[post-gamble\npass OR fail\nsuccess]:::gitGambleHookStyle
end
gamble -->|Error| Error
subgraph Error
direction TB
git_reset([git reset --hard]):::gitGambleInternalStyle
--> post-gamble-error[post-gamble\npass OR fail\nerror]:::gitGambleHookStyle
end
end
subgraph Legend
direction TB
subgraph Legend_[" "]
direction LR
command([Command executed by user])
git-gamble_command([Command executed by git-gamble]):::gitGambleInternalStyle
condition{Condition ?}:::gitGambleInternalStyle
end
subgraph Hooks
direction LR
hook[git's hook]:::gitHookStyle
hook_with_argument[git's hook\nfirst argument\nsecond argument]:::gitHookStyle
git-gamble_hook_with_argument[git-gamble's hook\nfirst argument\nsecond argument]:::gitGambleHookStyle
end
end
classDef gitHookStyle fill:#f05133,color:black,stroke:black;
classDef gitGambleHookStyle fill:#5a3730,color:white,stroke:white;
classDef gitGambleInternalStyle fill:#411d16,color:white,stroke:white;
When to use it ?
- You want to :
- learn nor practice TDD
- learn nor practice TCR without the drawbacks
- practice a new language
- You follow the Test F.I.R.S.T. Principles
Backlog
- when revert ->
git clean
#3 git workspace
supportgit 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
- optional hook to revert if not gambled in a delay
- branch based developement
- 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 ?
- re-use
- stash instead of revert ?
- shell completion
- in the package ?
- Cargo
- AppImage
- Chocolatey
- for
git gamble
not onlygit-gamble
- in the package ?
Distribution / publishing backlog
- OS distribution
- Linux
- RPM
cargo-rpm
nix bundle
- make AppImage updatable
- bintray-zsync|pinage404|git-gamble-AppImages|git-gamble|git-gamble-_latestVersion-x86_64.AppImage.zsync
- SnapCraft ?
- FlatPak ?
fpm
: tool that help to generate to several packages- document AppImage with firejail ?
- document AppImage with bubblewrap ?
- Open Build Service seems to be a service that build for every Linux targets
- it can be use
- thougth REST
- badly documented
- with
ocs
a CLI who seems to be a VCS like SVN (commit = commit + push)- who use the REST API under the hood
- thougth REST
- it can be use
- RPM
- Container Image (Docker) ?
- Awesome Rust Deployment
- Awesome Rust Platform Specific
- Linux
- permanent URL to download latest version
- symlinks to URL containing the version name ?
- using GitLab Pages ?
- versioned Homebrew Formula
- Use Cargo-Release to bump version
- how to update sha256 in the versioned file ?
Adding package to the X packages repository
Where the X packages repository is e.g. Nixpgks, Debian, Homebrew, Chocolatey ...
Feel free to do it, we don't plan to do it at the moment, it's too long to learn and understand how each of them works
If you do it, please file an issue or open an MR to update the documentation
CheckList
- package in local
- package in CI
- upload
- make public available
- complete how to install
- manual test
- update backlog
Technical improvement opportunities
- licence check
- cargo license
- cargo deny
- smaller binary
- cargo bloat
- cargo deps
- refactor to iterate over
Shell
enum
's values instead of having an hard-coded array
Reinvent the wheel
Why reinvent the wheel?
This script already works well
Because i would like to learn Rust ¯\_(ツ)_/¯
Contributing
Any contributions (feedback, bug report, merge request ...) are welcome
Respect the code of conduct
Follow Keep a Changelog
Development
Setup
To contribute with merge request
Gitpod
Simple
Install Direnv
Install Nix
Let direnv
automagically set up the environment by executing the following command in the project directory
direnv allow
Troubleshooting
If you get an error like this one when entering in the folder
direnv: loading ~/Project/git-gamble/.envrc
direnv: using nix
direnv: using cached derivation
direnv: eval /home/pinage404/Project/git-gamble/.direnv/cache-.336020.2128d0aa28e
direnv: loading ./script/setup_variables.sh
Compiling git-gamble v2.4.0-alpha.0 (/home/pinage404/Project/git-gamble)
direnv: ([/nix/store/19arfqh2anf3cxzy8zsiqp08xv6iq6nl-direnv-2.29.0/bin/direnv export fish]) is taking a while to execute. Use CTRL-C to give up.
error: linker `cc` not found
|
= note: No such file or directory (os error 2)
error: could not compile `git-gamble` due to previous error
Just run the following command to fix it
direnv reload
Help wanted to permanently fix this
Manual
Debug
There are some logs in the programs, pretty_env_logger
is used to display them
There are 5 levels of logging (from the lightest to the most verbose) :
error
warn
info
debug
trace
The git-gamble
logs are "hidden" behind the with_log
feature
The option --features with_log
(or --all-features
) must be added to each cargo
command for which you want to see logs (e.g.) :
cargo build --all-features
cargo run --all-features
cargo test --all-features
Then, to display logs, add this environment variable :
export RUST_LOG="git_gamble=debug"
To display really everything :
export RUST_LOG="trace"
There are other possibilities for logging in the env_logger
documentation
Deployment
Just run cargo release (in a wide terminal, in order to have --help
not truncated in the usage section)
cargo release
Dependencies
~3.5–9MB
~179K SLoC