Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ INSTALL_DIR ?= $(or $(dir $(shell which $(BINARY_NAME) 2>/dev/null)),/usr/local/
deps: work
go mod tidy

build: deps
build:
go build -o $(BINARY_NAME) .

install: work build
Expand Down
71 changes: 0 additions & 71 deletions cmd/backup.go

This file was deleted.

19 changes: 12 additions & 7 deletions cmd/drush.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package cmd
import (
"fmt"

"github.com/kballard/go-shellquote"
"github.com/libops/sitectl/pkg/docker"
"github.com/spf13/cobra"
)

Expand All @@ -30,17 +30,22 @@ Examples:
sitectl drush sqlq "SHOW TABLES" # Run SQL query
sitectl drush --context prod status # Check status on prod context`,
RunE: func(cmd *cobra.Command, args []string) error {
filteredArgs, _, cli, containerName, err := getDrupalContainer(cmd, args)
filteredArgs, ctx, cli, containerName, err := getDrupalContainer(cmd, args)
if err != nil {
return err
}
defer cli.Close()

// Build the drush command with arguments
drushCmd := []string{"bash", "-c", fmt.Sprintf("drush %s", shellquote.Join(filteredArgs...))}

// Execute the command interactively using SDK helper
exitCode, err := cli.ExecInteractive(cmd.Context(), containerName, drushCmd)
drushArgs := append([]string{"drush"}, filteredArgs...)
exitCode, err := cli.Exec(cmd.Context(), docker.ExecOptions{
Container: containerName,
Cmd: drushArgs,
WorkingDir: ctx.EffectiveDrupalContainerRoot(),
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
Tty: true,
})
if err != nil {
return err
}
Expand Down
43 changes: 12 additions & 31 deletions cmd/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"strings"

"charm.land/lipgloss/v2"
"github.com/kballard/go-shellquote"
"github.com/libops/sitectl/pkg/config"
"github.com/libops/sitectl/pkg/docker"
"github.com/libops/sitectl/pkg/plugin"
Expand Down Expand Up @@ -110,7 +109,7 @@ func init() {
componentExtensionCmd.AddCommand(componentExtensionReconcileCmd)
componentExtensionCmd.AddCommand(componentExtensionSetCmd)

debugExtensionCmd.Flags().StringVar(&drupalRootfsPath, "drupal-rootfs", "drupal/rootfs/var/www/drupal", "Drupal rootfs path override")
debugExtensionCmd.Flags().StringVar(&drupalRootfsPath, "drupal-rootfs", "", "Drupal rootfs path override")
}

func renderDrupalDebug(runCtx context.Context) (string, error) {
Expand All @@ -130,8 +129,12 @@ func renderDrupalDebug(runCtx context.Context) (string, error) {
}
defer files.Close()

slog.Debug("resolving drupal root", "plugin", "drupal", "rootfs", drupalRootfsPath)
drupalRoot := resolveDrupalRoot(files, ctx.ProjectDir, drupalRootfsPath)
rootfs := strings.TrimSpace(drupalRootfsPath)
if rootfs == "" {
rootfs = ctx.EffectiveDrupalRootfs()
}
slog.Debug("resolving drupal root", "plugin", "drupal", "rootfs", rootfs)
drupalRoot := ctx.ResolveProjectPath(rootfs)
slog.Debug("resolved drupal root", "plugin", "drupal", "drupal_root", drupalRoot)
configDir := filepath.Join(drupalRoot, "config", "sync")
body := []string{
Expand Down Expand Up @@ -182,14 +185,14 @@ func renderDrupalDebug(runCtx context.Context) (string, error) {
}

func renderCachePageSummary(runCtx context.Context) (string, error) {
_, cli, containerName, err := getDrupalContainerForSDK(runCtx)
ctx, cli, containerName, err := getDrupalContainerForSDK(runCtx)
if err != nil {
return "", err
}
defer cli.Close()

query := "SELECT COALESCE(data_length + index_length, 0) FROM information_schema.TABLES WHERE table_schema = DATABASE() AND table_name = 'cache_page';"
output, err := execDrupalCommandCapture(runCtx, cli, containerName, []string{"drush", "sql:query", query, "--extra=--batch", "--extra=--skip-column-names"})
output, err := execDrupalCommandCapture(runCtx, cli, containerName, ctx.EffectiveDrupalContainerRoot(), []string{"drush", "sql:query", query, "--extra=--batch", "--extra=--skip-column-names"})
if err != nil {
return "", err
}
Expand Down Expand Up @@ -234,17 +237,15 @@ func getDrupalContainerForSDK(runCtx context.Context) (ctx *config.Context, cli
return ctx, cli, containerName, nil
}

func execDrupalCommandCapture(runCtx context.Context, cli *docker.DockerClient, containerName string, cmd []string) (string, error) {
func execDrupalCommandCapture(runCtx context.Context, cli *docker.DockerClient, containerName, containerRoot string, cmd []string) (string, error) {
slog.Debug(strings.Join(cmd, " "), "plugin", "drupal", "container", containerName)
var stdout bytes.Buffer
var stderr bytes.Buffer

wrappedCmd := []string{"bash", "-lc", fmt.Sprintf("cd /var/www/drupal && %s", shellquote.Join(cmd...))}

exitCode, err := cli.Exec(runCtx, docker.ExecOptions{
Container: containerName,
Cmd: wrappedCmd,
WorkingDir: "/var/www/drupal",
Cmd: cmd,
WorkingDir: containerRoot,
AttachStdout: true,
AttachStderr: true,
Stdout: &stdout,
Expand Down Expand Up @@ -291,26 +292,6 @@ func humanBytes(size int64) string {
return fmt.Sprintf("%.1f%ciB", float64(size)/float64(div), "KMGTPE"[exp])
}

func resolveDrupalRoot(files *plugin.FileAccessor, projectDir, drupalRootPath string) string {
candidates := []string{}
if trimmed := strings.TrimSpace(drupalRootPath); trimmed != "" {
if filepath.IsAbs(trimmed) {
candidates = append(candidates, filepath.Clean(trimmed))
} else {
candidates = append(candidates, filepath.Join(projectDir, trimmed))
}
}
if strings.TrimSpace(projectDir) != "" {
candidates = append(candidates, projectDir)
}
for _, candidate := range candidates {
if _, err := files.ReadFile(filepath.Join(candidate, "config", "sync", "core.extension.yml")); err == nil {
return candidate
}
}
return ""
}

func readCoreExtension(runCtx context.Context, files *plugin.FileAccessor, path string) ([]string, []string, error) {
data, err := files.ReadFileContext(runCtx, path)
if err != nil {
Expand Down
33 changes: 7 additions & 26 deletions cmd/extensions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func TestReadCoreExtensionMissingFileReturnsNilSlices(t *testing.T) {
}
}

func TestResolveDrupalRootFindsConfiguredRootfs(t *testing.T) {
func TestDrupalRootUsesConfiguredRootfs(t *testing.T) {
projectDir := t.TempDir()
drupalRoot := filepath.Join(projectDir, "drupal", "rootfs", "var", "www", "drupal")
configDir := filepath.Join(drupalRoot, "config", "sync")
Expand All @@ -81,37 +81,18 @@ func TestResolveDrupalRootFindsConfiguredRootfs(t *testing.T) {
t.Fatalf("WriteFile() error = %v", err)
}

files, err := plugin.NewFileAccessor(&config.Context{DockerHostType: config.ContextLocal})
if err != nil {
t.Fatalf("NewFileAccessor() error = %v", err)
}
defer files.Close()

got := resolveDrupalRoot(files, projectDir, "drupal/rootfs/var/www/drupal")
got := (&config.Context{ProjectDir: projectDir, DrupalRootfs: "drupal/rootfs/var/www/drupal"}).ResolveProjectPath((&config.Context{ProjectDir: projectDir, DrupalRootfs: "drupal/rootfs/var/www/drupal"}).EffectiveDrupalRootfs())
if got != drupalRoot {
t.Fatalf("resolveDrupalRoot() = %q, want %q", got, drupalRoot)
t.Fatalf("drupal root = %q, want %q", got, drupalRoot)
}
}

func TestResolveDrupalRootFallsBackToProjectDir(t *testing.T) {
func TestDrupalRootUsesProjectDirWhenConfigured(t *testing.T) {
projectDir := t.TempDir()
configDir := filepath.Join(projectDir, "config", "sync")
if err := os.MkdirAll(configDir, 0o755); err != nil {
t.Fatalf("MkdirAll() error = %v", err)
}
if err := os.WriteFile(filepath.Join(configDir, "core.extension.yml"), []byte("module: {}\ntheme: {}\n"), 0o644); err != nil {
t.Fatalf("WriteFile() error = %v", err)
}

files, err := plugin.NewFileAccessor(&config.Context{DockerHostType: config.ContextLocal})
if err != nil {
t.Fatalf("NewFileAccessor() error = %v", err)
}
defer files.Close()

got := resolveDrupalRoot(files, projectDir, "drupal/rootfs/var/www/drupal")
ctx := &config.Context{ProjectDir: projectDir, DrupalRootfs: "."}
got := ctx.ResolveProjectPath(ctx.EffectiveDrupalRootfs())
if got != projectDir {
t.Fatalf("resolveDrupalRoot() = %q, want %q", got, projectDir)
t.Fatalf("drupal root = %q, want %q", got, projectDir)
}
}

Expand Down
7 changes: 4 additions & 3 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
pluginjobs "github.com/libops/sitectl-drupal/pkg/jobs"
"github.com/libops/sitectl/pkg/plugin"
)

Expand All @@ -11,16 +12,16 @@ var (

func init() {
loginCmd.Flags().Uint("uid", 1, "Drupal user ID to provide a direct login link for")

backupCmd.Flags().StringVarP(drupalServiceName, "drupal-service", "d", "drupal", "The name of the drupal service in docker compose")
}

// RegisterCommands registers all drupal commands with the plugin SDK
func RegisterCommands(s *plugin.SDK) {
sdk = s
sdk.AddCommand(backupCmd)
pluginjobs.Register(s)
sdk.AddCommand(sdk.GetMetadataCommand())
sdk.AddCommand(componentExtensionCmd)
sdk.AddCommand(debugExtensionCmd)
sdk.AddCommand(drushCmd)
sdk.AddCommand(loginCmd)
sdk.AddCommand(syncCmd)
}
Loading
Loading