Skip to content

Commit

Permalink
Add Upsun support
Browse files Browse the repository at this point in the history
  • Loading branch information
fabpot committed Oct 17, 2023
1 parent aa59155 commit a319bcb
Show file tree
Hide file tree
Showing 12 changed files with 374 additions and 44 deletions.
21 changes: 11 additions & 10 deletions commands/cloud_env_debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,24 +30,25 @@ var cloudEnvDebugCmd = &console.Command{
if err != nil {
return err
}
prefix := platformsh.GuessCloudFromCommandName(c.Command.UserName).CommandPrefix

projectID := c.String("project")
if projectID == "" {
out, ok := psh.RunInteractive(terminal.Logger, "", []string{"project:info", "id", "-y"}, c.Bool("debug"), nil)
out, ok := psh.RunInteractive(terminal.Logger, "", []string{prefix + "project:info", "id", "-y"}, c.Bool("debug"), nil)
if !ok {
return errors.New("Unable to detect the project")
}
projectID = strings.TrimSpace(out.String())
}

out, ok := psh.RunInteractive(terminal.Logger, "", []string{"project:info", "default_branch", "--project=" + projectID, "-y"}, c.Bool("debug"), nil)
out, ok := psh.RunInteractive(terminal.Logger, "", []string{prefix + "project:info", "default_branch", "--project=" + projectID, "-y"}, c.Bool("debug"), nil)
if !ok {
return errors.New("Unable to detect the default branch name")
}
defaultEnvName := strings.TrimSpace(out.String())
envName := c.String("environment")
if envName == "" {
if out, ok := psh.RunInteractive(terminal.Logger, "", []string{"env:info", "id", "--project=" + projectID, "-y"}, false, nil); ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", []string{prefix + "env:info", "id", "--project=" + projectID, "-y"}, false, nil); ok {
envName = strings.TrimSpace(out.String())
} else {
envName = defaultEnvName
Expand All @@ -63,12 +64,12 @@ var cloudEnvDebugCmd = &console.Command{

if c.Bool("off") {
terminal.Println("Deleting APP_ENV and APP_DEBUG (can take some time, --debug to tail commands)")
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, "var:delete", "env:APP_ENV"), c.Bool("debug"), nil); !ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, prefix+"var:delete", "env:APP_ENV"), c.Bool("debug"), nil); !ok {
if !strings.Contains(out.String(), "Variable not found") {
return errors.New("An error occurred while removing APP_ENV")
}
}
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, "var:delete", "env:APP_DEBUG"), c.Bool("debug"), nil); !ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, prefix+"var:delete", "env:APP_DEBUG"), c.Bool("debug"), nil); !ok {
if !strings.Contains(out.String(), "Variable not found") {
return errors.New("An error occurred while removing APP_DEBUG")
}
Expand All @@ -77,7 +78,7 @@ var cloudEnvDebugCmd = &console.Command{
return nil
}

out, ok = psh.RunInteractive(terminal.Logger, "", []string{"project:info", "default_domain", "--project=" + projectID, "-y"}, c.Bool("debug"), nil)
out, ok = psh.RunInteractive(terminal.Logger, "", []string{prefix + "project:info", "default_domain", "--project=" + projectID, "-y"}, c.Bool("debug"), nil)
if !ok {
return errors.New("Unable to detect the default domain")
}
Expand All @@ -89,21 +90,21 @@ var cloudEnvDebugCmd = &console.Command{
}

terminal.Println("Setting APP_ENV and APP_DEBUG to dev/debug (can take some time, --debug to tail commands)")
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, "var:create", "--name=env:APP_ENV", "--value=dev"), c.Bool("debug"), nil); !ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, prefix+"var:create", "--name=env:APP_ENV", "--value=dev"), c.Bool("debug"), nil); !ok {
if !strings.Contains(out.String(), "already exists on the environment") {
return errors.New("An error occurred while adding APP_ENV")
}
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, "var:update", "--value=dev", "env:APP_ENV"), c.Bool("debug"), nil); !ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, prefix+"var:update", "--value=dev", "env:APP_ENV"), c.Bool("debug"), nil); !ok {
if !strings.Contains(out.String(), "No changes were provided") {
return errors.New("An error occurred while adding APP_ENV")
}
}
}
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, "var:create", "--name=env:APP_DEBUG", "--value=1"), c.Bool("debug"), nil); !ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, prefix+"var:create", "--name=env:APP_DEBUG", "--value=1"), c.Bool("debug"), nil); !ok {
if !strings.Contains(out.String(), "already exists on the environment") {
return errors.New("An error occurred while adding APP_DEBUG")
}
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, "var:update", "--value=1", "env:APP_DEBUG"), c.Bool("debug"), nil); !ok {
if out, ok := psh.RunInteractive(terminal.Logger, "", append(defaultArgs, prefix+"var:update", "--value=1", "env:APP_DEBUG"), c.Bool("debug"), nil); !ok {
if !strings.Contains(out.String(), "No changes were provided") {
return errors.New("An error occurred while adding APP_DEBUG")
}
Expand Down
9 changes: 6 additions & 3 deletions commands/init_templating.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,9 @@ type nopCloser struct {

func (nopCloser) Close() error { return nil }

func createRequiredFilesProject(rootDirectory, projectSlug, templateName string, minorPHPVersion string, cloudServices []*CloudService, dump, force bool) ([]string, error) {
func createRequiredFilesProject(brand platformsh.CloudBrand, rootDirectory, projectSlug, templateName string, minorPHPVersion string, cloudServices []*CloudService, dump, force bool) ([]string, error) {
createdFiles := []string{}
templates, err := getTemplates(rootDirectory, templateName, minorPHPVersion)
templates, err := getTemplates(brand, rootDirectory, templateName, minorPHPVersion)
if err != nil {
return nil, errors.Wrap(err, "could not determine template to use")
}
Expand Down Expand Up @@ -158,7 +158,7 @@ func isValidFilePath(toTest string) bool {
return true
}

func getTemplates(rootDirectory, chosenTemplateName string, minorPHPVersion string) (map[string]*template.Template, error) {
func getTemplates(brand platformsh.CloudBrand, rootDirectory, chosenTemplateName string, minorPHPVersion string) (map[string]*template.Template, error) {
var foundTemplate *configTemplate

s := terminal.NewSpinner(terminal.Stderr)
Expand Down Expand Up @@ -186,6 +186,9 @@ func getTemplates(rootDirectory, chosenTemplateName string, minorPHPVersion stri
}
}

if brand == platformsh.UpsunBrand {
chosenTemplateName = filepath.Join(brand.Slug, chosenTemplateName)
}
if isURL, isFile := isValidURL(chosenTemplateName), isValidFilePath(chosenTemplateName); isURL || isFile {
var (
templateConfigBytes []byte
Expand Down
8 changes: 5 additions & 3 deletions commands/local_new.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,20 +211,22 @@ func isEmpty(dir string) (bool, error) {
}

func initCloud(c *console.Context, s *terminal.Spinner, minorPHPVersion, dir string) error {
terminal.Println("* Adding Platform.sh configuration")
brand := platformsh.GuessCloudFromCommandName(c.Command.UserName)

terminal.Printfln("* Adding %s configuration", brand)

cloudServices, err := parseCloudServices(dir, c.StringSlice("service"))
if err != nil {
return err
}

// FIXME: display or hide output based on debug flag
_, err = createRequiredFilesProject(dir, "app", "", minorPHPVersion, cloudServices, c.Bool("dump"), c.Bool("force"))
_, err = createRequiredFilesProject(brand, dir, "app", "", minorPHPVersion, cloudServices, c.Bool("dump"), c.Bool("force"))
if err != nil {
return err
}

buf, err := git.AddAndCommit(dir, []string{"."}, "Add Platform.sh configuration", c.Bool("debug"))
buf, err := git.AddAndCommit(dir, []string{"."}, fmt.Sprintf("Add %s configuration", brand), c.Bool("debug"))
if err != nil {
fmt.Print(buf.String())
}
Expand Down
4 changes: 3 additions & 1 deletion commands/project_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (

"github.com/symfony-cli/console"
"github.com/symfony-cli/symfony-cli/git"
"github.com/symfony-cli/symfony-cli/local/platformsh"
"github.com/symfony-cli/terminal"
)

Expand Down Expand Up @@ -79,7 +80,8 @@ Templates used by this tool are fetched from ` + templatesGitRepository + `.
return err
}

createdFiles, err := createRequiredFilesProject(projectDir, slug, c.String("template"), minorPHPVersion, cloudServices, c.Bool("dump"), c.Bool("force"))
brand := platformsh.GuessCloudFromCommandName(c.Command.UserName)
createdFiles, err := createRequiredFilesProject(brand, projectDir, slug, c.String("template"), minorPHPVersion, cloudServices, c.Bool("dump"), c.Bool("force"))
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func initCLI() {
console.AppHelpTemplate += `
<comment>Available wrappers:</>
Runs PHP (version depends on project's configuration).
Environment variables to use Platform.sh relationships or Docker services are automatically defined.
Environment variables to use Platform.sh/Upsun relationships or Docker services are automatically defined.
{{with .Command "composer"}} <info>{{.PreferredName}}</>{{"\t"}}{{.Usage}}{{end}}
{{with .Command "console"}} <info>{{.PreferredName}}</>{{"\t"}}{{.Usage}}{{end}}
Expand Down
2 changes: 2 additions & 0 deletions local/platformsh/applications.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
yaml "gopkg.in/yaml.v2"
)

// FIXME: update the logic for Upsun

var skippedDirectories = map[string]interface{}{
".git": nil,
"vendor": nil,
Expand Down
70 changes: 70 additions & 0 deletions local/platformsh/brand.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Copyright (c) 2021-present Fabien Potencier <fabien@symfony.com>
*
* This file is part of Symfony CLI project
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package platformsh

import (
"os"
"strings"
)

type CloudBrand struct {
Name string
Slug string
CommandPrefix string
CLIPrefix string
}

var UpsunBrand = CloudBrand{
Name: "Upsun",
Slug: "upsun",
CommandPrefix: "upsun:",
CLIPrefix: "UPSUN_CLI_",
}
var PlatformshBrand = CloudBrand{
Name: "Platform.sh",
Slug: "platformsh",
CommandPrefix: "cloud:",
CLIPrefix: "PLATFORMSH_CLI_",
}

func (b CloudBrand) String() string {
return b.Name
}

func GuessCloudFromCommandName(name string) CloudBrand {
// if the namespace is upsun, then that's the brand we want to use
if strings.HasPrefix(name, "upsun:") {
return UpsunBrand
}

// FIXME: maybe there is something better by passing the dir to this function
dir, err := os.Getwd()
if err != nil {
return PlatformshBrand
}

return GuessCloudFromDirectory(dir)
}

func GuessCloudFromDirectory(dir string) CloudBrand {
// determine the brand when in a project directory with cloud configuration
// FIXME: determine based on the current directory project
return PlatformshBrand
}
24 changes: 14 additions & 10 deletions local/platformsh/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package platformsh
import (
"bytes"
_ "embed"
"fmt"
"io"
"os"
"os/exec"
Expand Down Expand Up @@ -87,7 +88,7 @@ func (p *CLI) AddBeforeHook(name string, f console.BeforeFunc) {
}
}

func (p *CLI) getPath() string {
func (p *CLI) getPath(brand string) string {
if p.path != "" {
return p.path
}
Expand All @@ -98,9 +99,9 @@ func (p *CLI) getPath() string {
}

// the Platform.sh CLI is always available on the containers thanks to the configurator
p.path = BinaryPath(home)
p.path = BinaryPath(home, brand)
if !util.InCloud() {
if cloudPath, err := Install(home); err == nil {
if cloudPath, err := Install(home, brand); err == nil {
p.path = cloudPath
}
}
Expand Down Expand Up @@ -142,17 +143,20 @@ func (p *CLI) proxyPSHCmd(commandName string) console.ActionFunc {
}

func (p *CLI) executor(args []string) *exec.Cmd {
brand := GuessCloudFromCommandName(args[0])
prefix := brand.CLIPrefix

env := []string{
"PLATFORMSH_CLI_APPLICATION_NAME=Platform.sh CLI for Symfony",
"PLATFORMSH_CLI_APPLICATION_EXECUTABLE=symfony",
fmt.Sprintf("%sAPPLICATION_NAME=%s CLI for Symfony", prefix, brand),
fmt.Sprintf("%sAPPLICATION_EXECUTABLE=symfony", prefix),
"XDEBUG_MODE=off",
"PLATFORMSH_CLI_WRAPPED=1",
fmt.Sprintf("%sWRAPPED=1", prefix),
}
if util.InCloud() {
env = append(env, "PLATFORMSH_CLI_UPDATES_CHECK=0")
env = append(env, fmt.Sprintf("%sUPDATES_CHECK=0", prefix))
}
args[0] = strings.TrimPrefix(args[0], "cloud:")
cmd := exec.Command(p.getPath(), args...)
args[0] = strings.TrimPrefix(strings.TrimPrefix(args[0], "upsun:"), "cloud:")
cmd := exec.Command(p.getPath(brand.Slug), args...)
cmd.Env = append(os.Environ(), env...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
Expand All @@ -176,7 +180,7 @@ func (p *CLI) RunInteractive(logger zerolog.Logger, projectDir string, args []st
if stdin != nil {
cmd.Stdin = stdin
}
logger.Debug().Str("cmd", strings.Join(cmd.Args, " ")).Msg("Executing Platform.sh CLI command interactively")
logger.Debug().Str("cmd", strings.Join(cmd.Args, " ")).Msgf("Executing %s CLI command interactively", GuessCloudFromCommandName(args[0]))
if err := cmd.Run(); err != nil {
return buf, false
}
Expand Down
Loading

0 comments on commit a319bcb

Please sign in to comment.