/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import {resolve} from 'path';

const TOOL_ROOT = resolve(__dirname, "../");
const FLOW_ROOT = resolve(__dirname, "../../../");
export const defaultTestsDirName = "newtests";

// This is where we look for tests to run and where we put newly converted
// tests
export function getTestsDir(relative_to?: string): string {
  if (relative_to !== undefined) {
    return resolve(relative_to, defaultTestsDirName);
  } else {
    return resolve(FLOW_ROOT, defaultTestsDirName);
  }
}

export const binOptions: Array<string> = [
  resolve(FLOW_ROOT, "bin/flow"), // Open source build
  resolve(FLOW_ROOT, "bin/flow.exe"), // Open source windows build
  resolve(FLOW_ROOT, "../buck-out/gen/flow/flow/flow"), // Buck
];

export const defaultFlowConfigName = "_flowconfig";

/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 * @format
 */

import {dirname, join, resolve} from 'path';

const FLOW_ROOT = resolve(__dirname, '../../../');
export const defaultTestsDirName = 'newtests';

// This is where we look for tests to run and where we put newly converted
// tests
export function getTestsDir(relative_to?: string): string {
  if (relative_to !== undefined) {
    return resolve(relative_to, defaultTestsDirName);
  } else {
    return dirname(require.resolve(join(defaultTestsDirName, 'package.json')));
  }
}

export const binOptions: Array<string> = [
  resolve(FLOW_ROOT, 'bin/flow'), // Open source build
  resolve(FLOW_ROOT, 'bin/flow.exe'), // Open source windows build
  resolve(FLOW_ROOT, '../buck-out/gen/flow/flow/flow'), // Buck
];

export const defaultFlowConfigName = '_flowconfig';

Allow workspaces outside of the workspace root
Allow workspaces outside of the workspace root

Summary:
As part of the workspace separation, and because our repo does not have an ideal layout (for example `react-native-github` consists of both product and tooling code, and is hard to move right now), I am in need of making workspaces outside of a workspace root work with Buck. This works with Yarn, assuming `$NODE_PATH` is used for correct resolutions, but did not work with Yarn's Buck Macros until this diff.

## How do the Yarn Buck Macros work?
Up until this week we didn't have anyone left at the company who understands this infrastructure. Now that I am the owner, here is a high-level overview of how things work:

* `yarn_workspace` creates a zip file of the workspace in `buck-out` (without `package.json` file).
* `yarn_workspace_root` creates a zip file of the `package.json` files of the root and all workspaces, `yarn.lock`, and `node_modules` for the corresponding workspace.
* `yarn_workspace_archive` merges the zip files for each workspace and the root to produce what is more or less the same as a Metronome package.
* `yarn_workspace_binary` which ties together all of the above to run a JavaScript tool given an entry point.

## Why does it use zip files?
The reason that this infrastructure uses zip files is because it was optimized for size and cache hits. In the past our `node_modules` folders were way too large and significantly slowed down buck builds. My end goal with the workspace separation is that product code will not use any of these rules at all (once the files are checked in), and that we should get rid of all the overhead and complexity of using zip files – either by using Metronome or by getting rid of the feature in the Yarn workspace rules.

## What does this diff do?
With all this context in mind, this diff changes the layout of the zip files created by `yarn_workspace_root` and `yarn_workspace_archive` to align with the behavior of Metronome. Instead of using relative paths mirroring the source locations in the zip files, we now use package names. For example, instead of `workspace.zip/tools/metro/packages/metro-symbolicate` we now simply put this file into the root, like `workspace.zip/metro-symbolicate`. For namespaced packages, we now use `fb-tools/gen-rn-routes/` (package name) instead of `tools/gen-rn-routes/` (file system path). This will allow us to use workspaces outside of the workspace root without breaking out of the assigned output folder in `buck-out`.

This also means that I had to update all callsites of `yarn_workspace_binary` to adjust the entry point to a package-relative path that can be resolved via node instead of a path generated from the source layout by Buck.

NOTE: Arguably, this is how it should have been from the beginning. However, it requires the codebase to be well-organized with packages and without relative requires across the repo. We only reached this state earlier this year after our big cleanup, so the previous solution to mirror the source locations made the most sense up until now.

Special thanks to davidaurelio for his patience and help over WhatsApp.

Reviewed By: yungsters

Differential Revision: D24359263

fbshipit-source-id: 40c4925ade1b8d87d2e65799bb059cda24c9a65b
