Skip to content

Commit

Permalink
Added initial Dev Container CLI tool
Browse files Browse the repository at this point in the history
  • Loading branch information
Roemer committed Feb 29, 2024
1 parent a82172d commit 563d4f9
Show file tree
Hide file tree
Showing 2 changed files with 243 additions and 20 deletions.
221 changes: 221 additions & 0 deletions gttools/devcontainer_cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package gttools

import (
"os/exec"

"github.com/roemer/gotaskr/execr"
"github.com/roemer/gotaskr/goext"
)

// This tool allows interacting with the Dev Container CLI.
type DevContainerCliTool struct {
}

func CreateDevContainerCliTool() *DevContainerCliTool {
return &DevContainerCliTool{}
}

type DevContainerCliBuildSettings struct {
ToolSettingsBase
// Host path to a directory that is intended to be persisted and share state between sessions.
UserDataFolder string
// Docker CLI path.
DockerPath string
// Docker Compose CLI path.
DockerComposePath string
// Workspace folder path. The devcontainer.json will be looked up relative to this path.
WorkspaceFolder string
// devcontainer.json path.
Config string
// Log level.
LogLevel DevContainerCliLogLevel
// Log format.
LogFormat DevContainerCliLogFormat
// Builds the image with `--no-cache`.
NoCache *bool
// Image name.
ImageName string
// Additional image to use as potential layer cache.
CacheFrom string
// A destination of buildx cache.
CacheTo string
// Control whether BuildKit should be used.
Buildkit DevContainerCliBuildkit
// Set target platforms.
Platform string
// Push to a container registry.
Push *bool
// Overrides the default behavior to load built images into the local docker registry. Valid options are the same ones provided to the --output option of docker buildx build.
Output string
// Additional features to apply to the dev container (JSON as per "features" section in devcontainer.json).
AdditionalFeatures string
}

func (tool *DevContainerCliTool) Build(settings *DevContainerCliBuildSettings) error {
args := []string{
"build",
}

args = addString(args, settings.UserDataFolder, addSettings{prependElements: []string{"--user-data-folder"}})
args = addString(args, settings.DockerPath, addSettings{prependElements: []string{"--docker-path"}})
args = addString(args, settings.DockerComposePath, addSettings{prependElements: []string{"--docker-compose-path"}})
args = addString(args, settings.WorkspaceFolder, addSettings{prependElements: []string{"--workspace-folder"}})
args = addString(args, settings.Config, addSettings{prependElements: []string{"--config"}})
args = addString(args, string(settings.LogLevel), addSettings{prependElements: []string{"--log-level"}})
args = addString(args, string(settings.LogFormat), addSettings{prependElements: []string{"--log-format"}})
args = addBoolean(args, settings.NoCache, addSettings{prependElements: []string{"--no-cache"}})
args = addString(args, settings.ImageName, addSettings{prependElements: []string{"--image-name"}})
args = addString(args, settings.CacheFrom, addSettings{prependElements: []string{"--cache-from"}})
args = addString(args, settings.CacheTo, addSettings{prependElements: []string{"--cache-to"}})
args = addString(args, string(settings.Buildkit), addSettings{prependElements: []string{"--buildkit"}})
args = addString(args, settings.Platform, addSettings{prependElements: []string{"--platform"}})
args = addBoolean(args, settings.Push, addSettings{prependElements: []string{"--push"}})
args = addString(args, settings.Output, addSettings{prependElements: []string{"--output"}})
args = addString(args, settings.AdditionalFeatures, addSettings{prependElements: []string{"--additional-features"}})

args = append(args, settings.CustomArguments...)
cmd := exec.Command("devcontainer", goext.RemoveEmpty(args)...)
cmd.Dir = settings.WorkingDirectory
return execr.RunCommand(settings.OutputToConsole, cmd)
}

type DevContainerCliFeaturesTestSettings struct {
ToolSettingsBase
// Path to folder containing 'src' and 'test' sub-folders.
ProjectFolder string
// Feature(s) to test .
Features []string
// Filter current tests to only run scenarios containing this string.
Filter string
// Run only scenario tests under 'tests/_global'
GlobalScenariosOnly *bool
// Skip all 'scenario' style tests.
SkipScenarios *bool
// Skip all 'autogenerated' style tests (test.sh)
SkipAutogenerated *bool
// Skip all 'duplicate' style tests (duplicate.sh).
SkipDuplicated *bool
// Allow an element of randomness in test cases.
PermitRandomization *bool
// Base Image. Not used for scenarios.
BaseImage string
// Remote user. Not used for scenarios.
RemoteUser string
// Log level.
LogLevel DevContainerCliLogLevel
// Do not remove test containers after running tests.
PreserveTestContainers *bool
// Quiets output.
Quiet *bool
}

func (tool *DevContainerCliTool) FeaturesTest(settings *DevContainerCliFeaturesTestSettings) error {
args := []string{
"features",
"test",
}

args = addString(args, settings.ProjectFolder, addSettings{prependElements: []string{"--project-folder"}})
args = addStringList(args, settings.Features, " ", addSettings{prependElements: []string{"--features"}})
args = addString(args, settings.Filter, addSettings{prependElements: []string{"--filter"}})
args = addBoolean(args, settings.GlobalScenariosOnly, addSettings{prependElements: []string{"--global-scenarios-only"}})
args = addBoolean(args, settings.SkipScenarios, addSettings{prependElements: []string{"--skip-scenarios"}})
args = addBoolean(args, settings.SkipAutogenerated, addSettings{prependElements: []string{"--skip-autogenerated"}})
args = addBoolean(args, settings.SkipDuplicated, addSettings{prependElements: []string{"--skip-duplicated"}})
args = addBoolean(args, settings.PermitRandomization, addSettings{prependElements: []string{"--permit-randomization"}})
args = addString(args, settings.BaseImage, addSettings{prependElements: []string{"--base-image"}})
args = addString(args, settings.RemoteUser, addSettings{prependElements: []string{"--remote-user"}})
args = addString(args, string(settings.LogLevel), addSettings{prependElements: []string{"--log-level"}})
args = addBoolean(args, settings.PreserveTestContainers, addSettings{prependElements: []string{"--preserve-test-containers"}})
args = addBoolean(args, settings.Quiet, addSettings{prependElements: []string{"--quiet"}})

args = append(args, settings.CustomArguments...)
cmd := exec.Command("devcontainer", goext.RemoveEmpty(args)...)
cmd.Dir = settings.WorkingDirectory
return execr.RunCommand(settings.OutputToConsole, cmd)
}

type DevContainerCliFeaturesPackageSettings struct {
ToolSettingsBase
// Path to a feature or folder of features to package.
Target string
// Path to output directory. Will create directories as needed.
OutputFolder string
// Automatically delete previous output directory before packaging.
ForceCleanOutputFolder *bool
// Log level.
LogLevel DevContainerCliLogLevel
}

func (tool *DevContainerCliTool) FeaturesPackage(settings *DevContainerCliFeaturesPackageSettings) error {
args := []string{
"features",
"package",
settings.Target,
}

args = addString(args, settings.OutputFolder, addSettings{prependElements: []string{"--output-folder"}})
args = addBoolean(args, settings.ForceCleanOutputFolder, addSettings{prependElements: []string{"--force-clean-output-folder"}})
args = addString(args, string(settings.LogLevel), addSettings{prependElements: []string{"--log-level"}})

args = append(args, settings.CustomArguments...)
cmd := exec.Command("devcontainer", goext.RemoveEmpty(args)...)
cmd.Dir = settings.WorkingDirectory
return execr.RunCommand(settings.OutputToConsole, cmd)
}

type DevContainerCliFeaturesPublishSettings struct {
ToolSettingsBase
// Path to a feature or folder of features to publish.
Target string
// Name of the OCI registry.
Registry string
// Unique indentifier for the collection of features.
Namespace string
// Log level.
LogLevel DevContainerCliLogLevel
}

func (tool *DevContainerCliTool) FeaturesPublish(settings *DevContainerCliFeaturesPublishSettings) error {
args := []string{
"features",
"publish",
settings.Target,
}

args = addString(args, settings.Registry, addSettings{prependElements: []string{"--registry"}})
args = addString(args, settings.Namespace, addSettings{prependElements: []string{"--namespace"}})
args = addString(args, string(settings.LogLevel), addSettings{prependElements: []string{"--log-level"}})

args = append(args, settings.CustomArguments...)
cmd := exec.Command("devcontainer", goext.RemoveEmpty(args)...)
cmd.Dir = settings.WorkingDirectory
return execr.RunCommand(settings.OutputToConsole, cmd)
}

////////// Types

type DevContainerCliLogLevel string

const (
DEV_CONTAINER_CLI_LOG_LEVEL_DEFAULT DevContainerCliLogLevel = ""
DEV_CONTAINER_CLI_LOG_LEVEL_INFO DevContainerCliLogLevel = "info"
DEV_CONTAINER_CLI_LOG_LEVEL_DEBUG DevContainerCliLogLevel = "debug"
DEV_CONTAINER_CLI_LOG_LEVEL_TRACE DevContainerCliLogLevel = "trace"
)

type DevContainerCliLogFormat string

const (
DEV_CONTAINER_CLI_LOG_FORMAT_DEFAULT DevContainerCliLogFormat = ""
DEV_CONTAINER_CLI_LOG_FORMAT_TEXT DevContainerCliLogFormat = "text"
DEV_CONTAINER_CLI_LOG_FORMAT_JSON DevContainerCliLogFormat = "json"
)

type DevContainerCliBuildkit string

const (
DEV_CONTAINER_CLI_BUILDKIT_DEFAULT DevContainerCliBuildkit = ""
DEV_CONTAINER_CLI_BUILDKIT_AUTO DevContainerCliBuildkit = "auto"
DEV_CONTAINER_CLI_BUILDKIT_NEVER DevContainerCliBuildkit = "never"
)
42 changes: 22 additions & 20 deletions gttools/gttools.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,33 @@ import (

// ToolsClient provides typed access to the different tools.
type ToolsClient struct {
Cypress *CypressTool
Docker *DockerTool
DotNet *DotNetTool
EsLint *EsLintTool
Flyway *FlywayTool
GitLab *GitLabTool
JFrog *JFrogTool
Mvn *MvnTool
Npm *NpmTool
Nx *NxTool
Cypress *CypressTool
DevContainerCli *DevContainerCliTool
Docker *DockerTool
DotNet *DotNetTool
EsLint *EsLintTool
Flyway *FlywayTool
GitLab *GitLabTool
JFrog *JFrogTool
Mvn *MvnTool
Npm *NpmTool
Nx *NxTool
}

// CreateToolsClient creates a new client to access the different tools.
func CreateToolsClient() *ToolsClient {
return &ToolsClient{
Cypress: CreateCypressTool(),
Docker: CreateDockerTool(),
DotNet: CreateDotNetTool(),
EsLint: CreateEsLintTool(),
Flyway: CreateFlywayTool(),
GitLab: CreateGitLabTool(),
JFrog: CreateJFrogTool(),
Mvn: CreateMvnTool(),
Npm: CreateNpmTool(),
Nx: CreateNxTool(),
Cypress: CreateCypressTool(),
DevContainerCli: CreateDevContainerCliTool(),
Docker: CreateDockerTool(),
DotNet: CreateDotNetTool(),
EsLint: CreateEsLintTool(),
Flyway: CreateFlywayTool(),
GitLab: CreateGitLabTool(),
JFrog: CreateJFrogTool(),
Mvn: CreateMvnTool(),
Npm: CreateNpmTool(),
Nx: CreateNxTool(),
}
}

Expand Down

0 comments on commit 563d4f9

Please sign in to comment.