Skip to content

Commit

Permalink
Add build utils for workflow tooling
Browse files Browse the repository at this point in the history
  • Loading branch information
deanishe committed Jun 30, 2019
1 parent b8c63c3 commit e5965ca
Show file tree
Hide file tree
Showing 24 changed files with 1,180 additions and 14 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module github.com/deanishe/awgo
go 1.12

require (
github.com/bmatcuk/doublestar v1.1.1
github.com/pkg/errors v0.8.1
golang.org/x/text v0.3.2
howett.net/plist v0.0.0-20181124034731-591f970eefbb
)
11 changes: 11 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
github.com/bmatcuk/doublestar v1.1.1 h1:YroD6BJCZBYx06yYFEWvUuKVWQn3vLLQAVmDmvTSaiQ=
github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
howett.net/plist v0.0.0-20181124034731-591f970eefbb h1:jhnBjNi9UFpfpl8YZhA9CrOqpnJdvzuiHsl/dnxl11M=
howett.net/plist v0.0.0-20181124034731-591f970eefbb/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
22 changes: 11 additions & 11 deletions modd.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@
# Rebuild examples
_examples/bookmarks/*.go {
prep: "
# build example bookmarks
GO11MODULE=on go build -o ./_examples/bookmarks/bookmarks ./_examples/bookmarks
# build example workflow: bookmarks
GO111MODULE=on go build -o ./_examples/bookmarks/bookmarks ./_examples/bookmarks
"
}

_examples/settings/*.go {
prep: "
# build example settings
GO11MODULE=on go build -o ./_examples/settings/settings ./_examples/settings
# build example workflow: settings
GO111MODULE=on go build -o ./_examples/settings/settings ./_examples/settings
"
}

_examples/fuzzy/*.go {
prep: "
# build example fuzzy
GO11MODULE=on go build -o ./_examples/fuzzy/fuzzy ./_examples/fuzzy
# build example workflow: fuzzy
GO111MODULE=on go build -o ./_examples/fuzzy/fuzzy ./_examples/fuzzy
"
}

_examples/update/*.go {
prep: "
# build example update
GO11MODULE=on go build -o ./_examples/update/update ./_examples/update
# build example workflow: update
GO111MODULE=on go build -o ./_examples/update/update ./_examples/update
"
}

_examples/workflows/*.go {
prep: "
# build example workflows
GO11MODULE=on go build -o ./_examples/workflows/workflows ./_examples/workflows
# build example workflow: workflow search
GO111MODULE=on go build -o ./_examples/workflows/workflows ./_examples/workflows
"
}

Expand All @@ -44,6 +44,6 @@ run-tests.sh
!vendor/** {
prep: "
# run unit tests
GO11MODULE=on ./run-tests.sh -ic @dirmods
GO111MODULE=on ./run-tests.sh -ic @dirmods
"
}
16 changes: 16 additions & 0 deletions util/build/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2019 Dean Jackson <[email protected]>
// MIT Licence applies http://opensource.org/licenses/MIT

/*
Package build provides helpers for developing and building workflows.
Info provides Alfred and workflow settings, read from the environment,
info.plist and Alfred's config files.
There are also utility functions to help build workflows:
Symlink() // symlink files
Export() // create an .alfredworkflow file from a directory
*/
package build
192 changes: 192 additions & 0 deletions util/build/files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
// Copyright (c) 2019 Dean Jackson <[email protected]>
// MIT Licence applies http://opensource.org/licenses/MIT

package build

import (
"archive/zip"
"errors"
"fmt"
"io"
"os"
"path/filepath"

"github.com/bmatcuk/doublestar"

"github.com/deanishe/awgo/util"
)

// Export builds an .alfredworkflow file in directory dest
// from the files in directory src. If src is an empty string,
// "build" is used; if dest is empty, "dist" is used.
//
// The filename of the workflow file is generated automatically from
// the workflow's info.plist and is returned if zipping succeeds.
func Export(src, dest string) (path string, err error) {
if src == "" {
src = "build"
}
if dest == "" {
dest = "dist"
}
var info *Info
if info, err = NewInfo(InfoPlist(filepath.Join(src, "info.plist"))); err != nil {
return
}
name := util.Slugify(fmt.Sprintf("%s-%s.alfredworkflow", info.Name, info.Version))
if err = os.MkdirAll(dest, 0700); err != nil {
return
}
path = filepath.Join(dest, name)

if util.PathExists(path) {
if err = os.Remove(path); err != nil {
return
}
}

var z *os.File
if z, err = os.Create(path); err != nil {
return
}
defer z.Close()

out := zip.NewWriter(z)

err = filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
if err != nil {
return err
}

if fi.IsDir() {
return nil
}

var (
name, orig string
info os.FileInfo
mode os.FileMode
)

if name, err = filepath.Rel(src, path); err != nil {
return err
}
if orig, err = filepath.EvalSymlinks(path); err != nil {
return err
}
if info, err = os.Stat(orig); err != nil {
return err
}
mode = info.Mode()

var (
f *os.File
w io.Writer
fh = &zip.FileHeader{
Name: name,
Method: zip.Deflate,
}
)
fh.SetMode(mode.Perm())
fh.SetModTime(info.ModTime())

if f, err = os.Open(orig); err != nil {
return err
}
defer f.Close()

if w, err = out.CreateHeader(fh); err != nil {
return err
}
if _, err = io.Copy(w, f); err != nil {
return err
}

return nil
})

if err != nil {
return
}

err = out.Close()

return
}

// Glob is a pattern and (relative) destination directory.
type Glob struct {
// Pattern is a glob-style pattern to match against filesystem
Pattern string
// DestDir is a relative directory within target directory
// to where files matching Pattern should be linked.
DestDir string
}

// Globs creates a slice of Globs for patterns.
func Globs(pattern ...string) []Glob {
globs := make([]Glob, len(pattern))

for i, s := range pattern {
globs[i] = Glob{Pattern: s}
}

return globs
}

// SymlinkGlobs symlinks multiple Globs to a directory.
func SymlinkGlobs(destDir string, globs ...Glob) error {
for _, g := range globs {
files, err := doublestar.Glob(g.Pattern)
if err != nil {
return err
}

for _, p := range files {
dest := filepath.Join(destDir, g.DestDir, p)
if err := Symlink(dest, p, true); err != nil {
return err
}
}
}
return nil
}

// Symlink creates a symlink to target.
func Symlink(link, target string, relative bool) error {
var (
dir string
path string
err error
)

if link == "" {
return errors.New("empty link")
}

if link, err = filepath.Abs(link); err != nil {
return err
}
dir = filepath.Dir(link)

if target, err = filepath.Abs(target); err != nil {
return err
}

if _, err := os.Stat(target); err != nil {
return err
}

if err = os.MkdirAll(dir, 0755); err != nil {
return err
}
path = target
if relative {
if path, err = filepath.Rel(dir, target); err != nil {
return err
}
}

fmt.Printf("%s --> %s\n", link, path)
return os.Symlink(path, link)
}
Loading

0 comments on commit e5965ca

Please sign in to comment.