tulpanomicon/sluggen/main.go

142 lines
2.9 KiB
Go

package main
import (
"archive/tar"
"compress/gzip"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"strings"
"time"
"github.com/otiai10/copy"
)
var (
fname = flag.String("fname", "slug.tar.gz", "slug name")
)
func main() {
flag.Parse()
fout, err := os.Create(*fname)
if err != nil {
log.Fatal(err)
}
defer fout.Close()
gzw := gzip.NewWriter(fout)
defer gzw.Close()
tw := tar.NewWriter(gzw)
defer tw.Close()
dir, err := ioutil.TempDir("", "sluggen")
if err != nil {
log.Fatal(err)
}
copy.Copy("./book", dir)
defer os.RemoveAll(dir) // clean up
os.MkdirAll(filepath.Join(dir, "bin"), 0777)
var scalefile string
scalefile += fmt.Sprintf("web=1\n")
os.MkdirAll(filepath.Join(dir, ".config"), 0777)
os.MkdirAll(filepath.Join(dir, "client_body_temp"), 0777)
os.MkdirAll(filepath.Join(dir, "proxy_temp"), 0777)
os.MkdirAll(filepath.Join(dir, "fastcgi_temp"), 0777)
os.MkdirAll(filepath.Join(dir, "uwsgi_temp"), 0777)
os.MkdirAll(filepath.Join(dir, "scgi_temp"), 0777)
err = ioutil.WriteFile(filepath.Join(dir, "static.json"), []byte(`{
"root": "."
}`), 0666)
err = ioutil.WriteFile(filepath.Join(dir, ".buildpacks"), []byte("https://github.com/heroku/heroku-buildpack-static"), 0666)
if err != nil {
log.Fatal(err)
}
err = ioutil.WriteFile(filepath.Join(dir, "DOKKU_SCALE"), []byte(scalefile), 0666)
if err != nil {
log.Fatal(err)
}
filepath.Walk(dir, func(file string, fi os.FileInfo, err error) error {
// return on any error
if err != nil {
return err
}
// create a new dir/file header
header, err := tar.FileInfoHeader(fi, fi.Name())
if err != nil {
return err
}
// update the name to correctly reflect the desired destination when untaring
header.Name = strings.TrimPrefix(strings.Replace(file, dir, "", -1), string(filepath.Separator))
// write the header
if err := tw.WriteHeader(header); err != nil {
return err
}
// return on non-regular files (thanks to [kumo](https://medium.com/@komuw/just-like-you-did-fbdd7df829d3) for this suggested update)
if !fi.Mode().IsRegular() {
return nil
}
// open files for taring
f, err := os.Open(file)
if err != nil {
return err
}
// copy file data into tar writer
if _, err := io.Copy(tw, f); err != nil {
return err
}
// manually close here after each file operation; defering would cause each file close
// to wait until all operations have completed.
f.Close()
return nil
})
time.Sleep(time.Second)
}
// Copy the src file to dst. Any existing file will be overwritten and will not
// copy file attributes.
func Copy(src, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
st, err := in.Stat()
if err != nil {
return err
}
out, err := os.OpenFile(dst, os.O_CREATE|os.O_WRONLY, st.Mode())
if err != nil {
return err
}
defer out.Close()
_, err = io.Copy(out, in)
if err != nil {
return err
}
return out.Close()
}