Files
gitea-release-resource/in_command.go
Ken Robertson d563c2714c Add support for downloading source artifacts from Github release
This adds support for retrieving the tarball or zip source artifact from a
Github release. This is done through defining a
"params.include_source_tarball" or "params.include_source_zip" boolean setting.

With this, the resource will download the respective source artfact into the
target directory as either "source.tar.gz" or "source.zip".
2015-09-23 14:22:21 -07:00

169 lines
3.4 KiB
Go

package resource
import (
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"path/filepath"
"github.com/zachgersh/go-github/github"
)
type InCommand struct {
github GitHub
writer io.Writer
}
func NewInCommand(github GitHub, writer io.Writer) *InCommand {
return &InCommand{
github: github,
writer: writer,
}
}
func (c *InCommand) Run(destDir string, request InRequest) (InResponse, error) {
err := os.MkdirAll(destDir, 0755)
if err != nil {
return InResponse{}, err
}
var foundRelease *github.RepositoryRelease
foundRelease, err = c.github.GetReleaseByTag(request.Version.Tag)
if err != nil {
return InResponse{}, err
}
if foundRelease == nil {
return InResponse{}, errors.New("no releases")
}
tagPath := filepath.Join(destDir, "tag")
err = ioutil.WriteFile(tagPath, []byte(*foundRelease.TagName), 0644)
if err != nil {
return InResponse{}, err
}
version := determineVersionFromTag(*foundRelease.TagName)
versionPath := filepath.Join(destDir, "version")
err = ioutil.WriteFile(versionPath, []byte(version), 0644)
if err != nil {
return InResponse{}, err
}
assets, err := c.github.ListReleaseAssets(*foundRelease)
if err != nil {
return InResponse{}, err
}
for _, asset := range assets {
path := filepath.Join(destDir, *asset.Name)
var matchFound bool
if len(request.Params.Globs) == 0 {
matchFound = true
} else {
for _, glob := range request.Params.Globs {
matches, err := filepath.Match(glob, *asset.Name)
if err != nil {
return InResponse{}, err
}
if matches {
matchFound = true
break
}
}
}
if !matchFound {
continue
}
fmt.Fprintf(c.writer, "downloading asset: %s\n", *asset.Name)
err := c.downloadAsset(asset, path)
if err != nil {
return InResponse{}, err
}
}
if request.Params.IncludeSourceTarball {
u, err := c.github.GetTarballLink(request.Version.Tag)
if err != nil {
return InResponse{}, err
}
fmt.Fprintln(c.writer, "downloading source tarball to source.tar.gz")
if err := c.downloadFile(u.String(), filepath.Join(destDir, "source.tar.gz")); err != nil {
return InResponse{}, err
}
}
if request.Params.IncludeSourceZip {
u, err := c.github.GetZipballLink(request.Version.Tag)
if err != nil {
return InResponse{}, err
}
fmt.Fprintln(c.writer, "downloading source zip to source.zip")
if err := c.downloadFile(u.String(), filepath.Join(destDir, "source.zip")); err != nil {
return InResponse{}, err
}
}
return InResponse{
Version: Version{
Tag: *foundRelease.TagName,
},
Metadata: metadataFromRelease(foundRelease),
}, nil
}
func (c *InCommand) downloadAsset(asset github.ReleaseAsset, destPath string) error {
out, err := os.Create(destPath)
if err != nil {
return err
}
defer out.Close()
content, err := c.github.DownloadReleaseAsset(asset)
if err != nil {
return err
}
defer content.Close()
_, err = io.Copy(out, content)
if err != nil {
return err
}
return nil
}
func (c *InCommand) downloadFile(url, destPath string) error {
out, err := os.Create(destPath)
if err != nil {
return err
}
defer out.Close()
resp, err := http.Get(url)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("failed to download file: HTTP status %d: %s", resp.StatusCode, resp.Status)
}
_, err = io.Copy(out, resp.Body)
if err != nil {
return err
}
return nil
}