Created
March 2, 2018 10:34
-
-
Save jhinrichsen/bec592f868e3e6a20f85399cf31ed5a8 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Fetch all deployed artifacts of a Maven build | |
package main | |
import ( | |
"bufio" | |
"flag" | |
"fmt" | |
"io" | |
"log" | |
"net/http" | |
"net/url" | |
"os" | |
"path" | |
"regexp" | |
"sync" | |
"time" | |
) | |
func main() { | |
var match = flag.String("match", `\.ear`, | |
"regexp for matching artifacts") | |
var todir = flag.String("todir", "out", | |
"output directory for artifacts") | |
flag.Usage = func() { | |
fmt.Fprintf(os.Stderr, | |
"Usage: %s [options] <Jenkins build URL>\n"+ | |
"Downloads artifacts that a Jenkins Maven build"+ | |
" has uploaded\n", | |
path.Base(os.Args[0])) | |
flag.PrintDefaults() | |
} | |
flag.Parse() | |
// Expect URL parameter | |
if flag.NArg() != 1 { | |
flag.Usage() | |
os.Exit(1) | |
} | |
buildURL, err := url.Parse(flag.Arg(0)) | |
if err != nil { | |
log.Fatal(err) | |
} | |
rel, _ := url.Parse("consoleText") | |
consoleURL := buildURL.ResolveReference(rel) | |
log.Printf("Fetching console for %v\n", consoleURL) | |
res, err := http.Get(consoleURL.String()) | |
if err != nil { | |
log.Fatal(err) | |
} | |
c := make(chan string) | |
go parse(res.Body, *match, c) | |
ensureDir(*todir) | |
// Make sure not to exit before all fetches are done | |
var wg sync.WaitGroup | |
for url := range c { | |
go func(u string) { | |
wg.Add(1) | |
fetch(u, *todir) | |
wg.Done() | |
}(url) | |
} | |
log.Println("Waiting for downloads to finish") | |
wg.Wait() | |
log.Println("Done.") | |
} | |
func parse(buf io.ReadCloser, match string, urls chan<- string) { | |
defer buf.Close() | |
scanner := bufio.NewScanner(buf) | |
re := regexp.MustCompile("Uploaded: (.+?) ") | |
for scanner.Scan() { | |
t := scanner.Text() | |
groups := re.FindStringSubmatch(t) | |
if len(groups) == 0 { | |
continue | |
} | |
if len(groups) > 2 { | |
log.Fatalf("Expected to find one group but found %q\n", | |
groups) | |
} | |
group := groups[1] | |
matched, err := regexp.MatchString(match, group) | |
if err != nil { | |
log.Fatal(err) | |
} | |
if matched { | |
urls <- group | |
} | |
} | |
close(urls) | |
if err := scanner.Err(); err != nil { | |
log.Fatal(err) | |
} | |
} | |
func ensureDir(dir string) { | |
if _, err := os.Stat(dir); os.IsNotExist(err) { | |
os.MkdirAll(dir, os.ModePerm) | |
} | |
} | |
func fetch(url string, todir string) { | |
filename := path.Base(url) | |
p := path.Join(todir, filename) | |
out, err := os.Create(p) | |
if err != nil { | |
log.Fatal(err) | |
} | |
defer out.Close() | |
res, err := http.Get(url) | |
if err != nil { | |
log.Fatal(err) | |
} | |
if res.StatusCode != http.StatusOK { | |
log.Fatalf("%v: expected status code 200 but got %v\n", | |
url, res.StatusCode) | |
} | |
defer res.Body.Close() | |
log.Printf("Creating %v\n", p) | |
start := time.Now() | |
n, err := io.Copy(out, res.Body) | |
if err != nil { | |
log.Fatal(err) | |
} | |
elapsed := time.Since(start) | |
log.Printf("Created %v (%v bytes) in %v\n", filename, n, elapsed) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment