diff --git a/assets/project/.localbeach.dist.env b/assets/project/.localbeach.dist.env index 51e5ba7..a40e11d 100644 --- a/assets/project/.localbeach.dist.env +++ b/assets/project/.localbeach.dist.env @@ -7,9 +7,13 @@ BEACH_VIRTUAL_HOSTS=${BEACH_PROJECT_NAME_LOWERCASE}.localbeach.net # Change the PHP version to the branch you use in your Beach instances. # Examples: 8.1 for PHP 8.1.x - BEACH_PHP_IMAGE_VERSION=8.3 +# Change these if your Flow setup is not in the project root +BEACH_FLOW_ROOTPATH=${BEACH_FLOW_ROOTPATH} +BEACH_APPLICATION_PATH=${BEACH_APPLICATION_PATH} + # You may specify additional environment variables below, for example # a URL of a service you use. Make sure to add this variable to the # "environment" section of the "php" container in ".localbeach.docker-compose.yaml". +# like so: MY_CUSTOM_VAR=${MY_CUSTOM_VAR} diff --git a/assets/project/.localbeach.docker-compose.yaml b/assets/project/.localbeach.docker-compose.yaml index a0dd3b6..89471de 100644 --- a/assets/project/.localbeach.docker-compose.yaml +++ b/assets/project/.localbeach.docker-compose.yaml @@ -24,6 +24,7 @@ services: - BEACH_PERSISTENT_RESOURCES_FALLBACK_BASE_URI=${BEACH_PERSISTENT_RESOURCES_FALLBACK_BASE_URI:-} - FLOW_HTTP_TRUSTED_PROXIES=* - NGINX_CACHE_ENABLE=false + - BEACH_APPLICATION_PATH=${BEACH_APPLICATION_PATH:-/application} php: image: ${BEACH_PHP_IMAGE:-flownative/beach-php}:${BEACH_PHP_IMAGE_VERSION:-8.2} @@ -54,6 +55,7 @@ services: - BEACH_PHP_TIMEZONE=${BEACH_PHP_TIMEZONE:-UTC} - BEACH_APPLICATION_USER_SERVICE_ENABLE=${BEACH_APPLICATION_USER_SERVICE_ENABLE:-false} - BEACH_APPLICATION_STARTUP_SCRIPTS_ENABLE=${BEACH_APPLICATION_STARTUP_SCRIPTS_ENABLE:-false} + - BEACH_APPLICATION_PATH=${BEACH_APPLICATION_PATH:-/application} redis: image: ${BEACH_REDIS_IMAGE:-flownative/redis}:${BEACH_REDIS_IMAGE_VERSION:-latest} diff --git a/cmd/beach/cmd/down.go b/cmd/beach/cmd/down.go index 33e738e..5c9a823 100644 --- a/cmd/beach/cmd/down.go +++ b/cmd/beach/cmd/down.go @@ -50,7 +50,7 @@ func handleDownRun(cmd *cobra.Command, args []string) { for _, instanceRoot := range instanceRoots { log.Info("Stopping instance in " + instanceRoot + "...") sandbox, err := beachsandbox.GetSandbox(instanceRoot) - if err != nil { + if err != nil && !errors.Is(err, beachsandbox.ErrNoFlowFound) { log.Fatal(err) return } diff --git a/cmd/beach/cmd/init.go b/cmd/beach/cmd/init.go index 4d1ceaa..3541605 100644 --- a/cmd/beach/cmd/init.go +++ b/cmd/beach/cmd/init.go @@ -17,15 +17,16 @@ package cmd import ( "os" "path" + "path/filepath" "regexp" "strings" - "github.com/flownative/localbeach/pkg/beachsandbox" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) var projectName string +var flowRootPath string // initCmd represents the init command var initCmd = &cobra.Command{ @@ -38,20 +39,22 @@ var initCmd = &cobra.Command{ func init() { initCmd.Flags().StringVar(&projectName, "project-name", "", "Defines the project name, defaults to folder name.") + initCmd.Flags().StringVar(&flowRootPath, "flow-path", "", "Defines the Flow project root, defaults to current folder.") rootCmd.AddCommand(initCmd) } func handleInitRun(cmd *cobra.Command, args []string) { - sandbox, err := beachsandbox.GetRawSandbox() - if err != nil { - log.Fatal(err) - return - } + var err error projectNameFilter := regexp.MustCompile(`[^a-zA-Z0-9-]`) projectName := strings.Trim(projectName, " ") if len(projectName) == 0 { - projectName = path.Base(sandbox.ProjectRootPath) + workingDirPath, err := os.Getwd() + if err != nil { + log.Fatal(err) + return + } + projectName = path.Base(workingDirPath) } projectName = projectNameFilter.ReplaceAllLiteralString(projectName, "") @@ -80,6 +83,8 @@ func handleInitRun(cmd *cobra.Command, args []string) { environmentContent := readFileFromAssets("project/.localbeach.dist.env") environmentContent = strings.ReplaceAll(environmentContent, "${BEACH_PROJECT_NAME}", projectName) environmentContent = strings.ReplaceAll(environmentContent, "${BEACH_PROJECT_NAME_LOWERCASE}", strings.ToLower(projectName)) + environmentContent = strings.ReplaceAll(environmentContent, "${BEACH_FLOW_ROOTPATH}", flowRootPath) + environmentContent = strings.ReplaceAll(environmentContent, "${BEACH_APPLICATION_PATH}", filepath.Join("/application", flowRootPath)) destination, err := os.Create(".localbeach.dist.env") if err != nil { diff --git a/cmd/beach/cmd/logs.go b/cmd/beach/cmd/logs.go index 41f2947..c8715d4 100644 --- a/cmd/beach/cmd/logs.go +++ b/cmd/beach/cmd/logs.go @@ -15,6 +15,7 @@ package cmd import ( + "path/filepath" "strconv" "github.com/flownative/localbeach/pkg/beachsandbox" @@ -52,11 +53,11 @@ Docker containers (--containers).`, return } } else { - commandArgs := []string{"exec", "-ti", sandbox.ProjectName + "_php"} + commandArgs := []string{"exec", "-ti", sandbox.ProjectName + "_php", "bash", "-c"} if follow { - commandArgs = append(commandArgs, "bash", "-c", "tail -n -"+strconv.Itoa(tail)+" -f /application/Data/Logs/*.log") + commandArgs = append(commandArgs, "tail -n -"+strconv.Itoa(tail)+" -f "+filepath.Join("/application", sandbox.FlowRootPath, "Data/Logs/*.log")) } else { - commandArgs = append(commandArgs, "bash", "-c", "tail -n -"+strconv.Itoa(tail)+" /application/Data/Logs/*.log") + commandArgs = append(commandArgs, "tail -n -"+strconv.Itoa(tail)+" "+filepath.Join("/application", sandbox.FlowRootPath, "Data/Logs/*.log")) } err = exec.RunInteractiveCommand("docker", commandArgs) diff --git a/pkg/beachsandbox/beachsandbox.go b/pkg/beachsandbox/beachsandbox.go index 5ed6c21..e4d8965 100644 --- a/pkg/beachsandbox/beachsandbox.go +++ b/pkg/beachsandbox/beachsandbox.go @@ -25,11 +25,11 @@ type BeachSandbox struct { ProjectRootPath string `` ProjectDataPersistentResourcesPath string `` DockerComposeFilePath string `` + FlowRootPath string `` } func (sandbox *BeachSandbox) Init(rootPath string) error { sandbox.ProjectRootPath = rootPath - sandbox.ProjectDataPersistentResourcesPath = rootPath + "/Data/Persistent/Resources" if err := loadLocalBeachEnvironment(rootPath); err != nil { return err @@ -37,8 +37,14 @@ func (sandbox *BeachSandbox) Init(rootPath string) error { sandbox.DockerComposeFilePath = filepath.Join(sandbox.ProjectRootPath, ".localbeach.docker-compose.yaml") sandbox.ProjectName = os.Getenv("BEACH_PROJECT_NAME") + sandbox.FlowRootPath = os.Getenv("BEACH_FLOW_ROOTPATH") + sandbox.ProjectDataPersistentResourcesPath = filepath.Join(rootPath, sandbox.FlowRootPath, "/Data/Persistent/Resources") - return nil + if info, err := os.Stat(filepath.Join(sandbox.ProjectRootPath, sandbox.FlowRootPath, "flow")); err == nil && !info.IsDir() { + return nil + } + + return ErrNoFlowFound } // GetActiveSandbox returns the active sandbox based on the current working dir @@ -51,16 +57,6 @@ func GetActiveSandbox() (*BeachSandbox, error) { return GetSandbox(rootPath) } -// GetRawSandbox returns the (unconfigured) sandbox based on the current working dir -func GetRawSandbox() (*BeachSandbox, error) { - rootPath, err := detectProjectRootPathFromWorkingDir() - if errors.Is(err, ErrNoFlowFound) { - return nil, err - } - - return GetSandbox(rootPath) -} - // GetSandbox returns the sandbox based on the given dir func GetSandbox(rootPath string) (*BeachSandbox, error) { sandbox := &BeachSandbox{} diff --git a/pkg/beachsandbox/helpers.go b/pkg/beachsandbox/helpers.go index c647005..8fb5350 100644 --- a/pkg/beachsandbox/helpers.go +++ b/pkg/beachsandbox/helpers.go @@ -24,8 +24,8 @@ import ( log "github.com/sirupsen/logrus" ) -var ErrNoLocalBeachConfigurationFound = errors.New("found a Flow or Neos installation but no Local Beach configuration – run \"beach init\" to create some") -var ErrNoFlowFound = errors.New("could not find Flow or Neos installation in your current path - try running \"composer install\" to fix that") +var ErrNoLocalBeachConfigurationFound = errors.New("could not find a Local Beach configuration – run \"beach init\" to create some") +var ErrNoFlowFound = errors.New("could not find Flow or Neos installation - try running \"composer install\" to fix that") func detectProjectRootPathFromWorkingDir() (rootPath string, err error) { workingDirPath, err := os.Getwd() @@ -40,13 +40,10 @@ func detectProjectRootPathFromWorkingDir() (rootPath string, err error) { func detectProjectRootPath(currentPath string) (projectRootPath string, err error) { projectRootPath = path.Clean(currentPath) - if info, err := os.Stat(filepath.Join(projectRootPath, "flow")); err == nil && !info.IsDir() { - if _, err := os.Stat(filepath.Join(projectRootPath, ".localbeach.docker-compose.yaml")); err == nil { - return projectRootPath, err - } - return projectRootPath, ErrNoLocalBeachConfigurationFound + if _, err := os.Stat(filepath.Join(projectRootPath, ".localbeach.docker-compose.yaml")); err == nil { + return projectRootPath, err } else if projectRootPath == "/" { - return "", ErrNoFlowFound + return "", ErrNoLocalBeachConfigurationFound } return detectProjectRootPath(path.Dir(projectRootPath))