Skip to content

Commit

Permalink
port(turborepo): Config (#4520)
Browse files Browse the repository at this point in the history
### Description

Creates an `ExecutionState` struct that gets serialized to the Go code.
The goal is to build up more and more of the info, such as config and
graph state in this struct, so that we can do more work on the Rust
side.

### Testing Instructions

<!--
  Give a quick description of steps to test your changes.
-->
  • Loading branch information
NicholasLYang committed Apr 25, 2023
1 parent f56af36 commit 27b654b
Show file tree
Hide file tree
Showing 22 changed files with 313 additions and 653 deletions.
10 changes: 5 additions & 5 deletions cli/cmd/turbo/main.go
Expand Up @@ -15,14 +15,14 @@ func main() {
os.Exit(1)
}

argsString := os.Args[1]
var args turbostate.ParsedArgsFromRust
err := json.Unmarshal([]byte(argsString), &args)
executionStateString := os.Args[1]
var executionState turbostate.ExecutionState
err := json.Unmarshal([]byte(executionStateString), &executionState)
if err != nil {
fmt.Printf("Error unmarshalling CLI args: %v\n Arg string: %v\n", err, argsString)
fmt.Printf("Error unmarshalling execution state: %v\n Execution state string: %v\n", err, executionStateString)
os.Exit(1)
}

exitCode := cmd.RunWithArgs(&args, turboVersion)
exitCode := cmd.RunWithExecutionState(&executionState, turboVersion)
os.Exit(exitCode)
}
32 changes: 8 additions & 24 deletions cli/internal/client/client.go
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-retryablehttp"
"github.com/vercel/turbo/cli/internal/ci"
"github.com/vercel/turbo/cli/internal/turbostate"
)

// APIClient is the main interface for making network requests to Vercel
Expand Down Expand Up @@ -47,42 +48,25 @@ func (c *APIClient) SetToken(token string) {
c.token = token
}

// RemoteConfig holds the authentication and endpoint details for the API client
type RemoteConfig struct {
Token string
TeamID string
TeamSlug string
APIURL string
}

// Opts holds values for configuring the behavior of the API client
type Opts struct {
UsePreflight bool
Timeout uint64
}

// ClientTimeout Exported ClientTimeout used in run.go
const ClientTimeout uint64 = 20

// NewClient creates a new APIClient
func NewClient(remoteConfig RemoteConfig, logger hclog.Logger, turboVersion string, opts Opts) *APIClient {
func NewClient(config turbostate.APIClientConfig, logger hclog.Logger, turboVersion string) *APIClient {
client := &APIClient{
baseURL: remoteConfig.APIURL,
baseURL: config.APIURL,
turboVersion: turboVersion,
HTTPClient: &retryablehttp.Client{
HTTPClient: &http.Client{
Timeout: time.Duration(opts.Timeout) * time.Second,
Timeout: time.Duration(config.Timeout) * time.Second,
},
RetryWaitMin: 2 * time.Second,
RetryWaitMax: 10 * time.Second,
RetryMax: 2,
Backoff: retryablehttp.DefaultBackoff,
Logger: logger,
},
token: remoteConfig.Token,
teamID: remoteConfig.TeamID,
teamSlug: remoteConfig.TeamSlug,
usePreflight: opts.UsePreflight,
token: config.Token,
teamID: config.TeamID,
teamSlug: config.TeamSlug,
usePreflight: config.UsePreflight,
}
client.HTTPClient.CheckRetry = client.checkRetry
return client
Expand Down
17 changes: 9 additions & 8 deletions cli/internal/client/client_test.go
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/google/uuid"
"github.com/hashicorp/go-hclog"
"github.com/vercel/turbo/cli/internal/turbostate"
"github.com/vercel/turbo/cli/internal/util"
)

Expand All @@ -30,12 +31,12 @@ func Test_sendToServer(t *testing.T) {
}))
defer ts.Close()

remoteConfig := RemoteConfig{
apiClientConfig := turbostate.APIClientConfig{
TeamSlug: "my-team-slug",
APIURL: ts.URL,
Token: "my-token",
}
apiClient := NewClient(remoteConfig, hclog.Default(), "v1", Opts{})
apiClient := NewClient(apiClientConfig, hclog.Default(), "v1")

myUUID, err := uuid.NewUUID()
if err != nil {
Expand Down Expand Up @@ -85,12 +86,12 @@ func Test_PutArtifact(t *testing.T) {
defer ts.Close()

// Set up test expected values
remoteConfig := RemoteConfig{
apiClientConfig := turbostate.APIClientConfig{
TeamSlug: "my-team-slug",
APIURL: ts.URL,
Token: "my-token",
}
apiClient := NewClient(remoteConfig, hclog.Default(), "v1", Opts{})
apiClient := NewClient(apiClientConfig, hclog.Default(), "v1")
expectedArtifactBody := []byte("My string artifact")

// Test Put Artifact
Expand All @@ -111,12 +112,12 @@ func Test_PutWhenCachingDisabled(t *testing.T) {
defer ts.Close()

// Set up test expected values
remoteConfig := RemoteConfig{
apiClientConfig := turbostate.APIClientConfig{
TeamSlug: "my-team-slug",
APIURL: ts.URL,
Token: "my-token",
}
apiClient := NewClient(remoteConfig, hclog.Default(), "v1", Opts{})
apiClient := NewClient(apiClientConfig, hclog.Default(), "v1")
expectedArtifactBody := []byte("My string artifact")
// Test Put Artifact
err := apiClient.PutArtifact("hash", expectedArtifactBody, 500, "")
Expand All @@ -138,12 +139,12 @@ func Test_FetchWhenCachingDisabled(t *testing.T) {
defer ts.Close()

// Set up test expected values
remoteConfig := RemoteConfig{
apiClientConfig := turbostate.APIClientConfig{
TeamSlug: "my-team-slug",
APIURL: ts.URL,
Token: "my-token",
}
apiClient := NewClient(remoteConfig, hclog.Default(), "v1", Opts{})
apiClient := NewClient(apiClientConfig, hclog.Default(), "v1")
// Test Put Artifact
resp, err := apiClient.FetchArtifact("hash")
cd := &util.CacheDisabledError{}
Expand Down
16 changes: 8 additions & 8 deletions cli/internal/cmd/root.go
Expand Up @@ -44,29 +44,29 @@ func initializeOutputFiles(helper *cmdutil.Helper, parsedArgs *turbostate.Parsed
return nil
}

// RunWithArgs runs turbo with the ParsedArgsFromRust that is passed from the Rust side.
func RunWithArgs(args *turbostate.ParsedArgsFromRust, turboVersion string) int {
// RunWithExecutionState runs turbo with the ParsedArgsFromRust that is passed from the Rust side.
func RunWithExecutionState(executionState *turbostate.ExecutionState, turboVersion string) int {
util.InitPrintf()
// TODO: replace this with a context
signalWatcher := signals.NewWatcher()
helper := cmdutil.NewHelper(turboVersion, args)
helper := cmdutil.NewHelper(turboVersion, &executionState.CLIArgs)
ctx := context.Background()

err := initializeOutputFiles(helper, args)
err := initializeOutputFiles(helper, &executionState.CLIArgs)
if err != nil {
fmt.Printf("%v", err)
return 1
}
defer helper.Cleanup(args)
defer helper.Cleanup(&executionState.CLIArgs)

doneCh := make(chan struct{})
var execErr error
go func() {
command := args.Command
command := executionState.CLIArgs.Command
if command.Prune != nil {
execErr = prune.ExecutePrune(helper, args)
execErr = prune.ExecutePrune(helper, executionState)
} else if command.Run != nil {
execErr = run.ExecuteRun(ctx, helper, signalWatcher, args)
execErr = run.ExecuteRun(ctx, helper, signalWatcher, executionState)
} else {
execErr = fmt.Errorf("unknown command: %v", command)
}
Expand Down
58 changes: 8 additions & 50 deletions cli/internal/cmdutil/cmdutil.go
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"io/ioutil"
"os"
"strconv"
"sync"

"github.com/hashicorp/go-hclog"
Expand Down Expand Up @@ -39,8 +38,6 @@ type Helper struct {

rawRepoRoot string

clientOpts client.Opts

// UserConfigPath is the path to where we expect to find
// a user-specific config file, if one is present. Public
// to allow overrides in tests
Expand Down Expand Up @@ -74,12 +71,12 @@ func (h *Helper) Cleanup(cliConfig *turbostate.ParsedArgsFromRust) {
}
}

func (h *Helper) getUI(cliConfig *turbostate.ParsedArgsFromRust) cli.Ui {
func (h *Helper) getUI(cliArgs *turbostate.ParsedArgsFromRust) cli.Ui {
colorMode := ui.GetColorModeFromEnv()
if cliConfig.GetNoColor() {
if cliArgs.NoColor {
colorMode = ui.ColorModeSuppressed
}
if cliConfig.GetColor() {
if cliArgs.Color {
colorMode = ui.ColorModeForced
}
return ui.BuildColoredUi(colorMode)
Expand Down Expand Up @@ -134,15 +131,15 @@ func NewHelper(turboVersion string, args *turbostate.ParsedArgsFromRust) *Helper

// GetCmdBase returns a CmdBase instance configured with values from this helper.
// It additionally returns a mechanism to set an error, so
func (h *Helper) GetCmdBase(cliConfig *turbostate.ParsedArgsFromRust) (*CmdBase, error) {
func (h *Helper) GetCmdBase(executionState *turbostate.ExecutionState) (*CmdBase, error) {
// terminal is for color/no-color output
terminal := h.getUI(cliConfig)
terminal := h.getUI(&executionState.CLIArgs)
// logger is configured with verbosity level using --verbosity flag from end users
logger, err := h.getLogger()
if err != nil {
return nil, err
}
cwdRaw, err := cliConfig.GetCwd()
cwdRaw := executionState.CLIArgs.CWD
if err != nil {
return nil, err
}
Expand All @@ -155,55 +152,19 @@ func (h *Helper) GetCmdBase(cliConfig *turbostate.ParsedArgsFromRust) (*CmdBase,
if err != nil {
return nil, err
}
repoConfig, err := config.ReadRepoConfigFile(config.GetRepoConfigPath(repoRoot), cliConfig)
if err != nil {
return nil, err
}
userConfig, err := config.ReadUserConfigFile(h.UserConfigPath, cliConfig)
if err != nil {
return nil, err
}
remoteConfig := repoConfig.GetRemoteConfig(userConfig.Token())
if remoteConfig.Token == "" && ui.IsCI {
vercelArtifactsToken := os.Getenv("VERCEL_ARTIFACTS_TOKEN")
vercelArtifactsOwner := os.Getenv("VERCEL_ARTIFACTS_OWNER")
if vercelArtifactsToken != "" {
remoteConfig.Token = vercelArtifactsToken
}
if vercelArtifactsOwner != "" {
remoteConfig.TeamID = vercelArtifactsOwner
}
}

// Primacy: Arg > Env
timeout, err := cliConfig.GetRemoteCacheTimeout()
if err == nil {
h.clientOpts.Timeout = timeout
} else {
val, ok := os.LookupEnv("TURBO_REMOTE_CACHE_TIMEOUT")
if ok {
number, err := strconv.ParseUint(val, 10, 64)
if err == nil {
h.clientOpts.Timeout = number
}
}
}
apiClientConfig := executionState.APIClientConfig

apiClient := client.NewClient(
remoteConfig,
apiClientConfig,
logger,
h.TurboVersion,
h.clientOpts,
)

return &CmdBase{
UI: terminal,
Logger: logger,
RepoRoot: repoRoot,
APIClient: apiClient,
RepoConfig: repoConfig,
UserConfig: userConfig,
RemoteConfig: remoteConfig,
TurboVersion: h.TurboVersion,
}, nil
}
Expand All @@ -214,9 +175,6 @@ type CmdBase struct {
Logger hclog.Logger
RepoRoot turbopath.AbsoluteSystemPath
APIClient *client.APIClient
RepoConfig *config.RepoConfig
UserConfig *config.UserConfig
RemoteConfig client.RemoteConfig
TurboVersion string
}

Expand Down

0 comments on commit 27b654b

Please sign in to comment.