Switch remote deploy to vendored source builds
Move remote deployment to a vendored source bundle built on the target host via Docker so redeploys no longer require local cross-compilation or host Go installation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
17
vendor/github.com/leaanthony/gosod/.gitignore
generated
vendored
Normal file
17
vendor/github.com/leaanthony/gosod/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
generated
|
||||
examples/ignore/ignore
|
||||
examples/basic/basic
|
||||
examples/filters/filters
|
||||
21
vendor/github.com/leaanthony/gosod/LICENSE
generated
vendored
Normal file
21
vendor/github.com/leaanthony/gosod/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Lea Anthony
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
105
vendor/github.com/leaanthony/gosod/README.md
generated
vendored
Normal file
105
vendor/github.com/leaanthony/gosod/README.md
generated
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
<p align="center" style="text-align: center">
|
||||
<img src="logo.png" width="50%"><br/>
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
Scaffolding simplified<br/><br/>
|
||||
<a href="https://github.com/leaanthony/gosod/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-blue.svg"></a>
|
||||
<a href="https://goreportcard.com/report/github.com/leaanthony/gosod"><img src="https://goreportcard.com/badge/github.com/leaanthony/gosod"/></a>
|
||||
<a href="https://godoc.org/github.com/leaanthony/gosod"><img src="https://img.shields.io/badge/godoc-reference-blue.svg"/></a>
|
||||
<a href="https://github.com/leaanthony/gosod/issues"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="CodeFactor" /></a>
|
||||
<a href="https://app.fossa.io/projects/git%2Bgithub.com%2Fleaanthony%2Fgosod?ref=badge_shield" alt="FOSSA Status"><img src="https://app.fossa.io/api/projects/git%2Bgithub.com%2Fleaanthony%2Fgosod.svg?type=shield"/></a>
|
||||
</p>
|
||||
|
||||
|
||||
Features:
|
||||
- Scaffold out project directories from templates
|
||||
- Uses Go's native templating engine
|
||||
- Uses `fs.FS` for input, so it works well with `go:embed` and [debme](https://github.com/leaanthony/debme)
|
||||
- Go alternative to [cookiecutter](https://github.com/cookiecutter/cookiecutter)
|
||||
|
||||
## Installation
|
||||
|
||||
`go get github.com/leaanthony/gosod`
|
||||
|
||||
## Usage
|
||||
|
||||
1. Define a template directory
|
||||
2. Define some data
|
||||
3. Extract to a target directory
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/leaanthony/gosod"
|
||||
)
|
||||
|
||||
type config struct {
|
||||
Name string
|
||||
}
|
||||
|
||||
|
||||
// mytemplate/
|
||||
// ├── custom.filtername.txt
|
||||
// ├── ignored.txt
|
||||
// ├── subdir
|
||||
// │ ├── included.txt
|
||||
// │ └── sub.tmpl.go
|
||||
// └── test.tmpl.go
|
||||
//go:embed mytemplate/*
|
||||
var mytemplate embed.FS
|
||||
|
||||
func main() {
|
||||
|
||||
// Define a new Template directory
|
||||
basic, err := gosod.New(mytemplate)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Make some config data
|
||||
myConfig := &config{
|
||||
Name: "Mat",
|
||||
}
|
||||
|
||||
// Ignore files
|
||||
basic.IgnoreFile("ignored.txt")
|
||||
|
||||
// Custom template filters
|
||||
basic.SetTemplateFilters([]string{ ".filtername", ".tmpl" })
|
||||
|
||||
// Create a new directory using the template and config
|
||||
err = basic.Extract("./generated", myConfig)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Ouput FS:
|
||||
// generated/
|
||||
// ├── custom.txt
|
||||
// ├── subdir
|
||||
// │ ├── included.txt
|
||||
// │ └── sub.go
|
||||
// └── test.go
|
||||
}
|
||||
```
|
||||
|
||||
## Template Directories
|
||||
|
||||
A template directory is simply a directory structure contianing files you wish to copy. The algorithm for copying is:
|
||||
|
||||
* Categorise all files into one of: directory, standard file and template files
|
||||
* Create the directory structure
|
||||
* Copy standard files
|
||||
* Copy template files, assembled using the given data
|
||||
|
||||
Template files, by default, are any file with ".tmpl" in their filename. To change this, use `SetTemplateFilters([]string)`. This allows you to set any number of filters.
|
||||
|
||||
Files may also be ignored by using the `IgnoreFilename(string)` method.
|
||||
|
||||
## What's with the name?
|
||||
|
||||
Google is your [friend](https://translate.google.com/?sl=cy&tl=en&text=gosod&op=translate)
|
||||
11
vendor/github.com/leaanthony/gosod/gosod.go
generated
vendored
Normal file
11
vendor/github.com/leaanthony/gosod/gosod.go
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
package gosod
|
||||
|
||||
import (
|
||||
"github.com/leaanthony/gosod/internal/templatedir"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
// New creates a new TemplateDir structure for the given filesystem
|
||||
func New(fs fs.FS) *templatedir.TemplateDir {
|
||||
return templatedir.New(fs)
|
||||
}
|
||||
287
vendor/github.com/leaanthony/gosod/internal/templatedir/templatedir.go
generated
vendored
Normal file
287
vendor/github.com/leaanthony/gosod/internal/templatedir/templatedir.go
generated
vendored
Normal file
@@ -0,0 +1,287 @@
|
||||
package templatedir
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
// TemplateDir defines a directory containing directories and files, including template files
|
||||
type TemplateDir struct {
|
||||
fs fs.FS
|
||||
templateFilters []string
|
||||
dirs []string
|
||||
standardFiles []string
|
||||
templateFiles []string
|
||||
ignoredFiles map[string]struct{}
|
||||
renameFiles map[string]string
|
||||
}
|
||||
|
||||
// New attempts to create a new TemplateDir from the given FS
|
||||
func New(fs fs.FS) *TemplateDir {
|
||||
|
||||
return &TemplateDir{
|
||||
fs: fs,
|
||||
templateFilters: []string{".tmpl"},
|
||||
ignoredFiles: make(map[string]struct{}),
|
||||
renameFiles: make(map[string]string),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// IgnoreFile will add the given filename to the list of files to ignore
|
||||
// during extraction
|
||||
func (t *TemplateDir) IgnoreFile(filename string) {
|
||||
t.ignoredFiles[filename] = struct{}{}
|
||||
}
|
||||
|
||||
// SetTemplateFilters sets the template filter. Each filename is checked to see if
|
||||
// it contains this string and if so, it is deemed to be a template file
|
||||
func (t *TemplateDir) SetTemplateFilters(filters []string) {
|
||||
t.templateFilters = filters
|
||||
}
|
||||
|
||||
func (t *TemplateDir) RenameFiles(renameFiles map[string]string) {
|
||||
t.renameFiles = renameFiles
|
||||
}
|
||||
|
||||
// Extract the templates to the given directory, using data as input
|
||||
func (t *TemplateDir) Extract(targetDirectory string, data interface{}) error {
|
||||
|
||||
// Get the absolute path
|
||||
targetDirectory, err := filepath.Abs(targetDirectory)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// If the targetDirectory doesn't exist, then create it
|
||||
if _, err := os.Stat(targetDirectory); os.IsNotExist(err) == true {
|
||||
// Create the targetDirectory
|
||||
err = os.MkdirAll(targetDirectory, 0755)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Process the template files
|
||||
err = t.processTemplateDirFiles(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) processTemplateDirFiles(targetDirectory string, data interface{}) error {
|
||||
// Categorise all files
|
||||
err := t.categoriseFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create all directories
|
||||
err = t.createDirectories(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Process TemplateDirs
|
||||
err = t.processTemplateDirs(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy files
|
||||
err = t.copyFiles(targetDirectory, data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) categoriseFiles() error {
|
||||
return fs.WalkDir(t.fs, ".", t.categoriseFile)
|
||||
}
|
||||
|
||||
func (t *TemplateDir) categoriseFile(path string, info fs.DirEntry, err error) error {
|
||||
|
||||
// Process error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Is it a directory?
|
||||
if info.IsDir() {
|
||||
// Ignore base dir
|
||||
if path != "." {
|
||||
t.dirs = append(t.dirs, path)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get the filename
|
||||
filename := filepath.Base(path)
|
||||
|
||||
// Is it a file we are ignoring?
|
||||
_, ignored := t.ignoredFiles[filename]
|
||||
if ignored {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Is it a template?
|
||||
for _, filter := range t.templateFilters {
|
||||
if strings.Index(filename, filter) > -1 {
|
||||
t.templateFiles = append(t.templateFiles, path)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Treat as standard file
|
||||
t.standardFiles = append(t.standardFiles, path)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) convertPathTarget(path string, targetDirectory string, data any) string {
|
||||
|
||||
result := filepath.Join(targetDirectory, path)
|
||||
if data == nil {
|
||||
return result
|
||||
}
|
||||
|
||||
// Load the filename as a template
|
||||
tmpl, err := template.New("filename").Parse(result)
|
||||
if err != nil {
|
||||
return result
|
||||
}
|
||||
|
||||
// Execute the template
|
||||
var buf bytes.Buffer
|
||||
err = tmpl.Execute(&buf, data)
|
||||
if err != nil {
|
||||
return result
|
||||
}
|
||||
|
||||
// Return the result
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func (t *TemplateDir) createDirectories(targetDirectory string, data any) error {
|
||||
|
||||
// Iterate all directories and attempt to create them
|
||||
for _, dirPath := range t.dirs {
|
||||
|
||||
targetDir := t.convertPathTarget(dirPath, targetDirectory, data)
|
||||
|
||||
// Create the directory
|
||||
err := os.MkdirAll(targetDir, 0755)
|
||||
|
||||
// Ignore directory exists errors
|
||||
if err != nil && err != syscall.EEXIST {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) processTemplateDirs(targetDirectory string, data interface{}) error {
|
||||
|
||||
// Iterate template files
|
||||
for _, templateFile := range t.templateFiles {
|
||||
|
||||
// Parse template
|
||||
tmpl, err := template.ParseFS(t.fs, templateFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Convert path to target path
|
||||
targetFile := t.convertPathTarget(templateFile, targetDirectory, data)
|
||||
|
||||
// update filename
|
||||
baseDir := filepath.Dir(targetFile)
|
||||
filename := filepath.Base(targetFile)
|
||||
for _, filter := range t.templateFilters {
|
||||
filename = strings.ReplaceAll(filename, filter, "")
|
||||
}
|
||||
renamedFile := t.renameFiles[filename]
|
||||
if renamedFile != "" {
|
||||
filename = renamedFile
|
||||
}
|
||||
targetFile = filepath.Join(baseDir, filename)
|
||||
|
||||
// Create target file
|
||||
writer, err := os.Create(targetFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = tmpl.Execute(writer, data)
|
||||
if err != nil {
|
||||
err2 := writer.Close()
|
||||
if err2 != nil {
|
||||
return err2
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
err = writer.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) copyFiles(targetDirectory string, data any) error {
|
||||
|
||||
// Iterate over files
|
||||
for _, filename := range t.standardFiles {
|
||||
targetFile := filename
|
||||
renamedFile := t.renameFiles[filename]
|
||||
if renamedFile != "" {
|
||||
targetFile = renamedFile
|
||||
}
|
||||
|
||||
targetFilename := t.convertPathTarget(targetFile, targetDirectory, data)
|
||||
err := t.copyFile(filename, targetFilename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (t *TemplateDir) copyFile(source, target string) error {
|
||||
s, err := t.fs.Open(source)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(s fs.File) {
|
||||
err := s.Close()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}(s)
|
||||
d, err := os.Create(target)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := io.Copy(d, s); err != nil {
|
||||
err := d.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
return d.Close()
|
||||
}
|
||||
BIN
vendor/github.com/leaanthony/gosod/logo.png
generated
vendored
Normal file
BIN
vendor/github.com/leaanthony/gosod/logo.png
generated
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
Reference in New Issue
Block a user