Skip to content

Commit

Permalink
get zip from Github and unzip
Browse files Browse the repository at this point in the history
  • Loading branch information
mingwho committed Sep 13, 2019
1 parent 10a9f14 commit a8f5bb4
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 48 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ builds/*
!builds/.gitkeep
.idea/
.vscode/
alias
191 changes: 191 additions & 0 deletions install/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
package install

import (
"archive/zip"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"strings"
"time"
)

func valid(module string) bool {
return strings.HasPrefix(module, "github.com/")
}

func Install(module string) {

if !valid(module) {
fmt.Printf(`Error reading URL. Please use "github.com/USER/REPO" format to install`)
return
}

err := getZip(module)
if err != nil {
return
}

err = unzip(module)
if err != nil {
return
}

err = createAlias(module)
if err != nil {
return
}

base := filepath.Base(module)

fmt.Printf("Install Success. You can use the module with \"require('%s')\"\n", base)
return
}

func getZip(module string) error {
path := fmt.Sprintf("./vendor/%s", module)
// Create all the parent directories if needed
err := os.MkdirAll(filepath.Dir(path), 0755)

if err != nil {
fmt.Printf("Error making directory %s\n", err)
return err
}

out, err := os.OpenFile(path, os.O_RDWR|os.O_CREATE, os.FileMode(0666))
if err != nil {
fmt.Printf("Error opening file %s\n", err)
return err
}
defer out.Close()

client := http.Client{
Timeout: time.Duration(10 * time.Second),
}
req, err := http.NewRequest("GET", fmt.Sprintf("https://%s/archive/master.zip", module), nil)
if err != nil {
fmt.Printf("Error creating new request %s", err)
return err
}

resp, err := client.Do(req)

if err != nil {
fmt.Printf("Could not get module: %s\n", err)
return err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode >= 300 {
fmt.Errorf("Bad response code: %d", resp.StatusCode)
return err
}

_, err = io.Copy(out, resp.Body)
if err != nil {
fmt.Printf("Error copying file %s", err)
return err
}
return err
}

// Unzip will decompress a zip archive, moving all files and folders
// within the zip file (parameter 1) to an output directory (parameter 2).
func unzip(module string) error {
src := fmt.Sprintf("./vendor/%s", module)
dest := filepath.Dir(src)

r, err := zip.OpenReader(src)
if err != nil {
return err
}
defer r.Close()

for _, f := range r.File {
// Store filename/path for returning and using later on
fpath := filepath.Join(dest, f.Name)

// Check for ZipSlip. More Info: http://bit.ly/2MsjAWE
if !strings.HasPrefix(fpath, filepath.Clean(dest)+string(os.PathSeparator)) {
return fmt.Errorf("%s: illegal file path", fpath)
}

if f.FileInfo().IsDir() {
// Make Folder
os.MkdirAll(fpath, 0755)
continue
}

// Make File
if err = os.MkdirAll(filepath.Dir(fpath), 0755); err != nil {
return err
}

outFile, err := os.OpenFile(fpath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}

rc, err := f.Open()
if err != nil {
return err
}

_, err = io.Copy(outFile, rc)

// Close the file without defer to close before next iteration of loop
outFile.Close()
rc.Close()

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

func createAlias(module string) error {

f, err := os.OpenFile("./alias", os.O_RDWR|os.O_CREATE, 0666)
if err != nil {
fmt.Printf("Could not open alias file %s\n", err)
return err
}
defer f.Close()

b, err := ioutil.ReadAll(f)
data := make(map[string]string)
err = json.Unmarshal(b, &data)
if err != nil {
fmt.Printf("Could not unmarshal alias json %s\n", err)
return err
}

moduleName := filepath.Base(module)

if data[moduleName] != "" {
fmt.Printf("This module could not be aliased because module of same name exists")
return err
}

// appending "-master" because the zip file from Github has "-master" suffix to it
modulePath := fmt.Sprintf("./vendor/github.com/%s-master", module)

// add alias key-value pair to file
data[moduleName] = modulePath

newData, err := json.MarshalIndent(data, "", " ")
if err != nil {
fmt.Printf("Error with json when installing module %s\n", err)
return err
}

_, err = f.WriteAt(newData, 0)
if err != nil {
fmt.Printf("Could not write to alias file %s\n", err)
return err
}
return err
}
51 changes: 3 additions & 48 deletions main.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
package main

import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"os/user"
"path/filepath"

"github.com/abs-lang/abs/install"
"github.com/abs-lang/abs/repl"
"github.com/hashicorp/go-getter"
)

var Version = "1.8.0"

func check(e error) {
if e != nil {
panic(e)
}
}

// The ABS interpreter
func main() {
args := os.Args
Expand All @@ -28,43 +18,8 @@ func main() {
return
}

if args[1] == "--get" {
if len(args) < 3 {
fmt.Println("No module given")
return
}
dir := fmt.Sprintf("./vendor/%s", args[2])
module := args[2]
err := getter.GetAny(dir, module)

u, _ := user.Current()
str, _ := getter.Detect(module, u.HomeDir, getter.Detectors)
fmt.Println("detected", str)
if err != nil {
fmt.Printf("Could not get module: %s\n", err)
return
}

f, err := os.OpenFile("./alias", os.O_RDWR|os.O_CREATE, 0666)
check(err)
defer f.Close()

b, err := ioutil.ReadAll(f)
data := make(map[string]string)
err = json.Unmarshal(b, &data)

base := filepath.Base(module)

// add alias pairs to file
data[base] = module

newData, err := json.MarshalIndent(data, "", " ")
check(err)

_, err = f.WriteAt(newData, 0)
check(err)

fmt.Println("Success")
if len(args) == 3 && args[1] == "get" {
install.Install(args[2])
return
}

Expand Down

0 comments on commit a8f5bb4

Please sign in to comment.