Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
070320f
feat: start abstracting executors
shyim Mar 3, 2026
52ab012
feat: enhance executor initialization and add compatibility date checks
shyim Mar 3, 2026
86fd8b9
fix: remove duplicate import of os/exec in project.go
shyim Mar 3, 2026
c9e3af4
feat: devui
shyim Mar 6, 2026
00ba517
refactor
shyim Mar 6, 2026
2c7a5f7
feat: enhance devtui with improved layout and styling, remove obsolet…
shyim Mar 6, 2026
1731368
feat: set default username and improve style rendering in devtui
shyim Mar 6, 2026
1e23377
feat: implement WithEnv method for executors to manage environment va…
shyim Mar 6, 2026
efc7106
Merge remote-tracking branch 'origin/main' into feat/dev-mode
shyim Mar 9, 2026
c9ac071
feat: Add compatibility check for development mode based on compatibi…
shyim Mar 10, 2026
e82d397
feat: Adjust overlay rendering and footer positioning for improved UI…
shyim Mar 10, 2026
8a312be
feat: Enhance rendering functions for improved layout and padding in …
shyim Mar 10, 2026
82344d1
Merge remote-tracking branch 'origin/main' into feat/dev-mode
shyim Mar 10, 2026
fb245bc
feat: let the cli manage compose file
shyim Mar 10, 2026
858ae7d
feat: update compose file header to include documentation link
shyim Mar 10, 2026
a834d59
feat: refactor package fetching methods for improved clarity and cons…
shyim Mar 10, 2026
8eb8ab7
feat: simplify comments in executor and config files for clarity
shyim Mar 10, 2026
18ce915
feat: remove redundant comments for improved code clarity
shyim Mar 10, 2026
d7f336f
feat: remove unnecessary whitespace in project_create.go
shyim Mar 10, 2026
e4f605a
feat: add shopware PaaS application template and update command flags
shyim Mar 11, 2026
20525ea
feat: make overlay buffer dynamic based on terminal height
shyim Mar 12, 2026
5700198
feat: enhance Docker configuration with PHP and Node version options
shyim Mar 16, 2026
bfe3ed1
Merge remote-tracking branch 'origin/main' into feat/dev-mode
shyim Mar 16, 2026
773b82e
feat: start to integrate executor
shyim Mar 18, 2026
043ae8e
Merge remote-tracking branch 'origin/main' into feat/dev-mode
shyim Mar 19, 2026
700349d
refactor(extension): update InstallNodeModulesOfConfigs to use AssetB…
shyim Mar 20, 2026
c4a697e
Refactor TUI components for improved readability and maintainability
shyim Mar 20, 2026
ee8e2c8
feat(command-palette): implement command palette functionality and ke…
shyim Mar 20, 2026
4a0ac3c
refactor(devtui): split model.go and reduce code duplication
shyim Mar 20, 2026
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 cmd/extension/extension_admin_watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ var extensionAdminWatchCmd = &cobra.Command{
return fmt.Errorf("found nothing to compile")
}

if _, err := extension.InstallNodeModulesOfConfigs(cmd.Context(), cfgs, false); err != nil {
if _, err := extension.InstallNodeModulesOfConfigs(cmd.Context(), cfgs, extension.AssetBuildConfig{}); err != nil {
return err
}

Expand Down
20 changes: 9 additions & 11 deletions cmd/project/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"github.com/shopware/shopware-cli/internal/extension"
"github.com/shopware/shopware-cli/internal/mjml"
"github.com/shopware/shopware-cli/internal/packagist"
"github.com/shopware/shopware-cli/internal/phpexec"
"github.com/shopware/shopware-cli/internal/shop"
"github.com/shopware/shopware-cli/logging"
)
Expand Down Expand Up @@ -62,6 +61,11 @@ var projectCI = &cobra.Command{
// Remove annoying cache invalidation errors while asset install
_ = os.Setenv("SHOPWARE_SKIP_ASSET_INSTALL_CACHE_INVALIDATION", "1")

cmdExecutor, err := resolveExecutor(cmd, args[0])
if err != nil {
return err
}

shopCfg, err := shop.ReadConfig(cmd.Context(), projectConfigPath, true)
if err != nil {
return err
Expand Down Expand Up @@ -99,8 +103,7 @@ var projectCI = &cobra.Command{

composerInstallSection := ci.Default.Section(cmd.Context(), "Composer Installation")

composer := phpexec.ComposerCommand(cmd.Context(), composerFlags...)
composer.Dir = args[0]
composer := cmdExecutor.ComposerCommand(cmd.Context(), composerFlags...)
composer.Stdin = os.Stdin
composer.Stdout = os.Stdout
composer.Stderr = os.Stderr
Expand Down Expand Up @@ -152,6 +155,7 @@ var projectCI = &cobra.Command{
ForceExtensionBuild: convertForceExtensionBuild(shopCfg.Build.ForceExtensionBuild),
ForceAdminBuild: shopCfg.Build.ForceAdminBuild,
KeepNodeModules: shopCfg.Build.KeepNodeModules,
Executor: cmdExecutor,
}

if shopCfg.Build.Hooks != nil && len(shopCfg.Build.Hooks.PreAssets) > 0 {
Expand Down Expand Up @@ -215,7 +219,7 @@ var projectCI = &cobra.Command{

warumupSection := ci.Default.Section(cmd.Context(), "Warming up container cache")

if err := runTransparentCommand(phpexec.PHPCommand(cmd.Context(), path.Join(args[0], "bin", "ci"), "--version")); err != nil { //nolint: gosec
if err := runTransparentCommand(cmdExecutor.PHPCommand(cmd.Context(), path.Join(args[0], "bin", "ci"), "--version")); err != nil { //nolint: gosec
return fmt.Errorf("failed to warmup container cache (php bin/ci --version): %w", err)
}

Expand All @@ -230,7 +234,7 @@ var projectCI = &cobra.Command{
}
}

if err := runTransparentCommand(phpexec.PHPCommand(cmd.Context(), path.Join(args[0], "bin", "ci"), "asset:install")); err != nil { //nolint: gosec
if err := runTransparentCommand(cmdExecutor.PHPCommand(cmd.Context(), path.Join(args[0], "bin", "ci"), "asset:install")); err != nil { //nolint: gosec
return fmt.Errorf("failed to install assets (php bin/ci asset:install): %w", err)
}
}
Expand Down Expand Up @@ -344,12 +348,6 @@ func init() {
projectCI.PersistentFlags().Bool("with-dev-dependencies", false, "Install dev dependencies")
}

func commandWithRoot(cmd *exec.Cmd, root string) *exec.Cmd {
cmd.Dir = root

return cmd
}

func runTransparentCommand(cmd *exec.Cmd) error {
cmd.Stdin = os.Stdin
cmd.Stdout = os.Stdout
Expand Down
23 changes: 23 additions & 0 deletions cmd/project/executor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package project

import (
"github.com/spf13/cobra"

"github.com/shopware/shopware-cli/internal/executor"
"github.com/shopware/shopware-cli/internal/shop"
)

// resolveExecutor returns the Executor for the current environment.
func resolveExecutor(cmd *cobra.Command, projectRoot string) (executor.Executor, error) {
cfg, err := shop.ReadConfig(cmd.Context(), projectConfigPath, true)
if err != nil {
return nil, err
}

envCfg, err := cfg.ResolveEnvironment(environmentName)
if err != nil {
return nil, err
}

return executor.New(projectRoot, envCfg, cfg)
}
30 changes: 25 additions & 5 deletions cmd/project/platform.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import (
"github.com/spf13/cobra"

"github.com/shopware/shopware-cli/internal/asset"
"github.com/shopware/shopware-cli/internal/executor"
"github.com/shopware/shopware-cli/internal/extension"
"github.com/shopware/shopware-cli/internal/phpexec"
"github.com/shopware/shopware-cli/internal/shop"
"github.com/shopware/shopware-cli/logging"
)
Expand Down Expand Up @@ -64,18 +64,33 @@ func findClosestShopwareProject() (string, error) {
return "", fmt.Errorf("cannot find Shopware project in current directory")
}

func filterAndWritePluginJson(cmd *cobra.Command, projectRoot string, shopCfg *shop.Config) error {
func filterAndWritePluginJson(cmd *cobra.Command, projectRoot string, shopCfg *shop.Config, cmdExecutor executor.Executor) error {
sources, err := filterAndGetSources(cmd, projectRoot, shopCfg)
if err != nil {
return err
}

cfgs := extension.BuildAssetConfigFromExtensions(cmd.Context(), sources, extension.AssetBuildConfig{})
assetConfig := extension.AssetBuildConfig{
ShopwareRoot: projectRoot,
Executor: cmdExecutor,
}

cfgs := extension.BuildAssetConfigFromExtensions(cmd.Context(), sources, assetConfig)

if _, err := extension.InstallNodeModulesOfConfigs(cmd.Context(), cfgs, false); err != nil {
if _, err := extension.InstallNodeModulesOfConfigs(cmd.Context(), cfgs, assetConfig); err != nil {
return err
}

// Normalize paths for the execution environment (e.g. Docker container).
for _, cfg := range cfgs {
cfg.BasePath = cmdExecutor.NormalizePath(cfg.BasePath)
for i, v := range cfg.Views {
cfg.Views[i] = cmdExecutor.NormalizePath(v)
}
}

fmt.Println(cfgs)

pluginJson, err := json.MarshalIndent(cfgs, "", " ")
if err != nil {
return err
Expand All @@ -89,7 +104,12 @@ func filterAndWritePluginJson(cmd *cobra.Command, projectRoot string, shopCfg *s
}

func filterAndGetSources(cmd *cobra.Command, projectRoot string, shopCfg *shop.Config) ([]asset.Source, error) {
sources, err := extension.DumpAndLoadAssetSourcesOfProject(phpexec.AllowBinCI(cmd.Context()), projectRoot, shopCfg)
cmdExecutor, err := resolveExecutor(cmd, projectRoot)
if err != nil {
return nil, err
}

sources, err := extension.DumpAndLoadAssetSourcesOfProject(executor.AllowBinCI(cmd.Context()), projectRoot, shopCfg, cmdExecutor.ConsoleCommand)
if err != nil {
return nil, err
}
Expand Down
6 changes: 5 additions & 1 deletion cmd/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import (
"github.com/shopware/shopware-cli/internal/shop"
)

var projectConfigPath string
var (
projectConfigPath string
environmentName string
)

var projectRootCmd = &cobra.Command{
Use: "project",
Expand All @@ -16,4 +19,5 @@ var projectRootCmd = &cobra.Command{
func Register(rootCmd *cobra.Command) {
rootCmd.AddCommand(projectRootCmd)
projectRootCmd.PersistentFlags().StringVar(&projectConfigPath, "project-config", shop.DefaultConfigFileName(), "Path to config")
projectRootCmd.PersistentFlags().StringVarP(&environmentName, "env", "e", "", "Target environment name")
}
12 changes: 9 additions & 3 deletions cmd/project/project_admin_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import (

"github.com/spf13/cobra"

"github.com/shopware/shopware-cli/internal/executor"
"github.com/shopware/shopware-cli/internal/extension"
"github.com/shopware/shopware-cli/internal/phpexec"
"github.com/shopware/shopware-cli/internal/shop"
"github.com/shopware/shopware-cli/logging"
)
Expand Down Expand Up @@ -34,9 +34,14 @@ var projectAdminBuildCmd = &cobra.Command{
return err
}

cmdExecutor, err := resolveExecutor(cmd, projectRoot)
if err != nil {
return err
}

logging.FromContext(cmd.Context()).Infof("Looking for extensions to build assets in project")

if err := runTransparentCommand(commandWithRoot(phpexec.ConsoleCommand(phpexec.AllowBinCI(cmd.Context()), "feature:dump"), projectRoot)); err != nil {
if err := runTransparentCommand(cmdExecutor.ConsoleCommand(executor.AllowBinCI(cmd.Context()), "feature:dump")); err != nil {
return err
}

Expand All @@ -58,6 +63,7 @@ var projectAdminBuildCmd = &cobra.Command{
ShopwareVersion: shopwareConstraint,
NPMForceInstall: forceInstall,
ForceAdminBuild: shopCfg.Build.ForceAdminBuild,
Executor: cmdExecutor,
}

if err := extension.BuildAssetsForExtensions(cmd.Context(), sources, assetCfg); err != nil {
Expand All @@ -69,7 +75,7 @@ var projectAdminBuildCmd = &cobra.Command{
return nil
}

return runTransparentCommand(commandWithRoot(phpexec.ConsoleCommand(cmd.Context(), "assets:install"), projectRoot))
return runTransparentCommand(cmdExecutor.ConsoleCommand(cmd.Context(), "assets:install"))
},
}

Expand Down
32 changes: 21 additions & 11 deletions cmd/project/project_admin_watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@ package project

import (
"os"
"os/exec"
"path"
"path/filepath"

"github.com/spf13/cobra"

"github.com/shopware/shopware-cli/internal/envfile"
"github.com/shopware/shopware-cli/internal/extension"
"github.com/shopware/shopware-cli/internal/npm"
"github.com/shopware/shopware-cli/internal/phpexec"
"github.com/shopware/shopware-cli/internal/shop"
)

Expand All @@ -37,26 +35,32 @@ var projectAdminWatchCmd = &cobra.Command{
return err
}

if err := filterAndWritePluginJson(cmd, projectRoot, shopCfg); err != nil {
cmdExecutor, err := resolveExecutor(cmd, projectRoot)
if err != nil {
return err
}

if err := runTransparentCommand(commandWithRoot(phpexec.ConsoleCommand(cmd.Context(), "feature:dump"), projectRoot)); err != nil {
if err := filterAndWritePluginJson(cmd, projectRoot, shopCfg, cmdExecutor); err != nil {
return err
}

if err := runTransparentCommand(cmdExecutor.ConsoleCommand(cmd.Context(), "feature:dump")); err != nil {
return err
}

if err := os.Setenv("PROJECT_ROOT", projectRoot); err != nil {
return err
}

adminRelPath := extension.PlatformRelPath(projectRoot, "Administration", "Resources/app/administration")
adminExecutor := cmdExecutor.WithRelDir(adminRelPath)

if _, err := os.Stat(extension.PlatformPath(projectRoot, "Administration", "Resources/app/administration/node_modules/webpack-dev-server")); os.IsNotExist(err) {
if err := npm.InstallDependencies(cmd.Context(), extension.PlatformPath(projectRoot, "Administration", "Resources/app/administration"), npm.NonEmptyPackage); err != nil {
if err := npm.InstallDependencies(cmd.Context(), adminExecutor, npm.NonEmptyPackage); err != nil {
return err
}
}

adminRoot := extension.PlatformPath(projectRoot, "Administration", "Resources/app/administration")

if err := os.Setenv("ADMIN_ROOT", extension.PlatformPath(projectRoot, "Administration", "")); err != nil {
return err
}
Expand All @@ -69,16 +73,22 @@ var projectAdminWatchCmd = &cobra.Command{
}
}

if err := runTransparentCommand(commandWithRoot(phpexec.ConsoleCommand(cmd.Context(), "framework:schema", "-s", "entity-schema", path.Join(mockDirectory, "entity-schema.json")), projectRoot)); err != nil {
relMockDir, err := filepath.Rel(projectRoot, mockDirectory)

if err != nil {
return err
}

if err := runTransparentCommand(cmdExecutor.ConsoleCommand(cmd.Context(), "framework:schema", "-s", "entity-schema", filepath.Join(relMockDir, "entity-schema.json"))); err != nil {
return err
}

if err := runTransparentCommand(commandWithRoot(exec.CommandContext(cmd.Context(), "npm", "run", "convert-entity-schema"), adminRoot)); err != nil {
if err := runTransparentCommand(adminExecutor.NPMCommand(cmd.Context(), "run", "convert-entity-schema")); err != nil {
return err
}
}

return runTransparentCommand(commandWithRoot(exec.CommandContext(cmd.Context(), "npm", "run", "dev"), adminRoot))
return runTransparentCommand(adminExecutor.NPMCommand(cmd.Context(), "run", "dev"))
},
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/project/project_autofix_composer.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ var projectAutofixComposerCmd = &cobra.Command{
_ = spinner.New().Context(ctx).Title("Fetching packages").Run()
}()

packagistResponse, err := packagist.GetPackages(cmd.Context(), token)
packagistResponse, err := packagist.GetAvailablePackagesFromShopwareStore(cmd.Context(), token)

cancel()

Expand Down
9 changes: 1 addition & 8 deletions cmd/project/project_config_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ package project

import (
"fmt"
"os"

"charm.land/huh/v2"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"

"github.com/shopware/shopware-cli/internal/compatibility"
"github.com/shopware/shopware-cli/internal/shop"
Expand All @@ -30,12 +28,7 @@ var projectConfigInitCmd = &cobra.Command{
return err
}

content, err := yaml.Marshal(config)
if err != nil {
return err
}

if err := os.WriteFile(".shopware-project.yml", content, os.ModePerm); err != nil {
if err := shop.WriteConfig(config, "."); err != nil {
return err
}

Expand Down
16 changes: 12 additions & 4 deletions cmd/project/project_console.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"github.com/spf13/cobra"

"github.com/shopware/shopware-cli/internal/extension"
"github.com/shopware/shopware-cli/internal/phpexec"
"github.com/shopware/shopware-cli/internal/shop"
)

Expand All @@ -26,7 +25,12 @@ var projectConsoleCmd = &cobra.Command{
return nil, cobra.ShellCompDirectiveDefault
}

parsedCommands, err := shop.GetConsoleCompletion(cmd.Context(), projectRoot)
exec, err := resolveExecutor(cmd, projectRoot)
if err != nil {
return nil, cobra.ShellCompDirectiveDefault
}

parsedCommands, err := shop.GetConsoleCompletion(cmd.Context(), projectRoot, exec.ConsoleCommand)
if err != nil {
return nil, cobra.ShellCompDirectiveDefault
}
Expand Down Expand Up @@ -79,8 +83,12 @@ var projectConsoleCmd = &cobra.Command{
return err
}

consoleCmd := phpexec.ConsoleCommand(cmd.Context(), args...)
consoleCmd.Dir = projectRoot
exec, err := resolveExecutor(cmd, projectRoot)
if err != nil {
return err
}

consoleCmd := exec.ConsoleCommand(cmd.Context(), args...)
consoleCmd.Stdin = cmd.InOrStdin()
consoleCmd.Stdout = cmd.OutOrStdout()
consoleCmd.Stderr = cmd.ErrOrStderr()
Expand Down
Loading