diff options
-rw-r--r-- | tools/updater/download.go | 62 | ||||
-rw-r--r-- | tools/updater/main.go | 133 | ||||
-rw-r--r-- | tools/updater/manifest.go | 41 |
3 files changed, 157 insertions, 79 deletions
diff --git a/tools/updater/download.go b/tools/updater/download.go new file mode 100644 index 0000000..b89703b --- /dev/null +++ b/tools/updater/download.go @@ -0,0 +1,62 @@ +package main + +import ( + "fmt" + "strings" + "os" + "io" + "net/http" + "path/filepath" +) + +// WriteCounter counts the number of bytes written to it +type WriteCounter struct { + Filepath string + Total uint64 +} + +func (wc *WriteCounter) Write(p []byte) (int, error) { + n := len(p) + wc.Total += uint64(n) + wc.PrintProgress() + return n, nil +} + +func (wc *WriteCounter) PrintProgress() { + // clear the line by using a character return to go back to the start of the + // line and remove the remaining characters + fmt.Printf("\r%s", strings.Repeat(" ", 35)) + fmt.Printf("\r[%s]... %d bytes complete", wc.Filepath, wc.Total) +} + +func downloadFile(path string, url string) error { + // make sure dir exists + os.MkdirAll(filepath.Dir(path), 0777) + + // create .part file + output, err := os.Create(path + ".part") + if err != nil { + return err + } + defer output.Close() + + // get data + response, err := http.Get(url) + if err != nil { + return err + } + defer response.Body.Close() + + // create progress reporter + counter := &WriteCounter{path, 0} + _, err = io.Copy(output, io.TeeReader(response.Body, counter)) + if err != nil { + return err + } + + fmt.Printf("\n") + //fmt.Printf("\r%s", strings.Repeat(" ", 40)) + os.Rename(path + ".part", path) + //fmt.Printf("\r[%s] complete\n", path) + return nil +} diff --git a/tools/updater/main.go b/tools/updater/main.go index eda229b..f4feb62 100644 --- a/tools/updater/main.go +++ b/tools/updater/main.go @@ -1,88 +1,63 @@ package main import ( - "flag" - "fmt" - "io/ioutil" - "net/http" - "os" - "os/exec" - "strings" + "flag" + "fmt" + "os" + "net/http" + "bufio" + "strings" ) -// get branchmap of mercurial repository served over http -func branchmap(repository string) (branches map[string]string, err error) { - resp, err := http.Get(repository + "/?cmd=branchmap") - - if err != nil { - return - } - - defer resp.Body.Close() - body, err := ioutil.ReadAll(resp.Body) - - branches = make(map[string]string) - for _, line := range strings.Split(string(body), "\n") { - a := strings.Split(line, " ") - branches[a[0]] = a[1] - } - - return -} - -func poi(executable string) (version string, commit string, err error) { - cmd := exec.Command(executable, "--build") - - // wait for complete - err = cmd.Wait() - - // return output - output, err := cmd.Output() - v := strings.Split(string(output), ":") - version = v[0] - commit = v[1] - return -} - func main() { - helpFlag := flag.Bool("help", false, "Show help information") - verboseFlag := flag.Bool("verbose", false, "Print more information") - execFlag := flag.String("exec", "poi", "Executable path") - repoFlag := flag.String("repo", "https://neueland.iserlohn-fortress.net/smolbote.hg", "Repository path") - flag.Parse() - - // help flag --> show usage and exit - if *helpFlag { - fmt.Println("Usage:") - flag.PrintDefaults() - os.Exit(0) - } - - fmt.Println("Getting poi build...") - if *verboseFlag { - fmt.Println("[exec =", *execFlag, "]") - } - - poi_branch, poi_commit, err := poi(*execFlag) - if err != nil { - fmt.Println("error:", err) - } - fmt.Println("-", poi_branch, ":", poi_commit) - - // get branchmap - fmt.Println("Getting branchmap...") - if *verboseFlag { - fmt.Println("[repo =", *repoFlag, "]") - } - - branches, err := branchmap(*repoFlag) - if err != nil { - fmt.Println("Error getting branchmap:", err) - os.Exit(1) - } + helpFlag := flag.Bool("help", false, "Show help information") + verboseFlag := flag.Bool("verbose", false, "Print more information") + repoFlag := flag.String("repo", "https://neueland.iserlohn-fortress.net/smolbote/downloads", "Repository path") + //dryRunFlag := flag.Bool("dry-run", false, "Dry run") + + flag.Parse() + + // help flag --> show usage and exit + if *helpFlag { + fmt.Println("Usage:") + flag.PrintDefaults() + os.Exit(0) + } + + manifestPath := *repoFlag + "/windows-sha512.txt" + repoPath := *repoFlag + "/windows/" + + if *verboseFlag { + fmt.Println("repoFlag =", *repoFlag) + fmt.Println("manifest =", manifestPath) + fmt.Println("repoPath =", repoPath) + } + + response, err := http.Get(manifestPath) + if err != nil { + panic(err) + } + defer response.Body.Close() + + scanner := bufio.NewScanner(response.Body) + for scanner.Scan() { + s := strings.Split(scanner.Text(), " ") + + filepath := s[1] + checksum := s[0] + + state, err := checkFile(filepath, checksum) + if err != nil { + panic(err) + } + + if(state) { + fmt.Printf("[%s] passed\n", filepath) + } else { + fmt.Printf("[%s] missing or mismatching\n", filepath) + downloadFile(filepath, repoPath + filepath) + } + } - for branch, commit := range branches { - fmt.Println("-", branch, ":", commit[0:12]) - } } diff --git a/tools/updater/manifest.go b/tools/updater/manifest.go new file mode 100644 index 0000000..942a5e7 --- /dev/null +++ b/tools/updater/manifest.go @@ -0,0 +1,41 @@ +package main + +import ( + "crypto/sha512" + "os" + "io" + "fmt" +) + +func checkFile(filepath string, checksum string) (bool, error) { + if _, err := os.Stat(filepath); os.IsNotExist(err) { + return false, nil + } + + // file exists, check checksum + lsum, err := hash(filepath) + if err != nil { + return false, err + } + + if checksum != fmt.Sprintf("%x", lsum) { + return false, nil + } + + return true, nil +} + +func hash(filepath string) ([]byte, error) { + file, err := os.Open(filepath) + if err != nil { + return nil, err + } + defer file.Close() + + hasher := sha512.New() + if _, err := io.Copy(hasher, file); err != nil { + return nil, err + } + + return hasher.Sum(nil), nil +} |