Created
April 12, 2018 12:12
-
-
Save jhinrichsen/7bf7282b6d1cb077575d5adca4bdca95 to your computer and use it in GitHub Desktop.
Jenkins: commandline utility that downloads artifacts a Maven build has deployed to a Maven repository. Useful because Nexus does not offer a build brace.
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
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