Git Cola Development

This garden file sets up a development garden with the latest version of Git, Git Cola, qtpy and vx.

Run the following commands to see this in action.

# Create a directory we'll clone and build a few repositories.
mkdir -p cola && cd cola

# Download and audit the garden file we're going to run.
wget https://gitlab.com/garden-rs/garden/-/raw/main/doc/src/examples/git-cola/garden.yaml
cat garden.yaml

# One-time setup: Clone all of the repos in the "cola" garden and use a custom
# "garden grow" is a garden built-in command that clones.
garden grow cola

# "garden setup" command defined in "garden.yaml" to initializes the environment.
garden setup cola

# All set! Now we can run Git Cola from the development environment.
garden run

# Daily development workflow: run tests in each repository in-place.
garden test cola

# Commands can be passed to the underlying "run" command to run Git Cola
# against any Git repository.
garden run -- --repo path/to/any/git/tree

# These projects don't need to be "built", so this is technically a no-op.
# A Rust or C++ Rust project could use something like this to run "make"
# in each repository.
garden build cola

The development repositories are now in your current directory and a development virtualenv is present in the ./dist directory.

garden.yaml

The following is the contents of the garden.yaml file used in this example.

# Create environments for developing Git Cola against development versions of Git.
#
# The following gardens are defined: "cola", "cola/main" and "cola/next".
#
# The "cola" garden runs git-cola using the "git" command from your $PATH.
# The "cola/main" garden runs git-cola using git.git's "main" branch.
# The "cola/next" garden runs git-cola using git.git's "next" branch.
#
# One-time Setup:
#
# * Clone repositories and create worktrees:
#
#   garden grow cola/main cola/next
#
# * Initialize git-cola's Python virtualenv environment.
#
#   garden setup cola
#
# Development workflows:
#
# * Build the "cola/main" garden using git.git's "main" branch:
#   garden build cola/main
#
# * Build the "cola/next" garden using git.git's "next" branch:
#   garden build cola/next
#
# * Run Git Cola
#   garden run
#
# * Run Git Cola on the git/next and git-cola trees using the cola/next garden environment:
#   garden run --trees git/next cola/next
#   garden run -t git-cola cola/next
#
# * Open a shell for running Git Cola in different enviornments
#   garden shell cola/main
#   garden shell cola/next
#
# * Run just Git Cola's tests in each environment.
#   garden test/cola cola
#   garden test/cola cola/main
#   garden test/cola cola/next
#
# * Run tests for all projects in each environment. Also runs Git's testsuite.
#   garden test cola
#   garden test cola/main
#   garden test cola/next

# The following variables are used in the custom commands below.
variables:
  # A virtualenv is created in the ./dist/git-cola/env3 directory.
  prefix: ${GARDEN_ROOT}/git-cola/env3
  jobs: $ nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 8

commands:
  add-all: git add --update
  diff: GIT_PAGER= git diff --patience --color-words "$@"
  lol: git log --decorate --graph --oneline "$@" && echo
  run: vx ${prefix} git cola "$@"
  status:
    - git status --short
    - git branch

templates:
  bin:
    environment:
      PATH: ${TREE_PATH}/bin
  python:
    environment:
      PYTHONPATH: ${TREE_PATH}
  makefile:
    commands:
      build: make -j ${jobs} prefix="${prefix}" all "$@"
      install: make -j ${jobs} prefix="${prefix}" install "$@"
      test: make -j ${jobs} prefix="${prefix}" test "$@"
      doc: make -j ${jobs} prefix="${prefix}" doc "$@"

trees:
  # git/main is the parent worktree that shares its .git storage with the child
  # git/next worktrees using "git worktree" -- https://git-scm.com/docs/git-worktree
  git/main:
    url: https://github.com/git/git.git
    templates: makefile
    environment:
      PATH: ${TREE_PATH}/bin-wrappers
      # git/next is a "git worktree" for git.git's "next" branch.
  git/next:
    worktree: git/main
    branch: next

  # git-cola's worktree can be reused alongside any of the git/* trees defined above.
  git-cola:
    url: https://gitlab.com/git-cola/git-cola.git
    templates: [bin, python]
    commands:
      setup: garden dev
      test/cola: garden test "$@"
      install: garden -D prefix="${prefix}" install "$@"
      test: garden test "$@"
      doc: garden doc "$@"

  qtpy:
    description: Qt abstraction library used by git-cola
    url: https://github.com/spyder-ide/qtpy.git
    templates: python
    setup: vx ${prefix} pip install pytest-qt

  vx:
    description: Utility for activating Python virtualenvs
    url: https://gitlab.com/davvid/vx.git
    depth: 1  # Create a shallow clone using "git clone --depth=1"
    environment:
      PATH: ${TREE_PATH}
    commands:
      test: make test

  # This tree allows the "run" command to be run from any directory.
  cwd:
    path: ${PWD}

groups:
  cola-repos-grp:
    - git-cola
    - qtpy
    - vx

gardens:
  cola:
    groups: cola-repos-grp
    environment:
      PATH: ${prefix}/bin
  cola/main:
    groups: cola-repos-grp
    trees: git/main
    environment:
      PATH: ${prefix}/bin
  cola/next:
    groups: cola-repos-grp
    trees: git/next
    environment:
      PATH: ${prefix}/bin

Pre-defined Custom Commands and Ad-Hoc Commands

Included in garden.yaml are a few few helpful commands that give us a quick view of what's going on in each tree:

garden diff cola
garden status cola
garden lol cola

If we want to perform git stuff (like fetch the latest changes), we can always use garden exec to run arbitrary commands:

garden exec cola git fetch --verbose

# When needed, we can hop into a shell with all of the environment variables set
garden shell cola

Self-contained installation demo

The garden run example runs git and git cola in-place in their respective trees. The git-cola project is not installed into the ./dist directory. It contains just the virtualenv created needed to run it.

In order to create a self-contained installation to run the tools independently of their source repositories we have to install them into the ./dist directory.

The following example installs Git and Git Cola into the ./dist directory by running the "make install" targets in each repo:

garden install cola

Now we can test the installed tools directly by adding ./dist/bin to our $PATH, or just invoke the script directly:

./dist/bin/git-cola

Voila, we now have a fully functional development environment with PyQt5, qtpy and Git Cola ready to go for development.