Skip to content

Commit

Permalink
Hooked up package manager to Go code
Browse files Browse the repository at this point in the history
  • Loading branch information
NicholasLYang committed Apr 28, 2023
1 parent 376e9a7 commit 8dc6486
Show file tree
Hide file tree
Showing 13 changed files with 83 additions and 454 deletions.
5 changes: 2 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions cli/internal/context/context.go
Expand Up @@ -142,7 +142,7 @@ func isWorkspaceReference(packageVersion string, dependencyVersion string, cwd s
}

// SinglePackageGraph constructs a Context instance from a single package.
func SinglePackageGraph(repoRoot turbopath.AbsoluteSystemPath, rootPackageJSON *fs.PackageJSON) (*Context, error) {
func SinglePackageGraph(rootPackageJSON *fs.PackageJSON, packageManagerName string) (*Context, error) {
workspaceInfos := workspace.Catalog{
PackageJSONs: map[string]*fs.PackageJSON{util.RootPkgName: rootPackageJSON},
TurboConfigs: map[string]*fs.TurboJSON{},
Expand All @@ -152,7 +152,7 @@ func SinglePackageGraph(repoRoot turbopath.AbsoluteSystemPath, rootPackageJSON *
RootNode: core.ROOT_NODE_NAME,
}
c.WorkspaceGraph.Connect(dag.BasicEdge(util.RootPkgName, core.ROOT_NODE_NAME))
packageManager, err := packagemanager.GetPackageManager(repoRoot, rootPackageJSON)
packageManager, err := packagemanager.GetPackageManager(packageManagerName)
if err != nil {
return nil, err
}
Expand All @@ -161,7 +161,7 @@ func SinglePackageGraph(repoRoot turbopath.AbsoluteSystemPath, rootPackageJSON *
}

// BuildPackageGraph constructs a Context instance with information about the package dependency graph
func BuildPackageGraph(repoRoot turbopath.AbsoluteSystemPath, rootPackageJSON *fs.PackageJSON) (*Context, error) {
func BuildPackageGraph(repoRoot turbopath.AbsoluteSystemPath, rootPackageJSON *fs.PackageJSON, packageManagerName string) (*Context, error) {
c := &Context{}
rootpath := repoRoot.ToStringDuringMigration()
c.WorkspaceInfos = workspace.Catalog{
Expand All @@ -172,7 +172,7 @@ func BuildPackageGraph(repoRoot turbopath.AbsoluteSystemPath, rootPackageJSON *f

var warnings Warnings

packageManager, err := packagemanager.GetPackageManager(repoRoot, rootPackageJSON)
packageManager, err := packagemanager.GetPackageManager(packageManagerName)
if err != nil {
return nil, err
}
Expand Down
4 changes: 2 additions & 2 deletions cli/internal/context/context_test.go
Expand Up @@ -141,7 +141,7 @@ func TestBuildPackageGraph_DuplicateNames(t *testing.T) {
PackageManager: "pnpm@7.15.0",
}

_, actualErr := BuildPackageGraph(path, pkgJSON)
_, actualErr := BuildPackageGraph(path, pkgJSON, "pnpm")

// Not asserting the full error message, because it includes a path with slashes and backslashes
// getting the regex incantation to check that is not worth it.
Expand All @@ -157,7 +157,7 @@ func Test_populateExternalDeps_NoTransitiveDepsWithoutLockfile(t *testing.T) {
PackageManager: "pnpm@7.15.0",
}

pm, err := packagemanager.GetPackageManager(path, pkgJSON)
pm, err := packagemanager.GetPackageManager("pnpm")
assert.NilError(t, err)
pm.UnmarshalLockfile = func(rootPackageJSON *fs.PackageJSON, contents []byte) (lockfile.Lockfile, error) {
return nil, errors.New("bad lockfile")
Expand Down
68 changes: 15 additions & 53 deletions cli/internal/packagemanager/packagemanager.go
Expand Up @@ -8,14 +8,12 @@ import (
"fmt"
"path/filepath"
"regexp"
"strings"

"github.com/pkg/errors"
"github.com/vercel/turbo/cli/internal/fs"
"github.com/vercel/turbo/cli/internal/globby"
"github.com/vercel/turbo/cli/internal/lockfile"
"github.com/vercel/turbo/cli/internal/turbopath"
"github.com/vercel/turbo/cli/internal/util"
)

// PackageManager is an abstraction across package managers
Expand Down Expand Up @@ -80,58 +78,22 @@ var (
packageManagerRegex = regexp.MustCompile(packageManagerPattern)
)

// ParsePackageManagerString takes a package manager version string parses it into consituent components
func ParsePackageManagerString(packageManager string) (manager string, version string, err error) {
match := packageManagerRegex.FindString(packageManager)
if len(match) == 0 {
return "", "", fmt.Errorf("We could not parse packageManager field in package.json, expected: %s, received: %s", packageManagerPattern, packageManager)
// GetPackageManager reads the package manager name sent by the Rust side
func GetPackageManager(name string) (packageManager *PackageManager, err error) {
switch name {
case "yarn":
return &nodejsYarn, nil
case "berry":
return &nodejsBerry, nil
case "npm":
return &nodejsNpm, nil
case "pnpm":
return &nodejsPnpm, nil
case "pnpm6":
return &nodejsPnpm6, nil
default:
return nil, errors.New("Unknown package manager")
}

return strings.Split(match, "@")[0], strings.Split(match, "@")[1], nil
}

// GetPackageManager attempts all methods for identifying the package manager in use.
func GetPackageManager(projectDirectory turbopath.AbsoluteSystemPath, pkg *fs.PackageJSON) (packageManager *PackageManager, err error) {
result, _ := readPackageManager(pkg)
if result != nil {
return result, nil
}

return detectPackageManager(projectDirectory)
}

// readPackageManager attempts to read the package manager from the package.json.
func readPackageManager(pkg *fs.PackageJSON) (packageManager *PackageManager, err error) {
if pkg.PackageManager != "" {
manager, version, err := ParsePackageManagerString(pkg.PackageManager)
if err != nil {
return nil, err
}

for _, packageManager := range packageManagers {
isResponsible, err := packageManager.Matches(manager, version)
if isResponsible && (err == nil) {
return &packageManager, nil
}
}
}

return nil, errors.New(util.Sprintf("We did not find a package manager specified in your root package.json. Please set the \"packageManager\" property in your root package.json (${UNDERLINE}https://nodejs.org/api/packages.html#packagemanager)${RESET} or run `npx @turbo/codemod add-package-manager` in the root of your monorepo."))
}

// detectPackageManager attempts to detect the package manager by inspecting the project directory state.
func detectPackageManager(projectDirectory turbopath.AbsoluteSystemPath) (packageManager *PackageManager, err error) {
for _, packageManager := range packageManagers {
isResponsible, err := packageManager.detect(projectDirectory, &packageManager)
if err != nil {
return nil, err
}
if isResponsible {
return &packageManager, nil
}
}

return nil, errors.New(util.Sprintf("We did not detect an in-use package manager for your project. Please set the \"packageManager\" property in your root package.json (${UNDERLINE}https://nodejs.org/api/packages.html#packagemanager)${RESET} or run `npx @turbo/codemod add-package-manager` in the root of your monorepo."))
}

// GetWorkspaces returns the list of package.json files for the current repository.
Expand Down

0 comments on commit 8dc6486

Please sign in to comment.