From c8b451faa3fcaeae115fd03d9ce85bd54c6cd8e7 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Tue, 5 Nov 2024 15:45:01 +0000 Subject: [PATCH 1/4] feat: allow changing default workspaces folder Fixes #384 --- docs/env-variables.md | 3 +- integration/integration_test.go | 22 +++++ options/defaults.go | 23 +++--- options/defaults_test.go | 140 +++++++++++++++++++------------- options/options.go | 19 ++++- options/testdata/options.golden | 6 ++ 6 files changed, 143 insertions(+), 70 deletions(-) diff --git a/docs/env-variables.md b/docs/env-variables.md index 6f9653bd..6a98e1d9 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -31,7 +31,8 @@ | `--git-ssh-private-key-path` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH` | | Path to an SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_BASE64 cannot be set. | | `--git-ssh-private-key-base64` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64` | | Base64 encoded SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_PATH cannot be set. | | `--git-http-proxy-url` | `ENVBUILDER_GIT_HTTP_PROXY_URL` | | The URL for the HTTP proxy. This is optional. | -| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. | +| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. Defaults to `[workspaces folder]/[name]` where name is the name of the repository or `empty`. | +| `--workspaces-folder` | `ENVBUILDER_WORKSPACES_FOLDER` | `/workspaces` | The path under which workspaces will be placed when workspace folder option is not given. | | `--ssl-cert-base64` | `ENVBUILDER_SSL_CERT_BASE64` | | The content of an SSL cert file. This is useful for self-signed certificates. | | `--export-env-file` | `ENVBUILDER_EXPORT_ENV_FILE` | | Optional file path to a .env file where envbuilder will dump environment variables from devcontainer.json and the built container image. | | `--post-start-script-path` | `ENVBUILDER_POST_START_SCRIPT_PATH` | | The path to a script that will be created by envbuilder based on the postStartCommand in devcontainer.json, if any is specified (otherwise the script is not created). If this is set, the specified InitCommand should check for the presence of this script and execute it after successful startup. | diff --git a/integration/integration_test.go b/integration/integration_test.go index 204ff907..b70c7398 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -834,6 +834,28 @@ func TestBuildFromDevcontainerInCustomPath(t *testing.T) { require.Equal(t, "hello", strings.TrimSpace(output)) } +func TestBuildFromCustomWorkspacesFolder(t *testing.T) { + t.Parallel() + + // Ensures that a Git repository with a devcontainer.json is cloned and built. + srv := gittest.CreateGitServer(t, gittest.Options{ + Files: map[string]string{ + "Dockerfile": "FROM " + testImageUbuntu, + }, + }) + ctr, err := runEnvbuilder(t, runOpts{ + env: []string{ + envbuilderEnv("DOCKERFILE_PATH", "Dockerfile"), + envbuilderEnv("WORKSPACES_FOLDER", "/foo"), + envbuilderEnv("GIT_URL", srv.URL), + }, + }) + require.NoError(t, err) + + output := execContainer(t, ctr, "readlink /proc/1/cwd") + require.Contains(t, output, "/foo/") +} + func TestBuildFromDevcontainerInSubfolder(t *testing.T) { t.Parallel() diff --git a/options/defaults.go b/options/defaults.go index 4b153c8f..9ee55cd8 100644 --- a/options/defaults.go +++ b/options/defaults.go @@ -12,29 +12,29 @@ import ( "github.com/coder/envbuilder/internal/workingdir" ) -// EmptyWorkspaceDir is the path to a workspace that has -// nothing going on... it's empty! -var EmptyWorkspaceDir = "/workspaces/empty" - // DefaultWorkspaceFolder returns the default workspace folder // for a given repository URL. -func DefaultWorkspaceFolder(repoURL string) string { +func DefaultWorkspaceFolder(workspacesFolder, repoURL string) string { + // emptyWorkspaceDir is the path to a workspace that has + // nothing going on... it's empty! + emptyWorkspaceDir := workspacesFolder + "/empty" + if repoURL == "" { - return EmptyWorkspaceDir + return emptyWorkspaceDir } parsed, err := giturls.Parse(repoURL) if err != nil { - return EmptyWorkspaceDir + return emptyWorkspaceDir } repo := path.Base(parsed.Path) // Giturls parsing never actually fails since ParseLocal never // errors and places the entire URL in the Path field. This check // ensures it's at least a Unix path containing forwardslash. if repo == repoURL || repo == "/" || repo == "." || repo == "" { - return EmptyWorkspaceDir + return emptyWorkspaceDir } repo = strings.TrimSuffix(repo, ".git") - return fmt.Sprintf("/workspaces/%s", repo) + return fmt.Sprintf("%s/%s", workspacesFolder, repo) } func (o *Options) SetDefaults() { @@ -59,8 +59,11 @@ func (o *Options) SetDefaults() { if o.Filesystem == nil { o.Filesystem = chmodfs.New(osfs.New("/")) } + if o.WorkspacesFolder == "" { + o.WorkspacesFolder = "/workspaces" + } if o.WorkspaceFolder == "" { - o.WorkspaceFolder = DefaultWorkspaceFolder(o.GitURL) + o.WorkspaceFolder = DefaultWorkspaceFolder(o.WorkspacesFolder, o.GitURL) } if o.BinaryPath == "" { o.BinaryPath = "/.envbuilder/bin/envbuilder" diff --git a/options/defaults_test.go b/options/defaults_test.go index 20aacc6a..646d9397 100644 --- a/options/defaults_test.go +++ b/options/defaults_test.go @@ -16,84 +16,111 @@ func TestDefaultWorkspaceFolder(t *testing.T) { t.Parallel() successTests := []struct { - name string - gitURL string - expected string + name string + workspacesFolder string + gitURL string + expected string }{ { - name: "HTTP", - gitURL: "https://github.com/coder/envbuilder.git", - expected: "/workspaces/envbuilder", + name: "HTTP", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git", + expected: "/workspaces/envbuilder", }, { - name: "SSH", - gitURL: "git@github.com:coder/envbuilder.git", - expected: "/workspaces/envbuilder", + name: "SSH", + workspacesFolder: "/workspaces", + gitURL: "git@github.com:coder/envbuilder.git", + expected: "/workspaces/envbuilder", }, { - name: "username and password", - gitURL: "https://username:password@github.com/coder/envbuilder.git", - expected: "/workspaces/envbuilder", + name: "username and password", + workspacesFolder: "/workspaces", + gitURL: "https://username:password@github.com/coder/envbuilder.git", + expected: "/workspaces/envbuilder", }, { - name: "trailing", - gitURL: "https://github.com/coder/envbuilder.git/", - expected: "/workspaces/envbuilder", + name: "trailing", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git/", + expected: "/workspaces/envbuilder", }, { - name: "trailing-x2", - gitURL: "https://github.com/coder/envbuilder.git//", - expected: "/workspaces/envbuilder", + name: "trailing-x2", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git//", + expected: "/workspaces/envbuilder", }, { - name: "no .git", - gitURL: "https://github.com/coder/envbuilder", - expected: "/workspaces/envbuilder", + name: "no .git", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder", + expected: "/workspaces/envbuilder", }, { - name: "trailing no .git", - gitURL: "https://github.com/coder/envbuilder/", - expected: "/workspaces/envbuilder", + name: "trailing no .git", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder/", + expected: "/workspaces/envbuilder", }, { - name: "fragment", - gitURL: "https://github.com/coder/envbuilder.git#feature-branch", - expected: "/workspaces/envbuilder", + name: "fragment", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git#feature-branch", + expected: "/workspaces/envbuilder", }, { - name: "fragment-trailing", - gitURL: "https://github.com/coder/envbuilder.git/#refs/heads/feature-branch", - expected: "/workspaces/envbuilder", + name: "fragment-trailing", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git/#refs/heads/feature-branch", + expected: "/workspaces/envbuilder", }, { - name: "fragment-trailing no .git", - gitURL: "https://github.com/coder/envbuilder/#refs/heads/feature-branch", - expected: "/workspaces/envbuilder", + name: "fragment-trailing no .git", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/envbuilder/#refs/heads/feature-branch", + expected: "/workspaces/envbuilder", }, { - name: "space", - gitURL: "https://github.com/coder/env%20builder.git", - expected: "/workspaces/env builder", + name: "space", + workspacesFolder: "/workspaces", + gitURL: "https://github.com/coder/env%20builder.git", + expected: "/workspaces/env builder", }, { - name: "Unix path", - gitURL: "/repo", - expected: "/workspaces/repo", + name: "Unix path", + workspacesFolder: "/workspaces", + gitURL: "/repo", + expected: "/workspaces/repo", }, { - name: "Unix subpath", - gitURL: "/path/to/repo", - expected: "/workspaces/repo", + name: "Unix subpath", + workspacesFolder: "/workspaces", + gitURL: "/path/to/repo", + expected: "/workspaces/repo", }, { - name: "empty", - gitURL: "", - expected: options.EmptyWorkspaceDir, + name: "empty", + workspacesFolder: "/workspaces", + gitURL: "", + expected: "/workspaces/empty", + }, + { + name: "non default workspaces folder", + workspacesFolder: "/foo", + gitURL: "https://github.com/coder/envbuilder.git", + expected: "/foo/envbuilder", + }, + { + name: "non default workspaces folder empty git URL", + workspacesFolder: "/foo", + gitURL: "", + expected: "/foo/empty", }, } for _, tt := range successTests { t.Run(tt.name, func(t *testing.T) { - dir := options.DefaultWorkspaceFolder(tt.gitURL) + dir := options.DefaultWorkspaceFolder(tt.workspacesFolder, tt.gitURL) require.Equal(t, tt.expected, dir) }) } @@ -125,8 +152,8 @@ func TestDefaultWorkspaceFolder(t *testing.T) { } for _, tt := range invalidTests { t.Run(tt.name, func(t *testing.T) { - dir := options.DefaultWorkspaceFolder(tt.invalidURL) - require.Equal(t, options.EmptyWorkspaceDir, dir) + dir := options.DefaultWorkspaceFolder("/workspaces", tt.invalidURL) + require.Equal(t, "/workspaces/empty", dir) }) } } @@ -135,14 +162,15 @@ func TestOptions_SetDefaults(t *testing.T) { t.Parallel() expected := options.Options{ - InitScript: "sleep infinity", - InitCommand: "/bin/sh", - IgnorePaths: []string{"/var/run", "/product_uuid", "/product_name"}, - Filesystem: chmodfs.New(osfs.New("/")), - GitURL: "", - WorkspaceFolder: options.EmptyWorkspaceDir, - WorkingDirBase: "/.envbuilder", - BinaryPath: "/.envbuilder/bin/envbuilder", + InitScript: "sleep infinity", + InitCommand: "/bin/sh", + IgnorePaths: []string{"/var/run", "/product_uuid", "/product_name"}, + Filesystem: chmodfs.New(osfs.New("/")), + GitURL: "", + WorkspacesFolder: "/workspaces", + WorkspaceFolder: "/workspaces/empty", + WorkingDirBase: "/.envbuilder", + BinaryPath: "/.envbuilder/bin/envbuilder", } var actual options.Options diff --git a/options/options.go b/options/options.go index 01ed510d..1f72b775 100644 --- a/options/options.go +++ b/options/options.go @@ -117,8 +117,12 @@ type Options struct { // GitHTTPProxyURL is the URL for the HTTP proxy. This is optional. GitHTTPProxyURL string // WorkspaceFolder is the path to the workspace folder that will be built. - // This is optional. + // This is optional. Defaults to `[workspaces folder]/[name]` where name is + // the name of the repository or "empty". WorkspaceFolder string + // WorkspacesFolder is the path under which workspaces will be placed when + // workspace folder option is not given. + WorkspacesFolder string // SSLCertBase64 is the content of an SSL cert file. This is useful for // self-signed certificates. SSLCertBase64 string @@ -395,8 +399,17 @@ func (o *Options) CLI() serpent.OptionSet { Flag: "workspace-folder", Env: WithEnvPrefix("WORKSPACE_FOLDER"), Value: serpent.StringOf(&o.WorkspaceFolder), - Description: "The path to the workspace folder that will " + - "be built. This is optional.", + Description: "The path to the workspace folder that will be built. " + + "This is optional. Defaults to `[workspaces folder]/[name]` where " + + "name is the name of the repository or `empty`.", + }, + { + Flag: "workspaces-folder", + Env: WithEnvPrefix("WORKSPACES_FOLDER"), + Value: serpent.StringOf(&o.WorkspacesFolder), + Default: "/workspaces", + Description: "The path under which workspaces will be placed when " + + "workspace folder option is not given.", }, { Flag: "ssl-cert-base64", diff --git a/options/testdata/options.golden b/options/testdata/options.golden index 840b2340..ee2ac7c7 100644 --- a/options/testdata/options.golden +++ b/options/testdata/options.golden @@ -178,4 +178,10 @@ OPTIONS: --workspace-folder string, $ENVBUILDER_WORKSPACE_FOLDER The path to the workspace folder that will be built. This is optional. + Defaults to `[workspaces folder]/[name]` where name is the name of the + repository or `empty`. + + --workspaces-folder string, $ENVBUILDER_WORKSPACES_FOLDER (default: /workspaces) + The path under which workspaces will be placed when workspace folder + option is not given. From 23af8085103179aa34b3dfebd94868a04fba23fb Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Tue, 5 Nov 2024 16:29:57 +0000 Subject: [PATCH 2/4] base dir --- docs/env-variables.md | 4 +- options/defaults.go | 6 +- options/defaults_test.go | 140 ++++++++++++++++---------------- options/options.go | 14 ++-- options/testdata/options.golden | 12 +-- 5 files changed, 88 insertions(+), 88 deletions(-) diff --git a/docs/env-variables.md b/docs/env-variables.md index 6a98e1d9..fbf0d921 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -31,8 +31,8 @@ | `--git-ssh-private-key-path` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH` | | Path to an SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_BASE64 cannot be set. | | `--git-ssh-private-key-base64` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64` | | Base64 encoded SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_PATH cannot be set. | | `--git-http-proxy-url` | `ENVBUILDER_GIT_HTTP_PROXY_URL` | | The URL for the HTTP proxy. This is optional. | -| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. Defaults to `[workspaces folder]/[name]` where name is the name of the repository or `empty`. | -| `--workspaces-folder` | `ENVBUILDER_WORKSPACES_FOLDER` | `/workspaces` | The path under which workspaces will be placed when workspace folder option is not given. | +| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. Defaults to `[workspace base dir]/[name]` where name is the name of the repository or `empty`. | +| `--workspace-base-dir` | `ENVBUILDER_WORKSPACE_BASE_DIR` | `/workspaces` | The path under which workspaces will be placed when workspace folder option is not given. | | `--ssl-cert-base64` | `ENVBUILDER_SSL_CERT_BASE64` | | The content of an SSL cert file. This is useful for self-signed certificates. | | `--export-env-file` | `ENVBUILDER_EXPORT_ENV_FILE` | | Optional file path to a .env file where envbuilder will dump environment variables from devcontainer.json and the built container image. | | `--post-start-script-path` | `ENVBUILDER_POST_START_SCRIPT_PATH` | | The path to a script that will be created by envbuilder based on the postStartCommand in devcontainer.json, if any is specified (otherwise the script is not created). If this is set, the specified InitCommand should check for the presence of this script and execute it after successful startup. | diff --git a/options/defaults.go b/options/defaults.go index 9ee55cd8..ee2543f7 100644 --- a/options/defaults.go +++ b/options/defaults.go @@ -59,11 +59,11 @@ func (o *Options) SetDefaults() { if o.Filesystem == nil { o.Filesystem = chmodfs.New(osfs.New("/")) } - if o.WorkspacesFolder == "" { - o.WorkspacesFolder = "/workspaces" + if o.WorkspaceBaseDir == "" { + o.WorkspaceBaseDir = "/workspaces" } if o.WorkspaceFolder == "" { - o.WorkspaceFolder = DefaultWorkspaceFolder(o.WorkspacesFolder, o.GitURL) + o.WorkspaceFolder = DefaultWorkspaceFolder(o.WorkspaceBaseDir, o.GitURL) } if o.BinaryPath == "" { o.BinaryPath = "/.envbuilder/bin/envbuilder" diff --git a/options/defaults_test.go b/options/defaults_test.go index 646d9397..91dac3bd 100644 --- a/options/defaults_test.go +++ b/options/defaults_test.go @@ -16,111 +16,111 @@ func TestDefaultWorkspaceFolder(t *testing.T) { t.Parallel() successTests := []struct { - name string - workspacesFolder string - gitURL string - expected string + name string + baseDir string + gitURL string + expected string }{ { - name: "HTTP", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder.git", - expected: "/workspaces/envbuilder", + name: "HTTP", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git", + expected: "/workspaces/envbuilder", }, { - name: "SSH", - workspacesFolder: "/workspaces", - gitURL: "git@github.com:coder/envbuilder.git", - expected: "/workspaces/envbuilder", + name: "SSH", + baseDir: "/workspaces", + gitURL: "git@github.com:coder/envbuilder.git", + expected: "/workspaces/envbuilder", }, { - name: "username and password", - workspacesFolder: "/workspaces", - gitURL: "https://username:password@github.com/coder/envbuilder.git", - expected: "/workspaces/envbuilder", + name: "username and password", + baseDir: "/workspaces", + gitURL: "https://username:password@github.com/coder/envbuilder.git", + expected: "/workspaces/envbuilder", }, { - name: "trailing", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder.git/", - expected: "/workspaces/envbuilder", + name: "trailing", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git/", + expected: "/workspaces/envbuilder", }, { - name: "trailing-x2", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder.git//", - expected: "/workspaces/envbuilder", + name: "trailing-x2", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git//", + expected: "/workspaces/envbuilder", }, { - name: "no .git", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder", - expected: "/workspaces/envbuilder", + name: "no .git", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder", + expected: "/workspaces/envbuilder", }, { - name: "trailing no .git", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder/", - expected: "/workspaces/envbuilder", + name: "trailing no .git", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder/", + expected: "/workspaces/envbuilder", }, { - name: "fragment", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder.git#feature-branch", - expected: "/workspaces/envbuilder", + name: "fragment", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git#feature-branch", + expected: "/workspaces/envbuilder", }, { - name: "fragment-trailing", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder.git/#refs/heads/feature-branch", - expected: "/workspaces/envbuilder", + name: "fragment-trailing", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder.git/#refs/heads/feature-branch", + expected: "/workspaces/envbuilder", }, { - name: "fragment-trailing no .git", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/envbuilder/#refs/heads/feature-branch", - expected: "/workspaces/envbuilder", + name: "fragment-trailing no .git", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/envbuilder/#refs/heads/feature-branch", + expected: "/workspaces/envbuilder", }, { - name: "space", - workspacesFolder: "/workspaces", - gitURL: "https://github.com/coder/env%20builder.git", - expected: "/workspaces/env builder", + name: "space", + baseDir: "/workspaces", + gitURL: "https://github.com/coder/env%20builder.git", + expected: "/workspaces/env builder", }, { - name: "Unix path", - workspacesFolder: "/workspaces", - gitURL: "/repo", - expected: "/workspaces/repo", + name: "Unix path", + baseDir: "/workspaces", + gitURL: "/repo", + expected: "/workspaces/repo", }, { - name: "Unix subpath", - workspacesFolder: "/workspaces", - gitURL: "/path/to/repo", - expected: "/workspaces/repo", + name: "Unix subpath", + baseDir: "/workspaces", + gitURL: "/path/to/repo", + expected: "/workspaces/repo", }, { - name: "empty", - workspacesFolder: "/workspaces", - gitURL: "", - expected: "/workspaces/empty", + name: "empty", + baseDir: "/workspaces", + gitURL: "", + expected: "/workspaces/empty", }, { - name: "non default workspaces folder", - workspacesFolder: "/foo", - gitURL: "https://github.com/coder/envbuilder.git", - expected: "/foo/envbuilder", + name: "non default workspaces folder", + baseDir: "/foo", + gitURL: "https://github.com/coder/envbuilder.git", + expected: "/foo/envbuilder", }, { - name: "non default workspaces folder empty git URL", - workspacesFolder: "/foo", - gitURL: "", - expected: "/foo/empty", + name: "non default workspaces folder empty git URL", + baseDir: "/foo", + gitURL: "", + expected: "/foo/empty", }, } for _, tt := range successTests { t.Run(tt.name, func(t *testing.T) { - dir := options.DefaultWorkspaceFolder(tt.workspacesFolder, tt.gitURL) + dir := options.DefaultWorkspaceFolder(tt.baseDir, tt.gitURL) require.Equal(t, tt.expected, dir) }) } @@ -167,7 +167,7 @@ func TestOptions_SetDefaults(t *testing.T) { IgnorePaths: []string{"/var/run", "/product_uuid", "/product_name"}, Filesystem: chmodfs.New(osfs.New("/")), GitURL: "", - WorkspacesFolder: "/workspaces", + WorkspaceBaseDir: "/workspaces", WorkspaceFolder: "/workspaces/empty", WorkingDirBase: "/.envbuilder", BinaryPath: "/.envbuilder/bin/envbuilder", diff --git a/options/options.go b/options/options.go index 1f72b775..6c77a816 100644 --- a/options/options.go +++ b/options/options.go @@ -117,12 +117,12 @@ type Options struct { // GitHTTPProxyURL is the URL for the HTTP proxy. This is optional. GitHTTPProxyURL string // WorkspaceFolder is the path to the workspace folder that will be built. - // This is optional. Defaults to `[workspaces folder]/[name]` where name is + // This is optional. Defaults to `[workspace base dir]/[name]` where name is // the name of the repository or "empty". WorkspaceFolder string - // WorkspacesFolder is the path under which workspaces will be placed when + // WorkspaceBaseDir is the path under which workspaces will be placed when // workspace folder option is not given. - WorkspacesFolder string + WorkspaceBaseDir string // SSLCertBase64 is the content of an SSL cert file. This is useful for // self-signed certificates. SSLCertBase64 string @@ -400,13 +400,13 @@ func (o *Options) CLI() serpent.OptionSet { Env: WithEnvPrefix("WORKSPACE_FOLDER"), Value: serpent.StringOf(&o.WorkspaceFolder), Description: "The path to the workspace folder that will be built. " + - "This is optional. Defaults to `[workspaces folder]/[name]` where " + + "This is optional. Defaults to `[workspace base dir]/[name]` where " + "name is the name of the repository or `empty`.", }, { - Flag: "workspaces-folder", - Env: WithEnvPrefix("WORKSPACES_FOLDER"), - Value: serpent.StringOf(&o.WorkspacesFolder), + Flag: "workspace-base-dir", + Env: WithEnvPrefix("WORKSPACE_BASE_DIR"), + Value: serpent.StringOf(&o.WorkspaceBaseDir), Default: "/workspaces", Description: "The path under which workspaces will be placed when " + "workspace folder option is not given.", diff --git a/options/testdata/options.golden b/options/testdata/options.golden index ee2ac7c7..114f4e9c 100644 --- a/options/testdata/options.golden +++ b/options/testdata/options.golden @@ -176,12 +176,12 @@ OPTIONS: --verbose bool, $ENVBUILDER_VERBOSE Enable verbose logging. - --workspace-folder string, $ENVBUILDER_WORKSPACE_FOLDER - The path to the workspace folder that will be built. This is optional. - Defaults to `[workspaces folder]/[name]` where name is the name of the - repository or `empty`. - - --workspaces-folder string, $ENVBUILDER_WORKSPACES_FOLDER (default: /workspaces) + --workspace-base-dir string, $ENVBUILDER_WORKSPACE_BASE_DIR (default: /workspaces) The path under which workspaces will be placed when workspace folder option is not given. + --workspace-folder string, $ENVBUILDER_WORKSPACE_FOLDER + The path to the workspace folder that will be built. This is optional. + Defaults to `[workspace base dir]/[name]` where name is the name of + the repository or `empty`. + From 57bf6648af99ea88326c8b1a0b7b27d6f77f0f1f Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Tue, 5 Nov 2024 16:31:41 +0000 Subject: [PATCH 3/4] sort --- docs/env-variables.md | 2 +- options/options.go | 22 +++++++++++----------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/env-variables.md b/docs/env-variables.md index fbf0d921..4035210c 100644 --- a/docs/env-variables.md +++ b/docs/env-variables.md @@ -31,8 +31,8 @@ | `--git-ssh-private-key-path` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_PATH` | | Path to an SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_BASE64 cannot be set. | | `--git-ssh-private-key-base64` | `ENVBUILDER_GIT_SSH_PRIVATE_KEY_BASE64` | | Base64 encoded SSH private key to be used for Git authentication. If this is set, then GIT_SSH_PRIVATE_KEY_PATH cannot be set. | | `--git-http-proxy-url` | `ENVBUILDER_GIT_HTTP_PROXY_URL` | | The URL for the HTTP proxy. This is optional. | -| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. Defaults to `[workspace base dir]/[name]` where name is the name of the repository or `empty`. | | `--workspace-base-dir` | `ENVBUILDER_WORKSPACE_BASE_DIR` | `/workspaces` | The path under which workspaces will be placed when workspace folder option is not given. | +| `--workspace-folder` | `ENVBUILDER_WORKSPACE_FOLDER` | | The path to the workspace folder that will be built. This is optional. Defaults to `[workspace base dir]/[name]` where name is the name of the repository or `empty`. | | `--ssl-cert-base64` | `ENVBUILDER_SSL_CERT_BASE64` | | The content of an SSL cert file. This is useful for self-signed certificates. | | `--export-env-file` | `ENVBUILDER_EXPORT_ENV_FILE` | | Optional file path to a .env file where envbuilder will dump environment variables from devcontainer.json and the built container image. | | `--post-start-script-path` | `ENVBUILDER_POST_START_SCRIPT_PATH` | | The path to a script that will be created by envbuilder based on the postStartCommand in devcontainer.json, if any is specified (otherwise the script is not created). If this is set, the specified InitCommand should check for the presence of this script and execute it after successful startup. | diff --git a/options/options.go b/options/options.go index 6c77a816..cec32b5f 100644 --- a/options/options.go +++ b/options/options.go @@ -116,13 +116,13 @@ type Options struct { GitSSHPrivateKeyBase64 string // GitHTTPProxyURL is the URL for the HTTP proxy. This is optional. GitHTTPProxyURL string + // WorkspaceBaseDir is the path under which workspaces will be placed when + // workspace folder option is not given. + WorkspaceBaseDir string // WorkspaceFolder is the path to the workspace folder that will be built. // This is optional. Defaults to `[workspace base dir]/[name]` where name is // the name of the repository or "empty". WorkspaceFolder string - // WorkspaceBaseDir is the path under which workspaces will be placed when - // workspace folder option is not given. - WorkspaceBaseDir string // SSLCertBase64 is the content of an SSL cert file. This is useful for // self-signed certificates. SSLCertBase64 string @@ -395,14 +395,6 @@ func (o *Options) CLI() serpent.OptionSet { Value: serpent.StringOf(&o.GitHTTPProxyURL), Description: "The URL for the HTTP proxy. This is optional.", }, - { - Flag: "workspace-folder", - Env: WithEnvPrefix("WORKSPACE_FOLDER"), - Value: serpent.StringOf(&o.WorkspaceFolder), - Description: "The path to the workspace folder that will be built. " + - "This is optional. Defaults to `[workspace base dir]/[name]` where " + - "name is the name of the repository or `empty`.", - }, { Flag: "workspace-base-dir", Env: WithEnvPrefix("WORKSPACE_BASE_DIR"), @@ -411,6 +403,14 @@ func (o *Options) CLI() serpent.OptionSet { Description: "The path under which workspaces will be placed when " + "workspace folder option is not given.", }, + { + Flag: "workspace-folder", + Env: WithEnvPrefix("WORKSPACE_FOLDER"), + Value: serpent.StringOf(&o.WorkspaceFolder), + Description: "The path to the workspace folder that will be built. " + + "This is optional. Defaults to `[workspace base dir]/[name]` where " + + "name is the name of the repository or `empty`.", + }, { Flag: "ssl-cert-base64", Env: WithEnvPrefix("SSL_CERT_BASE64"), From ef770496fad586b3701b3ea3c558486b1a701c90 Mon Sep 17 00:00:00 2001 From: Mathias Fredriksson Date: Tue, 5 Nov 2024 16:33:55 +0000 Subject: [PATCH 4/4] test --- integration/integration_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/integration/integration_test.go b/integration/integration_test.go index b70c7398..5c3d820e 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -834,7 +834,7 @@ func TestBuildFromDevcontainerInCustomPath(t *testing.T) { require.Equal(t, "hello", strings.TrimSpace(output)) } -func TestBuildFromCustomWorkspacesFolder(t *testing.T) { +func TestBuildFromCustomWorkspaceBaseDir(t *testing.T) { t.Parallel() // Ensures that a Git repository with a devcontainer.json is cloned and built. @@ -846,7 +846,7 @@ func TestBuildFromCustomWorkspacesFolder(t *testing.T) { ctr, err := runEnvbuilder(t, runOpts{ env: []string{ envbuilderEnv("DOCKERFILE_PATH", "Dockerfile"), - envbuilderEnv("WORKSPACES_FOLDER", "/foo"), + envbuilderEnv("WORKSPACE_BASE_DIR", "/foo"), envbuilderEnv("GIT_URL", srv.URL), }, })