mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-12-15 16:09:39 -05:00
bazel: deps mirror (#1522)
bazel-deps-mirror is an internal tools used to upload external dependencies that are referenced in the Bazel WORKSPACE to the Edgeless Systems' mirror. It also normalizes deps rules. * hack: add tool to mirror Bazel dependencies * hack: bazel-deps-mirror tests * bazel: add deps mirror commands * ci: upload Bazel dependencies on renovate PRs * update go mod * run deps_mirror_upload Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com> Co-authored-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
parent
d3e2f30f7b
commit
827c4f548d
36 changed files with 2698 additions and 529 deletions
158
hack/bazel-deps-mirror/internal/bazelfiles/files.go
Normal file
158
hack/bazel-deps-mirror/internal/bazelfiles/files.go
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// package bazelfiles is used to find and handle Bazel WORKSPACE and bzl files.
|
||||
package bazelfiles
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/bazelbuild/buildtools/build"
|
||||
"github.com/hexops/gotextdiff"
|
||||
"github.com/hexops/gotextdiff/myers"
|
||||
"github.com/hexops/gotextdiff/span"
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
// Helper is used to find and handle Bazel WORKSPACE and bzl files.
|
||||
type Helper struct {
|
||||
fs afero.Fs
|
||||
workspaceRoot string
|
||||
}
|
||||
|
||||
// New creates a new BazelFilesHelper.
|
||||
func New() (*Helper, error) {
|
||||
workspaceRoot, err := findWorkspaceRoot(os.LookupEnv)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Helper{
|
||||
fs: afero.NewBasePathFs(afero.NewOsFs(), workspaceRoot),
|
||||
workspaceRoot: workspaceRoot,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// FindFiles returns the paths to all Bazel files in the Bazel workspace.
|
||||
func (h *Helper) FindFiles() ([]BazelFile, error) {
|
||||
workspaceFile, err := h.findWorkspaceFile()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
bzlFiles, err := h.findBzlFiles()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return append(bzlFiles, workspaceFile), nil
|
||||
}
|
||||
|
||||
// findWorkspaceFile returns the path to the Bazel WORKSPACE.bazel file (or WORKSPACE if the former doesn't exist).
|
||||
func (h *Helper) findWorkspaceFile() (BazelFile, error) {
|
||||
if _, err := h.fs.Stat("WORKSPACE.bazel"); err == nil {
|
||||
return BazelFile{
|
||||
RelPath: "WORKSPACE.bazel",
|
||||
AbsPath: filepath.Join(h.workspaceRoot, "WORKSPACE.bazel"),
|
||||
Type: BazelFileTypeWorkspace,
|
||||
}, nil
|
||||
}
|
||||
if _, err := h.fs.Stat("WORKSPACE"); err == nil {
|
||||
return BazelFile{
|
||||
RelPath: "WORKSPACE",
|
||||
AbsPath: filepath.Join(h.workspaceRoot, "WORKSPACE"),
|
||||
Type: BazelFileTypeWorkspace,
|
||||
}, nil
|
||||
}
|
||||
return BazelFile{}, fmt.Errorf("failed to find Bazel WORKSPACE file")
|
||||
}
|
||||
|
||||
// findBzlFiles returns the paths to all .bzl files in the Bazel workspace.
|
||||
func (h *Helper) findBzlFiles() ([]BazelFile, error) {
|
||||
var bzlFiles []BazelFile
|
||||
err := afero.Walk(h.fs, ".", func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
if filepath.Ext(path) != ".bzl" {
|
||||
return nil
|
||||
}
|
||||
bzlFiles = append(bzlFiles, BazelFile{
|
||||
RelPath: path,
|
||||
AbsPath: filepath.Join(h.workspaceRoot, path),
|
||||
Type: BazelFileTypeBzl,
|
||||
})
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return bzlFiles, nil
|
||||
}
|
||||
|
||||
// LoadFile loads a Bazel file.
|
||||
func (h *Helper) LoadFile(bf BazelFile) (*build.File, error) {
|
||||
data, err := afero.ReadFile(h.fs, bf.RelPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch bf.Type {
|
||||
case BazelFileTypeBzl:
|
||||
return build.ParseBzl(bf.AbsPath, data)
|
||||
case BazelFileTypeWorkspace:
|
||||
return build.ParseWorkspace(bf.AbsPath, data)
|
||||
}
|
||||
return nil, fmt.Errorf("unknown Bazel file type: %d", bf.Type)
|
||||
}
|
||||
|
||||
// WriteFile writes (updates) a Bazel file.
|
||||
func (h *Helper) WriteFile(bf BazelFile, buildfile *build.File) error {
|
||||
return afero.WriteFile(h.fs, bf.RelPath, build.Format(buildfile), 0o644)
|
||||
}
|
||||
|
||||
// Diff returns the diff between the saved and the updated (in-memory) version of a Bazel file.
|
||||
func (h *Helper) Diff(bf BazelFile, buildfile *build.File) (string, error) {
|
||||
savedData, err := afero.ReadFile(h.fs, bf.RelPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
updatedData := build.Format(buildfile)
|
||||
edits := myers.ComputeEdits(span.URIFromPath(bf.RelPath), string(savedData), string(updatedData))
|
||||
diff := fmt.Sprint(gotextdiff.ToUnified("a/"+bf.RelPath, "b/"+bf.RelPath, string(savedData), edits))
|
||||
return diff, nil
|
||||
}
|
||||
|
||||
// findWorkspaceRoot returns the path to the Bazel workspace root.
|
||||
func findWorkspaceRoot(lookupEnv LookupEnv) (string, error) {
|
||||
workspaceRoot, ok := lookupEnv("BUILD_WORKSPACE_DIRECTORY")
|
||||
if !ok {
|
||||
return "", fmt.Errorf("failed to find Bazel workspace root: not executed via \"bazel run\" and BUILD_WORKSPACE_DIRECTORY not set")
|
||||
}
|
||||
return workspaceRoot, nil
|
||||
}
|
||||
|
||||
// BazelFile is a reference (path) to a Bazel file.
|
||||
type BazelFile struct {
|
||||
RelPath string
|
||||
AbsPath string
|
||||
Type BazelFileType
|
||||
}
|
||||
|
||||
// BazelFileType is the type of a Bazel file.
|
||||
type BazelFileType int
|
||||
|
||||
const (
|
||||
BazelFileTypeBzl = iota // BazelFileTypeBzl is a .bzl file
|
||||
BazelFileTypeWorkspace // BazelFileTypeWorkspace is a WORKSPACE or WORKSPACE.bazel file
|
||||
)
|
||||
|
||||
// LookupEnv can be the real os.LookupEnv or a mock for testing.
|
||||
type LookupEnv func(key string) (string, bool)
|
||||
Loading…
Add table
Add a link
Reference in a new issue