Skip to content

Commit

Permalink
feat: Add extension prepare and extension zip
Browse files Browse the repository at this point in the history
  • Loading branch information
shyim committed Jan 10, 2022
1 parent 2c914fc commit 510d080
Show file tree
Hide file tree
Showing 14 changed files with 1,405 additions and 0 deletions.
14 changes: 14 additions & 0 deletions cmd/extension.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package cmd

import (
"github.com/spf13/cobra"
)

var extensionRootCmd = &cobra.Command{
Use: "extension",
Short: "Shopware Extension utilities",
}

func init() {
rootCmd.AddCommand(extensionRootCmd)
}
37 changes: 37 additions & 0 deletions cmd/extension_prepare.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package cmd

import (
"github.com/spf13/cobra"
"log"
"path/filepath"
"shopware-cli/extension"
)

var extensionPrepareCmd = &cobra.Command{
Use: "prepare [path]",
Short: "Prepare a extension for zipping",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
path, err := filepath.Abs(args[0])

if err != nil {
log.Fatalln(err)
}

ext, err := extension.GetExtensionByFolder(path)

if err != nil {
log.Fatalln(err)
}

err = extension.PrepareFolderForZipping(path+"/", ext)

if err != nil {
log.Fatalln(err)
}
},
}

func init() {
extensionRootCmd.AddCommand(extensionPrepareCmd)
}
106 changes: 106 additions & 0 deletions cmd/extension_zip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package cmd

import (
"fmt"
termColor "github.com/fatih/color"
cp "github.com/otiai10/copy"
"github.com/spf13/cobra"
"io/ioutil"
"log"
"os"
"path/filepath"
"shopware-cli/extension"
)

var disableZip = false

var extensionZipCmd = &cobra.Command{
Use: "zip [path] [branch]",
Short: "Zip a Extension",
Args: cobra.MinimumNArgs(1),
Run: func(cmd *cobra.Command, args []string) {
path, err := filepath.Abs(args[0])
branch := ""

if len(args) == 2 {
branch = args[1]
}

if err != nil {
log.Fatalln(err)
}

ext, err := extension.GetExtensionByFolder(path)

if err != nil {
log.Fatalln(err)
}

// Clear previous zips
existingFiles, err := filepath.Glob(fmt.Sprintf("%s-*.zip", ext.GetName()))
if err != nil {
log.Fatalln(err)
}

for _, file := range existingFiles {
_ = os.Remove(file)
}

// Create temp dir
tempDir, err := ioutil.TempDir("", "extension")
tempDir = tempDir + "/"

if err != nil {
log.Fatalln(err)
}

defer func(path string) {
_ = os.RemoveAll(path)
}(tempDir)

tag := ""

// Extract files using strategy
if disableZip {
err = cp.Copy(path, tempDir)
} else {
tag, err = extension.GitCopyFolder(path, tempDir)
}

// User input wins
if len(branch) > 0 {
tag = branch
}

if err != nil {
log.Fatalln(err)
}

err = extension.PrepareFolderForZipping(tempDir, ext)

if err != nil {
log.Fatalln(err)
}

// Cleanup not wanted files
err = extension.CleanupExtensionFolder(tempDir)
if err != nil {
log.Fatalln(err)
}

fileName := fmt.Sprintf("%s-%s.zip", ext.GetName(), tag)

if len(tag) == 0 {
fileName = fmt.Sprintf("%s.zip", ext.GetName())
}

extension.CreateZip(tempDir, fileName)

termColor.Green("Created file %s", fileName)
},
}

func init() {
extensionRootCmd.AddCommand(extensionZipCmd)
extensionZipCmd.Flags().BoolVar(&disableZip, "disable-git", false, "Use the source folder as it is")
}
61 changes: 61 additions & 0 deletions extension/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package extension

import (
"archive/zip"
"bytes"
"os/exec"
"strings"
)

func gitTagOrBranchOfFolder(source string) (string, error) {
tagCmd := exec.Command("git", "-C", source, "tag", "--sort=-creatordate")

stdout, err := tagCmd.Output()

if err != nil {
return "", err
}

versions := strings.Split(string(stdout), "\n")

if len(versions) > 0 {
return versions[0], nil
}

branchCmd := exec.Command("git", "-C", source, "branch")

stdout, err = branchCmd.Output()

if err != nil {
return "", err
}

return strings.TrimLeft(string(stdout), "* "), nil
}

func GitCopyFolder(source, target string) (string, error) {
tag, err := gitTagOrBranchOfFolder(source)

if err != nil {
return "", err
}

archiveCmd := exec.Command("git", "-C", source, "archive", tag, "--format=zip")

stdout, err := archiveCmd.Output()
if err != nil {
return "", err
}

zipReader, err := zip.NewReader(bytes.NewReader(stdout), int64(len(stdout)))
if err != nil {
return "", err
}

err = Unzip(zipReader, target)
if err != nil {
return "", err
}

return tag, err
}
93 changes: 93 additions & 0 deletions extension/platform.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package extension

import (
"encoding/json"
"fmt"
"github.com/hashicorp/go-version"
"io/ioutil"
"os"
"strings"
)

type PlatformPlugin struct {
path string
name string
shopwareVersionConstraint version.Constraints
}

func newPlatformPlugin(path string) (*PlatformPlugin, error) {
composerJsonFile := fmt.Sprintf("%s/composer.json", path)
if _, err := os.Stat(composerJsonFile); err != nil {
return nil, err
}

jsonFile, err := ioutil.ReadFile(composerJsonFile)

if err != nil {
return nil, err
}

var composerJson platformComposerJson
err = json.Unmarshal(jsonFile, &composerJson)

if err != nil {
return nil, err
}

parts := strings.Split(composerJson.Extra.ShopwarePluginClass, "\\")
shopwareConstraintString, ok := composerJson.Require["shopware/core"]

if !ok {
return nil, fmt.Errorf("require.shopware/core is required")
}

shopwareConstraint, err := version.NewConstraint(shopwareConstraintString)

if err != nil {
return nil, err
}

extension := PlatformPlugin{
path: path,
name: parts[len(parts)-1],
shopwareVersionConstraint: shopwareConstraint,
}

return &extension, nil
}

type platformComposerJson struct {
Name string `json:"name"`
Keywords []string `json:"keywords"`
Description string `json:"description"`
Version string `json:"version"`
Type string `json:"type"`
License string `json:"license"`
Authors []struct {
Name string `json:"name"`
Homepage string `json:"homepage"`
} `json:"authors"`
Require map[string]string `json:"require"`
Extra struct {
ShopwarePluginClass string `json:"shopware-plugin-class"`
Label map[string]string `json:"label"`
Description map[string]string `json:"description"`
ManufacturerLink map[string]string `json:"manufacturerLink"`
SupportLink map[string]string `json:"supportLink"`
} `json:"extra"`
Autoload struct {
Psr4 map[string]string `json:"psr-4"`
} `json:"autoload"`
}

func (p PlatformPlugin) GetName() string {
return p.name
}

func (p PlatformPlugin) GetShopwareVersionConstraint() version.Constraints {
return p.shopwareVersionConstraint
}

func (p PlatformPlugin) GetType() string {
return "platform"
}
29 changes: 29 additions & 0 deletions extension/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package extension

import (
"fmt"
"github.com/hashicorp/go-version"
"os"
)

func GetExtensionByFolder(path string) (Extension, error) {
if _, err := os.Stat(fmt.Sprintf("%s/plugin.xml", path)); err == nil {
return nil, fmt.Errorf("shopware 5 is currently not supported")
}

if _, err := os.Stat(fmt.Sprintf("%s/manifest.xml", path)); err == nil {
return nil, fmt.Errorf("apps are currently not supported")
}

if _, err := os.Stat(fmt.Sprintf("%s/composer.json", path)); err == nil {
return newPlatformPlugin(path)
}

return nil, fmt.Errorf("cannot detect extension type")
}

type Extension interface {
GetName() string
GetShopwareVersionConstraint() version.Constraints
GetType() string
}
Loading

0 comments on commit 510d080

Please sign in to comment.