turbo icon indicating copy to clipboard operation
turbo copied to clipboard

Execute `turbo` from anywhere in a monorepo

Open ObliviousHarmony opened this issue 2 years ago • 10 comments

Describe the feature you'd like to request

Right now you need to be in the repository root in order to run turbo commands. This is because it looks for the turbo.json file in the current directory. We've run into some problems with people running pnpm -- turbo run build in subdirectories when working in the monorepo. It would be great if it could run from anywhere in a monorepo.

Describe the solution you'd like

I think a fair solution would be for turbo to traverse the directory tree seeking out a turbo.json. This would support every kind of monorepo, as well as those that aren't using npm.

Describe alternatives you've considered

Another option I considered was implementing functionality for detecting the workspace root according to the package manager. This seems aligned with some of the existing code that's specific to the package manager, but, I think it further entrenches Turborepo in the JavaScript ecosystem. It seems more appropriate that turbo commands should find the root based on its own configuration file.

ObliviousHarmony avatar Jun 15 '22 22:06 ObliviousHarmony

Just chiming in to say we are definitely intending on doing this.

gsoltis avatar Jun 21 '22 03:06 gsoltis

In that case, it would be nice if a turbo command in a package would automatically have an implicit --filter on that package, so that a

mypackage $ turbo run server

...would correspond to:

repo-root $ turbo run server --filter=mypackage

robaca avatar Jun 21 '22 13:06 robaca

Sweet, I don't have to open this feature request. I'm so excited that two issues I have ran into with adoption turbo are already underway! This use case is supported with ultra-runner.

tomdavidson avatar Jun 29 '22 22:06 tomdavidson

I've been working around this issue with the following script with-deps:

#!/bin/bash
set -e
set -o pipefail

# Usage from the command line:
#   some/package$ yarn with-deps build arg1 arg2
# This is equivalent to running from the repo root:
#   yarn turbo build --filter=./some/package -- arg1 arg2
#
#
# Usage from package.json scripts:
#   "dev": "with-args webpack-dev-server arg1 arg2",
# This makes `yarn dev` run `yarn turbo dev --filter=./your/package`
# and when turbo runs your "dev" script, with-args passes through
# `webpack-dev-server arg1 arg2` to yarn.


if [ -z "$TURBO_HASH" ]; then
  # Called by the user. Need to run turbo from the root.
  root=$(git rev-parse --show-toplevel)
  cd $root

  if [ -z "$npm_lifecycle_event" ] || [ "$npm_lifecycle_event" = "with-deps" ]; then
    # Called from the command line.  First arg is the task.  Forward args.
    if [ $# -eq 0 ]; then
      echo "Usage: $0 <task> [args...]" >/dev/stderr
      exit 1
    fi
    task="$1"
    shift
    turbo run "$task" --filter=$npm_package_name --output-logs=new-only -- "$@"
  else
    # Called from package scripts.  Ask turbo to run the script.
    task="$npm_lifecycle_event"
    turbo run "$task" --filter=$npm_package_name --output-logs=new-only
  fi

else
  # Called by turbo.  Run the script.
  if [ $# -eq 0 ]; then
    echo "Usage: $0 <command> [args...]" >/dev/stderr
    exit 1
  fi
  task="$1"
  shift

  yarn "$task" "$@"
fi

Use like this in your package.json:

{
  "name": "the-package",
  ...
  "scripts": {
    "test": "with-deps jest",
    ...
  }
}

yarn test, npm run test, pnpm run test will run turbo run test --filter=the-package from the root of the repo, and when turbo runs the test script in the-package, it'll run jest.

dsilvasc avatar Jun 29 '22 23:06 dsilvasc

that feature would be awesome. it would certainly make it easier to use turbo 💖

alexn-s avatar Jul 05 '22 16:07 alexn-s

is there any progress regarding this? or decoupling turbo from package.json tasks in general?

alexn-s avatar Sep 05 '22 20:09 alexn-s

Yes! I am working on this. There's a bit of work to be done to make this all work out, but running from anywhere, with package being inferred from location, is very much one of my current goals.

Decoupling from package.json will come sometime after that.

gsoltis avatar Sep 06 '22 17:09 gsoltis

The filter inference PR is #2112

gsoltis avatar Oct 13 '22 21:10 gsoltis

@gsoltis does it mean that we have to always add --infer-filter-root to the turbo command?

Would it be possible to set this as default via turbo.json? When calling at the repository root, no filter should be applied.

robaca avatar Oct 14 '22 16:10 robaca

@robaca that flag is an implementation detail that you can forget you saw. 😜 We are using that to communicate between our Rust and Go portions.

nathanhammond avatar Oct 14 '22 16:10 nathanhammond

Done! You can run turbo from anywhere in your turborepo

NicholasLYang avatar Aug 28 '23 19:08 NicholasLYang

It seems that this feature is broken when used with workspaces containing other turbo.json files as described here: https://turbo.build/repo/docs/core-concepts/monorepos/configuring-workspaces

My guess is that it sees the first turbo.json and thinks this is the root. The error I'm gettng is:

We did not find a package manager specified in your root package.json. Please set the "packageManager" property in your root package.json (https://nodejs.org/api/packages.html#packagemanager) or run npx @turbo/codemod add-package-manager in the root of your monorepo.

Contrary to the error message, I do in fact have packageManager declared in the root package.json. It was set by pnpm to "packageManager": "[email protected]+sha1.97019f5a8ec2416123506419ab36dd558e4c72eb".

However, if I add that same line to any of the inner workspace package.json, then turbo works, but it once again gets stuck with the caching stuff. Only running from root actually produces the correct results

smac89 avatar Mar 09 '24 06:03 smac89