Skip to content

Instantly share code, notes, and snippets.

@Proximyst
Last active May 27, 2017 13:39
Show Gist options
  • Save Proximyst/843fa3f39fc7de73b54078c7e66ff302 to your computer and use it in GitHub Desktop.
Save Proximyst/843fa3f39fc7de73b54078c7e66ff302 to your computer and use it in GitHub Desktop.
package main
import (
"flag"
"strings"
"os/exec"
"log"
"os"
"io"
"net/http"
"fmt"
"github.com/mholt/archiver"
)
var (
Directory string
Command string
Args string
Url string
File string
WgetArgs string
Prelaunch string
Wget bool
IgnorePrelaunch bool
PrelaunchOrder int
// External tools
ToolDir string
InstallJava bool
JavaUrl string
)
const (
ExitErrDownload = 1
ExitNoCommand = 2
ExitAppError = 3
ExitPrelaunchError = 4
)
func init() {
flag.StringVar(&Directory, "dir", ".", "Working Directory")
flag.StringVar(&Command, "cmd", "", "Command to run to launch")
flag.StringVar(&Args, "args", "", "Arguments to pass to command")
flag.StringVar(&Url, "url", "", "The URL to download from")
flag.StringVar(&File, "file", "runFile", "File name to download to and set as variable")
flag.StringVar(&WgetArgs, "wgetargs", "", "The arguments passed to wget before the output & URL. Only applicable if -wget is true or error on native")
flag.StringVar(&Prelaunch, "prelaunch", "", "The commands (linked with &&) to execute before the main command")
flag.IntVar(&PrelaunchOrder, "prelaunchorder", 1, "0 - Before download, 1 - after download but before command, 2 - after command")
flag.BoolVar(&IgnorePrelaunch, "ignoreprelaunch", false, "Whether or not to ignore prelaunch errors")
flag.BoolVar(&Wget, "wget", false, "Whether or not to use wget or own downloader")
// External tools
flag.StringVar(&ToolDir, "tools", "tools/", "The directory for tools to be put")
flag.BoolVar(&InstallJava, "java", false, "Whether or not to install java under {ToolDir}")
flag.StringVar(&JavaUrl, "javaurl", "http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jre-8u131-linux-x64.tar.gz", "Location to download Java from and then extract")
flag.Parse()
flag.PrintDefaults()
}
func main() {
if Command == "" {
fmt.Println("There is no command to run.")
os.Exit(ExitNoCommand)
return
}
if err := ExecutePrelaunch(0); err != nil {
log.Fatal(err)
log.Fatal("An error occured during prelaunch! Ignore? ", FormatBool(IgnorePrelaunch))
if !IgnorePrelaunch {
os.Exit(ExitPrelaunchError)
return
}
}
Command = strings.Replace(Command, "{File}", File, -1)
downloader := getDownloader()
if Url != "" {
if !downloader(Directory+"/"+File, Url) {
fmt.Println("Couldn't download file. Exiting..")
os.Exit(ExitErrDownload)
return
}
}
if InstallJava {
if !downloader("java.tar.gz", JavaUrl) {
fmt.Println("Couldn't download Java!")
os.Exit(ExitErrDownload)
return
}
archiver.TarGz.Open("java.tar.gz", ToolDir+"/java")
os.Setenv("JAVA_HOME", ToolDir+"/java")
os.Setenv("PATH", os.Getenv("PATH")+";"+ToolDir+"/java/bin")
}
if err := ExecutePrelaunch(1); err != nil {
log.Fatal(err)
log.Fatal("An error occured during prelaunch! Ignore? ", FormatBool(IgnorePrelaunch))
if !IgnorePrelaunch {
os.Exit(ExitPrelaunchError)
return
}
}
cmd := exec.Command(Command)
cmd.Dir = Directory
if Args != "" {
cmd.Args = strings.Split(Args, " ")
}
cmd.Stderr = os.Stderr
cmd.Stdout = os.Stdout
cmd.Stdin = os.Stdin
err := cmd.Run()
if err != nil {
log.Fatal(err.Error())
os.Exit(ExitAppError)
return
}
if err := ExecutePrelaunch(2); err != nil {
log.Fatal(err)
log.Fatal("An error occured during prelaunch! Ignore? ", FormatBool(IgnorePrelaunch))
if !IgnorePrelaunch {
os.Exit(ExitPrelaunchError)
return
}
}
}
func FormatBool(format bool) string {
if format {
return "Yes"
}
return "No"
}
func ExecutePrelaunch(current int) (cmderr error) {
if PrelaunchOrder != current {
return
}
cmd := exec.Command(Prelaunch)
cmderr = cmd.Run()
return
}
func getDownloader() func(filename, url string) bool { // filename includes args too
if Wget {
return func(filename, url string) bool {
cmd := exec.Command("wget", "-O ", filename, url)
err := cmd.Run()
if err != nil {
log.Fatal(err)
return false
}
info, err := os.Stat(Directory + "/" + File)
if os.IsNotExist(err) {
log.Fatal(err)
log.Fatal("Couldn't download file!")
return false
}
if info.Size() == 0 {
log.Fatal("File size is 0 bytes! Unsure if intended, thus erroring.")
return false
}
return true
}
}
return func(filename, url string) bool {
file, err := os.Create(filename)
if err != nil {
_, err := os.Stat(filename)
if os.IsNotExist(err) {
log.Fatal(err)
log.Fatal("File couldn't be created. Retrying with wget...")
Wget = true
return getDownloader()(filename, url)
}
}
defer file.Close()
// File now exists.
resp, err := http.Get(url)
if err != nil {
log.Fatal(err)
log.Fatal("Couldn't download file! Retrying with wget...")
Wget = true
return getDownloader()(filename, url)
}
defer resp.Body.Close()
bytes, err := io.Copy(file, resp.Body)
if err != nil {
log.Fatal(err)
log.Fatal("Couldn't copy file to location! Retrying with wget...")
Wget = true
return getDownloader()(filename, url)
}
fmt.Println("Successfully copied", bytes, "bytes in total!")
return true
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment