Rename "deployment" to "environment": code

Signed-off-by: Solomon Hykes <sh.github.6811@hykes.org>
This commit is contained in:
Solomon Hykes 2021-04-27 18:59:04 +00:00
parent d1853f9e4b
commit e6e8ab390d
29 changed files with 282 additions and 282 deletions

View File

@ -9,18 +9,18 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
func GetCurrentDeploymentState(ctx context.Context, store *dagger.Store) *dagger.DeploymentState { func GetCurrentEnvironmentState(ctx context.Context, store *dagger.Store) *dagger.EnvironmentState {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
deploymentName := viper.GetString("deployment") environmentName := viper.GetString("environment")
if deploymentName != "" { if environmentName != "" {
st, err := store.LookupDeploymentByName(ctx, deploymentName) st, err := store.LookupEnvironmentByName(ctx, environmentName)
if err != nil { if err != nil {
lg. lg.
Fatal(). Fatal().
Err(err). Err(err).
Str("deploymentName", deploymentName). Str("environmentName", environmentName).
Msg("failed to lookup deployment by name") Msg("failed to lookup environment by name")
} }
return st return st
} }
@ -29,50 +29,50 @@ func GetCurrentDeploymentState(ctx context.Context, store *dagger.Store) *dagger
if err != nil { if err != nil {
lg.Fatal().Err(err).Msg("cannot get current working directory") lg.Fatal().Err(err).Msg("cannot get current working directory")
} }
st, err := store.LookupDeploymentByPath(ctx, wd) st, err := store.LookupEnvironmentByPath(ctx, wd)
if err != nil { if err != nil {
lg. lg.
Fatal(). Fatal().
Err(err). Err(err).
Str("deploymentPath", wd). Str("environmentPath", wd).
Msg("failed to lookup deployment by path") Msg("failed to lookup environment by path")
} }
if len(st) == 0 { if len(st) == 0 {
lg. lg.
Fatal(). Fatal().
Err(err). Err(err).
Str("deploymentPath", wd). Str("environmentPath", wd).
Msg("no deployments match the current directory") Msg("no environments match the current directory")
} }
if len(st) > 1 { if len(st) > 1 {
deployments := []string{} environments := []string{}
for _, s := range st { for _, s := range st {
deployments = append(deployments, s.Name) environments = append(environments, s.Name)
} }
lg. lg.
Fatal(). Fatal().
Err(err). Err(err).
Str("deploymentPath", wd). Str("environmentPath", wd).
Strs("deployments", deployments). Strs("environments", environments).
Msg("multiple deployments match the current directory, select one with `--deployment`") Msg("multiple environments match the current directory, select one with `--environment`")
} }
return st[0] return st[0]
} }
// Re-compute a deployment (equivalent to `dagger up`). // Re-compute an environment (equivalent to `dagger up`).
func DeploymentUp(ctx context.Context, state *dagger.DeploymentState, noCache bool) *dagger.Deployment { func EnvironmentUp(ctx context.Context, state *dagger.EnvironmentState, noCache bool) *dagger.Environment {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
c, err := dagger.NewClient(ctx, "", noCache) c, err := dagger.NewClient(ctx, "", noCache)
if err != nil { if err != nil {
lg.Fatal().Err(err).Msg("unable to create client") lg.Fatal().Err(err).Msg("unable to create client")
} }
result, err := c.Do(ctx, state, func(ctx context.Context, deployment *dagger.Deployment, s dagger.Solver) error { result, err := c.Do(ctx, state, func(ctx context.Context, environment *dagger.Environment, s dagger.Solver) error {
log.Ctx(ctx).Debug().Msg("bringing deployment up") log.Ctx(ctx).Debug().Msg("bringing environment up")
return deployment.Up(ctx, s) return environment.Up(ctx, s)
}) })
if err != nil { if err != nil {
lg.Fatal().Err(err).Msg("failed to up deployment") lg.Fatal().Err(err).Msg("failed to up environment")
} }
return result return result
} }

View File

@ -35,7 +35,7 @@ var computeCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
st := &dagger.DeploymentState{ st := &dagger.EnvironmentState{
ID: uuid.New().String(), ID: uuid.New().String(),
Name: "FIXME", Name: "FIXME",
PlanSource: dagger.DirInput(args[0], []string{"*.cue", "cue.mod"}), PlanSource: dagger.DirInput(args[0], []string{"*.cue", "cue.mod"}),
@ -149,16 +149,16 @@ var computeCmd = &cobra.Command{
} }
} }
deployment := common.DeploymentUp(ctx, st, viper.GetBool("no-cache")) environment := common.EnvironmentUp(ctx, st, viper.GetBool("no-cache"))
v := compiler.NewValue() v := compiler.NewValue()
if err := v.FillPath(cue.MakePath(), deployment.Plan()); err != nil { if err := v.FillPath(cue.MakePath(), environment.Plan()); err != nil {
lg.Fatal().Err(err).Msg("failed to merge") lg.Fatal().Err(err).Msg("failed to merge")
} }
if err := v.FillPath(cue.MakePath(), deployment.Input()); err != nil { if err := v.FillPath(cue.MakePath(), environment.Input()); err != nil {
lg.Fatal().Err(err).Msg("failed to merge") lg.Fatal().Err(err).Msg("failed to merge")
} }
if err := v.FillPath(cue.MakePath(), deployment.Computed()); err != nil { if err := v.FillPath(cue.MakePath(), environment.Computed()); err != nil {
lg.Fatal().Err(err).Msg("failed to merge") lg.Fatal().Err(err).Msg("failed to merge")
} }

View File

@ -7,7 +7,7 @@ import (
var deleteCmd = &cobra.Command{ var deleteCmd = &cobra.Command{
Use: "delete", Use: "delete",
Short: "Delete a deployment after taking it offline (WARNING: may destroy infrastructure)", Short: "Delete an environment after taking it offline (WARNING: may destroy infrastructure)",
Args: cobra.NoArgs, Args: cobra.NoArgs,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:

View File

@ -7,7 +7,7 @@ import (
var downCmd = &cobra.Command{ var downCmd = &cobra.Command{
Use: "down", Use: "down",
Short: "Take a deployment offline (WARNING: may destroy infrastructure)", Short: "Take an environment offline (WARNING: may destroy infrastructure)",
Args: cobra.NoArgs, Args: cobra.NoArgs,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:

View File

@ -7,7 +7,7 @@ import (
var historyCmd = &cobra.Command{ var historyCmd = &cobra.Command{
Use: "history", Use: "history",
Short: "List past changes to a deployment", Short: "List past changes to an environment",
Args: cobra.NoArgs, Args: cobra.NoArgs,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:

View File

@ -22,7 +22,7 @@ var containerCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
updateDeploymentInput(ctx, args[0], dagger.DockerInput(args[1])) updateEnvironmentInput(ctx, args[0], dagger.DockerInput(args[1]))
}, },
} }

View File

@ -22,7 +22,7 @@ var dirCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
updateDeploymentInput(ctx, args[0], dagger.DirInput(args[1], []string{})) updateEnvironmentInput(ctx, args[0], dagger.DirInput(args[1], []string{}))
}, },
} }

View File

@ -32,7 +32,7 @@ var gitCmd = &cobra.Command{
subDir = args[3] subDir = args[3]
} }
updateDeploymentInput(ctx, args[0], dagger.GitInput(args[1], ref, subDir)) updateEnvironmentInput(ctx, args[0], dagger.GitInput(args[1], ref, subDir))
}, },
} }

View File

@ -22,7 +22,7 @@ var jsonCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
updateDeploymentInput( updateEnvironmentInput(
ctx, ctx,
args[0], args[0],
dagger.JSONInput(readInput(ctx, args[1])), dagger.JSONInput(readInput(ctx, args[1])),

View File

@ -17,7 +17,7 @@ import (
var listCmd = &cobra.Command{ var listCmd = &cobra.Command{
Use: "list [TARGET] [flags]", Use: "list [TARGET] [flags]",
Short: "List for the inputs of a deployment", Short: "List for the inputs of an environment",
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:
@ -35,12 +35,12 @@ var listCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
deployment := common.GetCurrentDeploymentState(ctx, store) environment := common.GetCurrentEnvironmentState(ctx, store)
// print any persisted inputs // print any persisted inputs
if len(deployment.Inputs) > 0 { if len(environment.Inputs) > 0 {
fmt.Println("Saved Inputs:") fmt.Println("Saved Inputs:")
for _, input := range deployment.Inputs { for _, input := range environment.Inputs {
// Todo, how to pull apart an input to print relevant information // Todo, how to pull apart an input to print relevant information
fmt.Printf("%s: %v\n", input.Key, input.Value) fmt.Printf("%s: %v\n", input.Key, input.Value)
} }
@ -49,8 +49,8 @@ var listCmd = &cobra.Command{
} }
lg = lg.With(). lg = lg.With().
Str("deploymentName", deployment.Name). Str("environmentName", environment.Name).
Str("deploymentId", deployment.ID). Str("environmentId", environment.ID).
Logger() Logger()
c, err := dagger.NewClient(ctx, "", false) c, err := dagger.NewClient(ctx, "", false)
@ -58,7 +58,7 @@ var listCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("unable to create client") lg.Fatal().Err(err).Msg("unable to create client")
} }
_, err = c.Do(ctx, deployment, func(lCtx context.Context, lDeploy *dagger.Deployment, lSolver dagger.Solver) error { _, err = c.Do(ctx, environment, func(lCtx context.Context, lDeploy *dagger.Environment, lSolver dagger.Solver) error {
inputs, err := lDeploy.ScanInputs() inputs, err := lDeploy.ScanInputs()
if err != nil { if err != nil {
return err return err
@ -105,7 +105,7 @@ var listCmd = &cobra.Command{
}) })
if err != nil { if err != nil {
lg.Fatal().Err(err).Msg("failed to query deployment") lg.Fatal().Err(err).Msg("failed to query environment")
} }
}, },

View File

@ -15,7 +15,7 @@ import (
// Cmd exposes the top-level command // Cmd exposes the top-level command
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "input", Use: "input",
Short: "Manage a deployment's inputs", Short: "Manage an environment's inputs",
} }
func init() { func init() {
@ -31,7 +31,7 @@ func init() {
) )
} }
func updateDeploymentInput(ctx context.Context, target string, input dagger.Input) { func updateEnvironmentInput(ctx context.Context, target string, input dagger.Input) {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
store, err := dagger.DefaultStore() store, err := dagger.DefaultStore()
@ -39,13 +39,13 @@ func updateDeploymentInput(ctx context.Context, target string, input dagger.Inpu
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
st := common.GetCurrentDeploymentState(ctx, store) st := common.GetCurrentEnvironmentState(ctx, store)
st.SetInput(target, input) st.SetInput(target, input)
if err := store.UpdateDeployment(ctx, st, nil); err != nil { if err := store.UpdateEnvironment(ctx, st, nil); err != nil {
lg.Fatal().Err(err).Str("deploymentId", st.ID).Str("deploymentName", st.Name).Msg("cannot update deployment") lg.Fatal().Err(err).Str("environmentId", st.ID).Str("environmentName", st.Name).Msg("cannot update environment")
} }
lg.Info().Str("deploymentId", st.ID).Str("deploymentName", st.Name).Msg("updated deployment") lg.Info().Str("environmentId", st.ID).Str("environmentName", st.Name).Msg("updated environment")
} }
func readInput(ctx context.Context, source string) string { func readInput(ctx context.Context, source string) string {

View File

@ -22,7 +22,7 @@ var textCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
updateDeploymentInput( updateEnvironmentInput(
ctx, ctx,
args[0], args[0],
dagger.TextInput(readInput(ctx, args[1])), dagger.TextInput(readInput(ctx, args[1])),

View File

@ -22,7 +22,7 @@ var yamlCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
updateDeploymentInput( updateEnvironmentInput(
ctx, ctx,
args[0], args[0],
dagger.YAMLInput(readInput(ctx, args[1])), dagger.YAMLInput(readInput(ctx, args[1])),

View File

@ -18,7 +18,7 @@ import (
var listCmd = &cobra.Command{ var listCmd = &cobra.Command{
Use: "list", Use: "list",
Short: "List available deployments", Short: "List available environments",
Args: cobra.NoArgs, Args: cobra.NoArgs,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:
@ -35,20 +35,20 @@ var listCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
deployments, err := store.ListDeployments(ctx) environments, err := store.ListEnvironments(ctx)
if err != nil { if err != nil {
lg. lg.
Fatal(). Fatal().
Err(err). Err(err).
Msg("cannot list deployments") Msg("cannot list environments")
} }
deploymentID := getCurrentDeploymentID(ctx, store) environmentID := getCurrentEnvironmentID(ctx, store)
w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.TabIndent) w := tabwriter.NewWriter(os.Stdout, 0, 0, 1, ' ', tabwriter.TabIndent)
for _, r := range deployments { for _, r := range environments {
line := fmt.Sprintf("%s\t%s\t", r.Name, formatPlanSource(r.PlanSource)) line := fmt.Sprintf("%s\t%s\t", r.Name, formatPlanSource(r.PlanSource))
if r.ID == deploymentID { if r.ID == environmentID {
line = fmt.Sprintf("%s- active deployment", line) line = fmt.Sprintf("%s- active environment", line)
} }
fmt.Fprintln(w, line) fmt.Fprintln(w, line)
} }
@ -62,7 +62,7 @@ func init() {
} }
} }
func getCurrentDeploymentID(ctx context.Context, store *dagger.Store) string { func getCurrentEnvironmentID(ctx context.Context, store *dagger.Store) string {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
wd, err := os.Getwd() wd, err := os.Getwd()
@ -71,7 +71,7 @@ func getCurrentDeploymentID(ctx context.Context, store *dagger.Store) string {
return "" return ""
} }
st, err := store.LookupDeploymentByPath(ctx, wd) st, err := store.LookupEnvironmentByPath(ctx, wd)
if err != nil { if err != nil {
// Ignore error // Ignore error
return "" return ""

View File

@ -17,7 +17,7 @@ import (
var newCmd = &cobra.Command{ var newCmd = &cobra.Command{
Use: "new", Use: "new",
Short: "Create a new deployment", Short: "Create a new environment",
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:
@ -34,41 +34,41 @@ var newCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
if viper.GetString("deployment") != "" { if viper.GetString("environment") != "" {
lg. lg.
Fatal(). Fatal().
Msg("cannot use option -d,--deployment for this command") Msg("cannot use option -d,--environment for this command")
} }
name := "" name := ""
if len(args) > 0 { if len(args) > 0 {
name = args[0] name = args[0]
} else { } else {
name = getNewDeploymentName(ctx) name = getNewEnvironmentName(ctx)
} }
st := &dagger.DeploymentState{ st := &dagger.EnvironmentState{
Name: name, Name: name,
PlanSource: getPlanSource(ctx), PlanSource: getPlanSource(ctx),
} }
err = store.CreateDeployment(ctx, st) err = store.CreateEnvironment(ctx, st)
if err != nil { if err != nil {
lg.Fatal().Err(err).Msg("failed to create deployment") lg.Fatal().Err(err).Msg("failed to create environment")
} }
lg. lg.
Info(). Info().
Str("deploymentId", st.ID). Str("environmentId", st.ID).
Str("deploymentName", st.Name). Str("environmentName", st.Name).
Msg("deployment created") Msg("environment created")
if viper.GetBool("up") { if viper.GetBool("up") {
common.DeploymentUp(ctx, st, false) common.EnvironmentUp(ctx, st, false)
} }
}, },
} }
func getNewDeploymentName(ctx context.Context) string { func getNewEnvironmentName(ctx context.Context) string {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
workDir, err := os.Getwd() workDir, err := os.Getwd()
@ -133,7 +133,7 @@ func getPlanSource(ctx context.Context) dagger.Input {
} }
func init() { func init() {
newCmd.Flags().BoolP("up", "u", false, "Bring the deployment online") newCmd.Flags().BoolP("up", "u", false, "Bring the environment online")
newCmd.Flags().String("plan-dir", "", "Load plan from a local directory") newCmd.Flags().String("plan-dir", "", "Load plan from a local directory")
newCmd.Flags().String("plan-git", "", "Load plan from a git repository") newCmd.Flags().String("plan-git", "", "Load plan from a git repository")

View File

@ -5,7 +5,7 @@ import "github.com/spf13/cobra"
// Cmd exposes the top-level command // Cmd exposes the top-level command
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "output", Use: "output",
Short: "Manage a deployment's outputs", Short: "Manage an environment's outputs",
} }
func init() { func init() {

View File

@ -22,7 +22,7 @@ var dirCmd = &cobra.Command{
lg := logger.New() lg := logger.New()
ctx := lg.WithContext(cmd.Context()) ctx := lg.WithContext(cmd.Context())
updateDeploymentPlan(ctx, dagger.DirInput(args[0], []string{"*.cue", "cue.mod"})) updateEnvironmentPlan(ctx, dagger.DirInput(args[0], []string{"*.cue", "cue.mod"}))
}, },
} }

View File

@ -32,7 +32,7 @@ var gitCmd = &cobra.Command{
subDir = args[2] subDir = args[2]
} }
updateDeploymentPlan(ctx, dagger.GitInput(args[0], ref, subDir)) updateEnvironmentPlan(ctx, dagger.GitInput(args[0], ref, subDir))
}, },
} }

View File

@ -12,7 +12,7 @@ import (
// Cmd exposes the top-level command // Cmd exposes the top-level command
var Cmd = &cobra.Command{ var Cmd = &cobra.Command{
Use: "plan", Use: "plan",
Short: "Manage a deployment's plan", Short: "Manage an environment's plan",
} }
func init() { func init() {
@ -24,7 +24,7 @@ func init() {
) )
} }
func updateDeploymentPlan(ctx context.Context, planSource dagger.Input) { func updateEnvironmentPlan(ctx context.Context, planSource dagger.Input) {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
store, err := dagger.DefaultStore() store, err := dagger.DefaultStore()
@ -32,11 +32,11 @@ func updateDeploymentPlan(ctx context.Context, planSource dagger.Input) {
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
st := common.GetCurrentDeploymentState(ctx, store) st := common.GetCurrentEnvironmentState(ctx, store)
st.PlanSource = planSource st.PlanSource = planSource
if err := store.UpdateDeployment(ctx, st, nil); err != nil { if err := store.UpdateEnvironment(ctx, st, nil); err != nil {
lg.Fatal().Err(err).Str("deploymentId", st.ID).Str("deploymentName", st.Name).Msg("cannot update deployment") lg.Fatal().Err(err).Str("environmentId", st.ID).Str("environmentName", st.Name).Msg("cannot update environment")
} }
lg.Info().Str("deploymentId", st.ID).Str("deploymentName", st.Name).Msg("updated deployment") lg.Info().Str("environmentId", st.ID).Str("environmentName", st.Name).Msg("updated environment")
} }

View File

@ -15,7 +15,7 @@ import (
var queryCmd = &cobra.Command{ var queryCmd = &cobra.Command{
Use: "query [TARGET] [flags]", Use: "query [TARGET] [flags]",
Short: "Query the contents of a deployment", Short: "Query the contents of an environment",
Args: cobra.MaximumNArgs(1), Args: cobra.MaximumNArgs(1),
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:
@ -35,11 +35,11 @@ var queryCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
state := common.GetCurrentDeploymentState(ctx, store) state := common.GetCurrentEnvironmentState(ctx, store)
lg = lg.With(). lg = lg.With().
Str("deploymentName", state.Name). Str("environmentName", state.Name).
Str("deploymentId", state.ID). Str("environmentId", state.ID).
Logger() Logger()
cuePath := cue.MakePath() cuePath := cue.MakePath()
@ -52,21 +52,21 @@ var queryCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("unable to create client") lg.Fatal().Err(err).Msg("unable to create client")
} }
deployment, err := c.Do(ctx, state, nil) environment, err := c.Do(ctx, state, nil)
if err != nil { if err != nil {
lg.Fatal().Err(err).Msg("failed to query deployment") lg.Fatal().Err(err).Msg("failed to query environment")
} }
cueVal := compiler.NewValue() cueVal := compiler.NewValue()
if !viper.GetBool("no-plan") { if !viper.GetBool("no-plan") {
if err := cueVal.FillPath(cue.MakePath(), deployment.Plan()); err != nil { if err := cueVal.FillPath(cue.MakePath(), environment.Plan()); err != nil {
lg.Fatal().Err(err).Msg("failed to merge plan") lg.Fatal().Err(err).Msg("failed to merge plan")
} }
} }
if !viper.GetBool("no-input") { if !viper.GetBool("no-input") {
if err := cueVal.FillPath(cue.MakePath(), deployment.Input()); err != nil { if err := cueVal.FillPath(cue.MakePath(), environment.Input()); err != nil {
lg.Fatal().Err(err).Msg("failed to merge plan with output") lg.Fatal().Err(err).Msg("failed to merge plan with output")
} }
} }
@ -139,7 +139,7 @@ func init() {
queryCmd.Flags().BoolP("show-attributes", "A", false, "Display field attributes (cue format only)") queryCmd.Flags().BoolP("show-attributes", "A", false, "Display field attributes (cue format only)")
// FIXME: implement the flags below // FIXME: implement the flags below
// queryCmd.Flags().String("revision", "latest", "Query a specific version of the deployment") // queryCmd.Flags().String("revision", "latest", "Query a specific version of the environment")
queryCmd.Flags().StringP("format", "f", "json", "Output format (json|yaml|cue|text|env)") queryCmd.Flags().StringP("format", "f", "json", "Output format (json|yaml|cue|text|env)")
queryCmd.Flags().BoolP("no-plan", "P", false, "Exclude plan from query") queryCmd.Flags().BoolP("no-plan", "P", false, "Exclude plan from query")
queryCmd.Flags().BoolP("no-input", "I", false, "Exclude inputs from query") queryCmd.Flags().BoolP("no-input", "I", false, "Exclude inputs from query")

View File

@ -17,13 +17,13 @@ import (
var rootCmd = &cobra.Command{ var rootCmd = &cobra.Command{
Use: "dagger", Use: "dagger",
Short: "A programmable deployment system", Short: "A programmable environment system",
} }
func init() { func init() {
rootCmd.PersistentFlags().String("log-format", "", "Log format (json, pretty). Defaults to json if the terminal is not a tty") rootCmd.PersistentFlags().String("log-format", "", "Log format (json, pretty). Defaults to json if the terminal is not a tty")
rootCmd.PersistentFlags().StringP("log-level", "l", "info", "Log level") rootCmd.PersistentFlags().StringP("log-level", "l", "info", "Log level")
rootCmd.PersistentFlags().StringP("deployment", "d", "", "Select a deployment") rootCmd.PersistentFlags().StringP("environment", "e", "", "Select an environment")
rootCmd.AddCommand( rootCmd.AddCommand(
computeCmd, computeCmd,

View File

@ -11,7 +11,7 @@ import (
var upCmd = &cobra.Command{ var upCmd = &cobra.Command{
Use: "up", Use: "up",
Short: "Bring a deployment online with latest plan and inputs", Short: "Bring an environment online with latest plan and inputs",
Args: cobra.NoArgs, Args: cobra.NoArgs,
PreRun: func(cmd *cobra.Command, args []string) { PreRun: func(cmd *cobra.Command, args []string) {
// Fix Viper bug for duplicate flags: // Fix Viper bug for duplicate flags:
@ -28,11 +28,11 @@ var upCmd = &cobra.Command{
lg.Fatal().Err(err).Msg("failed to load store") lg.Fatal().Err(err).Msg("failed to load store")
} }
state := common.GetCurrentDeploymentState(ctx, store) state := common.GetCurrentEnvironmentState(ctx, store)
result := common.DeploymentUp(ctx, state, viper.GetBool("no-cache")) result := common.EnvironmentUp(ctx, state, viper.GetBool("no-cache"))
state.Computed = result.Computed().JSON().String() state.Computed = result.Computed().JSON().String()
if err := store.UpdateDeployment(ctx, state, nil); err != nil { if err := store.UpdateEnvironment(ctx, state, nil); err != nil {
lg.Fatal().Err(err).Msg("failed to update deployment") lg.Fatal().Err(err).Msg("failed to update environment")
} }
}, },
} }

View File

@ -29,27 +29,27 @@ import (
description: "Write code to deploy your code" description: "Write code to deploy your code"
doc: """ doc: """
A Dagger deployment is a continuously running workflow delivering a specific application in a specific way. A Dagger environment is a continuously running workflow delivering a specific application in a specific way.
The same application can be delivered via different deployments, each with a different configuration. The same application can be delivered via different environments, each with a different configuration.
For example a production deployment might include manual validation and addition performance testing, For example a production environment might include manual validation and addition performance testing,
while a staging deployment might automatically deploy from a git branch, load test data into the database, while a staging environment might automatically deploy from a git branch, load test data into the database,
and run on a separate cluster. and run on a separate cluster.
A deployment is made of 3 parts: a deployment plan, inputs, and outputs. An environment is made of 3 parts: a plan, inputs, and outputs.
""" """
flag: { flag: {
"--deployment": { "--environment": {
alt: "-d" alt: "-d"
description: description:
""" """
Select a deployment Select an environment
If no deployment is specified, dagger searches for deployments using the current If no environment is specified, dagger searches for environments using the current
directory as input. directory as input.
* If exactly one deployment matches the search, it is selected. * If exactly one environment matches the search, it is selected.
* If there is more than one match, the user is prompted to select one. * If there is more than one match, the user is prompted to select one.
* If there is no match, the command returns an error. * If there is no match, the command returns an error.
""" """
@ -69,25 +69,25 @@ import (
command: { command: {
new: { new: {
description: "Create a new deployment" description: "Create a new environment"
flag: { flag: {
"--name": { "--name": {
alt: "-n" alt: "-n"
description: "Specify a deployment name" description: "Specify an environment name"
default: "name of current directory" default: "name of current directory"
} }
"--plan-dir": description: "Load deployment plan from a local directory" "--plan-dir": description: "Load plan from a local directory"
"--plan-git": description: "Load deployment plan from a git repository" "--plan-git": description: "Load plan from a git repository"
"--plan-package": description: "Load deployment plan from a cue package" "--plan-package": description: "Load plan from a cue package"
"--plan-file": description: "Load deployment plan from a cue or json file" "--plan-file": description: "Load plan from a cue or json file"
"--up": { "--up": {
alt: "-u" alt: "-u"
description: "Bring the deployment online" description: "Bring the environment online"
} }
"--setup": { "--setup": {
@ -97,26 +97,26 @@ import (
} }
} }
list: description: "List available deployments" list: description: "List available environments"
query: { query: {
arg: "[EXPR] [flags]" arg: "[EXPR] [flags]"
description: "Query the contents of a deployment" description: "Query the contents of an environment"
doc: doc:
""" """
EXPR may be any valid CUE expression. The expression is evaluated against the deployment contents. The deployment is not changed. EXPR may be any valid CUE expression. The expression is evaluated against the environment contents. The environment is not changed.
Examples: Examples:
# Print the entire deployment plan with inputs merged in (but no outputs) # Print the entire plan with inputs merged in (but no outputs)
$ dagger query --no-output $ dagger query --no-output
# Print the deployment plan, inputs and outputs of a particular step # Print the plan, inputs and outputs of a particular step
$ dagger query www.build $ dagger query www.build
# Print the URL of a deployed service # Print the URL of a deployed service
$ dagger query api.url $ dagger query api.url
# Export environment variables from a deployment # Export environment variables from an environment
$ dagger query -f json api.environment $ dagger query -f json api.environment
""" """
@ -127,7 +127,7 @@ import (
// Use --revision or --change or --change-id instead? // Use --revision or --change or --change-id instead?
"--version": { "--version": {
alt: "-v" alt: "-v"
description: "Query a specific version of the deployment" description: "Query a specific version of the environment"
default: "latest" default: "latest"
} }
@ -147,29 +147,29 @@ import (
} }
"--no-plan": { "--no-plan": {
alt: "-L" alt: "-L"
description: "Exclude deployment plan from query" description: "Exclude plan from query"
} }
} }
} }
up: { up: {
description: "Bring a deployment online with latest deployment plan and inputs" description: "Bring an environment online with latest plan and inputs"
flag: "--no-cache": description: "Disable all run cache" flag: "--no-cache": description: "Disable all run cache"
} }
down: { down: {
description: "Take a deployment offline (WARNING: may destroy infrastructure)" description: "Take an environment offline (WARNING: may destroy infrastructure)"
flag: "--no-cache": description: "Disable all run cache" flag: "--no-cache": description: "Disable all run cache"
} }
history: description: "List past changes to a deployment" history: description: "List past changes to an environment"
delete: { delete: {
description: "Delete a deployment after taking it offline (WARNING: may destroy infrastructure)" description: "Delete an environment after taking it offline (WARNING: may destroy infrastructure)"
} }
plan: { plan: {
description: "Manage a deployment plan" description: "Manage an environment plan"
command: { command: {
package: { package: {
@ -216,7 +216,7 @@ import (
} }
input: { input: {
description: "Manage a deployment's inputs" description: "Manage an environment's inputs"
command: { command: {
// FIXME: details of individual input commands // FIXME: details of individual input commands
@ -229,10 +229,10 @@ import (
} }
output: { output: {
description: "Manage a deployment's outputs" description: "Manage an environment's outputs"
// FIXME: bind output values or artifacts // FIXME: bind output values or artifacts
// to local dir or file // to local dir or file
// BONUS: bind a deployment output to another deployment's input? // BONUS: bind an environment output to another environment's input?
} }
login: description: "Login to Dagger Cloud" login: description: "Login to Dagger Cloud"

View File

@ -60,14 +60,14 @@ func NewClient(ctx context.Context, host string, noCache bool) (*Client, error)
}, nil }, nil
} }
type ClientDoFunc func(context.Context, *Deployment, Solver) error type ClientDoFunc func(context.Context, *Environment, Solver) error
// FIXME: return completed *Route, instead of *compiler.Value // FIXME: return completed *Route, instead of *compiler.Value
func (c *Client) Do(ctx context.Context, state *DeploymentState, fn ClientDoFunc) (*Deployment, error) { func (c *Client) Do(ctx context.Context, state *EnvironmentState, fn ClientDoFunc) (*Environment, error) {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
eg, gctx := errgroup.WithContext(ctx) eg, gctx := errgroup.WithContext(ctx)
deployment, err := NewDeployment(state) environment, err := NewEnvironment(state)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -83,17 +83,17 @@ func (c *Client) Do(ctx context.Context, state *DeploymentState, fn ClientDoFunc
// Spawn build function // Spawn build function
eg.Go(func() error { eg.Go(func() error {
return c.buildfn(gctx, deployment, fn, events) return c.buildfn(gctx, environment, fn, events)
}) })
return deployment, eg.Wait() return environment, eg.Wait()
} }
func (c *Client) buildfn(ctx context.Context, deployment *Deployment, fn ClientDoFunc, ch chan *bk.SolveStatus) error { func (c *Client) buildfn(ctx context.Context, environment *Environment, fn ClientDoFunc, ch chan *bk.SolveStatus) error {
lg := log.Ctx(ctx) lg := log.Ctx(ctx)
// Scan local dirs to grant access // Scan local dirs to grant access
localdirs := deployment.LocalDirs() localdirs := environment.LocalDirs()
for label, dir := range localdirs { for label, dir := range localdirs {
abs, err := filepath.Abs(dir) abs, err := filepath.Abs(dir)
if err != nil { if err != nil {
@ -121,24 +121,24 @@ func (c *Client) buildfn(ctx context.Context, deployment *Deployment, fn ClientD
s := NewSolver(c.c, gw, ch, auth, c.noCache) s := NewSolver(c.c, gw, ch, auth, c.noCache)
lg.Debug().Msg("loading configuration") lg.Debug().Msg("loading configuration")
if err := deployment.LoadPlan(ctx, s); err != nil { if err := environment.LoadPlan(ctx, s); err != nil {
return nil, err return nil, err
} }
// Compute output overlay // Compute output overlay
if fn != nil { if fn != nil {
if err := fn(ctx, deployment, s); err != nil { if err := fn(ctx, environment, s); err != nil {
return nil, compiler.Err(err) return nil, compiler.Err(err)
} }
} }
// Export deployment to a cue directory // Export environment to a cue directory
// FIXME: this should be elsewhere // FIXME: this should be elsewhere
lg.Debug().Msg("exporting deployment") lg.Debug().Msg("exporting environment")
span, _ := opentracing.StartSpanFromContext(ctx, "Deployment.Export") span, _ := opentracing.StartSpanFromContext(ctx, "Environment.Export")
defer span.Finish() defer span.Finish()
computed := deployment.Computed().JSON().PrettyString() computed := environment.Computed().JSON().PrettyString()
st := llb. st := llb.
Scratch(). Scratch().
File( File(

View File

@ -19,8 +19,8 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
type Deployment struct { type Environment struct {
state *DeploymentState state *EnvironmentState
// Layer 1: plan configuration // Layer 1: plan configuration
plan *compiler.Value plan *compiler.Value
@ -32,8 +32,8 @@ type Deployment struct {
computed *compiler.Value computed *compiler.Value
} }
func NewDeployment(st *DeploymentState) (*Deployment, error) { func NewEnvironment(st *EnvironmentState) (*Environment, error) {
d := &Deployment{ d := &Environment{
state: st, state: st,
plan: compiler.NewValue(), plan: compiler.NewValue(),
@ -60,33 +60,33 @@ func NewDeployment(st *DeploymentState) (*Deployment, error) {
return d, nil return d, nil
} }
func (d *Deployment) ID() string { func (d *Environment) ID() string {
return d.state.ID return d.state.ID
} }
func (d *Deployment) Name() string { func (d *Environment) Name() string {
return d.state.Name return d.state.Name
} }
func (d *Deployment) PlanSource() Input { func (d *Environment) PlanSource() Input {
return d.state.PlanSource return d.state.PlanSource
} }
func (d *Deployment) Plan() *compiler.Value { func (d *Environment) Plan() *compiler.Value {
return d.plan return d.plan
} }
func (d *Deployment) Input() *compiler.Value { func (d *Environment) Input() *compiler.Value {
return d.input return d.input
} }
func (d *Deployment) Computed() *compiler.Value { func (d *Environment) Computed() *compiler.Value {
return d.computed return d.computed
} }
// LoadPlan loads the plan // LoadPlan loads the plan
func (d *Deployment) LoadPlan(ctx context.Context, s Solver) error { func (d *Environment) LoadPlan(ctx context.Context, s Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "deployment.LoadPlan") span, ctx := opentracing.StartSpanFromContext(ctx, "environment.LoadPlan")
defer span.Finish() defer span.Finish()
planSource, err := d.state.PlanSource.Compile() planSource, err := d.state.PlanSource.Compile()
@ -114,11 +114,11 @@ func (d *Deployment) LoadPlan(ctx context.Context, s Solver) error {
return nil return nil
} }
// Scan all scripts in the deployment for references to local directories (do:"local"), // Scan all scripts in the environment for references to local directories (do:"local"),
// and return all referenced directory names. // and return all referenced directory names.
// This is used by clients to grant access to local directories when they are referenced // This is used by clients to grant access to local directories when they are referenced
// by user-specified scripts. // by user-specified scripts.
func (d *Deployment) LocalDirs() map[string]string { func (d *Environment) LocalDirs() map[string]string {
dirs := map[string]string{} dirs := map[string]string{}
localdirs := func(code ...*compiler.Value) { localdirs := func(code ...*compiler.Value) {
Analyze( Analyze(
@ -140,7 +140,7 @@ func (d *Deployment) LocalDirs() map[string]string {
code..., code...,
) )
} }
// 1. Scan the deployment state // 1. Scan the environment state
// FIXME: use a common `flow` instance to avoid rescanning the tree. // FIXME: use a common `flow` instance to avoid rescanning the tree.
src, err := compiler.InstanceMerge(d.plan, d.input) src, err := compiler.InstanceMerge(d.plan, d.input)
if err != nil { if err != nil {
@ -165,9 +165,9 @@ func (d *Deployment) LocalDirs() map[string]string {
return dirs return dirs
} }
// Up missing values in deployment configuration, and write them to state. // Up missing values in environment configuration, and write them to state.
func (d *Deployment) Up(ctx context.Context, s Solver) error { func (d *Environment) Up(ctx context.Context, s Solver) error {
span, ctx := opentracing.StartSpanFromContext(ctx, "deployment.Up") span, ctx := opentracing.StartSpanFromContext(ctx, "environment.Up")
defer span.Finish() defer span.Finish()
// Reset the computed values // Reset the computed values
@ -194,7 +194,7 @@ func (d *Deployment) Up(ctx context.Context, s Solver) error {
type DownOpts struct{} type DownOpts struct{}
func (d *Deployment) Down(ctx context.Context, _ *DownOpts) error { func (d *Environment) Down(ctx context.Context, _ *DownOpts) error {
panic("NOT IMPLEMENTED") panic("NOT IMPLEMENTED")
} }
@ -292,7 +292,7 @@ func newPipelineRunner(inst *cue.Instance, computed *compiler.Value, s Solver) c
}) })
} }
func (d *Deployment) ScanInputs() ([]cue.Value, error) { func (d *Environment) ScanInputs() ([]cue.Value, error) {
vals, err := cuetils.ScanForInputs(d.plan.Cue()) vals, err := cuetils.ScanForInputs(d.plan.Cue())
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -7,15 +7,15 @@ import (
) )
func TestInputDir(t *testing.T) { func TestInputDir(t *testing.T) {
st := &DeploymentState{ st := &EnvironmentState{
PlanSource: DirInput("/tmp/source", []string{}), PlanSource: DirInput("/tmp/source", []string{}),
} }
require.NoError(t, st.SetInput("www.source", DirInput("/", []string{}))) require.NoError(t, st.SetInput("www.source", DirInput("/", []string{})))
deployment, err := NewDeployment(st) environment, err := NewEnvironment(st)
require.NoError(t, err) require.NoError(t, err)
localdirs := deployment.LocalDirs() localdirs := environment.LocalDirs()
require.Len(t, localdirs, 2) require.Len(t, localdirs, 2)
require.Contains(t, localdirs, "/") require.Contains(t, localdirs, "/")
require.Contains(t, localdirs, "/tmp/source") require.Contains(t, localdirs, "/tmp/source")

View File

@ -1,16 +1,16 @@
package dagger package dagger
// Contents of a deployment serialized to a file // Contents of an environment serialized to a file
type DeploymentState struct { type EnvironmentState struct {
// Globally unique deployment ID // Globally unique environment ID
ID string `json:"id,omitempty"` ID string `json:"id,omitempty"`
// Human-friendly deployment name. // Human-friendly environment name.
// A deployment may have more than one name. // A environment may have more than one name.
// FIXME: store multiple names? // FIXME: store multiple names?
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
// Cue module containing the deployment plan // Cue module containing the environment plan
// The input's top-level artifact is used as a module directory. // The input's top-level artifact is used as a module directory.
PlanSource Input `json:"plan,omitempty"` PlanSource Input `json:"plan,omitempty"`
@ -26,7 +26,7 @@ type inputKV struct {
Value Input `json:"value,omitempty"` Value Input `json:"value,omitempty"`
} }
func (s *DeploymentState) SetInput(key string, value Input) error { func (s *EnvironmentState) SetInput(key string, value Input) error {
for i, inp := range s.Inputs { for i, inp := range s.Inputs {
if inp.Key != key { if inp.Key != key {
continue continue
@ -42,7 +42,7 @@ func (s *DeploymentState) SetInput(key string, value Input) error {
// Remove all inputs at the given key, including sub-keys. // Remove all inputs at the given key, including sub-keys.
// For example RemoveInputs("foo.bar") will remove all inputs // For example RemoveInputs("foo.bar") will remove all inputs
// at foo.bar, foo.bar.baz, etc. // at foo.bar, foo.bar.baz, etc.
func (s *DeploymentState) RemoveInputs(key string) error { func (s *EnvironmentState) RemoveInputs(key string) error {
newInputs := make([]inputKV, 0, len(s.Inputs)) newInputs := make([]inputKV, 0, len(s.Inputs))
for _, i := range s.Inputs { for _, i := range s.Inputs {
if i.Key == key { if i.Key == key {

View File

@ -13,8 +13,8 @@ import (
) )
var ( var (
ErrDeploymentExist = errors.New("deployment already exists") ErrEnvironmentExist = errors.New("environment already exists")
ErrDeploymentNotExist = errors.New("deployment doesn't exist") ErrEnvironmentNotExist = errors.New("environment doesn't exist")
) )
const ( const (
@ -26,26 +26,26 @@ type Store struct {
l sync.RWMutex l sync.RWMutex
// ID -> Deployment // ID -> Environment
deployments map[string]*DeploymentState environments map[string]*EnvironmentState
// Name -> Deployment // Name -> Environment
deploymentsByName map[string]*DeploymentState environmentsByName map[string]*EnvironmentState
// Path -> (ID->Deployment) // Path -> (ID->Environment)
deploymentsByPath map[string]map[string]*DeploymentState environmentsByPath map[string]map[string]*EnvironmentState
// ID -> (Path->{}) // ID -> (Path->{})
pathsByDeploymentID map[string]map[string]struct{} pathsByEnvironmentID map[string]map[string]struct{}
} }
func NewStore(root string) (*Store, error) { func NewStore(root string) (*Store, error) {
store := &Store{ store := &Store{
root: root, root: root,
deployments: make(map[string]*DeploymentState), environments: make(map[string]*EnvironmentState),
deploymentsByName: make(map[string]*DeploymentState), environmentsByName: make(map[string]*EnvironmentState),
deploymentsByPath: make(map[string]map[string]*DeploymentState), environmentsByPath: make(map[string]map[string]*EnvironmentState),
pathsByDeploymentID: make(map[string]map[string]struct{}), pathsByEnvironmentID: make(map[string]map[string]struct{}),
} }
return store, store.loadAll() return store, store.loadAll()
} }
@ -58,8 +58,8 @@ func DefaultStore() (*Store, error) {
return NewStore(os.ExpandEnv(defaultStoreRoot)) return NewStore(os.ExpandEnv(defaultStoreRoot))
} }
func (s *Store) deploymentPath(name string) string { func (s *Store) environmentPath(name string) string {
return path.Join(s.root, name, "deployment.json") return path.Join(s.root, name, "environment.json")
} }
func (s *Store) loadAll() error { func (s *Store) loadAll() error {
@ -75,7 +75,7 @@ func (s *Store) loadAll() error {
if !f.IsDir() { if !f.IsDir() {
continue continue
} }
if err := s.loadDeployment(f.Name()); err != nil { if err := s.loadEnvironment(f.Name()); err != nil {
return err return err
} }
} }
@ -83,21 +83,21 @@ func (s *Store) loadAll() error {
return nil return nil
} }
func (s *Store) loadDeployment(name string) error { func (s *Store) loadEnvironment(name string) error {
data, err := os.ReadFile(s.deploymentPath(name)) data, err := os.ReadFile(s.environmentPath(name))
if err != nil { if err != nil {
return err return err
} }
var st DeploymentState var st EnvironmentState
if err := json.Unmarshal(data, &st); err != nil { if err := json.Unmarshal(data, &st); err != nil {
return err return err
} }
s.indexDeployment(&st) s.indexEnvironment(&st)
return nil return nil
} }
func (s *Store) syncDeployment(r *DeploymentState) error { func (s *Store) syncEnvironment(r *EnvironmentState) error {
p := s.deploymentPath(r.Name) p := s.environmentPath(r.Name)
if err := os.MkdirAll(path.Dir(p), 0755); err != nil { if err := os.MkdirAll(path.Dir(p), 0755); err != nil {
return err return err
@ -112,28 +112,28 @@ func (s *Store) syncDeployment(r *DeploymentState) error {
return err return err
} }
s.reindexDeployment(r) s.reindexEnvironment(r)
return nil return nil
} }
func (s *Store) indexDeployment(r *DeploymentState) { func (s *Store) indexEnvironment(r *EnvironmentState) {
s.deployments[r.ID] = r s.environments[r.ID] = r
s.deploymentsByName[r.Name] = r s.environmentsByName[r.Name] = r
mapPath := func(i Input) { mapPath := func(i Input) {
if i.Type != InputTypeDir { if i.Type != InputTypeDir {
return return
} }
if s.deploymentsByPath[i.Dir.Path] == nil { if s.environmentsByPath[i.Dir.Path] == nil {
s.deploymentsByPath[i.Dir.Path] = make(map[string]*DeploymentState) s.environmentsByPath[i.Dir.Path] = make(map[string]*EnvironmentState)
} }
s.deploymentsByPath[i.Dir.Path][r.ID] = r s.environmentsByPath[i.Dir.Path][r.ID] = r
if s.pathsByDeploymentID[r.ID] == nil { if s.pathsByEnvironmentID[r.ID] == nil {
s.pathsByDeploymentID[r.ID] = make(map[string]struct{}) s.pathsByEnvironmentID[r.ID] = make(map[string]struct{})
} }
s.pathsByDeploymentID[r.ID][i.Dir.Path] = struct{}{} s.pathsByEnvironmentID[r.ID][i.Dir.Path] = struct{}{}
} }
mapPath(r.PlanSource) mapPath(r.PlanSource)
@ -142,108 +142,108 @@ func (s *Store) indexDeployment(r *DeploymentState) {
} }
} }
func (s *Store) deindexDeployment(id string) { func (s *Store) deindexEnvironment(id string) {
r, ok := s.deployments[id] r, ok := s.environments[id]
if !ok { if !ok {
return return
} }
delete(s.deployments, r.ID) delete(s.environments, r.ID)
delete(s.deploymentsByName, r.Name) delete(s.environmentsByName, r.Name)
for p := range s.pathsByDeploymentID[r.ID] { for p := range s.pathsByEnvironmentID[r.ID] {
delete(s.deploymentsByPath[p], r.ID) delete(s.environmentsByPath[p], r.ID)
} }
delete(s.pathsByDeploymentID, r.ID) delete(s.pathsByEnvironmentID, r.ID)
} }
func (s *Store) reindexDeployment(r *DeploymentState) { func (s *Store) reindexEnvironment(r *EnvironmentState) {
s.deindexDeployment(r.ID) s.deindexEnvironment(r.ID)
s.indexDeployment(r) s.indexEnvironment(r)
} }
func (s *Store) CreateDeployment(ctx context.Context, st *DeploymentState) error { func (s *Store) CreateEnvironment(ctx context.Context, st *EnvironmentState) error {
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
if _, ok := s.deploymentsByName[st.Name]; ok { if _, ok := s.environmentsByName[st.Name]; ok {
return fmt.Errorf("%s: %w", st.Name, ErrDeploymentExist) return fmt.Errorf("%s: %w", st.Name, ErrEnvironmentExist)
} }
st.ID = uuid.New().String() st.ID = uuid.New().String()
return s.syncDeployment(st) return s.syncEnvironment(st)
} }
type UpdateOpts struct{} type UpdateOpts struct{}
func (s *Store) UpdateDeployment(ctx context.Context, r *DeploymentState, o *UpdateOpts) error { func (s *Store) UpdateEnvironment(ctx context.Context, r *EnvironmentState, o *UpdateOpts) error {
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
return s.syncDeployment(r) return s.syncEnvironment(r)
} }
type DeleteOpts struct{} type DeleteOpts struct{}
func (s *Store) DeleteDeployment(ctx context.Context, r *DeploymentState, o *DeleteOpts) error { func (s *Store) DeleteEnvironment(ctx context.Context, r *EnvironmentState, o *DeleteOpts) error {
s.l.Lock() s.l.Lock()
defer s.l.Unlock() defer s.l.Unlock()
if err := os.Remove(s.deploymentPath(r.Name)); err != nil { if err := os.Remove(s.environmentPath(r.Name)); err != nil {
return err return err
} }
s.deindexDeployment(r.ID) s.deindexEnvironment(r.ID)
return nil return nil
} }
func (s *Store) LookupDeploymentByID(ctx context.Context, id string) (*DeploymentState, error) { func (s *Store) LookupEnvironmentByID(ctx context.Context, id string) (*EnvironmentState, error) {
s.l.RLock() s.l.RLock()
defer s.l.RUnlock() defer s.l.RUnlock()
st, ok := s.deployments[id] st, ok := s.environments[id]
if !ok { if !ok {
return nil, fmt.Errorf("%s: %w", id, ErrDeploymentNotExist) return nil, fmt.Errorf("%s: %w", id, ErrEnvironmentNotExist)
} }
return st, nil return st, nil
} }
func (s *Store) LookupDeploymentByName(ctx context.Context, name string) (*DeploymentState, error) { func (s *Store) LookupEnvironmentByName(ctx context.Context, name string) (*EnvironmentState, error) {
s.l.RLock() s.l.RLock()
defer s.l.RUnlock() defer s.l.RUnlock()
st, ok := s.deploymentsByName[name] st, ok := s.environmentsByName[name]
if !ok { if !ok {
return nil, fmt.Errorf("%s: %w", name, ErrDeploymentNotExist) return nil, fmt.Errorf("%s: %w", name, ErrEnvironmentNotExist)
} }
return st, nil return st, nil
} }
func (s *Store) LookupDeploymentByPath(ctx context.Context, path string) ([]*DeploymentState, error) { func (s *Store) LookupEnvironmentByPath(ctx context.Context, path string) ([]*EnvironmentState, error) {
s.l.RLock() s.l.RLock()
defer s.l.RUnlock() defer s.l.RUnlock()
res := []*DeploymentState{} res := []*EnvironmentState{}
deployments, ok := s.deploymentsByPath[path] environments, ok := s.environmentsByPath[path]
if !ok { if !ok {
return res, nil return res, nil
} }
for _, d := range deployments { for _, d := range environments {
res = append(res, d) res = append(res, d)
} }
return res, nil return res, nil
} }
func (s *Store) ListDeployments(ctx context.Context) ([]*DeploymentState, error) { func (s *Store) ListEnvironments(ctx context.Context) ([]*EnvironmentState, error) {
s.l.RLock() s.l.RLock()
defer s.l.RUnlock() defer s.l.RUnlock()
deployments := make([]*DeploymentState, 0, len(s.deployments)) environments := make([]*EnvironmentState, 0, len(s.environments))
for _, st := range s.deployments { for _, st := range s.environments {
deployments = append(deployments, st) environments = append(environments, st)
} }
return deployments, nil return environments, nil
} }

View File

@ -17,38 +17,38 @@ func TestStoreLoad(t *testing.T) {
store, err := NewStore(root) store, err := NewStore(root)
require.NoError(t, err) require.NoError(t, err)
_, err = store.LookupDeploymentByName(ctx, "notexist") _, err = store.LookupEnvironmentByName(ctx, "notexist")
require.Error(t, err) require.Error(t, err)
require.True(t, errors.Is(err, ErrDeploymentNotExist)) require.True(t, errors.Is(err, ErrEnvironmentNotExist))
st := &DeploymentState{ st := &EnvironmentState{
Name: "test", Name: "test",
} }
require.NoError(t, store.CreateDeployment(ctx, st)) require.NoError(t, store.CreateEnvironment(ctx, st))
checkDeployments := func(store *Store) { checkEnvironments := func(store *Store) {
r, err := store.LookupDeploymentByID(ctx, st.ID) r, err := store.LookupEnvironmentByID(ctx, st.ID)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, r) require.NotNil(t, r)
require.Equal(t, "test", r.Name) require.Equal(t, "test", r.Name)
r, err = store.LookupDeploymentByName(ctx, "test") r, err = store.LookupEnvironmentByName(ctx, "test")
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, r) require.NotNil(t, r)
require.Equal(t, "test", r.Name) require.Equal(t, "test", r.Name)
deployments, err := store.ListDeployments(ctx) environments, err := store.ListEnvironments(ctx)
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 1) require.Len(t, environments, 1)
require.Equal(t, "test", deployments[0].Name) require.Equal(t, "test", environments[0].Name)
} }
checkDeployments(store) checkEnvironments(store)
// Reload the deployments from disk and check again // Reload the environments from disk and check again
newStore, err := NewStore(root) newStore, err := NewStore(root)
require.NoError(t, err) require.NoError(t, err)
checkDeployments(newStore) checkEnvironments(newStore)
} }
func TestStoreLookupByPath(t *testing.T) { func TestStoreLookupByPath(t *testing.T) {
@ -59,65 +59,65 @@ func TestStoreLookupByPath(t *testing.T) {
store, err := NewStore(root) store, err := NewStore(root)
require.NoError(t, err) require.NoError(t, err)
st := &DeploymentState{ st := &EnvironmentState{
Name: "test", Name: "test",
} }
require.NoError(t, st.SetInput("foo", DirInput("/test/path", []string{}))) require.NoError(t, st.SetInput("foo", DirInput("/test/path", []string{})))
require.NoError(t, store.CreateDeployment(ctx, st)) require.NoError(t, store.CreateEnvironment(ctx, st))
// Lookup by path // Lookup by path
deployments, err := store.LookupDeploymentByPath(ctx, "/test/path") environments, err := store.LookupEnvironmentByPath(ctx, "/test/path")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 1) require.Len(t, environments, 1)
require.Equal(t, st.ID, deployments[0].ID) require.Equal(t, st.ID, environments[0].ID)
// Add a new path // Add a new path
require.NoError(t, st.SetInput("bar", DirInput("/test/anotherpath", []string{}))) require.NoError(t, st.SetInput("bar", DirInput("/test/anotherpath", []string{})))
require.NoError(t, store.UpdateDeployment(ctx, st, nil)) require.NoError(t, store.UpdateEnvironment(ctx, st, nil))
// Lookup by the previous path // Lookup by the previous path
deployments, err = store.LookupDeploymentByPath(ctx, "/test/path") environments, err = store.LookupEnvironmentByPath(ctx, "/test/path")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 1) require.Len(t, environments, 1)
require.Equal(t, st.ID, deployments[0].ID) require.Equal(t, st.ID, environments[0].ID)
// Lookup by the new path // Lookup by the new path
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath") environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 1) require.Len(t, environments, 1)
require.Equal(t, st.ID, deployments[0].ID) require.Equal(t, st.ID, environments[0].ID)
// Remove a path // Remove a path
require.NoError(t, st.RemoveInputs("foo")) require.NoError(t, st.RemoveInputs("foo"))
require.NoError(t, store.UpdateDeployment(ctx, st, nil)) require.NoError(t, store.UpdateEnvironment(ctx, st, nil))
// Lookup by the removed path should fail // Lookup by the removed path should fail
deployments, err = store.LookupDeploymentByPath(ctx, "/test/path") environments, err = store.LookupEnvironmentByPath(ctx, "/test/path")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 0) require.Len(t, environments, 0)
// Lookup by the other path should still work // Lookup by the other path should still work
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath") environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 1) require.Len(t, environments, 1)
// Add another deployment using the same path // Add another environment using the same path
otherSt := &DeploymentState{ otherSt := &EnvironmentState{
Name: "test2", Name: "test2",
} }
require.NoError(t, otherSt.SetInput("foo", DirInput("/test/anotherpath", []string{}))) require.NoError(t, otherSt.SetInput("foo", DirInput("/test/anotherpath", []string{})))
require.NoError(t, store.CreateDeployment(ctx, otherSt)) require.NoError(t, store.CreateEnvironment(ctx, otherSt))
// Lookup by path should return both deployments // Lookup by path should return both environments
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath") environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 2) require.Len(t, environments, 2)
// Remove the first deployment. Lookup by path should still return the // Remove the first environment. Lookup by path should still return the
// second deployment. // second environment.
require.NoError(t, store.DeleteDeployment(ctx, st, nil)) require.NoError(t, store.DeleteEnvironment(ctx, st, nil))
deployments, err = store.LookupDeploymentByPath(ctx, "/test/anotherpath") environments, err = store.LookupEnvironmentByPath(ctx, "/test/anotherpath")
require.NoError(t, err) require.NoError(t, err)
require.Len(t, deployments, 1) require.Len(t, environments, 1)
require.Equal(t, otherSt.ID, deployments[0].ID) require.Equal(t, otherSt.ID, environments[0].ID)
} }