Skip to content

Commit

Permalink
Merge pull request #33 from Glow-Project/add-godot-asset-support
Browse files Browse the repository at this point in the history
Add godot asset support
  • Loading branch information
Tch1b0 authored Nov 27, 2022
2 parents b30b86b + 162e013 commit fa481d4
Show file tree
Hide file tree
Showing 16 changed files with 432 additions and 161 deletions.
File renamed without changes.
5 changes: 5 additions & 0 deletions pkg/commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"errors"
"fmt"
"path"

"github.com/Glow-Project/ppm/pkg/utility"
"github.com/fatih/color"
Expand All @@ -22,5 +23,9 @@ func initialize(ctx *cli.Context) error {

fmt.Println(color.GreenString("new ppm.json config-file generated"))

if ok, _ := utility.DoesPathExist(path.Join(paths.Root, ".git")); ok {
fmt.Println(color.YellowString("when using ppm it is recommended to add the addons directory to your .gitignore file"))
}

return nil
}
28 changes: 12 additions & 16 deletions pkg/commands/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package commands
import (
"fmt"

"github.com/Glow-Project/ppm/pkg/fetch"
"github.com/Glow-Project/ppm/pkg/utility"
"github.com/fatih/color"
"github.com/urfave/cli/v2"
Expand All @@ -18,19 +19,19 @@ func install(ctx *cli.Context) error {

dependencies := ctx.Args()
if dependencies.Len() == 0 {
installAllDependencies(&config, paths)
installAllDependencies(&config, &paths)
}

for _, repo := range dependencies.Slice() {
if err = installDependency(&config, paths, repo, false); err != nil {
for _, dep := range dependencies.Slice() {
if err = installDependency(&config, &paths, utility.DependencyFromString(dep), false); err != nil {
return err
}
}

return nil
}

func installAllDependencies(config *utility.PpmConfig, paths utility.Paths) error {
func installAllDependencies(config *utility.PpmConfig, paths *utility.Paths) error {
for _, dependency := range config.Dependencies {
if err := installDependency(config, paths, dependency, false); err != nil {
return err
Expand All @@ -39,25 +40,20 @@ func installAllDependencies(config *utility.PpmConfig, paths utility.Paths) erro
return nil
}

func installDependency(config *utility.PpmConfig, paths utility.Paths, dependency string, isSubDependency bool) error {
dependency, version := utility.GetVersionOrNot(dependency)
func installDependency(config *utility.PpmConfig, paths *utility.Paths, dependency *utility.Dependency, isSubDependency bool) error {
if !isSubDependency {
fmt.Printf("\rinstalling %s\n", color.YellowString(utility.GetPluginIdentifier(dependency)))
fmt.Printf("\rinstalling %s\n", color.YellowString(utility.GetPluginIdentifier(dependency.Identifier)))
} else {
fmt.Printf("\t -> installing %s\n", color.YellowString(utility.GetPluginIdentifier(dependency)))
fmt.Printf("\t -> installing %s\n", color.YellowString(utility.GetPluginIdentifier(dependency.Identifier)))
}
loadAnim := utility.StartLoading()

err := utility.Clone(paths.Addons, dependency, version)
err := fetch.InstallDependency(dependency, paths)
loadAnim.Stop()

if err != nil {
if err.Error() == "repository already exists" {
alreadyInstalled(dependency)
} else {
installError(dependency)
return err
}
installError(dependency.Identifier)
return err
}

shouldAddDep := (!isSubDependency && !config.HasDependency(dependency)) ||
Expand All @@ -69,7 +65,7 @@ func installDependency(config *utility.PpmConfig, paths utility.Paths, dependenc
config.AddDependency(dependency)
}

subConfig, err := utility.GetPluginConfig(paths.Addons, dependency)
subConfig, err := utility.GetPluginConfig(paths.Addons, dependency.Identifier)
if err != nil {
if !isSubDependency {
utility.PrintDone()
Expand Down
2 changes: 1 addition & 1 deletion pkg/commands/reinstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ func reinstall(ctx *cli.Context) error {
return err
}

err = installAllDependencies(&config, paths)
err = installAllDependencies(&config, &paths)
if err != nil {
return err
}
Expand Down
41 changes: 34 additions & 7 deletions pkg/commands/tidy.go
Original file line number Diff line number Diff line change
@@ -1,24 +1,51 @@
package commands

import (
"fmt"
"strings"
"encoding/json"
"os"

"github.com/Glow-Project/ppm/pkg/utility"
"github.com/urfave/cli/v2"
)

func tidy(ctx *cli.Context) error {
_, config, err := utility.GetPathsAndConfig()
paths, err := utility.CreatePathsFromCwd()
if err != nil {
return err
}

for i, dep := range config.Dependencies {
if utility.IsGithubRepoUrl(dep) {
tmp := strings.Split(dep, "/")
config.Dependencies[i] = fmt.Sprintf("%s/%s", tmp[len(tmp)-2], tmp[len(tmp)-1])
content, err := os.ReadFile(paths.ConfigFile)
if err != nil {
return err
}

var jsonContent map[string]interface{}
err = json.Unmarshal(content, &jsonContent)
if err != nil {
return err
}

strDeps, ok := jsonContent["dependencies"].([]interface{})
if !ok {
return nil
}

deps := []*utility.Dependency{}
for _, dep := range strDeps {
str, ok := dep.(string)
if !ok {
return nil
}
deps = append(deps, utility.DependencyFromString(str))
}

jsonContent["dependencies"] = deps
jsonData, err := json.MarshalIndent(jsonContent, "", "\t")
os.WriteFile(paths.ConfigFile, jsonData, 0644)

config, err := utility.ParsePpmConfig(paths.ConfigFile)
if err != nil {
return err
}

return config.Write()
Expand Down
21 changes: 10 additions & 11 deletions pkg/commands/uninstall.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ func uninstall(ctx *cli.Context) error {
}

for i := 0; i < dependencies.Len(); i++ {
dep := dependencies.Get(i)
dep := utility.DependencyFromString(dependencies.Get(i))
if config.HasDependency(dep) && !config.HasSubDependency(dep) {
uninstallDependency(&config, paths, dep, false)
} else if config.HasSubDependency(dep) {
fmt.Println(color.RedString("the plugin"), color.YellowString(dep), color.RedString("is a sub dependency and can only be uninstalled by uninstalling its parent"))
fmt.Println(color.RedString("the plugin"), color.YellowString(dep.Identifier), color.RedString("is a sub dependency and can only be uninstalled by uninstalling its parent"))
} else {
fmt.Println(color.RedString("the plugin"), color.YellowString(dep), color.RedString("is not installed"))
fmt.Println(color.RedString("the plugin"), color.YellowString(dep.Identifier), color.RedString("is not installed"))
}
}

Expand All @@ -53,16 +53,15 @@ func uninstallAllDependencies(config *utility.PpmConfig, paths utility.Paths, ha
return nil
}

func uninstallDependency(config *utility.PpmConfig, paths utility.Paths, dependency string, isSubDependency bool) error {
dep := utility.GetPluginIdentifier(dependency)
func uninstallDependency(config *utility.PpmConfig, paths utility.Paths, dependency *utility.Dependency, isSubDependency bool) error {
if !isSubDependency {
fmt.Println("\runinstalling", color.YellowString(dep))
fmt.Println("\runinstalling", color.YellowString(dependency.Identifier))
} else {
fmt.Println("\t -> uninstalling", color.YellowString(dep))
fmt.Println("\t -> uninstalling", color.YellowString(dependency.Identifier))
}
loadAnim := utility.StartLoading()

subConfig, err := utility.GetPluginConfig(paths.Addons, dep)
subConfig, err := utility.GetPluginConfig(paths.Addons, dependency.Identifier)
if err == nil {
for i := 0; i < len(subConfig.Dependencies); i++ {
subDep := subConfig.Dependencies[i]
Expand All @@ -73,16 +72,16 @@ func uninstallDependency(config *utility.PpmConfig, paths utility.Paths, depende
}

// path: root/addons/dependency
err = os.RemoveAll(path.Join(paths.Addons, utility.GetPluginName(dep)))
err = os.RemoveAll(path.Join(paths.Addons, dependency.Identifier))
loadAnim.Stop()
if err != nil {
return err
}

if !isSubDependency {
config.RemoveDependency(dep)
config.RemoveDependency(dependency)
} else {
config.RemoveSubDependency(dep)
config.RemoveSubDependency(dependency)
}

if !isSubDependency {
Expand Down
5 changes: 2 additions & 3 deletions pkg/commands/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@ func update(ctx *cli.Context) error {

func updateAllDependencies(config utility.PpmConfig, paths utility.Paths) error {
for _, dependency := range config.Dependencies {
_, version := utility.GetVersionOrNot(dependency)
if len(version) > 0 {
if dependency.Type != utility.GithubAsset {
continue
}

err := utility.Update(filepath.Join(paths.Addons, dependency))
err := utility.UpdateGithubRepo(filepath.Join(paths.Addons, dependency.Identifier))
if err != nil {
return err
}
Expand Down
153 changes: 153 additions & 0 deletions pkg/fetch/fetch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package fetch

import (
"archive/zip"
"fmt"
"io"
"os"
"path"
"path/filepath"
"regexp"
"strings"

"github.com/Glow-Project/ppm/pkg/utility"
"github.com/go-git/go-git/v5"
)

// install a dependency `dep` into its directory inside the `addons` directory
func InstallDependency(dep *utility.Dependency, paths *utility.Paths) error {
var err error
if dep.Type == utility.GithubAsset {
err = installGithubRepo(dep, paths)
} else {
err = installGodotAsset(dep, paths)
}

return err
}

// install a plugin from github
func installGithubRepo(dep *utility.Dependency, paths *utility.Paths) error {
fullPath := path.Join(paths.Addons, dep.Identifier)
_, err := git.PlainClone(fullPath, false, &git.CloneOptions{
URL: dep.Url,
})
if err != nil {
return err
}

return nil
}

// install a plugin from the godot asset store
func installGodotAsset(dep *utility.Dependency, paths *utility.Paths) error {
r := Requester{}
data, err := r.Get(dep.Url)
if err != nil {
return err
}

/* structure of data:
{
"result": [
{
"asset_id": "<id>"
}
]
}
*/
results := data["result"].([]interface{})
if len(results) == 0 {
return fmt.Errorf("No results for dependency \"%s\"", dep.Identifier)
}

id := results[0].(map[string]interface{})["asset_id"].(string)

data, err = r.Get(fmt.Sprintf("https://godotengine.org/asset-library/api/asset/%s", id))
if err != nil {
return err
}

dwdUrl := data["download_url"].(string)
f, err := os.CreateTemp("", "tempfile")
if err != nil {
return err
}
defer os.Remove(f.Name())

r.Download(dwdUrl, f)
f.Close()
err = unzip(f.Name(), paths.Addons)
if err != nil {
return err
}

return nil
}

// unzip a .zip file from src into dest
func unzip(src, dest string) error {
r, err := zip.OpenReader(src)
if err != nil {
return err
}
defer func() {
if err := r.Close(); err != nil {
panic(err)
}
}()

os.MkdirAll(dest, 0755)

shaRegex := regexp.MustCompile("-[0-9a-f]{40}")

writeFile := func(f *zip.File) error {
rc, err := f.Open()
if err != nil {
return err
}
defer func() {
if err := rc.Close(); err != nil {
panic(err)
}
}()

fileName := string(shaRegex.ReplaceAll([]byte(f.Name), []byte("")))
path := filepath.Join(dest, fileName)

// Check for ZipSlip (Directory traversal)
if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
return fmt.Errorf("illegal file path: %s", path)
}

if f.FileInfo().IsDir() {
os.MkdirAll(path, f.Mode())
} else {
os.MkdirAll(filepath.Dir(path), f.Mode())
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
defer func() {
if err := f.Close(); err != nil {
panic(err)
}
}()

_, err = io.Copy(f, rc)
if err != nil {
return err
}
}
return nil
}

for _, f := range r.File {
err := writeFile(f)
if err != nil {
return err
}
}

return nil
}
Loading

0 comments on commit fa481d4

Please sign in to comment.