From 4b9583c5379121a65bfb3b0866b7bfd593d8f9f1 Mon Sep 17 00:00:00 2001 From: sudoforge Date: Tue, 8 Apr 2025 03:49:06 -0700 Subject: docs: update install, contrib, and usage documentation This change refactors documentation, especially //:README.md, //:CONTRIBUTING.md, and centralized most of the rest of the contributing and usage documentation into `//doc`. Documentation changes focus on cleaning up erroneous language, reformatting, and restructuring docs in order to reduce visual noise - the goals are to enable users and contributors to find what they're looking for much more quickly, reduce (sometimes erroneous) duplication, and present a structured approach for where to put docs. Additionally: - Added CI pipeline badge for the `trunk` workflow in `//:README.md` - Converted embedded emoji characters to GitHub's emoji syntax - Moved most sections with image and installation instructions into `
` elements - Replaced references to gitter with matrix - Introduced `treefmt-nix` to `devShells.default` in the flake, and all non-generated documentation was formatted with `nix fmt` (running `mdformat` under the hood) - Regenerated //doc/md and //doc/man and refactored inline docs from various pages that were iterating out command line details so that they simply point to //doc/md instead - Rewrote contributing docs to focus on using `nix`, to ensure that the development shell is used. This enforces consistency across different platforms with the revision and configuration of each tool we use, and simplifies the onboarding story for contributors -- they only need to install and configure nix (and optionally direnv). A dev container will be provided in the future [0] as an alternative for users on Windows (who can use WSL) or want to avoid installing `nix`. [0]: https://github.com/git-bug/git-bug/issues/1364 Closes: #1212 #1276 #1330 #1357 Change-Id: I6f4b5f5ca73780cecf66a553cce80aa3f75df2ce --- .envrc | 1 + .github/FUNDING.yml | 3 +- .github/dependabot.yml | 13 +- .github/workflows/build-and-test.yml | 18 ++ .github/workflows/cron.yml | 1 + .github/workflows/lifecycle.yml | 1 + .github/workflows/lint.yml | 50 +--- .github/workflows/release.yml | 1 + .github/workflows/scan.yml | 5 +- CONTRIBUTING.md | 283 ++++++++++++++++++----- INSTALLATION.md | 263 +++++++++++++++++++++ Makefile | 6 +- README.md | 402 +++++++++------------------------ api/graphql/gqlgen.yml | 1 + bridge/gitlab/export_test.go | 12 +- bridge/gitlab/import.go | 2 +- doc/README.md | 30 ++- doc/architecture.md | 103 --------- doc/assets/bridge-workflow.png | Bin 0 -> 24172 bytes doc/assets/bug-graph.png | Bin 0 -> 56863 bytes doc/assets/merge-1.png | Bin 0 -> 56989 bytes doc/assets/merge-2.png | Bin 0 -> 65479 bytes doc/assets/native-workflow.png | Bin 0 -> 26582 bytes doc/assets/operations.png | Bin 0 -> 12842 bytes doc/assets/tui-recording.gif | Bin 0 -> 879036 bytes doc/assets/web-screenshot-comments.png | Bin 0 -> 109054 bytes doc/assets/web-screenshot-feed.png | Bin 0 -> 92028 bytes doc/assets/webui-workflow.png | Bin 0 -> 27271 bytes doc/bug-graph-1.png | Bin 56863 -> 0 bytes doc/cli-convention.md | 13 -- doc/design/architecture.md | 149 ++++++++++++ doc/design/bridges/jira.md | 379 +++++++++++++++++++++++++++++++ doc/design/cli-convention.md | 13 ++ doc/design/data-model.md | 215 ++++++++++++++++++ doc/feature-matrix.md | 151 +++++++++++++ doc/feature_matrix.md | 137 ----------- doc/gen_docs.go | 84 ------- doc/generate.go | 110 +++++++++ doc/howto-github.md | 80 ------- doc/jira_bridge.md | 377 ------------------------------- doc/merge1.png | Bin 56989 -> 0 bytes doc/merge2.png | Bin 65479 -> 0 bytes doc/model.md | 145 ------------ doc/operations.png | Bin 12842 -> 0 bytes doc/queries.md | 113 --------- doc/usage/bridges.md | 113 +++++++++ doc/usage/interfaces.md | 66 ++++++ doc/usage/query-language.md | 166 ++++++++++++++ doc/usage/workflows.md | 62 +++++ entity/dag/example_test.go | 2 +- flake-hook.bash | 16 ++ flake.lock | 69 +++++- flake.nix | 62 ++--- git-bug.go | 4 +- misc/completion/gen_completion.go | 127 ----------- misc/completion/generate.go | 127 +++++++++++ misc/diagrams/Readme.md | 1 - misc/diagrams/bridge_workflow.png | Bin 24172 -> 0 bytes misc/diagrams/native_workflow.png | Bin 26582 -> 0 bytes misc/diagrams/webui-workflow.png | Bin 27271 -> 0 bytes misc/termui_recording.gif | Bin 879036 -> 0 bytes misc/termui_recording.svg | 43 ---- misc/webui1.png | Bin 92028 -> 0 bytes misc/webui2.png | Bin 109054 -> 0 bytes treefmt.nix | 86 +++++++ webui/README.md | 35 +++ webui/Readme.md | 35 --- 67 files changed, 2440 insertions(+), 1735 deletions(-) create mode 100644 INSTALLATION.md delete mode 100644 doc/architecture.md create mode 100644 doc/assets/bridge-workflow.png create mode 100644 doc/assets/bug-graph.png create mode 100644 doc/assets/merge-1.png create mode 100644 doc/assets/merge-2.png create mode 100644 doc/assets/native-workflow.png create mode 100644 doc/assets/operations.png create mode 100644 doc/assets/tui-recording.gif create mode 100644 doc/assets/web-screenshot-comments.png create mode 100644 doc/assets/web-screenshot-feed.png create mode 100644 doc/assets/webui-workflow.png delete mode 100644 doc/bug-graph-1.png delete mode 100644 doc/cli-convention.md create mode 100644 doc/design/architecture.md create mode 100644 doc/design/bridges/jira.md create mode 100644 doc/design/cli-convention.md create mode 100644 doc/design/data-model.md create mode 100644 doc/feature-matrix.md delete mode 100644 doc/feature_matrix.md delete mode 100644 doc/gen_docs.go create mode 100644 doc/generate.go delete mode 100644 doc/howto-github.md delete mode 100644 doc/jira_bridge.md delete mode 100644 doc/merge1.png delete mode 100644 doc/merge2.png delete mode 100644 doc/model.md delete mode 100644 doc/operations.png delete mode 100644 doc/queries.md create mode 100644 doc/usage/bridges.md create mode 100644 doc/usage/interfaces.md create mode 100644 doc/usage/query-language.md create mode 100644 doc/usage/workflows.md create mode 100644 flake-hook.bash delete mode 100644 misc/completion/gen_completion.go create mode 100644 misc/completion/generate.go delete mode 100644 misc/diagrams/Readme.md delete mode 100644 misc/diagrams/bridge_workflow.png delete mode 100644 misc/diagrams/native_workflow.png delete mode 100644 misc/diagrams/webui-workflow.png delete mode 100644 misc/termui_recording.gif delete mode 100644 misc/termui_recording.svg delete mode 100644 misc/webui1.png delete mode 100644 misc/webui2.png create mode 100644 treefmt.nix create mode 100644 webui/README.md delete mode 100644 webui/Readme.md diff --git a/.envrc b/.envrc index 9b41f79b..efba7f6e 100644 --- a/.envrc +++ b/.envrc @@ -18,3 +18,4 @@ use flake # files to watch watch_file .envrc.local +watch_file flake-hook.bash diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index dca4e756..48d8a862 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,2 @@ -# These are supported funding model platforms - +--- open_collective: git-bug diff --git a/.github/dependabot.yml b/.github/dependabot.yml index bd192262..cbad80b9 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,8 +1,9 @@ +--- version: 2 updates: -- package-ecosystem: gomod - directory: "/" - schedule: - interval: daily - time: "04:00" - open-pull-requests-limit: 10 + - package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + time: "04:00" + open-pull-requests-limit: 10 diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 9b36a648..fb9526a8 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -1,3 +1,4 @@ +--- name: build-and-test on: @@ -57,3 +58,20 @@ jobs: - name: Test run: make test + + with-nix: + strategy: + matrix: + platform: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.platform }} + steps: + # refs/tags/4.2.2 @ 2025-04-10 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 + + # refs/heads/main @ 2025-04-10 + - uses: DeterminateSystems/nix-installer-action@0d28deea2bab0f135fcdbb0bd8e4c6ba469c7b32 + + # refs/heads/main @ 2025-04-10 + - uses: nicknovitski/nix-develop@5da6ac475f1ffbcf54ee562fa3056646e146be95 + + - run: nix flake check diff --git a/.github/workflows/cron.yml b/.github/workflows/cron.yml index 13147a0c..85ee78c1 100644 --- a/.github/workflows/cron.yml +++ b/.github/workflows/cron.yml @@ -1,3 +1,4 @@ +--- name: cron on: diff --git a/.github/workflows/lifecycle.yml b/.github/workflows/lifecycle.yml index a52c6466..50e45996 100644 --- a/.github/workflows/lifecycle.yml +++ b/.github/workflows/lifecycle.yml @@ -1,3 +1,4 @@ +--- name: lifecycle on: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 6b6434d2..09bf6fcc 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,40 +1,10 @@ +--- name: lint on: workflow_call: jobs: - filter: - name: filter - runs-on: ubuntu-latest - outputs: - golang: ${{ steps.filter.outputs.golang }} - golang_files: ${{ steps.filter.outputs.golang_files }} - steps: - - uses: actions/checkout@v4 - - uses: dorny/paths-filter@v3 - id: filter - with: - list-files: shell - filters: | - golang: - - added|modified: '**/*.go' - - added|modified: '/go.sum' - - added|modified: '/go.mod' - - codeql: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - # We must fetch at least the immediate parents so that if this is - # a pull request then we can checkout the head. - fetch-depth: 2 - - - run: git checkout HEAD^2 - if: ${{ github.event_name == 'pull_request' }} - spelling: runs-on: ubuntu-latest steps: @@ -43,21 +13,3 @@ jobs: - name: Check spelling uses: codespell-project/actions-codespell@v2 - - go: - runs-on: ubuntu-latest - needs: - - filter - if: needs.filter.outputs.golang == 'true' - steps: - - name: Install Go - uses: actions/setup-go@v5 - with: - go-version: 1.22.5 - - - name: Checkout code - uses: actions/checkout@v4 - - - name: Check Code Formatting - run: | - test -z "$(gofmt -d ${{ needs.filter.outputs.golang_files }})" || exit 1 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 335bec2d..95c85fe9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,3 +1,4 @@ +--- name: Build release binaries on: diff --git a/.github/workflows/scan.yml b/.github/workflows/scan.yml index ed69aed7..3a194af0 100644 --- a/.github/workflows/scan.yml +++ b/.github/workflows/scan.yml @@ -1,10 +1,11 @@ +--- name: scan on: push: - branches: [ master ] + branches: [master] pull_request: - branches: [ master ] + branches: [master] schedule: - cron: '0 12 * * 6' diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4d3fd58a..ebe65ab2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,99 +1,264 @@ -# Contributing +# Contributing :wave: Hey there! Thanks for considering taking the time to contribute to `git-bug`. This page contains some general guidelines, and instructions for getting started as a contributor to this project. -## Get the source code + + +- [Get the source code](#get-the-source-code) +- [Software requirements](#software-requirements) + - [1.0 | Install nix](#10--install-nix) + - [2.0 | Enable `nix-command` and `flakes`](#20--enable-nix-command-and-flakes) + - [3.0 | Install and configure `direnv`](#30--install-and-configure-direnv) +- [4.0 | Post-installation tasks](#40--post-installation-tasks) + - [4.1 | Open a new shell](#41--open-a-new-shell) +- [Useful development commands](#useful-development-commands) +- [Submitting changes](#submitting-changes) + + + +## Get the source code Clone this repository to your system in a way you're comfortable with. Below, we -show a command that [clones the repository][how-to-clone] using SSH, and places -it in `~/code/git-bug`. +show a command that clones the repository using SSH, and places it in +`~/code/git-bug`. ``` git clone git@github.com:git-bug/git-bug ~/code/git-bug ``` -> [!IMPORTANT] +> [!TIP] > If you wish to clone the repository to another location on disk, change -> `~/code/git-bug` to your desired path. The rest of this documentation will -> refer to `~/code/git-bug` in all instances, so make sure you change them -> there, too. +> `~/code/git-bug` to your desired path (e.g. your current directory can be used +> with `.` or by omitting the path argument). The rest of this documentation +> will refer to `~/code/git-bug` in all instances, so make sure you change them +> there to match the location you've cloned the repository. -## Software recommendations +## Software requirements -While you can install Golang and hack on this project on your own, you're likely -to have a better experience if you install the following software. +This repository uses `nix` to provide a consistent development environment, +ensuring that each contributor has the same revision of each dependency and tool +installed. It is **strongly** encouraged to use `nix` when contributing to +`git-bug` to remove the "it works on my machine" class of errors, and ensure you +have a smoother experience passing the CI pipelines (wrt formatting and such). -### `nix` (_recommended_) +While you can manually install the [tools and packages we use](./flake.nix) and +hack on this project on your own, you will miss out on the hermeticity and +standardization that our development shell provides. You may end up fighting +with failing CI pipelines more often, or have to figure out how to perform +various tasks on your own. Using the development shell ensures you always have +every tool you need to contribute to `git-bug`, and that each tool is always +configured correctly. -[`nix`][install/nix] is used in this repository to provide a common development -shell, with a complete set of the appropriate version of the tools used to work -on `git-bug`. +Because of this, we encourage all contributors to follow the documentation below +to install the dependencies for the development shell. -You can install `nix` by following [the official instructions][install/nix], but -we recommend adding some additional flags in order to enable some (technically -experimental, but largely stable) configuration options: +> [!NOTE] +> In the future, we will provide a container image with `nix` pre-installed and +> everything configured to get you started. This will be able to be pulled like +> any other image, and will be made compatible with VSCode's "devcontainer" +> feature and GitHub Codespaces. +> +> For more information, see the [tracking issue][issue/1364]. -``` -curl -L https://nixos.org/nix/install | sh -s -- --daemon --nix-extra-conf-file <( \ -cat << EOF | sed -e 's/^ *//' - experimental-features = nix-command flakes -EOF -) -``` +______________________________________________________________________ -> [!TIP] -> Make sure you read the prompts from the installation script carefully. After -> installation, you'll need to start a new shell. +### 1.0 | Install nix + +To install `nix`, you can follow [the official instructions][install/nix]. + +We recommend following the instructions for `multi-user mode` where applicable, +instead of `single-user mode`. + +> [!IMPORTANT] +> The rest of this document assumes you have successfully installed `nix`. + +______________________________________________________________________ + +### 2.0 | Enable `nix-command` and `flakes` + +`nix-command` and `flakes` are two optional configuration properties that we +depend on in order to provide the development shell. You'll need to make sure +that these are enabled. -### `direnv` (_recommended_) +
+NixOS -[`direnv`][install/direnv] is used to automatically activate the development -shell (because of the `.envrc` in the root of this repository). +Add the following to your system configuration: -#### With `nix` +
+nix.settings.experimental-features = [ "nix-command" "flakes" ];
+
+ +
+ +
+Other + +Add the following to `~/.config/nix.conf` or `/etc/nix/nix.conf`: + +
+experimental-features = nix-command flakes
+
+ +
> [!IMPORTANT] -> If you are not comfortable with `nix`, we recommend [installing `direnv` -> without nix][install/install-direnv-without-nix]. +> The rest of this document assume you have enabled these options. -``` +______________________________________________________________________ + +### 3.0 | Install and configure `direnv` + +[`direnv`][install/direnv] can be used to automatically activate the development +shell (using [`//:.envrc`][envrc]). It can be installed either with `nix`, or +independently. + +
+With nix (suggested for users new to nix) + +
 nix --extra-experimental-options 'flakes nix-command' profile install nixpkgs\#direnv
-```
+
-There's a second step that is critical -- be sure to [configure your -shell][install/direnv/shell]. +Next, run the following commands to apply the **optional** configuration for +direnv. Be sure to change references to `~/code/git-bug` if you have cloned the +repository somewhere else. -#### Without `nix` +Create a configuration file for direnv -You can install `direnv` by following [the official -instructions][install/direnv]. There's a second step that is critical -- be sure -to [configure your shell][install/direnv/shell]. +
touch ~/.config/direnv/direnv.toml
-After installation, you'll need to start a new shell. +Disable the warning for shells with longer load times -##### direnv configuration (_recommended_) +_This is optional, but recommended, as it helps reduce visual clutter._ -If you install `direnv`, it is recommended to set the following configuration -options to improve your user experience. At the time of writing, these go in -`~/.config/direnv/direnv.toml`. +
+nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv/direnv.toml \
+  put -t int -v 0 ".global.warn_timeout"
+
-This configuration, namely, the `whitelist.exact` property, will ensure that -`direnv` always automatically sources the `.envrc` in this repository. +Disable printing of the environment variables that change -``` -hide_env_diff = true -warn_timeout = 0 +_This is optional, but recommended, as it helps reduce visual clutter._ -[whitelist] -exact = ["~/code/git-bug/.envrc"] -``` +
+nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv/direnv.toml \
+  put -t bool -v true ".global.hide_env_diff"
+
-> [!IMPORTANT] -> Make sure you change the `~/code/git-bug` portion of the string to the -> appropriate path (the path that you cloned this repository to on your system). +Automatically activate the development shell -[install/nix]: https://nix.dev/install-nix +_This is optional, but strongly recommended._ + +
+nix run nixpkgs\#dasel -- -r toml -f ~/.config/direnv.toml \
+  put -v "~/code/git-bug/.envrc" ".whitelist.exact[]"
+
+ +Alternatively, simply run `direnv allow` after moving into the repository for +the first time. + +> **IMPORTANT**
If you choose not to allow the shell to be automatically +> activated, you will need to type `nix develop` every time you want to activate +> it, and this will swap you into bash and change your prompt. You'll have a far +> better experience allowing `direnv` to automatically manage activation and +> deactivation. + +Configure your shell + +This final step is crucial -- be sure to +[configure your shell][install/direnv/shell] for direnv. + +
+ +
+Using home-manager + +
+programs.direnv = {
+  enable = true;
+  nix-direnv.enable = true;
+
+  # one of the following, depending on your shell
+  # enableZshIntegration = true;
+  # enableBashIntegration = true;
+  # enableFishIntegration = true;
+  # enableNushellIntegration = true;
+
+  config = {
+    hide_env_diff = true;
+    warn_timeout = 0;
+
+    whitelist.exact = [ "~/code/git-bug/.envrc" ];
+  };
+}
+
+ +
+ +______________________________________________________________________ + +## 4.0 | Post-installation tasks + +Congratulations! If you've reached this section of the documentation, chances +are that you have a working development environment for contributing to this +repository. Read below for some additional tasks you should complete. + +### 4.1 | Open a new shell + +In order for the installation to take effect, you will need to open a new shell. +It is recommended to do this and complete the test (described below) prior to +closing the shell you ran the installation script in, just in case you run into +issues and need to refer to any output it provided. + +______________________________________________________________________ + +## Useful development commands + +- `make build` - build `git-bug` and output the binary at `./git-bug` + - `make build/debug` - build a debugger-friendly binary +- `make install` - build `git-bug`, and install it to `$GOPATH/bin` +- `nix fmt` - format everything (configured in [`//:treefmt.nix`][treefmt]) + - `nix fmt ` to restrict the scope to given directories or files + - see `nix fmt --help` for more information +- `go generate` - generate cli documentation and shell completion files + - this is automatically executed by many `make` targets, e.g. `make build` +- `go test ./commands -update` - update golden files used in tests + - this is _required_ when changing the output of CLI commands, if the files in + `//commands/testdata/...` do not match the new output format + +> [!NOTE] +> There is an ongoing effort to simplify the commands you need to call in our +> environment, with a trend toward `nix`, while `make` may continue to be +> supported for common workflows (e.g. building a release binary). + +## Submitting changes + +You can submit your changes in the typical fork-based workflow to this +repository on GitHub. That is: fork this repository, push to a branch to your +repository, and create a pull request. + +If you are in the development shell, you have the `gh` command line tool +available for use with github. + +______________________________________________________________________ + +##### See more + +- [An overview of the architecture][doc/design/arch] +- [Learn about the data model][doc/design/model] +- [Creating a new bridge][doc/design/bridges] +- [See how to create a new entity][example-entity] + +[doc/design/arch]: ./doc/design/architecture.md +[doc/design/bridges]: ./doc/design/bridges.md +[doc/design/model]: ./doc/design/data-model.md +[envrc]: ./.envrc +[example-entity]: ./entity/dag/example_test.go [install/direnv]: https://github.com/direnv/direnv/blob/master/docs/installation.md [install/direnv/shell]: https://github.com/direnv/direnv/blob/master/docs/hook.md +[install/nix]: https://nix.dev/install-nix +[issue/1364]: https://github.com/git-bug/git-bug/issues/1364 +[treefmt]: ./treefmt.nix diff --git a/INSTALLATION.md b/INSTALLATION.md new file mode 100644 index 00000000..d4a2f457 --- /dev/null +++ b/INSTALLATION.md @@ -0,0 +1,263 @@ + + +# Installation Guide + +`git-bug` is distributed as a single binary, and is available for multiple +platforms. Follow this document for instructions on how to install `git-bug`, +and verify your installation. + + + +- [Download a pre-compiled release binary](#download-a-pre-compiled-release-binary) +- [Linux](#linux) + - [Arch Linux](#arch-linux) + - [Nixpkgs](#nixpkgs) +- [FreeBSD](#freebsd) +- [MacOS](#macos) +- [Windows](#windows) +- [Build from source](#build-from-source) +- [Verify your installation](#verify-your-installation) + + + +## Download a pre-compiled release binary + +You can download the latest release binary from [the release page][rel/latest], +making sure to grab the appropriate binary for your system. + +Next, rename the binary to `git-bug`, or `git-bug.exe` if you're using Windows. + +Finally, place the binary in a directory that's in your `PATH`. That's it! You +should now have `git-bug` available as a command line tool. + +## Linux + +`git-bug` is available on a variety of Linux distributions, but how you install +it depends on your distribution and package manager(s), as there is no standard +package manager common to all distributions. + +### Arch Linux + +`git-bug` is available in the [Arch Linux User Repository (AUR)][p/aur]. + +Below, you'll find a **non-exhaustive** list of commands that use common third +party tools for installing packages from the AUR. + +
Using aurutils +
aur sync git-bug-bin && pacman -Syu git-bug-bin
+
+ +
Using yay +
yay -S git-bug-bin
+
+ +### Nixpkgs + +`git-bug` is available via [nixpkgs][p/nix]. + +
Using home-manager +
+home.package = with pkgs; [
+  git-bug
+];
+
+
+ +
Using system configuration +
+environment.systemPackages = with pkgs; [
+  git-bug
+];
+
+
+ +
Using nix profile +
nix profile install nixpkgs\#git-bug
+
+ +
Temporary installation with nix shell +
+nix shell nixpkgs\#git-bug
+
+
+ +## FreeBSD + +`git-bug` is available on FreeBSD through a few different methods. + +
Using pkg +
pkg install git-bug
+
+ +
Using the ports collection +
make -C /usr/ports/devel/git-bug install clean
+
+ +## MacOS + +`git-bug` is shipped via [**Homebrew**][brew.sh]: + +``` +brew install git-bug +``` + +## Windows + +`git-bug` is shipped via `scoop`: + +``` +scoop install git-bug +``` + +## Build from source + +You can also build `git-bug` from source, if you wish. You'll need the following +dependencies: + +- `git` +- `go` +- `make` + +Ensure that the `go` binary directory (`$GOPATH/bin`) is in your `PATH`. It is +recommended to set this within your shell configuration file(s), such as +`~/.zprofile` or `~/.bashrc`. + +``` +export PATH=$PATH:$(go env GOROOT)/bin:$(go env GOPATH)/bin +``` + +> [!NOTE] +> The commands below assume you do not want to keep the repository on disk, and +> thus clones the repository to a new temporary directory and performs a +> lightweight clone in order to reduce network latency and data transfer. +> +> As a result, the repository cloned during these steps will not contain the +> full history. If that is important to you, clone the repository using the +> method you prefer, check out your preferred revision, and run `make install`. + +**First, create a new repository on disk:** + +``` +cd $(mktemp -d) && git init . +``` + +**Next, set the remote to the upstream source:** + +``` +git remote add origin git@github.com:git-bug/git-bug.git +``` + +Next, choose whether you want to build from a release tag, branch, or +development head and expand the instructions below. + +
Build from a release tag + +First, list all of the tags from the repository (we use `sed` in the command +below to filter out some unnecessary visual noise): + +
+git ls-remote origin refs/tags/\* | sed -e 's/refs\/tags\///'
+
+ +You'll see output similar to: + +
+c1a08111b603403d4ee0a78c1214f322fecaa3ca        0.1.0
+d959acc29dcbc467790ae87389f9569bb830c8c6        0.2.0
+ad59f77fd425b00ae4b8d7360a64dc3dc1c73bd0        0.3.0
+...
+
+ +
Tip

+The tags are in the right-most column. Old revisions up to and +including 0.7.1 do not contain a v prefix, however, all +revisions after, do. +

+ +Select the tag you wish to build, and fetch it using the command below. Be sure +to replace REPLACE-ME with the tag you selected: + +
+git fetch --no-tags --depth 1 origin +refs/tags/REPLACE-ME:refs/tags/REPLACE-ME
+
+ +
NOTE

+The --no-tags flag might seem out of place, since we are +fetching a tag, but it isn't -- the reason we use this is avoid fetching other +tags, in case you have fetch.pruneTags enabled in your global +configuration, which causes git to fetch all tags. +

+ +Next, check out the tag, replacing REPLACE-ME with the tag you +selected: + +
+git checkout REPLACE-ME
+
+ +Finally, run the install target from //:Makefile: + +
+make install
+
+ +This will build git-bug and place it in your Go binary directory. + +
+ +
+ +Build the unstable development HEAD + + +First, fetch the most recent commit for the default branch: + +
+git fetch --no-tags --depth 1 origin HEAD:refs/remotes/origin/HEAD
+
+ +Next, check out the tree you pulled: + +
+git checkout origin/HEAD
+
+ +Finally, run the install target from //:Makefile: + +
+make install
+
+ +This will build git-bug and place it in your Go binary directory. + +
+ +## Verify your installation + +To verify that `git-bug` was installed correctly, you can run the following +command. If you see output similar to what's shown below (and without any +errors), you're all set! + +``` +git bug version +``` + +______________________________________________________________________ + +##### See more + +- [Documentation home][docs/home] + +[brew.sh]: https://brew.sh +[docs/home]: ./doc +[p/aur]: https://aur.archlinux.org/packages/git-bug-bin +[p/nix]: https://github.com/NixOS/nixpkgs/blob/nixos-unstable/pkgs/applications/version-management/git-bug/default.nix +[rel/latest]: https://github.com/git-bug/git-bug/releases/latest diff --git a/Makefile b/Makefile index 404612dc..b8cc3114 100644 --- a/Makefile +++ b/Makefile @@ -19,9 +19,9 @@ build: go generate go build -ldflags "$(LDFLAGS)" . -# produce a build debugger friendly -.PHONY: debug-build -debug-build: +# produce a debugger-friendly build +.PHONY: build/debug +build/debug: go generate go build -ldflags "$(LDFLAGS)" -gcflags=all="-N -l" . diff --git a/README.md b/README.md index 35382345..7b5f921f 100644 --- a/README.md +++ b/README.md @@ -1,336 +1,140 @@ -

- -

-

git-bug

-
-[![Backers on Open Collective](https://opencollective.com/git-bug/backers/badge.svg)](#backers) -[![Sponsors on Open Collective](https://opencollective.com/git-bug/sponsors/badge.svg)](#sponsors) -[![License: GPL v3](https://img.shields.io/badge/License-GPLv3+-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) -[![GoDoc](https://godoc.org/github.com/git-bug/git-bug?status.svg)](https://godoc.org/github.com/git-bug/git-bug) -[![Go Report Card](https://goreportcard.com/badge/github.com/git-bug/git-bug)](https://goreportcard.com/report/github.com/git-bug/git-bug) -[![Gitter chat](https://badges.gitter.im/gitterHQ/gitter.png)](https://gitter.im/the-git-bug/Lobby) - -
- -`git-bug` is a bug tracker that: - -- **is fully embedded in git**: you only need your git repository to have a bug tracker -- **is distributed**: use your normal git remote to collaborate, push and pull your bugs! -- **works offline**: in a plane or under the sea? Keep reading and writing bugs! -- **prevents vendor lock-in**: your usual service is down or went bad? You already have a full backup. -- **is fast**: listing bugs or opening them is a matter of milliseconds -- **doesn't pollute your project**: no files are added in your project -- **integrates with your tooling**: use the UI you like (CLI, terminal, web) or integrate with your existing tools through the CLI or the GraphQL API -- **bridges to other bug trackers**: use [bridges](#bridges) to import and export to other trackers. - -## Help needed! - -This project has grown bigger than I can handle by myself, especially with a day job. I'm looking for people to help on or maintain part of it: -- each bridges (go) -- the terminal UI (go) -- the web UI (Typescript/React/GraphQL) - -Individually, those pieces are not especially complex but doing everything make it hard for me to focus on the core where things get more complicated. If this is useful for you or you just want to join the fun, maybe consider it? - -## Installation - -
Pre-compiled binaries - -1. Go to the [release page](https://github.com/git-bug/git-bug/releases/latest) and download the appropriate binary for your system. -2. Copy the binary anywhere in your $PATH -3. Rename the binary to `git-bug` (or `git-bug.exe` on windows) - -That's all ! - -
- -
Windows packages - -* [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/git-bug.json) - ``` - scoop install git-bug - ``` - -
- -
Linux packages - -* [Archlinux (AUR)](https://aur.archlinux.org/packages/?K=git-bug) -* [NixOS](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/version-management/git-and-tools/git-bug/default.nix#L31) - -
- -
macOS packages - -* [Homebrew](https://formulae.brew.sh/formula/git-bug) - ``` - brew install git-bug - ``` - -
- -
FreeBSD package/port - -Install via the package manager - ``` - pkg install git-bug - ``` - -Or from the ports collection - ``` - cd /usr/ports/devel/git-bug && make install clean - ``` - -
- -
Compile from git (unstable) - -```shell -git clone https://github.com/git-bug/git-bug.git -cd git-bug -make install -``` - -If it's not done already, add the golang binary directory in your PATH: - -```bash -export PATH=$PATH:$(go env GOROOT)/bin:$(go env GOPATH)/bin -``` - -
- -## Workflows - -There are multiple ways to use `git-bug`: - -
Native workflow -

- Native workflow -

- -This is the pure `git-bug` experience. In a similar fashion as with code, use `git bug push` and `git bug pull` to push and pull your bugs between git remotes and collaborate with your teammate. - -
- -
Bridge workflow -

- Bridge workflow -

- -As `git-bug` has bridges with other bug-trackers, you can use it as your personal local remote interface. Sync with `git bug bridge pull` and `git bug bridge push`, work from your terminal, integrate into your editor, it's up to you. And it works offline ! - -
- -
Web UI workflow (WIP) -

- Web UI workflow -

- -Often, projects needs to have their bug-tracker public and accept editions from anyone facing a problem. To support this workflow, `git-bug` aims to have the web UI accept external OAuth authentication and act as a public portal. However the web UI is not up to speed for that yet. Contribution are very much welcome! + -
+# git-bug: a decentralized issue tracker -## CLI usage +[![Build Status][ci/badge]][ci/url] -Create a new identity: +[![Backers on Open Collective][backers/badge]][oc] +[![Sponsors on Open Collective][sponsors/badge]][oc] +[![GPL v3 License][license/badge]][license/url] +[![GoDoc][godoc/badge]][godoc/url] +[![Go Report Card][report-card/badge]][report-card/url] +[![Matrix][matrix/badge]][matrix/url] -``` -git bug user create -``` +[Issues] - [Documentation][doc] - [Feedback][discuss] -Create a new bug: - -``` -git bug add -``` - -Your favorite editor will open to write a title and a message. - -You can push your new entry to a remote: -``` -git bug push [] -``` - -And pull for updates: -``` -git bug pull [] -``` - -List existing bugs: -``` -git bug ls -``` - -Filter and sort bugs using a [query](doc/queries.md): -``` -git bug ls "status:open sort:edit" -``` - -Search for bugs by text content: -``` -git bug ls "foo bar" baz -``` - -You can now use commands like `show`, `comment`, `open` or `close` to display and modify bugs. For more details about each command, you can run `git bug --help` or read the [command's documentation](doc/md/git-bug.md). - -## Interactive terminal UI - -An interactive terminal UI is available using the command `git bug termui` to browse and edit bugs. - -![Termui recording](misc/termui_recording.gif) - -## Web UI - -You can launch a rich Web UI with `git bug webui`. - -

- Web UI screenshot 1 -

- -

- Web UI screenshot 2 -

- -This web UI is entirely packed inside the same go binary and serve static content through a localhost http server. - -The web UI interact with the backend through a GraphQL API. The schema is available [here](api/graphql/schema). - -## Bridges - -βœ…: working 🟠: partial implementation ❌: not working - -### Importer implementations - -| | Github | Gitlab | Jira | Launchpad | -|-------------------------------------------------|:------:|:------:|:----:|:---------:| -| **incremental**
(can import more than once) | βœ… | βœ… | βœ… | ❌ | -| **with resume**
(download only new data) | βœ… | βœ… | βœ… | ❌ | -| **identities** | 🟠 | 🟠 | 🟠 | 🟠 | -| **bugs** | βœ… | βœ… | βœ… | 🟠 | -| **board** | ❌ | ❌ | ❌ | ❌ | -| **media/files** | ❌ | ❌ | ❌ | ❌ | -| **automated test suite** | βœ… | βœ… | ❌ | ❌ | - -### Exporter implementations - -| | Github | Gitlab | Jira | Launchpad | -|--------------------------|:------:|:------:|:----:|:---------:| -| **identities** | 🟠 | 🟠 | 🟠 | 🟠 | -| **bug** | βœ… | βœ… | βœ… | ❌ | -| **board** | ❌ | ❌ | ❌ | ❌ | -| **automated test suite** | βœ… | βœ… | ❌ | ❌ | - -#### Bridge usage - -Interactively configure a new github bridge: - -```bash -git bug bridge new -``` - -Or manually: - -```bash -git bug bridge new \ - --name= \ - --target=github \ - --url=https://github.com/git-bug/git-bug \ - --login= \ - --token= -``` - -Import bugs: - -```bash -git bug bridge pull [] -``` - -Export modifications: - -```bash -git bug bridge push [] -``` - -Deleting a bridge: - -```bash -git bug bridge rm [] -``` + -## Internals +## Overview -Interested in how it works ? Have a look at the [data model](doc/model.md) and the [internal bird-view](doc/architecture.md). +[git-bug](https://github.com/git-bug/git-bug) is a standalone, distributed, +offline-first issue management tool that embeds issues, comments, and more as +objects in a git repository (_not files!_), enabling you to push and pull them +to one or more remotes. -Or maybe you want to [make your own distributed data-structure in git](entity/dag/example_test.go) ? + -See also all the [docs](doc). +- [Overview](#overview) +- [Key Features](#key-features) +- [Getting Started](#getting-started) +- [Our Community](#our-community) + - [Backers :star:](#backers-star) + - [Sponsors :star2:](#sponsors-star2) +- [License](#license) -## Misc + -- [Bash, Zsh, fish, powershell completion](misc/completion) -- [ManPages](doc/man) +## Key Features -## Planned features +- **Native Git Storage:** Manage issues, users, and comments directly within + your repository - keeping everything versioned and clutter-free +- **Distributed & Versioned:** Leverage Git’s decentralized architecture to work + offline and sync seamlessly later +- **Lightning Fast:** List and search issues in mere _milliseconds_ +- **Third-Party Bridges:** Easily synchronize issues with platforms like GitHub + and GitLab [using bridges][doc/usage/bridges] +- **Flexible Interfaces:** Choose how you interact - via CLI, TUI, or a web + browser +- **Effortless Integration:** Start managing issues your repository with minimal + setup -The [feature matrix](doc/feature_matrix.md) gives a good overview of what is planned, without being exhaustive. +## Getting Started -Additional planned feature: -- webUI that can be used as a public portal to accept user's input -- inflatable raptor +- :triangular_flag_on_post: **Install:** Check out + [`//:INSTALLATION.md`][doc/install] for step-by-step installation instructions + or explore [the latest release][rel/latest] to get started immediately. +- :page_with_curl: **Explore:** Read [the documentation][doc] to learn how to + use `git-bug` effectively +- :computer: **Contribute:** Interested in hacking on `git-bug`? Head over to + [`//:CONTRIBUTING.md`][contrib] and see how you can help shape the project +- :speech_balloon: **Connect:** Chat with us live on Matrix at + [`#git-bug:matrix.org`][matrix/url] +- :books: **Discuss:** Browse [existing discussions][discuss] or + [start a new one][discuss/new] to ask questions and share ideas -## Contribute +## Our Community -PRs accepted. Drop by the [Gitter lobby](https://gitter.im/the-git-bug/Lobby) or the [Matrix room](https://matrix.to/#/#git-bug:matrix.org) for a chat, look at the [feature matrix](doc/feature_matrix.md) or browse the issues to see what is worked on or discussed. +`git-bug` thrives thanks to the passion of its [contributors], the generosity of +independent [backers][oc], and the strategic support of our [sponsors][oc]. Each +of you plays a crucial role in our journey, and we deeply appreciate every +contribution that helps drive our project forward. -```shell -git clone git@github.com:git-bug/git-bug.git -``` +_[Make a contribution][oc] to support this project and get featured below!_ -You can now run `make` to build the project, or `make install` to install the binary in `$GOPATH/bin/`. +### Backers :star: -To work on the web UI, have a look at [the dedicated Readme.](webui/Readme.md) +
-Some tests for the CLI use golden files, if the output of CLI commands is -changed, run the following command, then inspect the changed files in -`commands/testdata/...` to make sure the output text is as expected: +[![backers][backers/image]][oc] -```shell -go test ./commands -update -``` +
-## Contributors :heart: +### Sponsors :star2: -This project exists thanks to all the people who contribute. - +
+[![][sponsor/0]][sponsor/0/url] -## Backers +
-Thank you to all our backers! πŸ™ [[Become a backer](https://opencollective.com/git-bug#backer)] +## License - +Unless otherwise stated, this project and all assets within it are released +under [GPLv3][license/url] or later, copyright [Michael MurΓ©][gh/mm]. +The `git-bug` logo is authored by and copyright [Viktor Teplov][gh/vandesign], +released under a [CC BY 4.0][license/logo] license. -## Sponsors +______________________________________________________________________ -Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/git-bug#sponsor)] +
- - - - - - - - - - +This project and its vibrant community was initially dreamt up and built by +[Michael MurΓ©][gh/mm]. +Thank you for all of your hard work! -## License +:heart: -Unless otherwise stated, this project is released under the [GPLv3](LICENSE) or later license Β© Michael MurΓ©. +
-The git-bug logo by [Viktor Teplov](https://github.com/vandesign) is released under the [Creative Commons Attribution 4.0 International (CC BY 4.0)](misc/logo/LICENSE) license Β© Viktor Teplov. +[backers/badge]: https://opencollective.com/git-bug/backers/badge.svg +[backers/image]: https://opencollective.com/git-bug/tiers/backer.svg?avatarHeight=50 +[ci/badge]: https://github.com/git-bug/git-bug/actions/workflows/trunk.yml/badge.svg +[ci/url]: https://github.com/git-bug/git-bug/actions/workflows/trunk.yml +[contrib]: ./CONTRIBUTING.md +[contributors]: https://github.com/git-bug/git-bug/graphs/contributors +[discuss]: https://github.com/git-bug/git-bug/discussions +[discuss/new]: https://github.com/git-bug/git-bug/discussions/new/choose +[doc]: ./doc +[doc/install]: ./INSTALLATION.md +[doc/usage/bridges]: ./doc/usage/bridges.md +[gh/mm]: https://github.com/MichaelMure +[gh/vandesign]: https://github.com/vandesign +[godoc/badge]: https://godoc.org/github.com/git-bug/git-bug?status.svg +[godoc/url]: https://godoc.org/github.com/git-bug/git-bug +[issues]: https://github.com/git-bug/git-bug/issues +[license/badge]: https://img.shields.io/badge/License-GPLv3+-blue.svg +[license/logo]: ./misc/logo/LICENSE +[license/url]: ./LICENSE +[matrix/badge]: https://img.shields.io/badge/chat%20on%20matrix-%23238636 +[matrix/url]: https://matrix.to/#/#git-bug:matrix.org +[oc]: https://opencollective.com/git-bug +[rel/latest]: https://github.com/git-bug/git-bug/releases/latest +[report-card/badge]: https://goreportcard.com/badge/github.com/git-bug/git-bug +[report-card/url]: https://goreportcard.com/report/github.com/git-bug/git-bug +[sponsor/0]: https://opencollective.com/git-bug/tiers/sponsor/0/avatar.svg +[sponsor/0/url]: https://opencollective.com/git-bug/sponsor/0/website +[sponsors/badge]: https://opencollective.com/git-bug/sponsors/badge.svg diff --git a/api/graphql/gqlgen.yml b/api/graphql/gqlgen.yml index c20b7618..8d6daf4f 100644 --- a/api/graphql/gqlgen.yml +++ b/api/graphql/gqlgen.yml @@ -1,3 +1,4 @@ +--- schema: "schema/*.graphql" exec: layout: follow-schema diff --git a/bridge/gitlab/export_test.go b/bridge/gitlab/export_test.go index 6846cb21..8098c1d0 100644 --- a/bridge/gitlab/export_test.go +++ b/bridge/gitlab/export_test.go @@ -182,12 +182,12 @@ func TestGitlabPushPull(t *testing.T) { fmt.Println("created repository", projectName) // Make sure to remove the Gitlab repository when the test end - defer func(t *testing.T) { - if err := deleteRepository(context.TODO(), projectID, token); err != nil { - t.Fatal(err) - } - fmt.Println("deleted repository:", projectName) - }(t) + // defer func(t *testing.T) { + // if err := deleteRepository(context.TODO(), projectID, token); err != nil { + // t.Fatal(err) + // } + // fmt.Println("deleted repository:", projectName) + // }(t) interrupt.RegisterCleaner(func() error { return deleteRepository(context.TODO(), projectID, token) diff --git a/bridge/gitlab/import.go b/bridge/gitlab/import.go index b33a2179..b51b924d 100644 --- a/bridge/gitlab/import.go +++ b/bridge/gitlab/import.go @@ -81,7 +81,7 @@ func (gi *gitlabImporter) ImportAll(ctx context.Context, repo *cache.RepoCache, continue } if err := gi.ensureIssueEvent(repo, b, issue, e); err != nil { - err := fmt.Errorf("issue event creation: %v", err) + err := fmt.Errorf("issue event creation: %v (%v)", err, e) out <- core.NewImportError(err, entity.Id(e.ID())) } } diff --git a/doc/README.md b/doc/README.md index e172ffd6..1b75798a 100644 --- a/doc/README.md +++ b/doc/README.md @@ -1,15 +1,27 @@ # Documentation -## For users +## Usage -- [data model](model.md) describes how the data model works and why. -- [query language](queries.md) describes git-bug's query language. -- [How-to: Read and edit offline your Github/Gitlab/Jira issues with git-bug](howto-github.md) +The documentation listed below aims to help provide insight into the usage of +`git-bug`. + +- Read about the different [types of workflows](./usage/workflows.md) and check + the [feature matrix](./feature-matrix.md) to learn about `git-bug` +- Check the [CLI documentation](./md/git-bug.md) for commands and options (or + run `man git-bug` after [installation](../INSTALLATION.md)) +- Filter results using the [query language](./usage/query-language.md) +- Learn how to [sync third party issues](./usage/third-party.md) for offline + reading and editing ## For developers -- :exclamation: [data model](model.md) describes how the data model works and why. -- :exclamation: [internal bird-view](architecture.md) gives an overview of the project architecture. -- :exclamation: [Entity/DAG](../entity/dag/example_test.go) explains how to easily make your own distributed entity in git. -- [query language](queries.md) describes git-bug's query language. -- [JIRA bridge dev notes](jira_bridge.md) +- Read through [`//:CONTRIBUTING.md`][contrib] +- Get a [bird's-eye overview](./design/architecture.md) of the architecture +- Read about the [data model](./design/data-model.md) to gain a deeper + understanding of the internals that comprise `git-bug` +- [`//entity/dag:example_test.go`](../entity/dag/example_test.go) is a good + reference to learn how to create a new distributed entity +- Read the [bridge design documents](./design/bridges) to learn more about each + bridge + +[contrib]: ../CONTRIBUTING.md diff --git a/doc/architecture.md b/doc/architecture.md deleted file mode 100644 index e3a7f0b0..00000000 --- a/doc/architecture.md +++ /dev/null @@ -1,103 +0,0 @@ -# Internal architecture - -This documentation only provides a bird's-eye view of git-bug's internals. For more details, you should read the other documentation and the various comment/documentation scattered in the codebase. - -## Overview - -``` - .--------------. - | | webui | | - | '--------------' | - | .---------------..-----------..------------..--------------. | - | | commands || bridge || termui || graphql | | - | '---------------''-----------''------------''--------------' | - | .----------------------------------------------------------. | - | | cache | | - | |----------------------------------------------------------| | - | | BugCache,BugExcerpt,IdentityCache,IdentityExcerpt | | - | '----------------------------------------------------------' | - | .-----------------------------..---------------------------. | - | | bug || identity | | - | |-----------------------------||---------------------------| | - | | Bug,Operation,Snapshot || Identity,Version | | - | '-----------------------------''---------------------------' | - | .----------------------------------------------------------. | - v | repository | v - '----------------------------------------------------------' -``` - -Here is the internal architecture of git-bug. As you can see, it's a layered architecture. - -As a general rule of thumb, each layer uses the directly underlying layer to access and interact with the data. As an example, the `commands` package will not directly use the `bug` or `repository` package. It will request the data from the `cache` layer and go from there. Of course, the `commands` package will ultimately use types defined in the lower level package like `Bug`, but retrieving and changing the data has to go through the `cache` layer to ensure that bugs are properly deduplicated in memory. - -## repository - -The package `repository` implement the interaction with the git repository on disk. - -A series of interfaces (`RepoCommon`, `Repo` and `ClockedRepo`) define convenient for our usage access and manipulation methods for the data stored in git. - -Those interfaces are implemented by `GitRepo` as well as a mock for testing. - -## identity - -The package `entities/identity` contains the identity data model and the related low-level functions. - -In particular, this package contains: -- `Identity`, the fully-featured identity, holding a series of `Version` stored in its dedicated structure in git -- `Bare`, the simple legacy identity, stored directly in a bug `Operation` - -## bug - -The package `entities/bug` contains the bug data model and the related low-level functions. - -In particular, this package contains: -- `Operation`, the interface to fulfill for an edit operation of a Bug -- `OpBase`, implementing the common code for all operations -- `OperationPack`, an array of `Operation` -- `Bug`, holding all the data of a bug -- `OperationIterator`, allowing to easily iterate over the operation of a bug -- all the existing operations (Create, AddComment, SetTitle ...) -- `Snapshot`, holding a compiled version of a bug - -## cache - -The package `cache` implements a caching layer on top of the low-level `bug` and `identity`package to provide efficient querying, filtering, sorting. - -This cache main function is to provide some guarantee and features for the upper layers: -1. After being loaded, a Bug is kept in memory in the cache, allowing for fast access later. -2. The cache maintain in memory and on disk a pre-digested excerpt for each bug, allowing for fast querying the whole set of bugs without having to load them individually. -3. The cache guarantee that a single instance of a Bug is loaded at once, avoiding loss of data that we could have with multiple copies in the same process. -4. The same way, the cache maintain in memory a single copy of the loaded identities. - -The cache also protect the on-disk data by locking the git repository for its own usage, by writing a lock file. Of course, normal git operations are not affected, only git-bug related one. - -In particular, this package contains: -- `BugCache`, wrapping a `Bug` in a cached version in memory, maintaining efficiently a `Snapshot` and providing a simplified API -- `BugExcerpt`, holding a small subset of data for each bug, allowing for a very fast indexing, filtering, sorting and querying -- `IdentityCache`, wrapping an `Identity` in a cached version in memory and providing a simplified API -- `IdentityExcerpt`, holding a small subset of data for each identity, allowing for a very fast indexing, filtering, sorting and querying. -- `Query` and a series of `Filter` to implement the query language - -## commands - -The package `commands` contains all the CLI commands and subcommands, implemented with the [cobra](https://github.com/spf13/cobra) library. Thanks to this library, bash and zsh completion, manpages and markdown documentation are automatically generated. - -## termui - -The package `termui` contains the interactive terminal user interface, implemented with the [gocui](https://github.com/jroimartin/gocui) library. - -## graphql - -The package `graphql` implement the GraphQL API, mapping the data model and providing read/write access from outside the process. This API is in particular used by the webUI but could be used to implement other user interfaces or bridges with other systems. - -## webui - -The package `webui` hold the web based user interface, implemented in both go and javascript. - -The javascript code is compiled and packaged inside the go binary, allowing for a single file distribution of git-bug. - -When the webUI is started from the CLI command, a localhost HTTP server is started to serve the webUI resources (html, js, css), as well as the GraphQL API. When the webUI is loaded in the browser, it interacts with the git-bug process through the GraphQL API to load and edit bugs. - -## bridge - -The package `bridge` contains the various bridge implementation with other external bug trackers. diff --git a/doc/assets/bridge-workflow.png b/doc/assets/bridge-workflow.png new file mode 100644 index 00000000..18fb8a77 Binary files /dev/null and b/doc/assets/bridge-workflow.png differ diff --git a/doc/assets/bug-graph.png b/doc/assets/bug-graph.png new file mode 100644 index 00000000..5f6f931f Binary files /dev/null and b/doc/assets/bug-graph.png differ diff --git a/doc/assets/merge-1.png b/doc/assets/merge-1.png new file mode 100644 index 00000000..7ba24173 Binary files /dev/null and b/doc/assets/merge-1.png differ diff --git a/doc/assets/merge-2.png b/doc/assets/merge-2.png new file mode 100644 index 00000000..614be5e8 Binary files /dev/null and b/doc/assets/merge-2.png differ diff --git a/doc/assets/native-workflow.png b/doc/assets/native-workflow.png new file mode 100644 index 00000000..8fa9d46c Binary files /dev/null and b/doc/assets/native-workflow.png differ diff --git a/doc/assets/operations.png b/doc/assets/operations.png new file mode 100644 index 00000000..79b6c8e7 Binary files /dev/null and b/doc/assets/operations.png differ diff --git a/doc/assets/tui-recording.gif b/doc/assets/tui-recording.gif new file mode 100644 index 00000000..43ba6eec Binary files /dev/null and b/doc/assets/tui-recording.gif differ diff --git a/doc/assets/web-screenshot-comments.png b/doc/assets/web-screenshot-comments.png new file mode 100644 index 00000000..f4b8dceb Binary files /dev/null and b/doc/assets/web-screenshot-comments.png differ diff --git a/doc/assets/web-screenshot-feed.png b/doc/assets/web-screenshot-feed.png new file mode 100644 index 00000000..502e71f0 Binary files /dev/null and b/doc/assets/web-screenshot-feed.png differ diff --git a/doc/assets/webui-workflow.png b/doc/assets/webui-workflow.png new file mode 100644 index 00000000..83d20d84 Binary files /dev/null and b/doc/assets/webui-workflow.png differ diff --git a/doc/bug-graph-1.png b/doc/bug-graph-1.png deleted file mode 100644 index 5f6f931f..00000000 Binary files a/doc/bug-graph-1.png and /dev/null differ diff --git a/doc/cli-convention.md b/doc/cli-convention.md deleted file mode 100644 index 47eccf69..00000000 --- a/doc/cli-convention.md +++ /dev/null @@ -1,13 +0,0 @@ -## Pattern - -CLI commands should consistently follow this pattern: - -``` -xxx --> list xxx things if list, otherwise show one -xxx new --> create thing -xxx rm --> delete thing -xxx show ID --> show one -xxx show --> show one with "select" implied ID -xxx yyy --> action commands for that thing, or subcommand -xxx select|deselect --> select/deselect implied ID -``` diff --git a/doc/design/architecture.md b/doc/design/architecture.md new file mode 100644 index 00000000..b63c149d --- /dev/null +++ b/doc/design/architecture.md @@ -0,0 +1,149 @@ +# Internal architecture + +This documentation only provides a bird's-eye view of git-bug's internals. For +more details, you should read the other documentation and the various +comment/documentation scattered in the codebase. + +## Overview + +``` + .--------------. + | | webui | | + | '--------------' | + | .---------------..-----------..------------..--------------. | + | | commands || bridge || termui || graphql | | + | '---------------''-----------''------------''--------------' | + | .----------------------------------------------------------. | + | | cache | | + | |----------------------------------------------------------| | + | | BugCache,BugExcerpt,IdentityCache,IdentityExcerpt | | + | '----------------------------------------------------------' | + | .-----------------------------..---------------------------. | + | | bug || identity | | + | |-----------------------------||---------------------------| | + | | Bug,Operation,Snapshot || Identity,Version | | + | '-----------------------------''---------------------------' | + | .----------------------------------------------------------. | + v | repository | v + '----------------------------------------------------------' +``` + +Here is the internal architecture of git-bug. As you can see, it's a layered +architecture. + +As a general rule of thumb, each layer uses the directly underlying layer to +access and interact with the data. As an example, the `commands` package will +not directly use the `bug` or `repository` package. It will request the data +from the `cache` layer and go from there. Of course, the `commands` package will +ultimately use types defined in the lower level package like `Bug`, but +retrieving and changing the data has to go through the `cache` layer to ensure +that bugs are properly deduplicated in memory. + +## repository + +The package `repository` implement the interaction with the git repository on +disk. + +A series of interfaces (`RepoCommon`, `Repo` and `ClockedRepo`) define +convenient for our usage access and manipulation methods for the data stored in +git. + +Those interfaces are implemented by `GitRepo` as well as a mock for testing. + +## identity + +The package `entities/identity` contains the identity data model and the related +low-level functions. + +In particular, this package contains: + +- `Identity`, the fully-featured identity, holding a series of `Version` stored + in its dedicated structure in git +- `Bare`, the simple legacy identity, stored directly in a bug `Operation` + +## bug + +The package `entities/bug` contains the bug data model and the related low-level +functions. + +In particular, this package contains: + +- `Operation`, the interface to fulfill for an edit operation of a Bug +- `OpBase`, implementing the common code for all operations +- `OperationPack`, an array of `Operation` +- `Bug`, holding all the data of a bug +- `OperationIterator`, allowing to easily iterate over the operation of a bug +- all the existing operations (Create, AddComment, SetTitle ...) +- `Snapshot`, holding a compiled version of a bug + +## cache + +The package `cache` implements a caching layer on top of the low-level `bug` and +`identity`package to provide efficient querying, filtering, sorting. + +This cache main function is to provide some guarantee and features for the upper +layers: + +1. After being loaded, a Bug is kept in memory in the cache, allowing for fast + access later. +2. The cache maintain in memory and on disk a pre-digested excerpt for each bug, + allowing for fast querying the whole set of bugs without having to load them + individually. +3. The cache guarantee that a single instance of a Bug is loaded at once, + avoiding loss of data that we could have with multiple copies in the same + process. +4. The same way, the cache maintain in memory a single copy of the loaded + identities. + +The cache also protect the on-disk data by locking the git repository for its +own usage, by writing a lock file. Of course, normal git operations are not +affected, only git-bug related one. + +In particular, this package contains: + +- `BugCache`, wrapping a `Bug` in a cached version in memory, maintaining + efficiently a `Snapshot` and providing a simplified API +- `BugExcerpt`, holding a small subset of data for each bug, allowing for a very + fast indexing, filtering, sorting and querying +- `IdentityCache`, wrapping an `Identity` in a cached version in memory and + providing a simplified API +- `IdentityExcerpt`, holding a small subset of data for each identity, allowing + for a very fast indexing, filtering, sorting and querying. +- `Query` and a series of `Filter` to implement the query language + +## commands + +The package `commands` contains all the CLI commands and subcommands, +implemented with the [cobra](https://github.com/spf13/cobra) library. Thanks to +this library, bash and zsh completion, manpages and markdown documentation are +automatically generated. + +## termui + +The package `termui` contains the interactive terminal user interface, +implemented with the [gocui](https://github.com/jroimartin/gocui) library. + +## graphql + +The package `graphql` implement the GraphQL API, mapping the data model and +providing read/write access from outside the process. This API is in particular +used by the webUI but could be used to implement other user interfaces or +bridges with other systems. + +## webui + +The package `webui` hold the web based user interface, implemented in both go +and javascript. + +The javascript code is compiled and packaged inside the go binary, allowing for +a single file distribution of git-bug. + +When the webUI is started from the CLI command, a localhost HTTP server is +started to serve the webUI resources (html, js, css), as well as the GraphQL +API. When the webUI is loaded in the browser, it interacts with the git-bug +process through the GraphQL API to load and edit bugs. + +## bridge + +The package `bridge` contains the various bridge implementation with other +external bug trackers. diff --git a/doc/design/bridges/jira.md b/doc/design/bridges/jira.md new file mode 100644 index 00000000..c3a7f29f --- /dev/null +++ b/doc/design/bridges/jira.md @@ -0,0 +1,379 @@ +# JIRA Bridge + +## Design Notes + +### One bridge = one project + +There aren't any huge technical barriers requiring this, but since git-bug lacks +a notion of "project" there is no way to know which project to export new bugs +to as issues. Also, JIRA projects are first-class immutable metadata and so we +*must* get it right on export. Therefore the bridge is configured with the `Key` +for the project it is assigned to. It will only import bugs from that project. + +### JIRA fields + +The bridge currently does nothing to import any of the JIRA fields that don't +have `git-bug` equivalents ("Assignee", "sprint", "story points", etc). +Hopefully the bridge will be able to enable synchronization of these soon. + +### Credentials + +JIRA does not support user/personal access tokens. They have experimental +3-legged oauth support but that requires an API token for the app configured by +the server administrator. The only reliable authentication mechanism then is the +username/password and session-token mechanism. We can acquire a session token +programmatically from the username/password but these are very short lived (i.e. +hours or less). As such the bridge currently requires an actual username and +password as user credentials. It supports three options: + +1. Storing both username and password in a separate file referred to by the + `git-config` (I like to use `.git/jira-credentials.json`) +2. Storing the username and password in clear-text in the git config +3. Storing the username only in the git config and asking for the password on + each `push` or `pull`. + +### Issue Creation Defaults + +When a new issues is created in JIRA there are often certain mandatory fields +that require a value or the creation is rejected. In the issue create form on +the JIRA web interface, these are annotated as "required". The `issuetype` is +always required (e.g. "bug", "story", "task", etc). The set of required metadata +is configurable (in JIRA) per `issuetype` so the set might be different between +"bug" and "story", for example. + +For now, the bridge only supports exporting issues as a single `issuetype`. If +no configuration is provided, then the default is `"id": "10001"` which is +`"story"` in the default set of issue types. + +In addition to specifying the `issuetype` of issues created on export, the +bridge will also allow you to specify a constant global set of default values +for any additional required fields. See the configuration section below for the +syntax. + +For longer term goals, see the section below on workflow validation + +### Assign git-bug id to field during issue creation + +JIRA allows for the inclusion of custom "fields" in all of their issues. The +JIRA bridge will store the JIRA issue "id" for any bugs which are synchronized +to JIRA, but it can also assign to a custom JIRA `field` the `git-bug` id. This +way the `git-bug` id can be displayed in the JIRA web interface and certain +integration activities become easier. + +See the configuration section below on how to specify the custom field where the +JIRA bridge should write this information. + +### Workflows and Transitions + +JIRA issue states are subject to customizable "workflows" (project managers +apparently validate themselves by introducing developer friction). In general, +issues can only transition from one state to another if there is an edge between +them in the state graph (a.k.a. "workflow"). JIRA calls these edges +"transitions". Furthermore, each transition may include a set of mandatory +fields which must be set in order for the transition to succeed. For example the +transition of `"status"` from `"In Progress"` to `"Closed"` might required a +`"resolution"` (i.e. `"Fixed"` or `"Working as intended"`). + +Dealing with complex workflows is going to be challenging. Some long-term +aspirations are described in the section below on "Workflow Validation". +Currently the JIRA bridge isn't very smart about transitions though, so you'll +need to tell it what you want it to do when importing and exporting a state +change (i.e. to "close" or "open" a bug). Currently the bridge accepts +configuration options which map the two `git-bug` statuses ("open", "closed") to +two JIRA statuses. On import, the JIRA status is mapped to a `git-bug` status +(if a mapping exists) and the `git-bug` status is assigned. On export, the +`git-bug` status is mapped to a JIRA status and if a mapping exists the bridge +will query the list of available transitions for the issue. If a transition +exists to the desired state the bridge will attempt to execute the transition. +It does not currently support assigning any fields during the transition so if +any fields are required the transition will fail during export and the status +will be out of sync. + +### JIRA Changelog + +Some operations on JIRA issues are visible in a timeline view known as the +`changelog`. The JIRA cloud product provides an +`/issue/{issueIdOrKey}/changelog` endpoint which provides a paginated view but +the JIRA server product does not. The changelog is visible by querying the issue +with the `expand=changelog` query parameter. Unfortunately in this case the +entire changelog is provided without paging. + +Each changelog entry is identified with a unique string `id`, but within a +single changelog entry is a list of multiple fields that are modified. In other +words a single "event" might atomically change multiple fields. As an example, +when an issue is closed the `"status"` might change to `"closed"` and the +`"resolution"` might change to `"fixed'`. + +When a changelog entry is imported by the JIRA bridge, each individual field +that was changed is treated as a separate `git-bug` operation. In other words a +single JIRA change event might create more than one `git-bug` operation. + +However, when a `git-bug` operation is exported to JIRA it will only create a +single changelog entry. Furthermore, when we modify JIRA issues over the REST +API JIRA does not provide any information to associate that modification event +with the changelog. We must, therefore, heuristically match changelog entries +against operations that we performed in order to not import them as duplicate +events. In order to assist in this matching process, the bridge will record the +JIRA server time of the response to the `POST` (as reported by the `"Date"` +response header). During import, we keep an iterator to the list of `git-bug` +operations for the bug mapped to the Jira issue. As we walk the JIRA changelog, +we keep the iterator pointing to the first operation with an annotation which is +*not before* that changelog entry. If the changelog entry is the result of an +exported `git-bug` operation, then this must be that operation. We then scan +through the list of changeitems (changed fields) in the changelog entry, and if +we can match a changed field to the candidate `git-bug` operation then we have +identified the match. + +### Unlogged Changes + +Comments (creation and edition) do not show up in the JIRA changelog. However +JIRA reports both a `created` and `updated` date for each comment. If we import +a comment which has an `updated` and `created` field which do not match, then we +treat that as a new comment edition. If we do not already have the comment +imported, then we import an empty comment followed by a comment edition. + +Because comment editions are not uniquely identified in JIRA we identify them in +`git-bug` by concatenating the JIRA issue `id` with the `updated` time of the +edition. + +### Workflow Validation (future) + +The long-term plan for the JIRA bridge is to download and store the workflow +specifications from the JIRA server. This includes the required metadata for +issue creation, and the status state graph, and the set of required metadata for +status transition. + +When an existing `git-bug` is initially marked for export, the bridge will hook +in and validate the bug state against the required metadata. Then it will prompt +for any missing metadata using a set of UI components appropriate for the field +schema as reported by JIRA. If the user cancels then the bug will not be marked +for export. + +When a bug already marked for JIRA export (including those that were imported) +is modified, the bridge will hook in and validate the modification against the +workflow specifications. It will prompt for any missing metadata as in the +creation process. + +During export, the bridge will validate any export operations and skip them if +we know they will fail due to violation of the cached workflow specification +(i.e. missing required fields for a transition). A list of bugs "blocked for +export" will be available to query. A UI command will allow the user to inspect +and resolve any bugs that are "blocked for export". + +## Configuration + +As mentioned in the notes above, there are a few optional configuration fields +that can be set beyond those that are prompted for during the initial bridge +configuration. You can set these options in your `.git/config` file: + +### Issue Creation Defaults + +The format for this config entry is a JSON object containing fields you wish to +set during issue creation when exporting bugs. If you provide a value for this +configuration option, it must include at least the `"issuetype"` field, or the +bridge will not be able to export any new issues. + +Let's say that we want bugs exported to JIRA to have a default issue type of +"Story" which is `issuetype` with id `10001`. Then we will add the following +entry to our git-config: + +``` +create-issue-defaults = {"issuetype":"10001"} +``` + +If you needed an additional required field `customfield_1234` and you wanted to +provide a default value of `"default"` then you would add the following to your +config: + +``` +create-issue-defaults = {"issuetype":"10001","customfield_1234":"default"} +``` + +Note that the content of this value is merged verbatim to the JSON object that +is `POST`ed to the JIRA rest API, so you can use arbitrary valid JSON. + +### Assign git-bug id to field + +If you want the bridge to fill a JIRA field with the `git-bug` id when exporting +issues, then provide the name of the field: + +``` +create-issue-gitbug-id = "customfield_5678" +``` + +### Status Map + +You can specify the mapping between `git-bug` status and JIRA status id's using +the following: + +``` +bug-id-map = {\"open\": \"1\", \"closed\": \"6\"} +``` + +The format of the map is `: `. In general +your jira instance will have more statuses than `git-bug` will and you may map +more than one jira-status to a git-bug status. You can do this with +`bug-id-revmap`: + +``` +bug-id-revmap = {\"10109\": \"open\", \"10006\": \"open\", \"10814\": \"open\"} +``` + +The reverse map `bug-id-revmap` will automatically include the inverse of the +forward map `bug-id-map`. + +Note that in JIRA each different `issuetype` can have a different set of +statuses. The bridge doesn't currently support more than one mapping, however. +Also, note that the format of the map is JSON and the git config file syntax +requires doublequotes to be escaped (as in the examples above). + +### Full example + +Here is an example configuration with all optional fields set + +``` +[git-bug "bridge.default"] + project = PROJ + credentials-file = .git/jira-credentials.json + target = jira + server = https://jira.example.com + create-issue-defaults = {"issuetype":"10001","customfield_1234":"default"} + create-issue-gitbug-id = "customfield_5678" + bug-open-id = 1 + bug-closed-id = 6 +``` + +## To-Do list + +- \[0cf5c71\] Assign git-bug to jira field on import +- \[8acce9c\] Download and cache workflow representation +- \[95e3d45\] Implement workflow gui +- \[c70e22a\] Implement additional query filters for import +- \[9ecefaa\] Create JIRA mock and add REST unit tests +- \[67bf520\] Create import/export integration tests +- \[1121826\] Add unit tests for utilities +- \[0597088\] Use OS keyring for credentials +- \[d3e8f79\] Don't count on the `Total` value in paginations + +## Using CURL to poke at your JIRA's REST API + +If you need to lookup the `id` for any `status`es or the `schema` for any +creation metadata, you can use CURL to query the API from the command line. Here +are a couple of examples to get you started. + +### Getting a session token + +``` +curl \ + --data '{"username":"", "password":""}' \ + --header "Content-Type: application/json" \ + --request POST \ + /rest/auth/1/session +``` + +[!NOTE] +If you have a json pretty printer installed (`sudo apt install jq`), pipe the +output through through that to make things more readable: + +``` +curl --silent \ + --data '{"username":"", "password":""}' \ + --header "Content-Type: application/json" \ + --request POST + /rest/auth/1/session | jq . +``` + +example output: + +``` +{ + "session": { + "name": "JSESSIONID", + "value": "{sessionToken}" + }, + "loginInfo": { + "loginCount": 268, + "previousLoginTime": "2019-11-12T08:03:35.300-0800" + } +} +``` + +Make note of the output value. On subsequent invocations of `curl`, append the +following command-line option: + +``` +--cookie "JSESSIONID={sessionToken}" +``` + +Where `{sessionToken}` is the output from the `POST` above. + +### Get a list of issuetype ids + +``` +curl --silent \ + --cookie "JSESSIONID={sessionToken}" \ + --header "Content-Type: application/json" \ + --request GET https://jira.example.com/rest/api/2/issuetype \ + | jq . +``` + +**example output**: + +``` + { + "self": "https://jira.example.com/rest/api/2/issuetype/13105", + "id": "13105", + "description": "", + "iconUrl": "https://jira.example.com/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype", + "name": "Test Plan Links", + "subtask": true, + "avatarId": 10316 + }, + { + "self": "https://jira.example.com/rest/api/2/issuetype/13106", + "id": "13106", + "description": "", + "iconUrl": "https://jira.example.com/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype", + "name": "Enable Initiatives on the project", + "subtask": true, + "avatarId": 10316 + }, + ... +``` + +### Get a list of statuses + +``` +curl --silent \ + --cookie "JSESSIONID={sessionToken}" \ + --header "Content-Type: application/json" \ + --request GET https://jira.example.com/rest/api/2/project/{projectIdOrKey}/statuses \ + | jq . +``` + +**example output:** + +``` +[ + { + "self": "https://example.com/rest/api/2/issuetype/3", + "id": "3", + "name": "Task", + "subtask": false, + "statuses": [ + { + "self": "https://example.com/rest/api/2/status/1", + "description": "The issue is open and ready for the assignee to start work on it.", + "iconUrl": "https://example.com/images/icons/statuses/open.png", + "name": "Open", + "id": "1", + "statusCategory": { + "self": "https://example.com/rest/api/2/statuscategory/2", + "id": 2, + "key": "new", + "colorName": "blue-gray", + "name": "To Do" + } + }, +... +``` diff --git a/doc/design/cli-convention.md b/doc/design/cli-convention.md new file mode 100644 index 00000000..d65e48db --- /dev/null +++ b/doc/design/cli-convention.md @@ -0,0 +1,13 @@ +## Pattern + +CLI commands should consistently follow this pattern: + +``` +xxx --> list xxx things if list, otherwise show one +xxx new --> create thing +xxx rm --> delete thing +xxx show ID --> show one +xxx show --> show one with "select" implied ID +xxx yyy --> action commands for that thing, or subcommand +xxx select|deselect --> select/deselect implied ID +``` diff --git a/doc/design/data-model.md b/doc/design/data-model.md new file mode 100644 index 00000000..0553ed25 --- /dev/null +++ b/doc/design/data-model.md @@ -0,0 +1,215 @@ +# git-bug's reusable entity data model + +This document explains how git-bug's reusable distributed data structure in git +is working. This data structure is capable of: + +- storing an entity (bug, pull-request, config...) and its complete history in + git +- carry signed authorship of editions +- use git remotes as a medium for synchronisation and collaboration +- merge conflicts +- respect the rules you define as to what edition are possible +- carry attached media + +If you are looking for a different writing format or to see how you can easily +make your own, checkout [the example code](../../entity/dag/example_test.go). + +If you are not familiar with +[git internals](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects), you +might first want to read about them, as the `git-bug` data model is built on top +of them. + +## Entities (bug, author, ...) are a series of edit operations + +As entities are stored and edited in multiple processes at the same time, it's +not possible to store the current state like it would be done in a normal +application. If two processes change the same entity and later try to merge the +states, we wouldn't know which change takes precedence or how to merge those +states. + +To deal with this problem, you need a way to merge these changes in a meaningful +way. Instead of storing the final bug data directly, we store a series of edit +`Operation`s. This is a common idea, notably with +[Operation-based CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#Operation-based_CRDTs). + +![ordered operations](../assets/operations.png) + +To get the final state of an entity, we apply these `Operation`s in the correct +order on an empty state, to compute (aka "compile") our view. + +## Entities are stored in git objects + +An `Operation` is a piece of data, including: + +- a type identifier +- an author (a reference to another entity) +- a timestamp (there is also one or two [Lamport time](#time-is-unreliable)) +- all the data required by that operation type (a message, a status ...) +- a random [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) to ensure + we have enough entropy, as the operation identifier is a hash of that data + (more on that later) + +These `Operation`s are aggregated in an `OperationPack`, a simple array. An +`OperationPack` represents an edit session of the entity. As the operation's +author is the same for all the `OperationPack` we only store it once. + +We store this pack in git as a git `Blob`; that consists of a string containing +a JSON array of operations. One such pack -- here with two operations -- might +look like this: + +```json +{ + "author": { + "id": "04bf6c1a69bb8e9679644874c85f82e337b40d92df9d8d4176f1c5e5c6627058" + }, + "ops": [ + { + "type": 3, + "timestamp": 1647377254, + "nonce": "SRQwUWTJCXAmQBIS+1ctKgOcbF0=", + "message": "Adding a comment", + "files": null + }, + { + "type": 4, + "timestamp": 1647377257, + "nonce": "la/HaRPMvD77/cJSJOUzKWuJdY8=", + "status": 1 + } + ] +} +``` + +To reference our `OperationPack`, we create a git `Tree`; it references our +`OperationPack` `Blob` under `"/ops"`. If any edit operation includes a media +(for instance in a text message), we can store that media as a `Blob` and +reference it here under `"/media"`. + +To complete the picture, we create a git `Commit` that references our `Tree`. +Each time we add more `Operation`s to our bug, we add a new `Commit` with the +same data-structure to form a chain of `Commit`s. + +This chain of `Commit`s is made available as a git `Reference` under +`refs//`. We can later use this reference to push our data to a +git remote. As git will push any data needed as well, everything will be pushed +to the remote, including the media. + +Here is the complete picture: + +![git graph of a simple bug](../assets/bug-graph.png) + +## Time is unreliable + +Before being able to merge conflicts, let's start with some building blocks. + +It would be very tempting to use the `Operation`'s timestamp to give us the +order to compile the final state. However, you can't rely on the time provided +by other people (their clock might be off) for anything other than just display. +This is a fundamental limitation of distributed system, and even more so when +actors might want to game the system. + +Instead, we are going to use +[Lamport logical clock](https://en.wikipedia.org/wiki/Lamport_timestamps). A +Lamport clock is a simple counter of events. This logical clock gives us a +partial ordering: + +- if L1 \< L2, L1 happened before L2 +- if L1 > L2, L1 happened after L2 +- if L1 == L2, we can't tell which happened first: it's a concurrent edition + +Each time we are appending something to the data (create an `Entity`, add an +`Operation`) a logical time will be attached, with the highest time value we are +aware of, plus one. This declares a causality in the events and allows ordering +entities and operations. + +The first commit of an `Entity` will have both a creation time and edit time +clock, while a later commit will only have an edit time clock. These clocks +value are serialized directly in the `Tree` entry name (for example: +`"create-clock-4"`). As a `Tree` entry needs to reference something, we +reference the git `Blob` with an empty content. As all of these entries will +reference the same `Blob`, no network transfer is needed as long as you already +have any entity in your repository. + +Example of a `Tree` of the first commit of an entity: + +``` +100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 create-clock-14 +100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 edit-clock-137 +100644 blob a020a85baa788e12699a4d83dd735578f0d78c75 ops +``` + +Example of a `Tree` of a later commit of an entity: + +``` +100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 edit-clock-154 +100644 blob 68383346c1a9503f28eec888efd300e9fc179ca0 ops +``` + +## Entities and Operation's ID + +`Operation`s can be referenced - in the data model or by users - with an +identifier. This identifier is computed from the `Operation`'s data itself, with +a hash of that data: `id = hash(json(op))` + +For entities, `git-bug` uses as identifier the hash of the first `Operation` of +the entity, as serialized on disk. + +The same way as git does, this hash is displayed truncated to a 7 characters +string to a human user. Note that when specifying a bug id in a command, you can +enter as few characters as you want, as long as there is no ambiguity. If +multiple entities match your prefix, `git-bug` will complain and display the +potential matches. + +## Entities support conflict resolution + +Now that we have all that, we can finally merge our entities without conflict, +and collaborate with other users. Let's start by getting rid of two simple +scenarios: + +- if we simply pull updates, we move forward our local reference. We get an + update of our graph that we read as usual. +- if we push fast-forward updates, we move forward the remote reference and + other users can update their reference as well. + +The tricky part happens when we have concurrent editions. If we pull updates +while we have local changes (non-straightforward in git term), `git-bug` creates +the equivalent of a merge commit to merge both branches into a DAG. This DAG has +a single root containing the first operation, but can have branches that get +merged back into a single head pointed by the reference. + +As we don't have a purely linear series of commits/`Operations`s, we need a +deterministic ordering to always apply operations in the same order. + +`git-bug` applies the following algorithm: + +1. load and read all the commits and the associated `OperationPack`s +2. make sure that the Lamport clocks respect the DAG structure: a parent + commit/`OperationPack` (that is, towards the head) cannot have a clock that + is higher or equal than its direct child. If such a problem happens, the + commit is refused/discarded. +3. individual `Operation`s are assembled together and ordered given the + following priorities: + 1. the edition's lamport clock if not concurrent + 2. the lexicographic order of the `OperationPack`'s identifier + +Step 2 is providing and enforcing a constraint over the `Operation`'s logical +clocks. What that means, is that **we inherit the implicit ordering given by the +DAG**. Later, logical clocks refine that ordering. This - coupled with signed +commits - has the nice property of limiting how this data model can be abused. + +Here is an example of such an ordering: + +![merge scenario 1](../assets/merge-1.png) + +We can see that: + +- Lamport clocks respect the DAG structure +- the final `Operation` order is \[A,B,C,D,E,F\], according to those clocks + +When we have concurrent editions, we apply a secondary ordering, based on the +`OperationPack`'s identifier: + +![merge scenario 2](../assets/merge-2.png) + +This secondary ordering doesn't carry much meaning, but it's unbiased and hard +to abuse. diff --git a/doc/feature-matrix.md b/doc/feature-matrix.md new file mode 100644 index 00000000..18e37c18 --- /dev/null +++ b/doc/feature-matrix.md @@ -0,0 +1,151 @@ +# User facing capabilities + +This document tries to give an overview of what is currently supported, and by +extension where effort can be focused to bring feature completion and parity. + +As git-bug is a free software project, accept and rely on contributor, those +feature matrices kinda define a roadmap, in the sense that anything mentioned +below is a planned feature and can be worked on. This does not mean that a +feature not mentioned here should not be considered, just maybe check the issue +tracker and come talk about it. + +This document however does not show all the untold work required to support +those user-facing capabilities. There has been a ton of work behind the scene +and more will be required over time. + +βœ…: working 🟠: partial implementation ❌: not working + +## Other goals + +Some goals don't really fit below, so I'll mention them here: + +- have the webUI accept external OAuth (Github, ...) and act as a public portal + where user outside the project can browse and interact with the project +- project configuration (valid labels, ...) +- commit signature to fully authenticate user's interaction +- interface with the system keyring, to distribute and expose known public keys + and allow checking signed commit in normal git workflow +- privileged roles (admin, ...) and enforcing the corresponding rules +- package the webui as a desktop app + +Additionally, some other are captured as +[Github issues](https://github.com/git-bug/git-bug/issues) or +[Discussions](https://github.com/git-bug/git-bug/discussions). + +## Entities + +The most high level overview of what kind of entities are supported and where. + +| | Core | CLI | TermUI | WebUI | +| -------------- | :--: | :-: | :----: | :---: | +| Identities | βœ… | βœ… | βœ… | βœ… | +| Bug | βœ… | βœ… | βœ… | βœ… | +| Board | 🟠 | 🟠 | ❌ | ❌ | +| Pull-request | ❌ | ❌ | ❌ | ❌ | +| Project Config | ❌ | ❌ | ❌ | ❌ | + +More specific features across the board. + +| | Core | CLI | TermUI | WebUI | +| ------------------ | :--: | :-: | :----: | :---: | +| Media embedding | 🟠 | ❌ | ❌ | ❌ | +| Fast indexing | βœ… | βœ… | βœ… | βœ… | +| Markdown rendering | N/A | ❌ | ❌ | βœ… | + +#### Identities + +| | Core | CLI | TermUI | WebUI | +| ----------------------- | :--: | :-: | :----: | :---: | +| Public keys | 🟠 | ❌ | ❌ | ❌ | +| Private keys management | 🟠 | ❌ | ❌ | ❌ | +| Identity edition | βœ… | βœ… | ❌ | ❌ | +| Identity adoption | βœ… | βœ… | ❌ | ❌ | +| Identity protection | 🟠 | ❌ | ❌ | ❌ | + +#### Bugs + +| | Core | CLI | TermUI | WebUI | +| ----------------- | :--: | :-: | :----: | :---: | +| Comments | βœ… | βœ… | βœ… | βœ… | +| Comments edition | βœ… | βœ… | βœ… | βœ… | +| Comments deletion | βœ… | ❌ | ❌ | ❌ | +| Labels | βœ… | βœ… | βœ… | βœ… | +| Status | βœ… | βœ… | βœ… | βœ… | +| Title edition | βœ… | βœ… | βœ… | βœ… | +| Assignee | ❌ | ❌ | ❌ | ❌ | +| Milestone | ❌ | ❌ | ❌ | ❌ | + +## Bridges + +### Importers + +General capabilities of importers: + +| | Github | Gitlab | Jira | Launchpad | +| ----------------------------------------------- | :----: | :----: | :--: | :-------: | +| **incremental**
(can import more than once) | βœ… | βœ… | βœ… | ❌ | +| **with resume**
(download only new data) | βœ… | βœ… | βœ… | ❌ | +| **media/files** | ❌ | ❌ | ❌ | ❌ | +| **automated test suite** | βœ… | βœ… | ❌ | ❌ | + +Identity support: + +| | Github | Gitlab | Jira | Launchpad | +| ----------------- | :----: | :----: | :--: | :-------: | +| **identities** | βœ… | βœ… | βœ… | βœ… | +| identities update | ❌ | ❌ | ❌ | ❌ | +| public keys | ❌ | ❌ | ❌ | ❌ | + +Bug support: + +| | Github | Gitlab | Jira | Launchpad | +| ---------------- | :----: | :----: | :--: | :-------: | +| **bug** | βœ… | βœ… | βœ… | βœ… | +| comments | βœ… | βœ… | βœ… | βœ… | +| comment editions | βœ… | ❌ | βœ… | ❌ | +| labels | βœ… | βœ… | βœ… | ❌ | +| status | βœ… | βœ… | βœ… | ❌ | +| title edition | βœ… | βœ… | βœ… | ❌ | +| Assignee | ❌ | ❌ | ❌ | ❌ | +| Milestone | ❌ | ❌ | ❌ | ❌ | + +Board support: + +| | Github | Gitlab | Jira | Launchpad | +| --------- | :----: | :----: | :--: | :-------: | +| **board** | ❌ | ❌ | ❌ | ❌ | + +### Exporters + +**General capabilities of exporters**: + +| | Github | Gitlab | Jira | +| ----------------------------------------------- | :----: | :----: | :--: | +| **incremental**
(can export more than once) | βœ… | βœ… | βœ… | +| **with resume**
(upload only new data) | βœ… | βœ… | βœ… | +| **automated test suite** | βœ… | βœ… | ❌ | + +**Identity support**: + +| | Github | Gitlab | Jira | +| ----------------- | :----: | :----: | :--: | +| **identities** | βœ… | βœ… | βœ… | +| identities update | ❌ | ❌ | ❌ | + +Note: as the target bug tracker require accounts and credentials, there is only +so much that an exporter can do about identities. A bridge should be able to +load and use credentials for multiple remote account, but when they are not +available, the corresponding changes can't be replicated. + +**Bug support**: + +| | Github | Gitlab | Jira | +| ---------------- | :----: | :----: | :--: | +| **bugs** | βœ… | βœ… | βœ… | +| comments | βœ… | βœ… | βœ… | +| comment editions | βœ… | βœ… | βœ… | +| labels | βœ… | βœ… | βœ… | +| status | βœ… | βœ… | βœ… | +| title edition | βœ… | βœ… | βœ… | +| Assignee | ❌ | ❌ | ❌ | +| Milestone | ❌ | ❌ | ❌ | diff --git a/doc/feature_matrix.md b/doc/feature_matrix.md deleted file mode 100644 index a0e19232..00000000 --- a/doc/feature_matrix.md +++ /dev/null @@ -1,137 +0,0 @@ -# User facing capabilities - -This document tries to give an overview of what is currently supported, and by extension where effort can be focused to bring feature completion and parity. - -As git-bug is a free software project, accept and rely on contributor, those feature matrices kinda define a roadmap, in the sense that anything mentioned below is a planned feature and can be worked on. This does not mean that a feature not mentioned here should not be considered, just maybe check the issue tracker and come talk about it. - -This document however does not show all the untold work required to support those user-facing capabilities. There has been a ton of work behind the scene and more will be required over time. - -βœ…: working 🟠: partial implementation ❌: not working - -## Other goals - -Some goals don't really fit below, so I'll mention them here: -- have the webUI accept external OAuth (Github, ...) and act as a public portal where user outside the project can browse and interact with the project -- project configuration (valid labels, ...) -- commit signature to fully authenticate user's interaction -- interface with the system keyring, to distribute and expose known public keys and allow checking signed commit in normal git workflow -- privileged roles (admin, ...) and enforcing the corresponding rules -- package the webui as a desktop app - -Additionally, some other are captured as [Github issues](https://github.com/git-bug/git-bug/issues) or [Discussions](https://github.com/git-bug/git-bug/discussions). - -## Entities - -The most high level overview of what kind of entities are supported and where. - -| | Core | CLI | TermUI | WebUI | -|----------------|:----:|:---:|:------:|:-----:| -| Identities | βœ… | βœ… | βœ… | βœ… | -| Bug | βœ… | βœ… | βœ… | βœ… | -| Board | 🟠 | 🟠 | ❌ | ❌ | -| Pull-request | ❌ | ❌ | ❌ | ❌ | -| Project Config | ❌ | ❌ | ❌ | ❌ | - -More specific features across the board. - -| | Core | CLI | TermUI | WebUI | -|--------------------|:----:|:---:|:------:|:-----:| -| Media embedding | 🟠 | ❌ | ❌ | ❌ | -| Fast indexing | βœ… | βœ… | βœ… | βœ… | -| Markdown rendering | N/A | ❌ | ❌ | βœ… | - -#### Identities - -| | Core | CLI | TermUI | WebUI | -|-------------------------|:----:|:---:|:------:|:-----:| -| Public keys | 🟠 | ❌ | ❌ | ❌ | -| Private keys management | 🟠 | ❌ | ❌ | ❌ | -| Identity edition | βœ… | βœ… | ❌ | ❌ | -| Identity adoption | βœ… | βœ… | ❌ | ❌ | -| Identity protection | 🟠 | ❌ | ❌ | ❌ | - -#### Bugs - -| | Core | CLI | TermUI | WebUI | -|-------------------|:----:|:---:|:------:|:-----:| -| Comments | βœ… | βœ… | βœ… | βœ… | -| Comments edition | βœ… | βœ… | βœ… | βœ… | -| Comments deletion | βœ… | ❌ | ❌ | ❌ | -| Labels | βœ… | βœ… | βœ… | βœ… | -| Status | βœ… | βœ… | βœ… | βœ… | -| Title edition | βœ… | βœ… | βœ… | βœ… | -| Assignee | ❌ | ❌ | ❌ | ❌ | -| Milestone | ❌ | ❌ | ❌ | ❌ | - - -## Bridges - -### Importers - -General capabilities of importers: - -| | Github | Gitlab | Jira | Launchpad | -|-------------------------------------------------|:------:|:------:|:----:|:---------:| -| **incremental**
(can import more than once) | βœ… | βœ… | βœ… | ❌ | -| **with resume**
(download only new data) | βœ… | βœ… | βœ… | ❌ | -| **media/files** | ❌ | ❌ | ❌ | ❌ | -| **automated test suite** | βœ… | βœ… | ❌ | ❌ | - -Identity support: - -| | Github | Gitlab | Jira | Launchpad | -|-------------------|:------:|:------:|:----:|:---------:| -| **identities** | βœ… | βœ… | βœ… | βœ… | -| identities update | ❌ | ❌ | ❌ | ❌ | -| public keys | ❌ | ❌ | ❌ | ❌ | - -Bug support: - -| | Github | Gitlab | Jira | Launchpad | -|------------------|:------:|:------:|:----:|:---------:| -| **bug** | βœ… | βœ… | βœ… | βœ… | -| comments | βœ… | βœ… | βœ… | βœ… | -| comment editions | βœ… | ❌ | βœ… | ❌ | -| labels | βœ… | βœ… | βœ… | ❌ | -| status | βœ… | βœ… | βœ… | ❌ | -| title edition | βœ… | βœ… | βœ… | ❌ | -| Assignee | ❌ | ❌ | ❌ | ❌ | -| Milestone | ❌ | ❌ | ❌ | ❌ | - -Board support: - -| | Github | Gitlab | Jira | Launchpad | -|-----------|:------:|:------:|:----:|:---------:| -| **board** | ❌ | ❌ | ❌ | ❌ | - -### Exporters - -**General capabilities of exporters**: - -| | Github | Gitlab | Jira | -|-------------------------------------------------|:------:|:------:|:----:| -| **incremental**
(can export more than once) | βœ… | βœ… | βœ… | -| **with resume**
(upload only new data) | βœ… | βœ… | βœ… | -| **automated test suite** | βœ… | βœ… | ❌ | - -**Identity support**: - -| | Github | Gitlab | Jira | -|-------------------|:------:|:------:|:----:| -| **identities** | βœ… | βœ… | βœ… | -| identities update | ❌ | ❌ | ❌ | - -Note: as the target bug tracker require accounts and credentials, there is only so much that an exporter can do about identities. A bridge should be able to load and use credentials for multiple remote account, but when they are not available, the corresponding changes can't be replicated. - -**Bug support**: - -| | Github | Gitlab | Jira | -|------------------|:------:|:------:|:----:| -| **bugs** | βœ… | βœ… | βœ… | -| comments | βœ… | βœ… | βœ… | -| comment editions | βœ… | βœ… | βœ… | -| labels | βœ… | βœ… | βœ… | -| status | βœ… | βœ… | βœ… | -| title edition | βœ… | βœ… | βœ… | -| Assignee | ❌ | ❌ | ❌ | -| Milestone | ❌ | ❌ | ❌ | diff --git a/doc/gen_docs.go b/doc/gen_docs.go deleted file mode 100644 index ac5417d8..00000000 --- a/doc/gen_docs.go +++ /dev/null @@ -1,84 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "sync" - "time" - - "github.com/spf13/cobra" - "github.com/spf13/cobra/doc" - - "github.com/git-bug/git-bug/commands" -) - -func main() { - fmt.Println("Generating documentation ...") - - tasks := map[string]func(*cobra.Command) error{ - "ManPage": genManPage, - "Markdown": genMarkdown, - } - - var wg sync.WaitGroup - for name, f := range tasks { - wg.Add(1) - go func(name string, f func(*cobra.Command) error) { - defer wg.Done() - root := commands.NewRootCommand() - err := f(root) - if err != nil { - fmt.Printf(" - %s: %v\n", name, err) - return - } - fmt.Printf(" - %s: ok\n", name) - }(name, f) - } - - wg.Wait() -} - -func genManPage(root *cobra.Command) error { - cwd, _ := os.Getwd() - dir := filepath.Join(cwd, "doc", "man") - - // fixed date to avoid having to commit each month - date := time.Date(2019, 4, 1, 12, 0, 0, 0, time.UTC) - - header := &doc.GenManHeader{ - Title: "GIT-BUG", - Section: "1", - Date: &date, - Source: "Generated from git-bug's source code", - } - - files, err := filepath.Glob(dir + "/*.1") - if err != nil { - return err - } - for _, f := range files { - if err := os.Remove(f); err != nil { - return err - } - } - - return doc.GenManTree(root, header, dir) -} - -func genMarkdown(root *cobra.Command) error { - cwd, _ := os.Getwd() - dir := filepath.Join(cwd, "doc", "md") - - files, err := filepath.Glob(dir + "/*.md") - if err != nil { - return err - } - for _, f := range files { - if err := os.Remove(f); err != nil { - return err - } - } - - return doc.GenMarkdownTree(root, dir) -} diff --git a/doc/generate.go b/doc/generate.go new file mode 100644 index 00000000..0001f1a7 --- /dev/null +++ b/doc/generate.go @@ -0,0 +1,110 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "strings" + "sync" + "time" + + "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" + + "github.com/git-bug/git-bug/commands" +) + +// TaskError holds a given task name and the error it returned (if any) +type TaskError struct { + name string + err error +} + +func main() { + fmt.Println("Generating documentation...") + + tasks := map[string]func(*cobra.Command) error{ + "ManPage": genManPage, + "Markdown": genMarkdown, + } + + var wg sync.WaitGroup + errs := make(chan TaskError, len(tasks)) + for name, f := range tasks { + wg.Add(1) + go func(name string, f func(*cobra.Command) error) { + defer wg.Done() + root := commands.NewRootCommand() + err := f(root) + if err != nil { + fmt.Printf(" - %s: FATAL\n", name) + errs <- TaskError{name: name, err: err} + return + } + fmt.Printf(" - %s: ok\n", name) + }(name, f) + } + + wg.Wait() + close(errs) + + if len(errs) > 0 { + fmt.Println() + for e := range errs { + fmt.Printf(" Error generating %s:\n", strings.ToLower(e.name)) + for _, line := range strings.Split(e.err.Error(), "\n") { + fmt.Printf(" %s\n", line) + } + fmt.Println() + } + os.Exit(1) + } +} + +func genManPage(root *cobra.Command) error { + cwd, _ := os.Getwd() + dir := filepath.Join(cwd, "doc", "man") + + // fixed date to avoid having to commit each month + date := time.Date(2019, 4, 1, 12, 0, 0, 0, time.UTC) + + header := &doc.GenManHeader{ + Title: "GIT-BUG", + Section: "1", + Date: &date, + Source: "Generated from git-bug's source code", + } + + files, err := filepath.Glob(dir + "/*.1") + if err != nil { + return err + } + for _, f := range files { + if err := os.Remove(f); err != nil { + return err + } + } + + return doc.GenManTree(root, header, dir) +} + +func genMarkdown(root *cobra.Command) error { + cwd, _ := os.Getwd() + dir := filepath.Join(cwd, "doc", "md") + + files, err := filepath.Glob(dir + "/*.md") + if err != nil { + return err + } + for _, f := range files { + if err := os.Remove(f); err != nil { + return err + } + } + + if err := doc.GenMarkdownTree(root, dir); err != nil { + return err + } + + return nil +} diff --git a/doc/howto-github.md b/doc/howto-github.md deleted file mode 100644 index c5668e82..00000000 --- a/doc/howto-github.md +++ /dev/null @@ -1,80 +0,0 @@ -# How-to: Read and edit offline your Github/Gitlab/Jira issues with git-bug - -[git-bug](https://github.com/git-bug/git-bug) is a standalone distributed bug-tracker that is embedded in git. In short, if you have a git repository you can use it to store bugs alongside your code (without mixing them though!), push and pull them to/from a normal git remote to collaborate. - -

- Native workflow -

- -Bridges with other bug-trackers are first-class citizen in `git-bug`. Notably, they are bidirectional, incremental and relatively fast. This means that a perfectly valid way to use `git-bug` is as a sort of remote for Github where you synchronize all the issues of a repository to later read and edit them and then propagate your changes back to Github. - -

- Bridge workflow -

- -This has several upsides: -- works offline, including edition -- browsing is pretty much instant -- you get to choose the UI you prefer between CLI, interactive terminal UI or web UI -- you get a near complete backup in case Github is down or no longer fit your needs - -Note: at the moment, Gitlab and Jira are also fully supported. - -## Installation - -Follow the [installation instruction](https://github.com/git-bug/git-bug#installation). The simplest way is to download a pre-compiled binary from [the latest release](https://github.com/git-bug/git-bug/releases/latest) and to put it anywhere in your `$PATH`. - -Check that `git-bug` is properly installed by running `git bug version`. If everything is alright, the version of the binary will be displayed. - -## Configuration - -1. From within the git repository you care about, run `git bug bridge configure` and follow the wizard's steps: - 1. Choose `github`. - 1. Type a name for the bridge configuration. As you can configure multiple bridges, this name will allow you to choose when there is an ambiguity. - 1. Setup the remote Github project. The wizard is smart enough to inspect the git remote and detect the potential project. Otherwise, enter the project URL like this: `https://github.com/git-bug/git-bug` - 1. Enter your login on Github - 1. Setup an authentication token. You can either use the interactive token creation, enter your own token or select an existing token, if any. -1. Run `git bug bridge pull` and let it run to import the issues and identities. - -## Basic usage - -You can interact with `git-bug` through the command line (see the [Readme](../README.md#cli-usage) for more details): -```bash -# Create a new bug -git bug add -# List existing bugs -git bug ls -# Display a bug's detail -git bug show -# Add a new comment -git bug comment -# Push everything to a normal git remote -git bug push [] -# Pull updates from a git remote -git bug pull [] -``` - -In particular, the key commands to interact with Github are: -```bash -# Replicate your changes to the remote bug-tracker -git bug bridge push [] -# Retrieve updates from the remote bug-tracker -git bug bridge pull [] -``` - -The command line tools are really meant for programmatic usage or to integrate `git-bug` into your editor of choice. For day to day usage, the recommended way is the interactive terminal UI. You can start it with `git bug termui`: - -![termui recording](../misc/termui_recording.gif) - -For a richer and more user friendly UI, `git-bug` proposes a web UI (read-only at the moment). You can start it with `git bug webui`: - -![web UI screenshot](../misc/webui2.png) - -## Want more? - -If you interested to read more about `git-bug`, have a look at the following: -- [the project itself, with a more complete readme](https://github.com/git-bug/git-bug) -- [a bird view of the internals](https://github.com/git-bug/git-bug/blob/master/doc/architecture.md) -- [a description of the data model](https://github.com/git-bug/git-bug/blob/master/doc/model.md) - -Of course, if you want to contribute the door is way open :-) diff --git a/doc/jira_bridge.md b/doc/jira_bridge.md deleted file mode 100644 index bf3c1a8b..00000000 --- a/doc/jira_bridge.md +++ /dev/null @@ -1,377 +0,0 @@ -# JIRA Bridge - -## Design Notes - -### One bridge = one project - -There aren't any huge technical barriers requiring this, but since git-bug lacks -a notion of "project" there is no way to know which project to export new bugs -to as issues. Also, JIRA projects are first-class immutable metadata and so we -*must* get it right on export. Therefore the bridge is configured with the `Key` -for the project it is assigned to. It will only import bugs from that project. - -### JIRA fields - -The bridge currently does nothing to import any of the JIRA fields that don't -have `git-bug` equivalents ("Assignee", "sprint", "story points", etc). -Hopefully the bridge will be able to enable synchronization of these soon. - -### Credentials - -JIRA does not support user/personal access tokens. They have experimental -3-legged oauth support but that requires an API token for the app configured -by the server administrator. The only reliable authentication mechanism then is -the username/password and session-token mechanism. We can acquire a session -token programmatically from the username/password but these are very short lived -(i.e. hours or less). As such the bridge currently requires an actual username -and password as user credentials. It supports three options: - -1. Storing both username and password in a separate file referred to by - the `git-config` (I like to use `.git/jira-credentials.json`) -2. Storing the username and password in clear-text in the git config -3. Storing the username only in the git config and asking for the password - on each `push` or `pull`. - -### Issue Creation Defaults - -When a new issues is created in JIRA there are often certain mandatory fields -that require a value or the creation is rejected. In the issue create form on -the JIRA web interface, these are annotated as "required". The `issuetype` is -always required (e.g. "bug", "story", "task", etc). The set of required metadata -is configurable (in JIRA) per `issuetype` so the set might be different between -"bug" and "story", for example. - -For now, the bridge only supports exporting issues as a single `issuetype`. If -no configuration is provided, then the default is `"id": "10001"` which is -`"story"` in the default set of issue types. - -In addition to specifying the `issuetype` of issues created on export, the -bridge will also allow you to specify a constant global set of default values -for any additional required fields. See the configuration section below for the -syntax. - -For longer term goals, see the section below on workflow validation - -### Assign git-bug id to field during issue creation - -JIRA allows for the inclusion of custom "fields" in all of their issues. The -JIRA bridge will store the JIRA issue "id" for any bugs which are synchronized -to JIRA, but it can also assign to a custom JIRA `field` the `git-bug` id. This -way the `git-bug` id can be displayed in the JIRA web interface and certain -integration activities become easier. - -See the configuration section below on how to specify the custom field where the -JIRA bridge should write this information. - - -### Workflows and Transitions - -JIRA issue states are subject to customizable "workflows" (project managers -apparently validate themselves by introducing developer friction). In general, -issues can only transition from one state to another if there is an edge between -them in the state graph (a.k.a. "workflow"). JIRA calls these edges -"transitions". Furthermore, each transition may include a set of mandatory -fields which must be set in order for the transition to succeed. For example the -transition of `"status"` from `"In Progress"` to `"Closed"` might required a -`"resolution"` (i.e. `"Fixed"` or `"Working as intended"`). - -Dealing with complex workflows is going to be challenging. Some long-term -aspirations are described in the section below on "Workflow Validation". -Currently the JIRA bridge isn't very smart about transitions though, so you'll -need to tell it what you want it to do when importing and exporting a state -change (i.e. to "close" or "open" a bug). Currently the bridge accepts -configuration options which map the two `git-bug` statuses ("open", "closed") to -two JIRA statuses. On import, the JIRA status is mapped to a `git-bug` status -(if a mapping exists) and the `git-bug` status is assigned. On export, the -`git-bug` status is mapped to a JIRA status and if a mapping exists the bridge -will query the list of available transitions for the issue. If a transition -exists to the desired state the bridge will attempt to execute the transition. -It does not currently support assigning any fields during the transition so if -any fields are required the transition will fail during export and the status -will be out of sync. - -### JIRA Changelog - -Some operations on JIRA issues are visible in a timeline view known as the -`changelog`. The JIRA cloud product provides an -`/issue/{issueIdOrKey}/changelog` endpoint which provides a paginated view but -the JIRA server product does not. The changelog is visible by querying the issue -with the `expand=changelog` query parameter. Unfortunately in this case the -entire changelog is provided without paging. - -Each changelog entry is identified with a unique string `id`, but within a -single changelog entry is a list of multiple fields that are modified. In other -words a single "event" might atomically change multiple fields. As an example, -when an issue is closed the `"status"` might change to `"closed"` and the -`"resolution"` might change to `"fixed'`. - -When a changelog entry is imported by the JIRA bridge, each individual field -that was changed is treated as a separate `git-bug` operation. In other words a -single JIRA change event might create more than one `git-bug` operation. - -However, when a `git-bug` operation is exported to JIRA it will only create a -single changelog entry. Furthermore, when we modify JIRA issues over the REST -API JIRA does not provide any information to associate that modification event -with the changelog. We must, therefore, heuristically match changelog entries -against operations that we performed in order to not import them as duplicate -events. In order to assist in this matching process, the bridge will record the -JIRA server time of the response to the `POST` (as reported by the `"Date"` -response header). During import, we keep an iterator to the list of `git-bug` -operations for the bug mapped to the Jira issue. As we walk the JIRA changelog, -we keep the iterator pointing to the first operation with an annotation which is -*not before* that changelog entry. If the changelog entry is the result of an -exported `git-bug` operation, then this must be that operation. We then scan -through the list of changeitems (changed fields) in the changelog entry, and if -we can match a changed field to the candidate `git-bug` operation then we have -identified the match. - -### Unlogged Changes - -Comments (creation and edition) do not show up in the JIRA changelog. However -JIRA reports both a `created` and `updated` date for each comment. If we -import a comment which has an `updated` and `created` field which do not match, -then we treat that as a new comment edition. If we do not already have the -comment imported, then we import an empty comment followed by a comment edition. - -Because comment editions are not uniquely identified in JIRA we identify them -in `git-bug` by concatenating the JIRA issue `id` with the `updated` time of -the edition. - -### Workflow Validation (future) - -The long-term plan for the JIRA bridge is to download and store the workflow -specifications from the JIRA server. This includes the required metadata for -issue creation, and the status state graph, and the set of required metadata for -status transition. - -When an existing `git-bug` is initially marked for export, the bridge will hook -in and validate the bug state against the required metadata. Then it will prompt -for any missing metadata using a set of UI components appropriate for the field -schema as reported by JIRA. If the user cancels then the bug will not be marked -for export. - -When a bug already marked for JIRA export (including those that were imported) -is modified, the bridge will hook in and validate the modification against the -workflow specifications. It will prompt for any missing metadata as in the -creation process. - -During export, the bridge will validate any export operations and skip them if -we know they will fail due to violation of the cached workflow specification -(i.e. missing required fields for a transition). A list of bugs "blocked for -export" will be available to query. A UI command will allow the user to inspect -and resolve any bugs that are "blocked for export". - -## Configuration - -As mentioned in the notes above, there are a few optional configuration fields -that can be set beyond those that are prompted for during the initial bridge -configuration. You can set these options in your `.git/config` file: - -### Issue Creation Defaults - -The format for this config entry is a JSON object containing fields you wish to -set during issue creation when exporting bugs. If you provide a value for this -configuration option, it must include at least the `"issuetype"` field, or -the bridge will not be able to export any new issues. - -Let's say that we want bugs exported to JIRA to have a default issue type of -"Story" which is `issuetype` with id `10001`. Then we will add the following -entry to our git-config: - -``` -create-issue-defaults = {"issuetype":"10001"} -``` - -If you needed an additional required field `customfield_1234` and you wanted to -provide a default value of `"default"` then you would add the following to your -config: - -``` -create-issue-defaults = {"issuetype":"10001","customfield_1234":"default"} -``` - -Note that the content of this value is merged verbatim to the JSON object that -is `POST`ed to the JIRA rest API, so you can use arbitrary valid JSON. - - -### Assign git-bug id to field - -If you want the bridge to fill a JIRA field with the `git-bug` id when exporting -issues, then provide the name of the field: - -``` -create-issue-gitbug-id = "customfield_5678" -``` - -### Status Map - -You can specify the mapping between `git-bug` status and JIRA status id's using -the following: -``` -bug-id-map = {\"open\": \"1\", \"closed\": \"6\"} -``` - -The format of the map is `: `. In general -your jira instance will have more statuses than `git-bug` will and you may map -more than one jira-status to a git-bug status. You can do this with -`bug-id-revmap`: -``` -bug-id-revmap = {\"10109\": \"open\", \"10006\": \"open\", \"10814\": \"open\"} -``` - -The reverse map `bug-id-revmap` will automatically include the inverse of the -forward map `bug-id-map`. - -Note that in JIRA each different `issuetype` can have a different set of -statuses. The bridge doesn't currently support more than one mapping, however. -Also, note that the format of the map is JSON and the git config file syntax -requires doublequotes to be escaped (as in the examples above). - -### Full example - -Here is an example configuration with all optional fields set -``` -[git-bug "bridge.default"] - project = PROJ - credentials-file = .git/jira-credentials.json - target = jira - server = https://jira.example.com - create-issue-defaults = {"issuetype":"10001","customfield_1234":"default"} - create-issue-gitbug-id = "customfield_5678" - bug-open-id = 1 - bug-closed-id = 6 -``` - -## To-Do list - -* [0cf5c71] Assign git-bug to jira field on import -* [8acce9c] Download and cache workflow representation -* [95e3d45] Implement workflow gui -* [c70e22a] Implement additional query filters for import -* [9ecefaa] Create JIRA mock and add REST unit tests -* [67bf520] Create import/export integration tests -* [1121826] Add unit tests for utilities -* [0597088] Use OS keyring for credentials -* [d3e8f79] Don't count on the `Total` value in paginations - - -## Using CURL to poke at your JIRA's REST API - -If you need to lookup the `id` for any `status`es or the `schema` for any -creation metadata, you can use CURL to query the API from the command line. -Here are a couple of examples to get you started. - -### Getting a session token - -``` -curl \ - --data '{"username":"", "password":""}' \ - --header "Content-Type: application/json" \ - --request POST \ - /rest/auth/1/session -``` - -**Note**: If you have a json pretty printer installed (`sudo apt install jq`), -pipe the output through through that to make things more readable: - -``` -curl --silent \ - --data '{"username":"", "password":""}' \ - --header "Content-Type: application/json" \ - --request POST - /rest/auth/1/session | jq . -``` - -example output: -``` -{ - "session": { - "name": "JSESSIONID", - "value": "{sessionToken}" - }, - "loginInfo": { - "loginCount": 268, - "previousLoginTime": "2019-11-12T08:03:35.300-0800" - } -} -``` - -Make note of the output value. On subsequent invocations of `curl`, append the -following command-line option: - -``` ---cookie "JSESSIONID={sessionToken}" -``` - -Where `{sessionToken}` is the output from the `POST` above. - -### Get a list of issuetype ids - -``` -curl --silent \ - --cookie "JSESSIONID={sessionToken}" \ - --header "Content-Type: application/json" \ - --request GET https://jira.example.com/rest/api/2/issuetype \ - | jq . -``` - -**example output**: -``` - { - "self": "https://jira.example.com/rest/api/2/issuetype/13105", - "id": "13105", - "description": "", - "iconUrl": "https://jira.example.com/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype", - "name": "Test Plan Links", - "subtask": true, - "avatarId": 10316 - }, - { - "self": "https://jira.example.com/rest/api/2/issuetype/13106", - "id": "13106", - "description": "", - "iconUrl": "https://jira.example.com/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype", - "name": "Enable Initiatives on the project", - "subtask": true, - "avatarId": 10316 - }, - ... -``` - - -### Get a list of statuses - - -``` -curl --silent \ - --cookie "JSESSIONID={sessionToken}" \ - --header "Content-Type: application/json" \ - --request GET https://jira.example.com/rest/api/2/project/{projectIdOrKey}/statuses \ - | jq . -``` - -**example output:** -``` -[ - { - "self": "https://example.com/rest/api/2/issuetype/3", - "id": "3", - "name": "Task", - "subtask": false, - "statuses": [ - { - "self": "https://example.com/rest/api/2/status/1", - "description": "The issue is open and ready for the assignee to start work on it.", - "iconUrl": "https://example.com/images/icons/statuses/open.png", - "name": "Open", - "id": "1", - "statusCategory": { - "self": "https://example.com/rest/api/2/statuscategory/2", - "id": 2, - "key": "new", - "colorName": "blue-gray", - "name": "To Do" - } - }, -... -``` diff --git a/doc/merge1.png b/doc/merge1.png deleted file mode 100644 index 7ba24173..00000000 Binary files a/doc/merge1.png and /dev/null differ diff --git a/doc/merge2.png b/doc/merge2.png deleted file mode 100644 index 614be5e8..00000000 Binary files a/doc/merge2.png and /dev/null differ diff --git a/doc/model.md b/doc/model.md deleted file mode 100644 index 266aa3ed..00000000 --- a/doc/model.md +++ /dev/null @@ -1,145 +0,0 @@ -git-bug's reusable entity data model -==================================== - -This document explains how git-bug's reusable distributed data structure in git is working. This data structure is capable of: -- storing an entity (bug, pull-request, config...) and its complete history in git -- carry signed authorship of editions -- use git remotes as a medium for synchronisation and collaboration -- merge conflicts -- respect the rules you define as to what edition are possible -- carry attached media - -If you are looking for a different writing format or to see how you can easily make your own, checkout [the example code](../entity/dag/example_test.go). - -If you are not familiar with [git internals](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects), you might first want to read about them, as the `git-bug` data model is built on top of them. - -## Entities (bug, author, ...) are a series of edit operations - -As entities are stored and edited in multiple processes at the same time, it's not possible to store the current state like it would be done in a normal application. If two processes change the same entity and later try to merge the states, we wouldn't know which change takes precedence or how to merge those states. - -To deal with this problem, you need a way to merge these changes in a meaningful way. Instead of storing the final bug data directly, we store a series of edit `Operation`s. This is a common idea, notably with [Operation-based CRDTs](https://en.wikipedia.org/wiki/Conflict-free_replicated_data_type#Operation-based_CRDTs). - -![ordered operations](operations.png) - -To get the final state of an entity, we apply these `Operation`s in the correct order on an empty state, to compute (aka "compile") our view. - -## Entities are stored in git objects - -An `Operation` is a piece of data, including: - -- a type identifier -- an author (a reference to another entity) -- a timestamp (there is also one or two [Lamport time](#time-is-unreliable)) -- all the data required by that operation type (a message, a status ...) -- a random [nonce](https://en.wikipedia.org/wiki/Cryptographic_nonce) to ensure we have enough entropy, as the operation identifier is a hash of that data (more on that later) - -These `Operation`s are aggregated in an `OperationPack`, a simple array. An `OperationPack` represents an edit session of the entity. As the operation's author is the same for all the `OperationPack` we only store it once. - -We store this pack in git as a git `Blob`; that consists of a string containing a JSON array of operations. One such pack -- here with two operations -- might look like this: - -```json -{ - "author": { - "id": "04bf6c1a69bb8e9679644874c85f82e337b40d92df9d8d4176f1c5e5c6627058" - }, - "ops": [ - { - "type": 3, - "timestamp": 1647377254, - "nonce": "SRQwUWTJCXAmQBIS+1ctKgOcbF0=", - "message": "Adding a comment", - "files": null - }, - { - "type": 4, - "timestamp": 1647377257, - "nonce": "la/HaRPMvD77/cJSJOUzKWuJdY8=", - "status": 1 - } - ] -} -``` - -To reference our `OperationPack`, we create a git `Tree`; it references our `OperationPack` `Blob` under `"/ops"`. If any edit operation includes a media (for instance in a text message), we can store that media as a `Blob` and reference it here under `"/media"`. - -To complete the picture, we create a git `Commit` that references our `Tree`. Each time we add more `Operation`s to our bug, we add a new `Commit` with the same data-structure to form a chain of `Commit`s. - -This chain of `Commit`s is made available as a git `Reference` under `refs//`. We can later use this reference to push our data to a git remote. As git will push any data needed as well, everything will be pushed to the remote, including the media. - -Here is the complete picture: - -![git graph of a simple bug](bug-graph-1.png) - -## Time is unreliable - -Before being able to merge conflicts, let's start with some building blocks. - -It would be very tempting to use the `Operation`'s timestamp to give us the order to compile the final state. However, you can't rely on the time provided by other people (their clock might be off) for anything other than just display. This is a fundamental limitation of distributed system, and even more so when actors might want to game the system. - -Instead, we are going to use [Lamport logical clock](https://en.wikipedia.org/wiki/Lamport_timestamps). A Lamport clock is a simple counter of events. This logical clock gives us a partial ordering: - -- if L1 < L2, L1 happened before L2 -- if L1 > L2, L1 happened after L2 -- if L1 == L2, we can't tell which happened first: it's a concurrent edition - - -Each time we are appending something to the data (create an `Entity`, add an `Operation`) a logical time will be attached, with the highest time value we are aware of, plus one. This declares a causality in the events and allows ordering entities and operations. - -The first commit of an `Entity` will have both a creation time and edit time clock, while a later commit will only have an edit time clock. These clocks value are serialized directly in the `Tree` entry name (for example: `"create-clock-4"`). As a `Tree` entry needs to reference something, we reference the git `Blob` with an empty content. As all of these entries will reference the same `Blob`, no network transfer is needed as long as you already have any entity in your repository. - -Example of a `Tree` of the first commit of an entity: -``` -100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 create-clock-14 -100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 edit-clock-137 -100644 blob a020a85baa788e12699a4d83dd735578f0d78c75 ops -``` - -Example of a `Tree` of a later commit of an entity: -``` -100644 blob e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 edit-clock-154 -100644 blob 68383346c1a9503f28eec888efd300e9fc179ca0 ops -``` - -## Entities and Operation's ID - -`Operation`s can be referenced - in the data model or by users - with an identifier. This identifier is computed from the `Operation`'s data itself, with a hash of that data: `id = hash(json(op))` - -For entities, `git-bug` uses as identifier the hash of the first `Operation` of the entity, as serialized on disk. - -The same way as git does, this hash is displayed truncated to a 7 characters string to a human user. Note that when specifying a bug id in a command, you can enter as few characters as you want, as long as there is no ambiguity. If multiple entities match your prefix, `git-bug` will complain and display the potential matches. - -## Entities support conflict resolution - -Now that we have all that, we can finally merge our entities without conflict, and collaborate with other users. Let's start by getting rid of two simple scenarios: - -- if we simply pull updates, we move forward our local reference. We get an update of our graph that we read as usual. -- if we push fast-forward updates, we move forward the remote reference and other users can update their reference as well. - -The tricky part happens when we have concurrent editions. If we pull updates while we have local changes (non-straightforward in git term), `git-bug` creates the equivalent of a merge commit to merge both branches into a DAG. This DAG has a single root containing the first operation, but can have branches that get merged back into a single head pointed by the reference. - -As we don't have a purely linear series of commits/`Operations`s, we need a deterministic ordering to always apply operations in the same order. - -`git-bug` applies the following algorithm: - -1. load and read all the commits and the associated `OperationPack`s -2. make sure that the Lamport clocks respect the DAG structure: a parent commit/`OperationPack` (that is, towards the head) cannot have a clock that is higher or equal than its direct child. If such a problem happens, the commit is refused/discarded. -3. individual `Operation`s are assembled together and ordered given the following priorities: - 1. the edition's lamport clock if not concurrent - 2. the lexicographic order of the `OperationPack`'s identifier - -Step 2 is providing and enforcing a constraint over the `Operation`'s logical clocks. What that means, is that **we inherit the implicit ordering given by the DAG**. Later, logical clocks refine that ordering. This - coupled with signed commits - has the nice property of limiting how this data model can be abused. - -Here is an example of such an ordering: - -![merge scenario 1](merge1.png) - -We can see that: - -- Lamport clocks respect the DAG structure -- the final `Operation` order is [A,B,C,D,E,F], according to those clocks - -When we have concurrent editions, we apply a secondary ordering, based on the `OperationPack`'s identifier: - -![merge scenario 2](merge2.png) - -This secondary ordering doesn't carry much meaning, but it's unbiased and hard to abuse. diff --git a/doc/operations.png b/doc/operations.png deleted file mode 100644 index 79b6c8e7..00000000 Binary files a/doc/operations.png and /dev/null differ diff --git a/doc/queries.md b/doc/queries.md deleted file mode 100644 index 358948eb..00000000 --- a/doc/queries.md +++ /dev/null @@ -1,113 +0,0 @@ -# Searching bugs - -You can search bugs using a micro query language for both filtering and sorting. A query could look like this: - -``` -status:open sort:edit -``` - -A few tips: - -- queries are case insensitive. -- you can combine as many qualifiers as you want. -- you can use double quotes for multi-word search terms. For example, `author:"RenΓ© Descartes"` searches for bugs opened by RenΓ© Descartes, whereas `author:RenΓ© Descartes` will search for bug with RenΓ© as the author and containing Descartes in a text. -- instead of a complete ID, you can use any prefix length, as long as there is no ambiguity. For example `participant=9ed1a`. - - -## Filtering - -### Filtering by status - -You can filter bugs based on their status. - -| Qualifier | Example | -|-----------------|-------------------------------------| -| `status:open` | `status:open` matches open bugs | -| `status:closed` | `status:closed` matches closed bugs | - -### Filtering by author - -You can filter based on the person who opened the bug. - -| Qualifier | Example | -|----------------|----------------------------------------------------------------------------------| -| `author:QUERY` | `author:descartes` matches bugs opened by `RenΓ© Descartes` or `Robert Descartes` | -| | `author:"renΓ© descartes"` matches bugs opened by `RenΓ© Descartes` | - -### Filtering by participant - -You can filter based on the person who participated in any activity related to the bug (opened bug or added a comment). - -| Qualifier | Example | -|---------------------|----------------------------------------------------------------------------------------------------| -| `participant:QUERY` | `participant:descartes` matches bugs opened or commented by `RenΓ© Descartes` or `Robert Descartes` | -| | `participant:"renΓ© descartes"` matches bugs opened or commented by `RenΓ© Descartes` | - -### Filtering by actor - -You can filter based on the person who interacted with the bug. - -| Qualifier | Example | -|---------------|---------------------------------------------------------------------------------| -| `actor:QUERY` | `actor:descartes` matches bugs edited by `RenΓ© Descartes` or `Robert Descartes` | -| | `actor:"renΓ© descartes"` matches bugs edited by `RenΓ© Descartes` | - -**NOTE**: interaction with bugs include: opening the bug, adding comments, adding/removing labels etc... - -### Filtering by label - -You can filter based on the bug's label. - -| Qualifier | Example | -|---------------|---------------------------------------------------------------------------| -| `label:LABEL` | `label:prod` matches bugs with the label `prod` | -| | `label:"Good first issue"` matches bugs with the label `Good first issue` | - -### Filtering by title - -You can filter based on the bug's title. - -| Qualifier | Example | -|---------------|--------------------------------------------------------------------------------| -| `title:TITLE` | `title:Critical` matches bugs with a title containing `Critical` | -| | `title:"Typo in string"` matches bugs with a title containing `Typo in string` | - - -### Filtering by missing feature - -You can filter bugs based on the absence of something. - -| Qualifier | Example | -|------------|----------------------------------------| -| `no:label` | `no:label` matches bugs with no labels | - -## Sorting - -You can sort results by adding a `sort:` qualifier to your query. β€œDescending” means most recent time or largest ID first, whereas β€œAscending” means oldest time or smallest ID first. - -Note: to deal with differently-set clocks on distributed computers, `git-bug` uses a logical clock internally rather than timestamps to order bug changes over time. That means that the timestamps recorded might not match the returned ordering. More on that in [the documentation](model.md#you-cant-rely-on-the-time-provided-by-other-people-their-clock-might-by-off-for-anything-other-than-just-display) - -### Sort by Id - -| Qualifier | Example | -|----------------------------|-------------------------------------------------------| -| `sort:id-desc` | `sort:id-desc` will sort bugs by their descending Ids | -| `sort:id` or `sort:id-asc` | `sort:id` will sort bugs by their ascending Ids | - -### Sort by Creation time - -You can sort bugs by their creation time. - -| Qualifier | Example | -|-----------------------------------------|---------------------------------------------------------------------| -| `sort:creation` or `sort:creation-desc` | `sort:creation` will sort bugs by their descending creation time | -| `sort:creation-asc` | `sort:creation-asc` will sort bugs by their ascending creation time | - -### Sort by Edit time - -You can sort bugs by their edit time. - -| Qualifier | Example | -|---------------------------------|---------------------------------------------------------------------| -| `sort:edit` or `sort:edit-desc` | `sort:edit` will sort bugs by their descending last edition time | -| `sort:edit-asc` | `sort:edit-asc` will sort bugs by their ascending last edition time | diff --git a/doc/usage/bridges.md b/doc/usage/bridges.md new file mode 100644 index 00000000..87b566e1 --- /dev/null +++ b/doc/usage/bridges.md @@ -0,0 +1,113 @@ +# Using bridges + +This page provides an overview of how to use _bridges_ to sync issues to and +from third-party platforms. + + + +- [Overview](#overview) +- [Supported bridges](#supported-bridges) +- [Getting started](#getting-started) +- [Interacting with the bridge](#interacting-with-the-bridge) + + + +## Overview + +Bridges within `git-bug` are bi-directional, incremental, and speedy gateways to +third-party platforms. Configuring a bridge allows you to push and pull issues +to and from a third party platform. + +This expands the utility and function of `git-bug`: because issues are just +objects in your git repository, you can import issues from a bridge to work on +them in bulk, offline, in your preferred environment, at your own pace. When +you're ready to push your issues back to the external platform again, you'll be +able to synchronize the changes you made with one simple command. + +

+ Bridge workflow +

+ +This has several benefits: + +- works offline, including edition +- browsing is pretty much instant +- you get to choose the UI you prefer between CLI, interactive terminal UI or + web UI +- you have a near-complete archive of issues locally, embedded in your git + repository, in case the external platform becomes inaccessible +- you are free to move to another platform -- your issues follow wherever your + repo goes! + +## Supported bridges + +We support a number of bridges: + +- Jira +- GitHub +- GitLab +- Launchpad + +_For a full list of the features enabled for each bridge, see the +[feature matrix][docs/feature-matrix]._ + +## Getting started + +1. From within a git repository, run `git bug bridge configure` to start the + configuration wizard +2. Choose the type of bridge you want to configure, e.g. `github` +3. Type a name for the bridge configuration. As you can configure multiple + bridges, this name will allow you to choose when there is an ambiguity. +4. If you already have a repository created on the external platform, and your + local git repository has that as a remote, the configuration wizard will + automatically detect the URL. Otherwise, please ensure you enter the + appropriate URL for the remote project: something like + `https://github.com/git-bug/git-bug` +5. Create an access token. You can either use the interactive token creation, + enter it on your own token, or use an existing token if you already have one + +That's it! Once you've completed the wizard, you'll have successfully configured +a bridge. + +## Interacting with the bridge + +To push issues out to the bridge, run: + +```bash +git bug bridge push [NAME] +``` + +To pull and integrate updates for issues from the bridge: + +```bash +git bug bridge pull [NAME] +``` + +> [!TIP] +> See the [CLI documentation][doc/cli/bridge] for more information on the +> command line arguments and options. + +The command line is primarily meant for programmatic usage or to interface with +`git-bug` with scripts or other tools. For day to day usage, we recommend taking +a look at \[the supported interfaces\]\[interfaces\], which include a robust TUI +and an in-progress Web UI. + +______________________________________________________________________ + +##### See more + +- [A bird's-eye view of the internal architecture][docs/design/arch] +- [A description of the data model][docs/design/model] +- [An overview of the native interfaces][docs/usage/interfaces] +- [Filtering query results][docs/usage/filter] +- [Understanding the workflow models][docs/usage/workflows] +- :house: [Documentation home][docs/home] + +[doc/cli/bridge]: ../md/git-bug_bridge.md +[docs/design/arch]: ../design/architecture.md +[docs/design/model]: ../design/data-model.md +[docs/feature-matrix]: ../feature-matrix.md +[docs/home]: ../README.md +[docs/usage/filter]: ./query-language.md +[docs/usage/interfaces]: ./interfaces.md +[docs/usage/workflows]: ./workflows.md diff --git a/doc/usage/interfaces.md b/doc/usage/interfaces.md new file mode 100644 index 00000000..1237928e --- /dev/null +++ b/doc/usage/interfaces.md @@ -0,0 +1,66 @@ +# Native interfaces + +This page provides an overview of the different interfaces `git-bug` supports. + + + +- [TUI](#tui) +- [Web UI](#web-ui) + + + +## TUI + +The integrated TUI (text-based user interface) is the recommended way to +interface with `git-bug` issues in your repository. + +To start it, run `git bug termui` in your terminal. + +![TUI recording](../assets/tui-recording.gif) + +## Web UI + +The web UI is packed inside the same binary and serves static content through an +http server running on the local machine. The frontend interacts with the +backend through a GraphQL API. [View the schema][gql-schema] for more +information. + +To serve the website locally, run `git bug webui` in your terminal. + +> [!NOTE] +> The web interface is alpha-level software and does not support all of the +> features of `git-bug`. We recommend using the TUI for most day-to-day +> operations at the moment. + +
+View the issue feed +
An example of viewing the issue feed in the web interface
+
+ +
+View the discussion for an issue +
An example of viewing the discussion for an issue in the web interface
+
+ +______________________________________________________________________ + +##### See more + +- [Filtering query results][docs/usage/filter] +- [How to use bridges][docs/usage/bridges] +- [Understanding the workflow models][docs/usage/workflows] +- :house: [Documentation home][docs/home] + +[docs/home]: ../README.md +[docs/usage/bridges]: ./bridges.md +[docs/usage/filter]: ./query-language.md +[docs/usage/workflows]: ./workflows.md +[gql-schema]: ../../api/graphql/schema diff --git a/doc/usage/query-language.md b/doc/usage/query-language.md new file mode 100644 index 00000000..15e8468d --- /dev/null +++ b/doc/usage/query-language.md @@ -0,0 +1,166 @@ +# Search filters + +When performing a search (e.g. listing issues), you can use different qualifiers +to narrow the results. This page provides an overview of these filters, and how +to use them. + + + +- [Overview](#overview) +- [Filtering](#filtering) + - [Filtering by status](#filtering-by-status) + - [Filtering by author](#filtering-by-author) + - [Filtering by participant](#filtering-by-participant) + - [Filtering by actor](#filtering-by-actor) + - [Filtering by label](#filtering-by-label) + - [Filtering by title](#filtering-by-title) + - [Filtering by missing feature](#filtering-by-missing-feature) +- [Sorting](#sorting) + - [Sort by Id](#sort-by-id) + - [Sort by Creation time](#sort-by-creation-time) + - [Sort by Edit time](#sort-by-edit-time) + + + +## Overview + +The query filters in `git-bug` have a familiar look and feel: + +``` +status:open sort:edit +``` + +**Key things to know** + +- All queries are case insensitive +- You can combine as many qualifiers as you want +- If you have a space in your qualifier, be sure to wrap it in double quotes. As + an example, `author:"RenΓ© Descartes"` would filter for issues opened by + `RenΓ© Descartes`, whereas `author:RenΓ© Descartes` filter for `RenΓ©` as the + author and return issues that contain `Descartes` somewhere in the title, + description, or comments. +- Instead of a complete ID, you can use any prefix length, as long as it is long + enough to be unique (similar to git commit hashes). For example, + `participant=9ed1a` would match against participants with an ID of + `9ed1af428...` and `9ed1ae24a...` + +## Filtering + +### Filtering by status + +You can filter bugs based on their status. + +| Qualifier | Example | +| --------------- | ----------------------------------- | +| `status:open` | `status:open` matches open bugs | +| `status:closed` | `status:closed` matches closed bugs | + +### Filtering by author + +You can filter based on the person who opened the bug. + +| Qualifier | Example | +| -------------- | -------------------------------------------------------------------------------- | +| `author:QUERY` | `author:descartes` matches bugs opened by `RenΓ© Descartes` or `Robert Descartes` | +| | `author:"renΓ© descartes"` matches bugs opened by `RenΓ© Descartes` | + +### Filtering by participant + +You can filter based on the person who participated in any activity related to +the bug (opened bug or added a comment). + +| Qualifier | Example | +| ------------------- | -------------------------------------------------------------------------------------------------- | +| `participant:QUERY` | `participant:descartes` matches bugs opened or commented by `RenΓ© Descartes` or `Robert Descartes` | +| | `participant:"renΓ© descartes"` matches bugs opened or commented by `RenΓ© Descartes` | + +### Filtering by actor + +You can filter based on the person who interacted with the bug. + +| Qualifier | Example | +| ------------- | ------------------------------------------------------------------------------- | +| `actor:QUERY` | `actor:descartes` matches bugs edited by `RenΓ© Descartes` or `Robert Descartes` | +| | `actor:"renΓ© descartes"` matches bugs edited by `RenΓ© Descartes` | + +> [!NOTE] +> Interactions with issues include opening the bug, adding comments, adding or +> removing labels, etc. + +### Filtering by label + +You can filter based on the bug's label. + +| Qualifier | Example | +| ------------- | ------------------------------------------------------------------------- | +| `label:LABEL` | `label:prod` matches bugs with the label `prod` | +| | `label:"Good first issue"` matches bugs with the label `Good first issue` | + +### Filtering by title + +You can filter based on the bug's title. + +| Qualifier | Example | +| ------------- | ------------------------------------------------------------------------------ | +| `title:TITLE` | `title:Critical` matches bugs with a title containing `Critical` | +| | `title:"Typo in string"` matches bugs with a title containing `Typo in string` | + +### Filtering by missing feature + +You can filter bugs based on the absence of something. + +| Qualifier | Example | +| ---------- | -------------------------------------- | +| `no:label` | `no:label` matches bugs with no labels | + +## Sorting + +You can sort results by adding a `sort:` qualifier to your query. β€œDescending” +means most recent time or largest ID first, whereas β€œAscending” means oldest +time or smallest ID first. + +Note: to deal with differently-set clocks on distributed computers, `git-bug` +uses a logical clock internally rather than timestamps to order bug changes over +time. That means that the timestamps recorded might not match the returned +ordering. To learn more, we encourage you to read about \[time \]\[data-model\]. + +### Sort by Id + +| Qualifier | Example | +| -------------------------- | ----------------------------------------------------- | +| `sort:id-desc` | `sort:id-desc` will sort bugs by their descending Ids | +| `sort:id` or `sort:id-asc` | `sort:id` will sort bugs by their ascending Ids | + +### Sort by Creation time + +You can sort bugs by their creation time. + +| Qualifier | Example | +| --------------------------------------- | ------------------------------------------------------------------- | +| `sort:creation` or `sort:creation-desc` | `sort:creation` will sort bugs by their descending creation time | +| `sort:creation-asc` | `sort:creation-asc` will sort bugs by their ascending creation time | + +### Sort by Edit time + +You can sort bugs by their edit time. + +| Qualifier | Example | +| ------------------------------- | ------------------------------------------------------------------- | +| `sort:edit` or `sort:edit-desc` | `sort:edit` will sort bugs by their descending last edition time | +| `sort:edit-asc` | `sort:edit-asc` will sort bugs by their ascending last edition time | + +______________________________________________________________________ + +##### See more + +- [A description of the data model][docs/design/model] +- [How to use bridges][docs/usage/bridges] +- [Learn about the native interfaces][docs/usage/interfaces] +- [Understanding the workflow models][docs/usage/workflows] +- :house: [Documentation home][docs/home] + +[docs/design/model]: ../design/data-model.md#you-cant-rely-on-the-time-provided-by-other-people-their-clock-might-by-off-for-anything-other-than-just-display +[docs/home]: ../README.md +[docs/usage/bridges]: ./bridges.md +[docs/usage/interfaces]: ./interfaces.md +[docs/usage/workflows]: ./workflows.md diff --git a/doc/usage/workflows.md b/doc/usage/workflows.md new file mode 100644 index 00000000..f2baeeec --- /dev/null +++ b/doc/usage/workflows.md @@ -0,0 +1,62 @@ +# Workflows + +This document provides an overview of different workflows that `git-bug` +supports. + + + +## Native workflow + +

+ Native workflow +

+ +This is the pure `git-bug` experience. In a similar fashion as with code, use +`git bug push` and `git bug pull` to push and pull your bugs between git remotes +and collaborate with your teammate. + +_Recommended reading: [CLI documentation][docs/cli]_ + +## Bridge workflow + +

+ Bridge workflow +

+ +`git-bug` supports syncing issues with third-party platforms, such as GitHub, +GitLab, and Jira. This lets you work on issues offline, editing issues in bulk +with your preferred editor, or to build an archive of any project's issues -- +it's up to you! + +_Recommended reading: [How to use bridges][docs/usage/bridges]_ + +## Web UI workflow + +

+ Web UI workflow +

+ +> [!NOTE] +> The web UI is a work in progress, and is not feature-complete. To utilize +> `git-bug` to its full potential, we recommend using the TUI or CLI. + +Often, projects needs to have their bug-tracker public and accept editions from +anyone facing a problem. To support this workflow, `git-bug` aims to have the +web UI accept external OAuth authentication and act as a public portal. However +the web UI is not up to speed for that yet. Contributions are very much welcome! + +______________________________________________________________________ + +##### See also + +- [CLI documentation][docs/cli] +- [Filtering query results][docs/usage/filter] +- [How to use bridges][docs/usage/bridges] +- [Learn about the native interfaces][docs/usage/interfaces] +- :house: [Documentation home][docs/home] + +[docs/cli]: ../md/git-bug.md +[docs/home]: ../README.md +[docs/usage/bridges]: ./bridges.md +[docs/usage/filter]: ./query-language.md +[docs/usage/interfaces]: ./interfaces.md diff --git a/entity/dag/example_test.go b/entity/dag/example_test.go index c9e4f352..3ffdb4fc 100644 --- a/entity/dag/example_test.go +++ b/entity/dag/example_test.go @@ -13,7 +13,7 @@ import ( ) // Note: you can find explanations about the underlying data model here: -// https://github.com/git-bug/git-bug/blob/master/doc/model.md +// https://github.com/git-bug/git-bug/blob/master/doc/design/data-model.md // This file explains how to define a replicated data structure, stored in and using git as a medium for // synchronisation. To do this, we'll use the entity/dag package, which will do all the complex handling. diff --git a/flake-hook.bash b/flake-hook.bash new file mode 100644 index 00000000..dde009dd --- /dev/null +++ b/flake-hook.bash @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# use //:.gitmessage as the commit message template +git config --local commit.template ".gitmessage" + +# use a common, shared file as the default for running git-blame with the +# `--ignore-revs` flag +git config --local blame.ignoreRevsFile ".git-blame-ignore-revs" + +# enable features.manyFiles, which improves repository performance by setting +# new values for several configuration options: +# - `core.untrackedCache = true` enables the untracked cache +# - `index.version = 4` enables path-prefix compression in the index +# - `index.skipHash = true` speeds up index writes by not computing a trailing +# checksum +git config --local features.manyFiles true diff --git a/flake.lock b/flake.lock index a88843cc..04c16c11 100644 --- a/flake.lock +++ b/flake.lock @@ -1,15 +1,33 @@ { "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1743550720, + "narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "c621e8422220273271f52058f618c94e405bb0f5", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, "flake-utils": { "inputs": { "systems": "systems" }, "locked": { - "lastModified": 1710146030, - "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=", + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", "owner": "numtide", "repo": "flake-utils", - "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", "type": "github" }, "original": { @@ -20,11 +38,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1721138476, - "narHash": "sha256-+W5eZOhhemLQxelojLxETfbFbc19NWawsXBlapYpqIA=", + "lastModified": 1744932701, + "narHash": "sha256-fusHbZCyv126cyArUwwKrLdCkgVAIaa/fQJYFlCEqiU=", "owner": "nixos", "repo": "nixpkgs", - "rev": "ad0b5eed1b6031efaed382844806550c3dcb4206", + "rev": "b024ced1aac25639f8ca8fdfc2f8c4fbd66c48ef", "type": "github" }, "original": { @@ -34,10 +52,27 @@ "type": "github" } }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1743296961, + "narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=", + "owner": "nix-community", + "repo": "nixpkgs.lib", + "rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nixpkgs.lib", + "type": "github" + } + }, "root": { "inputs": { + "flake-parts": "flake-parts", "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" + "nixpkgs": "nixpkgs", + "treefmt-nix": "treefmt-nix" } }, "systems": { @@ -54,6 +89,26 @@ "repo": "default", "type": "github" } + }, + "treefmt-nix": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1744961264, + "narHash": "sha256-aRmUh0AMwcbdjJHnytg1e5h5ECcaWtIFQa6d9gI85AI=", + "owner": "numtide", + "repo": "treefmt-nix", + "rev": "8d404a69efe76146368885110f29a2ca3700bee6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "treefmt-nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index dcf48ef8..42747c1e 100644 --- a/flake.nix +++ b/flake.nix @@ -4,41 +4,41 @@ inputs = { nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; + flake-parts.url = "github:hercules-ci/flake-parts"; + + treefmt-nix = { + url = "github:numtide/treefmt-nix"; + inputs.nixpkgs.follows = "nixpkgs"; + }; }; outputs = - { - self, - flake-utils, - nixpkgs, - }: - flake-utils.lib.eachDefaultSystem ( - system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in - { - devShell = pkgs.mkShell { - packages = with pkgs; [ - codespell - delve - gh - git - go - golangci-lint - nixfmt-rfc-style - nodePackages.prettier - ]; + { nixpkgs, ... }@inputs: + let + systems = inputs.flake-utils.lib.defaultSystems; + in + inputs.flake-parts.lib.mkFlake { inherit inputs; } { + inherit systems; + + imports = [ inputs.treefmt-nix.flakeModule ]; + + perSystem = + { pkgs, system, ... }: + { + treefmt = import ./treefmt.nix { inherit pkgs; }; - shellHook = '' - # Use //:.gitmessage as the commit message template - ${pkgs.git}/bin/git config --local commit.template ".gitmessage" + devShells.default = pkgs.mkShell { + packages = with pkgs; [ + codespell + delve + gh + git + go + golangci-lint + ]; - # Use a common, shared file as the default for running - # git-blame with the `--ignore-revs` flag - ${pkgs.git}/bin/git config --local blame.ignoreRevsFile ".git-blame-ignore-revs" - ''; + shellHook = builtins.readFile ./flake-hook.bash; + }; }; - } - ); + }; } diff --git a/git-bug.go b/git-bug.go index d60bff96..7a2034ba 100644 --- a/git-bug.go +++ b/git-bug.go @@ -1,5 +1,5 @@ -//go:generate go run doc/gen_docs.go -//go:generate go run misc/completion/gen_completion.go +//go:generate go run doc/generate.go +//go:generate go run misc/completion/generate.go package main diff --git a/misc/completion/gen_completion.go b/misc/completion/gen_completion.go deleted file mode 100644 index e2a8cc1b..00000000 --- a/misc/completion/gen_completion.go +++ /dev/null @@ -1,127 +0,0 @@ -package main - -import ( - "fmt" - "os" - "path/filepath" - "sync" - - "github.com/spf13/cobra" - - "github.com/git-bug/git-bug/commands" -) - -func main() { - fmt.Println("Generating completion files ...") - - tasks := map[string]func(*cobra.Command) error{ - "Bash": genBash, - "Fish": genFish, - "PowerShell": genPowerShell, - "ZSH": genZsh, - } - - var wg sync.WaitGroup - for name, f := range tasks { - wg.Add(1) - go func(name string, f func(*cobra.Command) error) { - defer wg.Done() - root := commands.NewRootCommand() - err := f(root) - if err != nil { - fmt.Printf(" - %s: %v\n", name, err) - return - } - fmt.Printf(" - %s: ok\n", name) - }(name, f) - } - - wg.Wait() -} - -func genBash(root *cobra.Command) error { - cwd, err := os.Getwd() - if err != nil { - return err - } - f, err := os.Create(filepath.Join(cwd, "misc", "completion", "bash", "git-bug")) - if err != nil { - return err - } - defer f.Close() - - const patch = ` -# Custom bash code to connect the git completion for "git bug" to the -# git-bug completion for "git-bug" -_git_bug() { - local cur prev words cword split - - COMPREPLY=() - - # Call _init_completion from the bash-completion package - # to prepare the arguments properly - if declare -F _init_completion >/dev/null 2>&1; then - _init_completion -n "=:" || return - else - __git-bug_init_completion -n "=:" || return - fi - - # START PATCH - # replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword - words=("git-bug" "${words[@]:2}") - cword=$(($cword-1)) - # END PATCH - - __git-bug_debug - __git-bug_debug "========= starting completion logic ==========" - __git-bug_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword" - - # The user could have moved the cursor backwards on the command-line. - # We need to trigger completion from the $cword location, so we need - # to truncate the command-line ($words) up to the $cword location. - words=("${words[@]:0:$cword+1}") - __git-bug_debug "Truncated words[*]: ${words[*]}," - - local out directive - __git-bug_get_completion_results - __git-bug_process_completion_results -} -` - err = root.GenBashCompletionV2(f, true) - if err != nil { - return err - } - - // Custom bash code to connect the git completion for "git bug" to the - // git-bug completion for "git-bug" - _, err = f.WriteString(patch) - - return err -} - -func genFish(root *cobra.Command) error { - cwd, err := os.Getwd() - if err != nil { - return err - } - dir := filepath.Join(cwd, "misc", "completion", "fish", "git-bug") - return root.GenFishCompletionFile(dir, true) -} - -func genPowerShell(root *cobra.Command) error { - cwd, err := os.Getwd() - if err != nil { - return err - } - path := filepath.Join(cwd, "misc", "completion", "powershell", "git-bug") - return root.GenPowerShellCompletionFile(path) -} - -func genZsh(root *cobra.Command) error { - cwd, err := os.Getwd() - if err != nil { - return err - } - path := filepath.Join(cwd, "misc", "completion", "zsh", "git-bug") - return root.GenZshCompletionFile(path) -} diff --git a/misc/completion/generate.go b/misc/completion/generate.go new file mode 100644 index 00000000..245c561c --- /dev/null +++ b/misc/completion/generate.go @@ -0,0 +1,127 @@ +package main + +import ( + "fmt" + "os" + "path/filepath" + "sync" + + "github.com/spf13/cobra" + + "github.com/git-bug/git-bug/commands" +) + +func main() { + fmt.Println("Generating completion files ...") + + tasks := map[string]func(*cobra.Command) error{ + "Bash": genBash, + "Fish": genFish, + "PowerShell": genPowerShell, + "ZSH": genZsh, + } + + var wg sync.WaitGroup + for name, f := range tasks { + wg.Add(1) + go func(name string, f func(*cobra.Command) error) { + defer wg.Done() + root := commands.NewRootCommand() + err := f(root) + if err != nil { + fmt.Printf(" - %s: %v\n", name, err) + return + } + fmt.Printf(" - %s: ok\n", name) + }(name, f) + } + + wg.Wait() +} + +func genBash(root *cobra.Command) error { + cwd, err := os.Getwd() + if err != nil { + return err + } + f, err := os.Create(filepath.Join(cwd, "misc", "completion", "bash", "git-bug")) + if err != nil { + return err + } + defer f.Close() + + const patch = ` +# Custom bash code to connect the git completion for "git bug" to the +# git-bug completion for "git-bug" +_git_bug() { + local cur prev words cword split + + COMPREPLY=() + + # Call _init_completion from the bash-completion package + # to prepare the arguments properly + if declare -F _init_completion >/dev/null 2>&1; then + _init_completion -n "=:" || return + else + __git-bug_init_completion -n "=:" || return + fi + + # START PATCH + # replace in the array ("git","bug", ...) to ("git-bug", ...) and adjust the index in cword + words=("git-bug" "${words[@]:2}") + cword=$(($cword-1)) + # END PATCH + + __git-bug_debug + __git-bug_debug "========= starting completion logic ==========" + __git-bug_debug "cur is ${cur}, words[*] is ${words[*]}, #words[@] is ${#words[@]}, cword is $cword" + + # The user could have moved the cursor backwards on the command-line. + # We need to trigger completion from the $cword location, so we need + # to truncate the command-line ($words) up to the $cword location. + words=("${words[@]:0:$cword+1}") + __git-bug_debug "Truncated words[*]: ${words[*]}," + + local out directive + __git-bug_get_completion_results + __git-bug_process_completion_results +} +` + err = root.GenBashCompletionV2(f, true) + if err != nil { + return err + } + + // Custom bash code to connect the git completion for "git bug" to the + // git-bug completion for "git-bug" + _, err = f.WriteString(patch) + + return err +} + +func genFish(root *cobra.Command) error { + cwd, err := os.Getwd() + if err != nil { + return err + } + dir := filepath.Join(cwd, "misc", "completion", "fish", "git-bug") + return root.GenFishCompletionFile(dir, true) +} + +func genPowerShell(root *cobra.Command) error { + cwd, err := os.Getwd() + if err != nil { + return err + } + path := filepath.Join(cwd, "misc", "completion", "powershell", "git-bug") + return root.GenPowerShellCompletionFile(path) +} + +func genZsh(root *cobra.Command) error { + cwd, err := os.Getwd() + if err != nil { + return err + } + path := filepath.Join(cwd, "misc", "completion", "zsh", "git-bug") + return root.GenZshCompletionFile(path) +} diff --git a/misc/diagrams/Readme.md b/misc/diagrams/Readme.md deleted file mode 100644 index 837a3212..00000000 --- a/misc/diagrams/Readme.md +++ /dev/null @@ -1 +0,0 @@ -The source of those diagrams is on draw.io. Couldn't find a good way to export :( diff --git a/misc/diagrams/bridge_workflow.png b/misc/diagrams/bridge_workflow.png deleted file mode 100644 index 18fb8a77..00000000 Binary files a/misc/diagrams/bridge_workflow.png and /dev/null differ diff --git a/misc/diagrams/native_workflow.png b/misc/diagrams/native_workflow.png deleted file mode 100644 index 8fa9d46c..00000000 Binary files a/misc/diagrams/native_workflow.png and /dev/null differ diff --git a/misc/diagrams/webui-workflow.png b/misc/diagrams/webui-workflow.png deleted file mode 100644 index 83d20d84..00000000 Binary files a/misc/diagrams/webui-workflow.png and /dev/null differ diff --git a/misc/termui_recording.gif b/misc/termui_recording.gif deleted file mode 100644 index 43ba6eec..00000000 Binary files a/misc/termui_recording.gif and /dev/null differ diff --git a/misc/termui_recording.svg b/misc/termui_recording.svg deleted file mode 100644 index e1cff4a7..00000000 --- a/misc/termui_recording.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - -  michael@debian ~/go/src/github.com/MichaelMure/git-bug master $  michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ g michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ gi michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git  michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git b michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bu michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug  michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug t michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug te michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug ter michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug term michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug termu michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug termui michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ git bug termui                                                                               1be2ac3f  open    Rename git-bug => git-issue                       Martin Delille (…  C:6  L:0   2 weeks ago        8f8bd854 open  feat:addpriority Tobias Mersmann …C:4L:01weekago 8f8bd854  open    feat: add priority                                Tobias Mersmann …  C:4  L:0   1 week ago         a6ef83c6 open  feat:deleteabuglocally Michael Muré (Mi…C:0L:11monthago a6ef83c6  open    feat: delete a bug locally                        Michael Muré (Mi…  C:0  L:1   1 month ago        d98af8ac open  feat:clearthechangesnotpushedyet Michael Muré (Mi…C:0L:11monthago d98af8ac  open    feat: clear the changes not pushed yet            Michael Muré (Mi…  C:0  L:1   1 month ago        1a716a62 open  feat:showthechangesnotpushedyet Michael Muré (Mi…C:0L:11monthago 1a716a62  open    feat: show the changes not pushed yet             Michael Muré (Mi…  C:0  L:1   1 month ago        34083737 open  feat:git-bugconfiguration Michael Muré (Mi…C:6L:11monthago 34083737  open    feat: git-bug configuration                       Michael Muré (Mi…  C:6  L:1   1 month ago        59b9f311 open  feat:Assignlabelsacolor Luke Adams (adam…C:5L:11monthago 59b9f311  open    feat: Assign labels a color                       Luke Adams (adam…  C:5  L:1   1 month ago        dcd57c3e open  feat:Githubexporter Michael Muré (Mi…C:5L:11monthago dcd57c3e  open    feat: Github exporter                             Michael Muré (Mi…  C:5  L:1   1 month ago        e5d4ec2b open  Identitymanagement Michael Muré (Mi…C:0L:22monthsago e5d4ec2b  open    Identity management                               Michael Muré (Mi…  C:0  L:2   2 months ago       b54d5c94 open  [featurerequest]Supporthooksthataudit`BUG… Zhongming Qu (qz…C:3L:01monthago 1be2ac3f  open    Rename git-bug => git-issue                       Martin Delille (…  C:6  L:0   2 weeks ago        8f8bd854  open    feat: add priority                                Tobias Mersmann …  C:4  L:0   1 week ago         a6ef83c6  open    feat: delete a bug locally                        Michael Muré (Mi…  C:0  L:1   1 month ago        d98af8ac  open    feat: clear the changes not pushed yet            Michael Muré (Mi…  C:0  L:1   1 month ago        1a716a62  open    feat: show the changes not pushed yet             Michael Muré (Mi…  C:0  L:1   1 month ago        34083737  open    feat: git-bug configuration                       Michael Muré (Mi…  C:6  L:1   1 month ago        59b9f311  open    feat: Assign labels a color                       Luke Adams (adam…  C:5  L:1   1 month ago        dcd57c3e  open    feat: Github exporter                             Michael Muré (Mi…  C:5  L:1   1 month ago        e5d4ec2b  open    Identity management                               Michael Muré (Mi…  C:0  L:2   2 months ago       b54d5c94  open    [feature request] Support hooks that audit `BUG…  Zhongming Qu (qz…  C:3  L:0   1 month ago        7d15d473 open  feat:commentedition/removal Michael Muré (Mi…C:2L:21monthago c318768f open  feat:favoritebug Michael Muré (Mi…C:0L:12monthsago 76559d04 open  feat:acommandtolistmatchingbugidfroma Michael Muré (Mi…C:0L:32monthsago 56787b1b open  feat:internationalization Michael Muré (Mi…C:2L:22monthsago 56ec0788 open  CLIExportCommand andyl            C:5L:02monthsago c7c71b5e open  feat:BetterZSHshellcompletion Jonas Rylund Gle…C:2L:02monthsago 009592b9 open  Cangithub/gitlab/gogs/etcdirectlysupportgit… udhos            C:5L:12monthsago 9dd20090 open  Makeanoverviewofthevariousbug-trackers Michael Muré (Mi…C:7L:12monthsago 44c354dc open  TerminalshellcompletionforWindows gedw99 (gedw99)  C:1L:13monthsago dfb1dded open  Referencebugsincommitmessages Ian Walter (ianw…C:3L:03monthsago f2b2d83f open  feat:Branchreviews theduke (theduke)C:2L:03monthsago 5c16913b open  Question:cangit-bugbeawareofbranchesand johnnyutahh      C:13L:13monthsagoShowing22of29bugs abf8bb60  open    feat: git-bug should store metadata for comment…  Michael Muré (Mi…  C:1  L:3   3 months ago       6767e5f4  open    feat: Github import                               Michael Muré (Mi…  C:34 L:3   1 month ago        0d786f28  open    Support for forking and then PR ?                 gedw99 (gedw99)    C:7  L:1   3 months ago       abf8bb60  open    feat: git-bug should store metadata for comment…  Michael Muré (Mi…  C:1  L:3   3 months ago       c5bc44f3  open    feat: media-embedding in messages                 Michael Muré (Mi…  C:2  L:3   3 weeks ago        0d786f28  open    Support for forking and then PR ?                 gedw99 (gedw99)    C:7  L:1   3 months ago       cf54e668  open    feat: replace the manual rebase code with built…  Ben Boeckel (mat…  C:1  L:1   3 months ago       adbca8cd  open    feat: render comments as Markdown                 Michael Muré (Mi…  C:3  L:2   2 months ago       c508298a  open    feat: configuration for the default remote        Michael Muré (Mi…  C:0  L:4   2 months ago       c5bc44f3  open    feat: media-embedding in messages                 Michael Muré (Mi…  C:2  L:3   3 weeks ago        6767e5f4  open    feat: Github import                               Michael Muré (Mi…  C:34 L:3   1 month ago                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     Showing7 of 29 bugs  ID        STATUS  TITLE                                             AUTHOR   SUMMARYLASTEDIT b54d5c94  open    [feature request] Support hooks that audit `BUG…  Zhongming Qu (qz…  C:3  L:0   1 month ago       Showing22 of 29 bugs[q] Quit [s] Search [←↓↑→,hjkl] Navigation [↵] Open bug [n] New bug [i] Pull [o] Push                                                                                                                                                 ^X Quitter                                                                                                           status:open                                                                                                          status:open                                                                                                                                                                                                                                 GNU nano 3.1         /home/michael/go/src/github.com/MichaelMure/git-bug/.git/BUG_MESSAGE_EDITMSG                  status:open                                                                                                          status:open                                                                                                          status:open l                                                                                                        status:open la                                                                                                       status:open lab                                                                                                      status:open labe                                                                                                     status:open label                                                                                                    status:open label:                                                                                                   status:open label:C                                                                                                  status:open label:Co                                                                                                 status:open label:Cor                                                                                                status:open label:Core                                                                                               [ Lecture de 25 lignes ]^G Aide        ^O Écrire^W Chercher     ^K Couper^J Justifier    ^C Pos. cur.    M-U Annuler^X Quitter      ^R Lire fich.   ^\ Remplacer    ^U Coller       ^T Orthograp.   ^_ Aller lig.   M-E Refaire          Écrire l'espace modifié ? (Répondre « Non » ABANDONNE les modifications.)                                             O Oui                                                                                                                N Non          ^C Annuler                                                                                           Nom du fichier à écrire: /home/michael/go/src/github.com/MichaelMure/git-bug/.git/BUG_MESSAGE_EDITMSG                  GNU nano 3.1         /home/michael/go/src/github.com/MichaelMure/git-bug/.git/BUG_MESSAGE_EDITMSG         Modifié  ^G Aide                      M-D Format DOS               M-A Ajout (à la fin)         M-B Copie de sécu.            ^C Annuler                   M-M Format Mac               M-P Ajout (au début)         ^T Parcourir                  status:open label:Core                                                                                               # Please edit the bug query.                                                                                         # Lines starting with '#' will be ignored, and an empty query aborts the operation.                                  #                                                                                                                    # Example: status:open author:"rené descartes" sort:edit                                                             # Valid filters are:                                                                                                 # - status:open, status:closed                                                                                       # - author:<query>                                                            # - label:<label>                                                  # - no:label                                                                             #                                                                          # Sorting                                                         #                                                                              # - sort:id, sort:id-desc, sort:id-asc                                                            # - sort:creation, sort:creation-desc, sort:creation-asc                                         # - sort:edit, sort:edit-desc, sort:edit-asc                                            #                                                                              # Notes                                                                                                                                                       44c354dc  open    Terminal shell completion for Windows             gedw99 (gedw99)    C:1  L:1   3 months ago       5c16913b  open    Question: can git-bug be aware of branches and …  johnnyutahh        C:13 L:1   3 months ago       5c16913b  open    Question: can git-bug be aware of branches and …  johnnyutahh        C:13 L:1   3 months ago       cf54e668  open    feat: replace the manual rebase code with built…  Ben Boeckel (mat…  C:1  L:1   3 months ago       44c354dc  open    Terminal shell completion for Windows             gedw99 (gedw99)    C:1  L:1   3 months ago       76559d04  open    feat: a command to list matching bug id from a …  Michael Muré (Mi…  C:0  L:3   2 months ago       7d15d473  open    feat: comment edition/removal                     Michael Muré (Mi…  C:2  L:2   1 month ago        76559d04  open    feat: a command to list matching bug id from a …  Michael Muré (Mi…  C:0  L:3   2 months ago       ID        STATUS  TITLE                                             AUTHOR             SUMMARY    LAST EDIT          7d15d473  open    feat: comment edition/removal                     Michael Muré (Mi…  C:2  L:2   1 month ago                                                                                                                                                                                                                                                                                                                                         Showing 10 of 10 bugs                                                                                                                                                                                  enhancement                             It would be neat to support comment edition or removal. A few notes:                                                 - require two new Operations                                                                                         - as the data model is immutable, it would not fully erase the previous                                              comment version. While it would not be visible in the UI anymore, it woul                                            still be readable through the bug history.                                                                           - in bug.Snapshot, a proper `Timeline` needs to be implemented and would                                             replace the currentusage of `Operations`. This`Timeline`would hold the                            data that isexpected to be displayedinaUI,insteadoftheraw stream                              of events                                                                           ┌─────────────────────────────────────────────────────────────────────────────┐   enhancement                        │    It would be neat to support comment edition or removal. A few notes:     │                                      │                                                                             │                                      │    - require two new Operations                                             │                                      │    - as the data model is immutable, it would not fully erase the previous  │                                      │    comment version. While it would not be visible in the UI anymore, it woul│                                      │    still be readable through the bug history.                               │                                      │    - in bug.Snapshot, a proper `Timeline` needs to be implemented and would │                                      │    replace the currentusage of `Operations`. This`Timeline`would hold the│                      │    data that isexpected to be displayedinaUI,insteadoftheraw stream │                       │    of events                                                   │                       └─────────────────────────────────────────────────────────────────────────────┘                        Michael Muré (MichaelMure) added "enhancement" labelonSep212018                                                                                                                                    ┌─────────────────────────────────────────────────────────────────────────────┐                       Michael Muré (MichaelMure) added "enhancement" labelonSep212018          │                                                                                                                         Michael Muré (MichaelMure) added "Core" label on Sep 212018                                  [7d15d473]feat: comment edition/removalLabels [openMichael Muré (MichaelMure) opened this bug on Sep 21 2018                 Core                                                                                                                                     Michael Muré (MichaelMure) added "Core" label on Sep 212018          │                        Michael Muré (MichaelMure) commented onSep 29 2018                                                    Alright, with https://github.com/MichaelMure/git-bug/pull/54 the core is                                             data that is expected to be displayed in a UI, instead of the raw stream                                            of events                           Labels Michael Muré (MichaelMure) added "enhancement" label on Sep 21 2018              enhancement                         Michael Muré (MichaelMure) added "Core" label on Sep 21 2018                                                        ┌─────────────────────────────────────────────────────────────────────────────┐                                      Michael Muré (MichaelMure) commented on Sep 29 2018                          │                                      │    Alright, with https://github.com/MichaelMure/git-bug/pull/54 the core is │                      │    mostly readyfor comment edition.                                 │                       │                                                                │                       │    - each operations can now be back referenced with their hash             │                       │    - add a new `EditCommentOperation` that edit a previous comment          │                       │    (including the initial comment yield by the CreateOperation)             │                       │    - the Snapshot now hold a `Timeline` in addition the the raw array of    │                       │    `Operation`, providing a processed view of the history, ready for each UI│                       │to                                                                   │                       │    use. In particular, comments now hold their edit history                 │                       │    Left for later: there is no check that the author is allowedto edit the │                        │    comment. We need crypto signature for that ...                           │                                                                                                                        Core                                Michael Muré (MichaelMure) commented on Sep 29 2018                              enhancement                             mostly ready for comment edition.                                                                                    - each operations can now be back referenced with their hash                                                         - add a new `EditCommentOperation` that edit a previous comment                                                      (including the initial comment yield by the CreateOperation)                                                         - the Snapshot now hold a `Timeline` in addition the the raw array of                                `Operation`,providing a processed view ofthehistory, readyfor each UI                         to                                                                                           use. In particular, comments now hold their edit history                                              Left for later: there is no check that the author is allowed to edit the                              comment. We need crypto signature for that ...                                                   Michael Muré (MichaelMure) commented on Oct 19 2018                          │                       │                                           │                       │    With https://github.com/MichaelMure/git-bug/pull/60, @adamslc made the   │                        │    comments editable in the termUI.                                         │                                      └─────────────────────────────────────────────────────────────────────────────┘                                      Michael Muré (MichaelMure) added "Core" labelonSep212018Labels┌─────────────────────────────────────────────────────────────────────────────┐   Core                               Michael Muré (MichaelMure) commented on Sep 29 2018                          │   enhancement                        │    Alright, with https://github.com/MichaelMure/git-bug/pull/54 the core is │                                      │    mostly ready for comment edition.                                        │                                      │    - each operations can now be back referenced with their hash             │                                      │    - add a new `EditCommentOperation` that edit a previous comment          │                                      │    (including the initial comment yield by the CreateOperation)             │                                      │    - the Snapshot now hold a `Timeline` in addition the the raw array of    │                      │    `Operation`,providing a processed view ofthehistory, readyfor each UI│                       │to                                                              │                       │                                                                             │                       │    Left for later: there is no check that the author is allowed to edit the │                       │    comment. We need crypto signature for that ...                           │                       Michael Muré (MichaelMure) added "Core" labelonSep212018Labels Michael Muré (MichaelMure) commented on Oct 19 2018                                                       With https://github.com/MichaelMure/git-bug/pull/60, @adamslc made the                                 comments editable in the termUI.                                                                                Michael Muré (MichaelMure) added "enhancement" labelonSep 212018Labels Michael Muré (MichaelMure) added "Core" label on Sep 21 2018                     enhancement                         Michael Muré (MichaelMure) commented on Sep 29 2018                                                                      - each operations can now be back referenced with their hash                                         - add a new `EditCommentOperation` that edit aprevious comment                                       (including the initial comment yield by the CreateOperation)                                        - the Snapshot now hold a `Timeline` in addition the the raw array of                                 `Operation`, providing a processed view of the history, ready for each UI                         to                                                                                                    Michael Muré (MichaelMure) commented on Oct 19 2018                                                                 │    It would be neat to support comment edition or removal. A few notes:Labels│    - require two new Operations                                             │   Core                               │    - as the data model is immutable, it would not fully erase the previous  │   enhancement                        │    replace the current usage of `Operations`. This `Timeline` would hold the│                                      │    data that is expected to be displayed in a UI, instead of the raw stream │                                      │    of events                                                                │                                                                                                                                            Michael Muré (MichaelMure) added "enhancement" label on Sep 21 2018                                                                                                                                       Michael Muré (MichaelMure) added "Core" label on Sep 21 2018                                          Michael Muré (MichaelMure) commented on Sep 29 2018                                                       Alright, with https://github.com/MichaelMure/git-bug/pull/54 the core is                              mostly readyfor comment edition.                                                                                                                                           [7d15d473feat: comment edition/removal                                 Labels│    replace the current usage of `Operations`. This `Timeline` would hold the│                      │    data that is expected to be displayed in a UI, instead of the raw stream │                       │    of events                                                              │                                                                                                      ┌───────────────────────────────────┐  [7d15d473feat: comment edition/removal                                 │Labels                                                                               │                                   │  [openMichael Muré (MichaelMure) opened this bug on Sep 21 2018              │  Core                             │                                                                                │  enhancement                      │      It would be neat to support comment edition or removal. A few notes:      └───────────────────────────────────┘      replace the current usage of `Operations`. This `Timeline` would hold the                            data that is expected to be displayed in a UI, instead of the raw stream                              of events                                                                                       [7d15d473feat: comment edition/removal                                  Labels Michael Muré (MichaelMure) added "enhancement" label on Sep 21 2018          │                        Michael Muré (MichaelMure) commented on Sep 29 2018                                                   [q] Save and return [←↓↑→,hjkl] Navigation [o] Toggle open/close [e] Edit [c] Comment [t] Change title                                                                                                                                                                         a                                                                                                                                                                                                                                       a n                                                                                                                  a ne                                                                                                                 a new                                                                                                                a new                                                                                                                a new b                                                                                                              a new bu                                                                                                             a new bug                                                                                                            # Please enter the title and comment message. The first non-empty line will be                                       # used as the title. Lines starting with '#' will be ignored.                                                        # An empty title aborts the operation.                                                                                                                              [ Lecture de 5 lignes ]                                               ^G Aide         ^O Écrire       ^W Chercher     ^K Couper       ^J Justifier    ^C Pos. cur.    M-U Annuler          a new bug                                                                                                            w wi wit with with  with a with a  with a c with a co with a com with a comm with a comme with a commen with a comment with a comment                   with a comment                                                                                                   [23dc77dda new bug                                                      Labels [open]Michael MuréopenedthisbugonDec22018┌─────────────────────────────────────────────────────────────────────────────┐│    with a comment                                                           │                                                                                                                                                              an                                                                                                                   ano                                                                                                                  anot                                                                                                                 anote                                                                                                                anoteh                                                                                                               anotehr                                                                                                              anotehr                                                                                                              anoth                                                                                                                anothe                                                                                                               another                                                                                                              another                                                                                                              another c                                                                                                            another co                                                                                                           another com                                                                                                          another comm                                                                                                         another comme                                                                                                        another commen                                                                                                       another comment                                                                                                                                                     [ Lecture de 4 lignes ]                                               another comment                                                                                                      # Please enter the comment message. Lines starting with '#' will be ignored,   # and an empty message aborts the operation.                                                                          Michael Muré commented on Dec 2 2018                                                                                     another comment                                                                                                 Michael Muré commented on Dec 2 2018                                         │                                      │    another comment                                                          │                                      ^G Aide                                                                                                              another comment                                                                                                      another comment                                                                                                      another comment                                                                                                      anther comment                                                                                                       anher comment                                                                                                        aner comment                                                                                                         anr comment                                                                                                          an comment                                                                                                           an  comment                                                                                                          an e comment                                                                                                         an ed comment                                                                                                        an edi comment                                                                                                       an edit comment                                                                                                      an edite comment                                                                                                     an edited comment                                                                                                    an edited comment                                                                                                    an edited comment                                                                                                    an edited comment !                                                                                                  an edited comment !                                                                                                  Michael Muré commented on Dec 2 2018 (edited)                                │                                      │    an edited comment !                                                      │                                       [23dc77dda new bug                                                     │Labels[open]Michael MuréopenedthisbugonDec22018                                                                               └───────────────────────────────────┘ Michael Muré commented on Dec 2 2018 (edited)                                                                            an edited comment !                                                                                                ┌───────────────────┐                                                                                                │ [ ] CLI           │                                                             └───────────────────┘                                                                                                 [ ] Core                                                                                                                                                      │ [ ] Core         │                        │ [x] Core         │                         └───────────────────┘                                                                                                 [ ] Easy pick                                                                                                      ┌───────────────────┐                                                                                               │ [ ] Easy pick     │                                                                                                  [ ] Non-actionable                                                                                                 │ [ ] Non-actionable│                                                                                                  [ ] RFC                                                                                                            │ [ ] RFC           │                                                                                                  [ ] CLI                                                                          [x] Core                                   │ [x] RFC           │                                                                                                  [ ] TermUI                                                                                                           [ ] WebUI                                                                                                            [ ] bug                                                                                               [ ] enhancement                                                                                       [ ] help wanted                                                                                  [q] Save and close [↓↑,jk] Nav [a] Add item                                                                          [openMichael MuréopenedthisbugonDec22018Core                                                                               │  RFC                              │     with a comment                                                            └───────────────────────────────────┘ ┌─────────────────────────────────────────────────────────────────────────────┐   RFC                                Michael Muré added "Core""RFC" labels on Dec 2 2018                                                               [openMichael MuréopenedthisbugonDec22018 Core                                                                                   RFC                               Michael Muré added "Core""RFC" labels on Dec 2 2018                        │                                      └─────────────────────────────────────────────────────────────────────────────┘                                                                      a new bug                                                                                                                                                             # Please enter the new title. Only one line will used.                                                              # Lines starting with '#' will be ignored, and an empty title aborts the operation.                                  a                                                                                               a b                                              a be                                             a bet                                            a bett                                           a bette                                          a better                                         a better                                         a better t                                       a better ti                                      a better tit                                     a better titl                                    a better title                                   a better title                                   Michael Muré added "Core""RFC" labels on Dec 2 2018                        │                                                                                                        RFC                                 [23dc77dda better title                                                 Labels                                                   [openMichael Muré opened this bug on Dec 2 2018                                Core                              ┌─────────────────────────────────────────────────────────────────────────────┐   RFC                                 Michael Muré added "Core""RFC" labels on Dec 2 2018                                                Michael Muré changed the title to a better title on Dec 2 2018                                        23dc77dd  open    abettertitle              Michael Muré     C:1L:24secondsago  23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   5 seconds ago      23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   10 seconds ago     23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   11 seconds ago     6767e5f4  open    feat: Git┌─Push to remote origin─────────────────────────────────────┐:34 L:3   1 month ago                                   │...                                                      │                                          └───────────────────────────────────────────────────────────┘               Showing 11 of 11 bugs                                                                                                                            ┌─Push to remote origin─────────────────────────────────────┐  23dc77dd  open    a better │refs/bugs/c7c71b5e94c3df8b9cbedcf53b773e3012f02afe ->      │:1  L:2   16 seconds ago     e5d4ec2b  open    Identity │refs/bugs/c7c71b5e94c3df8b9cbedcf53b773e3012f02afe         │:0  L:2   2 months ago       7d15d473  open    feat: com│ * [new branch]                                            │:2  L:2   1 month ago        76559d04  open    feat: a c│refs/bugs/cf54e668a8bb81d1f14418fde72ccb9315aed717 ->      │:0  L:3   2 months ago       44c354dc  open    Terminal │refs/bugs/cf54e668a8bb81d1f14418fde72ccb9315aed717         │:1  L:1   3 months ago       5c16913b  open    Question:│ * [new branch]                                            │:13 L:1   3 months ago       cf54e668  open    feat: rep│refs/bugs/d98af8ac83ab2b484ac15d28762dd9159f2f0def ->      │:1  L:1   3 months ago       c508298a  open    feat: con│refs/bugs/d98af8ac83ab2b484ac15d28762dd9159f2f0def         │:0  L:4   2 months ago       c5bc44f3  open    feat: med│ * [new branch]                                            │:2  L:3   3 weeks ago        abf8bb60  open    feat: git│refs/bugs/dcd57c3e688fdde3be86e7678dc3dc720dcdc6d4 ->      │:1  L:3   3 months ago       6767e5f4  open    feat: Git│refs/bugs/dcd57c3e688fdde3be86e7678dc3dc720dcdc6d4         │:34 L:3   1 month ago                                   │ * [new branch]                                          │                                          │refs/bugs/dfb1dded0a6e45363613a711cdfa3621abfc116c ->      │                                           │refs/bugs/dfb1dded0a6e45363613a711cdfa3621abfc116c       │                                           │ * [new branch]                                          │                                           │refs/bugs/e5d4ec2b0e588c42784480218139c0ed97acd854 ->    │                                           │refs/bugs/e5d4ec2b0e588c42784480218139c0ed97acd854       │                                           │refs/bugs/f2b2d83f42a6abeeb3a4fe26fc0b8ff0996c5315 ->    │                                           │refs/bugs/f2b2d83f42a6abeeb3a4fe26fc0b8ff0996c5315       │               │refs/bugs/f43890e66a2bed880b962086242327dd41c63a49->                            │refs/bugs/f43890e66a2bed880b962086242327dd41c63a49         │                            Showing 11 of 11 bugs       └───────────────────────────────────────────────────────────┘                             23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   18 seconds ago                                                                                                             23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   19 seconds ago     23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   21 seconds ago                                │                                                         │               23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   22 seconds ago     6767e5f4  open    feat: Git┌─Pull from remote origin───────────────────────────────────┐:34 L:3   1 month ago                                   │done                                                     │                                                                                                         23dc77dd  open    a better title                                    Michael Muré       C:1  L:2   23 seconds ago                                                          michael@debian ~/go/src/github.com/MichaelMure/git-bug master $                                                      michael@debian ~/go/src/github.com/MichaelMure/git-bug master $ exit                                                                                                                                            - \ No newline at end of file diff --git a/misc/webui1.png b/misc/webui1.png deleted file mode 100644 index 502e71f0..00000000 Binary files a/misc/webui1.png and /dev/null differ diff --git a/misc/webui2.png b/misc/webui2.png deleted file mode 100644 index f4b8dceb..00000000 Binary files a/misc/webui2.png and /dev/null differ diff --git a/treefmt.nix b/treefmt.nix new file mode 100644 index 00000000..1716d457 --- /dev/null +++ b/treefmt.nix @@ -0,0 +1,86 @@ +{ + pkgs, + excludes ? [ ], + ... +}: +{ + projectRootFile = "flake.nix"; + + programs = { + gofmt = { + enable = true; + }; + + mdformat = { + enable = true; + + package = pkgs.mdformat.withPlugins ( + p: with p; [ + # add support for github flavored markdown + mdformat-gfm + mdformat-gfm-alerts + + # add support for markdown tables + mdformat-tables + + # add the following comment before running `nix fmt` to generate a + # table of contents in markdown files: + # + mdformat-toc + ] + ); + + settings = { + end-of-line = "lf"; + number = true; + wrap = 80; + }; + }; + + nixfmt = { + enable = true; + strict = true; + }; + + # this is disabled due to `//webui` not yet being integrated with the flake. + # the entire package directory is ignored below in + # `settings.global.excludes`. + prettier = { + enable = false; + + settings = { + singleQuote = true; + trailingComma = "es5"; + }; + }; + + shfmt = { + enable = true; + }; + + yamlfmt = { + enable = true; + + settings.formatter = { + eof_newline = true; + include_document_start = true; + retain_line_breaks_single = true; + trim_trailing_whitespace = true; + }; + }; + }; + + settings.global.excludes = + pkgs.lib.lists.unique [ + "*.graphql" + "*.png" + "*.svg" + "*.txt" + "doc/man/*.1" # generated via //doc:generate.go + "doc/md/*" # generated via //doc:generate.go + "misc/completion/*/*" + "webui/*" # not currently supported, //webui is not yet flakeified + "Makefile" + ] + ++ excludes; +} diff --git a/webui/README.md b/webui/README.md new file mode 100644 index 00000000..45df1705 --- /dev/null +++ b/webui/README.md @@ -0,0 +1,35 @@ +# git-bug rich web UI + +## Prerequisites +[ReactJS](https://reactjs.org/) | [Material UI](https://material-ui.com/) | [GraphQL](https://graphql.org/) | [Apollo GraphQL](https://www.apollographql.com/docs/react/) + +## How to develop + +### Run GraphQL backend + +1. Download a git-bug stable binary or compile your own by running `make` in the **root** directory: + +2. Run the git-bug binary inside your git repository. It will manage issues and start the API: + - `git-bug webui -p 3001` + +### Run ReactJS front-end + +1. If you haven't already, clone the git-bug repository: + +2. Enter the `webui` directory and install the needed libraries: + - `make install` or `npm install` + +3. Generate the TS code from the GrapQL files and run the webui in development mode: + - `make start` or `npm start` + - If you get some lint errors, run the lint command below and start again: + - `make fix-lint` or `npm run lint -- --fix` + - `make start` or `npm start` + +The development version of the WebUI is configured to query the backend on the port 3001. You can now live edit the js code and use the normal backend. + +## Bundle the web UI + +Once the webUI is good enough for a new release: +1. run `make build` from webui folder +2. run `make pack-webui` from the *root directory* to bundle the compiled js into the go binary. + - You must have Go installed on Your machine to run this command. \ No newline at end of file diff --git a/webui/Readme.md b/webui/Readme.md deleted file mode 100644 index 45df1705..00000000 --- a/webui/Readme.md +++ /dev/null @@ -1,35 +0,0 @@ -# git-bug rich web UI - -## Prerequisites -[ReactJS](https://reactjs.org/) | [Material UI](https://material-ui.com/) | [GraphQL](https://graphql.org/) | [Apollo GraphQL](https://www.apollographql.com/docs/react/) - -## How to develop - -### Run GraphQL backend - -1. Download a git-bug stable binary or compile your own by running `make` in the **root** directory: - -2. Run the git-bug binary inside your git repository. It will manage issues and start the API: - - `git-bug webui -p 3001` - -### Run ReactJS front-end - -1. If you haven't already, clone the git-bug repository: - -2. Enter the `webui` directory and install the needed libraries: - - `make install` or `npm install` - -3. Generate the TS code from the GrapQL files and run the webui in development mode: - - `make start` or `npm start` - - If you get some lint errors, run the lint command below and start again: - - `make fix-lint` or `npm run lint -- --fix` - - `make start` or `npm start` - -The development version of the WebUI is configured to query the backend on the port 3001. You can now live edit the js code and use the normal backend. - -## Bundle the web UI - -Once the webUI is good enough for a new release: -1. run `make build` from webui folder -2. run `make pack-webui` from the *root directory* to bundle the compiled js into the go binary. - - You must have Go installed on Your machine to run this command. \ No newline at end of file -- cgit v1.2.3