mirror of https://github.com/pulumi/pulumi.git
94 lines
2.6 KiB
Go
94 lines
2.6 KiB
Go
package npm
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// pnpm is an implementation of PackageManager that uses PNPM,
|
|
// to install dependencies.
|
|
type pnpm struct {
|
|
executable string
|
|
}
|
|
|
|
// Assert that it is an instance of PackageManager.
|
|
var _ PackageManager = &pnpm{}
|
|
|
|
func newPNPM() (*pnpm, error) {
|
|
path, err := exec.LookPath("pnpm")
|
|
manager := &pnpm{
|
|
executable: path,
|
|
}
|
|
return manager, err
|
|
}
|
|
|
|
func (manager *pnpm) Name() string {
|
|
return "pnpm"
|
|
}
|
|
|
|
func (manager *pnpm) Install(ctx context.Context, dir string, production bool, stdout, stderr io.Writer) error {
|
|
command := manager.installCmd(ctx, production)
|
|
command.Dir = dir
|
|
command.Stdout = stdout
|
|
command.Stderr = stderr
|
|
return command.Run()
|
|
}
|
|
|
|
// Generates the command to install packages with PNPM.
|
|
func (manager *pnpm) installCmd(ctx context.Context, production bool) *exec.Cmd {
|
|
args := []string{"install"}
|
|
|
|
if production {
|
|
args = append(args, "--prod")
|
|
}
|
|
|
|
//nolint:gosec // False positive on tained command execution. We aren't accepting input from the user here.
|
|
return exec.CommandContext(ctx, manager.executable, args...)
|
|
}
|
|
|
|
// Pack runs `pnpm pack` in the given directory, packaging the Node.js app located
|
|
// there into a tarball an returning it as `[]byte`. `stdout` is ignored for this command,
|
|
// as it does not produce useful data.
|
|
func (manager *pnpm) Pack(ctx context.Context, dir string, stderr io.Writer) ([]byte, error) {
|
|
//nolint:gosec // False positive on tained command execution. We aren't accepting input from the user here.
|
|
command := exec.CommandContext(ctx, manager.executable, "pack")
|
|
command.Dir = dir
|
|
|
|
// Like NPM, stdout prints the name of the generated file.
|
|
var stdout bytes.Buffer
|
|
command.Stdout = &stdout
|
|
command.Stderr = stderr
|
|
err := command.Run()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Next, we try to read the name of the file from stdout.
|
|
// packfile is the name of the file containing the tarball,
|
|
// as produced by `pnpm pack`.
|
|
packfile := strings.TrimSpace(stdout.String())
|
|
defer os.Remove(packfile)
|
|
|
|
packTarball, err := os.ReadFile(packfile)
|
|
if err != nil {
|
|
newErr := fmt.Errorf("'pnpm pack' completed successfully but the packaged .tgz file was not generated: %v", err)
|
|
return nil, newErr
|
|
}
|
|
|
|
return packTarball, nil
|
|
}
|
|
|
|
// checkPNPMLock checks if there's a file named pnpm-lock.yaml in pwd.
|
|
// This function is used to indicate whether to prefer PNPM over
|
|
// other package managers.
|
|
func checkPNPMLock(pwd string) bool {
|
|
yarnFile := filepath.Join(pwd, "pnpm-lock.yaml")
|
|
_, err := os.Stat(yarnFile)
|
|
return err == nil
|
|
}
|