canarist

    2.3.2 • Public • Published

    canarist

    TLDR: A bit like npm link, but for workspaces / monorepos 🚀

    Introduction

    canarist is a tool that allows you to combine multiple yarn workspace monorepos into one single temporary workspace and execute commands inside each of them.

    This is useful if, for example, you have a tool or library that is being developed inside a monorepo and you want to test out new changes to your library in downstream projects by executing their test suites.

    At XING we have this automated within our CI, so that PRs to central repositories will be tested against a few downstream projects.

    If you want to read more into how and why this tool works, check out the overview (which I had prepared for a small presentation in our company).

    System requirements

    This tool is built with modern Node.js and needs at least Node.js 10.13 or higher.

    Since this is a tool for managing yarn workspaces, it is required to have yarn and git installed locally.

    Quick start

    You can use canarist as a CLI tool: Install it globally or use npx to run it as a one-off command:

    npx canarist -r . -r git@github.com:some/other.git

    This command will create a temporary folder and clone the repository from your current working directory (.) and the some/other repository from GitHub into a temporary folder and execute yarn test in both repositories.

    Configuration and projects

    canarist is fully configurable through cosmiconfig and even allows to specify multiple different combinations of repositories (called "projects") which can be run from the CLI.

    You can configure canarist through one of the following places:

    • a "canarist" key in the package.json
    • a .canaristrc{.json,.yml,.js} file
    • a canarist.config.js file

    Example single-mode configuration in package.json

    {
      "canarist": {
        "repositories": [
          {
            "url": ".",
            "directory": "local-repo",
            "commands": [""]
          },
          {
            "url": "git@github.com:some/other.git",
            "commands": ["yarn build"]
          },
          {
            "url": "git@github.com:my/other.git",
            "directory": "my-other",
            "branch": "next"
          }
        ],
        "rootManifest": {
          "resolutions": {
            "typescript": "3.2.4"
          }
        },
        "targetDirectory": "~/work/canarist-target",
        "yarnArguments": "--production"
      }
    }

    The above configuration can be executed by typing:

    npx canarist

    into the terminal and will do the following:

    • clone the local repository (.) into ~/work/canarist-target/local-repo
    • clone the remote repository (git@github.com:some/other.git) into ~/work/canarist-target/other
    • clone the remote repository (git@github.com:my/other.git) into ~/work/canarist-target/my-other
    • create a package.json in ~/work/canarist-target/ which combines all workspaces from the other repositories
    • execute yarn --production in ~/work/canarist-target/
    • execute yarn build in ~/work/canarist-target/other
    • execute yarn test in ~/work/canarist-target/my-other

    Note: This configuration will link all packages from all three configured repositories together.

    In case you want to test multiple different combinations, you can make use of projects (see below):

    Example project-mode configuration in package.json

    {
      "canarist": {
        "projects": [
          {
            "name": "canarist",
            "repositories": [
              {
                "url": "git@github.com:xing/canarist.git"
              },
              {
                "url": "git@github.com:my/canarist.git",
                "directory": "my-canarist",
                "branch": "next",
                "commands": ["yarn build", "yarn test"]
              }
            ],
            "rootManifest": {
              "resolutions": {
                "jest": "^24.0.0"
              }
            }
          },
          {
            "name": "other",
            "repositories": [
              {
                "url": "git@github.com:some/other.git",
                "branch": "next"
              },
              {
                "url": "git@github.com:my/other.git",
                "directory": "my-other"
              }
            ],
            "yarnArguments": "--ignore-scripts"
          }
        ]
      }
    }

    The above configuration specifies two projects, which can each be run by typing:

    npx canarist -p canarist

    or

    npx canarist -p other

    into the terminal.

    Note: This configuration allows to link canarist with my/canarist and some/other with my/other, this is useful when you want to test changes in several different repositories without linking all of them together at once.

    CLI output:

    $ canarist --help
    Usage: canarist options [<target>]
    
    Options:
        --repository, -r
            The URL (or local file path) to a repository to clone.
            This option accepts sub-arguments (see examples):
                --branch, -b
                    The branch that should be checked out (default: master).
                --command, -c
                    The command to execute in this repository (default: "yarn test").
                --directory, -d
                    This option allows to change the directory name in case of conflicts.
        --root-manifest, -m
            A valid JSON string that should be merged into the generated root manifest.
        --yarn-arguments, -y
            Additional arguments that should be passed to the "yarn install" command.
        --project, -p
            The name of a project to execute in a multi-project configuration.
    
    Examples:
        $ canarist -r git@github.com:xing/canarist.git -r git@github.com:some/other.git
            Clones xing/canarist and some/other into a temporary directory
            and executes "yarn test" in both repositories.
    
        $ canarist -r [git@github.com:xing/canarist.git -b next -c] -r git@github.com:some/other.git
            Clones the "next" branch of xing/canarist and the master branch of some/other
            and executes no command in xing/canarist and "yarn test" in some/other.
    
        $ canarist -r [git@github.com:xing/canarist.git -d canarist] -r [git@github.com:my/canarist.git -d my-canarist]
            Clones xing/canarist into canarist and my/canarist into my-canarist inside a temporary directory.
    
        $ canarist -r ~/work/canarist -r ~/work/other -m '{"resolutions":{"typescript":"3.2.4"},"devDependencies":{"jest":"23.0.0}}'
            Clones the master branches of both local repositories into a temporary directory
            and additionally installs yarn resolutions and a missing dev dependency.
    
        $ canarist -r ~/work/canarist -r ~/work/other -r ~/work/other2 -r ~/work/other3
            Clones the master branches of all four local repositories into a temporary directory
            and executes "yarn test" for each of them.
    
        $ canarist -r ~/work/canarist -r ~/work/other --y "--production=true"
            Clones the master branches of both repositories and installs production dependencies only
    
        $ canarist -p my-project
            Looks up the project configuration with the name "my-project" in the cosmiconfig
            of the current repository and clones and executes the repositories and commands therein.
            Read more: https://github.com/xing/canarist/blob/master/README.md
    

    TODOs

    • [ ] allow to unpin dependencies which would otherwise be installed multiple times (for example: packages of both repositories have "webpack" as a dependency, one has it pinned to "4.40.0" and the other has a semver range "^4.30.0". If webpack@latest is at 4.40.0 we have no issues, but if webpack has a new release, say 4.41.0, we now have two versions installed).
    • [ ] allow to configure which dotfiles should be copied / merged into the root (currently only ".npmrc" will be merged)
    • [ ] implement a --no-install or --no-commands flag, as a simple way to "link" two repositories and debug inside them?

    Keywords

    none

    Install

    npm i canarist

    DownloadsWeekly Downloads

    3

    Version

    2.3.2

    License

    MIT

    Unpacked Size

    219 kB

    Total Files

    63

    Last publish

    Collaborators

    • herschel666
    • zaubernerd
    • dmbch
    • robin-drexler
    • jhiode