feat: initial copy of v0.1.0
This commit is contained in:
parent
4cc801a7f3
commit
7d4cbb6b08
538 changed files with 63361 additions and 55213 deletions
297
generator/cmd/publish/provider.go
Normal file
297
generator/cmd/publish/provider.go
Normal file
|
|
@ -0,0 +1,297 @@
|
|||
package publish
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"log"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type Provider struct {
|
||||
RootPath string
|
||||
Namespace string
|
||||
Provider string
|
||||
DistPath string
|
||||
RepoName string
|
||||
Version string
|
||||
GpgFingerprint string
|
||||
GpgPubKeyFile string
|
||||
Domain string
|
||||
}
|
||||
|
||||
func (p *Provider) GetRoot() error {
|
||||
cmd := exec.Command("git", "rev-parse", "--show-toplevel")
|
||||
out, err := cmd.Output()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lines := strings.Split(string(out), "\n")
|
||||
p.RootPath = lines[0]
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) CreateV1Dir() error {
|
||||
// Path to semantic version dir
|
||||
versionPath := p.providerDirs()
|
||||
|
||||
// Files to create under v1/providers/[namespace]/[provider_name]
|
||||
err := p.createVersionsFile()
|
||||
if err != nil {
|
||||
return fmt.Errorf("[CreateV1Dir] - create versions file:%w", err)
|
||||
} // Creates version file one above download, which is why downloadPath isn't used
|
||||
|
||||
// Files/Directories to create under v1/providers/[namespace]/[provider_name]/[version]
|
||||
err = p.copyShaFiles(versionPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("[CreateV1Dir] - copy sha files: %w", err)
|
||||
}
|
||||
|
||||
log.Printf("* Creating download/ in %s directory", versionPath)
|
||||
downloadsPath := path.Join(versionPath, "download")
|
||||
err = CreateDir(downloadsPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create darwin, freebsd, linux, windows dirs
|
||||
for _, v := range [4]string{"darwin", "freebsd", "linux", "windows"} {
|
||||
err = CreateDir(path.Join(downloadsPath, v))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating dir '%s': %w", path.Join(downloadsPath, v), err)
|
||||
}
|
||||
}
|
||||
|
||||
// Copy all zips
|
||||
err = p.copyBuildZips(downloadsPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create all individual files for build targets and each architecture for the build targets
|
||||
err = p.CreateArchitectureFiles()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) copyBuildZips(destPath string) error {
|
||||
log.Println("* Copying build zips")
|
||||
|
||||
shaSums, err := p.GetShaSums()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Loop through and copy each
|
||||
for _, sum := range shaSums {
|
||||
zipSrcPath := path.Join(p.DistPath, sum.Path)
|
||||
zipDestPath := path.Join(destPath, sum.Path)
|
||||
|
||||
log.Printf(" - Zip Source: %s", zipSrcPath)
|
||||
log.Printf(" - Zip Dest: %s", zipDestPath)
|
||||
|
||||
// Copy the zip
|
||||
_, err = CopyFile(zipSrcPath, zipDestPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error copying file '%s': %w", zipSrcPath, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) copyShaFiles(destPath string) error {
|
||||
log.Printf("* Copying SHA files in %s directory", p.DistPath)
|
||||
|
||||
// Copy files from srcPath
|
||||
shaSum := p.RepoName + "_" + p.Version + "_SHA256SUMS"
|
||||
shaSumPath := path.Join(p.DistPath, shaSum)
|
||||
|
||||
// _SHA256SUMS file
|
||||
_, err := CopyFile(shaSumPath, path.Join(destPath, shaSum))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// _SHA256SUMS.sig file
|
||||
_, err = CopyFile(shaSumPath+".sig", path.Join(destPath, shaSum+".sig"))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) createVersionsFile() error {
|
||||
log.Println("* Writing to release/v1/providers/[namespace]/[repo]/versions file")
|
||||
|
||||
versionPath := path.Join("release", "v1", "providers", p.Namespace, p.Provider, "versions")
|
||||
|
||||
shasums, err := p.GetShaSums()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting sha sums: %w", err)
|
||||
}
|
||||
|
||||
// Build the versions file...
|
||||
version := Version{
|
||||
Version: p.Version,
|
||||
Protocols: []string{"5.1", "6.1"},
|
||||
Platforms: nil,
|
||||
}
|
||||
for _, sum := range shasums {
|
||||
// get os and arch from filename
|
||||
removeFileExtension := strings.Split(sum.Path, ".zip")
|
||||
if len(removeFileExtension) < 1 {
|
||||
log.Fatalf("error: %s does not have .zip extension", sum.Path)
|
||||
}
|
||||
fileNameSplit := strings.Split(removeFileExtension[0], "_")
|
||||
if len(fileNameSplit) < 4 {
|
||||
log.Fatalf("filename does not match our regex: %s", removeFileExtension[0])
|
||||
}
|
||||
|
||||
// Get build target and architecture from the zip file name
|
||||
target := fileNameSplit[2]
|
||||
arch := fileNameSplit[3]
|
||||
|
||||
version.Platforms = append(
|
||||
version.Platforms, Platform{
|
||||
OS: target,
|
||||
Arch: arch,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
data := Data{}
|
||||
|
||||
downloadPath := path.Join(p.Domain, "v1", "providers", p.Namespace, p.Provider, "versions")
|
||||
err = data.LoadFromUrl(fmt.Sprintf("https://%s", downloadPath))
|
||||
if err != nil {
|
||||
slog.Warn("error getting existing versions file, start with empty")
|
||||
// TODO: create flag for first use or make it more robust
|
||||
// return fmt.Errorf("error getting existing versions file: %w", err)
|
||||
}
|
||||
|
||||
err = data.AddVersion(version)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error appending version: %w", err)
|
||||
}
|
||||
|
||||
err = data.WriteToFile(versionPath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error saving file '%s':%w", versionPath, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (p *Provider) providerDirs() string {
|
||||
log.Println("* Creating release/v1/providers/[namespace]/[provider]/[version] directories")
|
||||
|
||||
target := path.Join("release", "v1", "providers", p.Namespace, p.Provider, p.Version)
|
||||
|
||||
err := CreateDir(target)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
func (p *Provider) CreateWellKnown() error {
|
||||
log.Println("* Creating .well-known directory")
|
||||
pathString := path.Join(p.RootPath, "release", ".well-known")
|
||||
|
||||
//nolint:gosec // this file is not sensitive, so we can use ModePerm
|
||||
err := os.MkdirAll(pathString, os.ModePerm)
|
||||
if err != nil && !errors.Is(err, fs.ErrExist) {
|
||||
return fmt.Errorf("error creating '%s' dir: %w", pathString, err)
|
||||
}
|
||||
|
||||
log.Println(" - Writing to .well-known/terraform.json file")
|
||||
|
||||
//nolint:gosec // this file is not sensitive, so we can use 0644
|
||||
err = os.WriteFile(
|
||||
fmt.Sprintf("%s/terraform.json", pathString),
|
||||
[]byte(`{"providers.v1": "/v1/providers/"}`),
|
||||
0o644,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateDir(pathValue string) error {
|
||||
log.Printf("* Creating %s directory", pathValue)
|
||||
//nolint:gosec // this file is not sensitive, so we can use ModePerm
|
||||
err := os.MkdirAll(pathValue, os.ModePerm)
|
||||
if errors.Is(err, fs.ErrExist) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func ReadFile(filePath string) ([]string, error) {
|
||||
rFile, err := os.Open(filePath)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileScanner := bufio.NewScanner(rFile)
|
||||
fileScanner.Split(bufio.ScanLines)
|
||||
var fileLines []string
|
||||
|
||||
for fileScanner.Scan() {
|
||||
fileLines = append(fileLines, fileScanner.Text())
|
||||
}
|
||||
|
||||
err = rFile.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fileLines, nil
|
||||
}
|
||||
|
||||
func CopyFile(src, dst string) (int64, error) {
|
||||
sourceFileStat, err := os.Stat(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !sourceFileStat.Mode().IsRegular() {
|
||||
return 0, fmt.Errorf("%s is not a regular file", src)
|
||||
}
|
||||
|
||||
source, err := os.Open(src)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func(source *os.File) {
|
||||
err := source.Close()
|
||||
if err != nil {
|
||||
slog.Error("error closing source file", slog.Any("err", err))
|
||||
}
|
||||
}(source)
|
||||
|
||||
destination, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer func(destination *os.File) {
|
||||
err := destination.Close()
|
||||
if err != nil {
|
||||
slog.Error("error closing destination file", slog.Any("err", err))
|
||||
}
|
||||
}(destination)
|
||||
nBytes, err := io.Copy(destination, source)
|
||||
return nBytes, err
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue