refactor: replace global 'buildr' variable with 'repo' and 'vcs'
This commit is contained in:
parent
99f863f1d6
commit
ab282b8dc0
|
@ -19,7 +19,7 @@ build "go_build" "linux" {
|
|||
|
||||
ldflags = [
|
||||
"-w -s",
|
||||
"-X 'code.icb4dc0.de/buildr/buildr/cmd.CurrentVersion=${buildr.repo.git.tag == "" ? buildr.repo.git.branch : buildr.repo.git.tag}'"
|
||||
"-X 'code.icb4dc0.de/buildr/buildr/cmd.CurrentVersion=${vcs.tag == "" ? vcs.branch : vcs.tag}'"
|
||||
]
|
||||
|
||||
environment = {
|
||||
|
|
|
@ -29,7 +29,7 @@ package "container_image" "buildr_image" {
|
|||
}
|
||||
|
||||
input_mapping = {
|
||||
"${buildr.repo.root}" = "."
|
||||
"${repo.root}" = "."
|
||||
"${builds.linux["amd64"].out_dir}" = "out/"
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
task "script" "go_fmt" {
|
||||
inline = [
|
||||
"go fmt ${join(" ", toset([for s in vcs.staged_files : "code.icb4dc0.de/buildr/buildr/${dirname(s)}" if ext(s) == ".go"]))}"
|
||||
]
|
||||
}
|
||||
|
||||
task "script" "buf_generate" {
|
||||
inline = [
|
||||
"buf generate --debug"
|
||||
]
|
||||
|
||||
out_dir = buildr.repo.root
|
||||
out_dir = repo.root
|
||||
|
||||
input_mapping = {
|
||||
"api" = "api",
|
||||
|
@ -48,7 +54,7 @@ task "script" "go_test" {
|
|||
}
|
||||
|
||||
input_mapping = {
|
||||
"${buildr.repo.root}" = "."
|
||||
"${repo.root}" = "."
|
||||
}
|
||||
|
||||
container {
|
||||
|
@ -73,11 +79,12 @@ task "script" "golangci_lint" {
|
|||
]
|
||||
|
||||
depends_on = [
|
||||
tasks.go_fmt.id,
|
||||
tasks.go_generate.id,
|
||||
tools.golangci_lint.id
|
||||
]
|
||||
|
||||
input_mapping = {
|
||||
"${buildr.repo.root}" = "."
|
||||
"${repo.root}" = "."
|
||||
}
|
||||
}
|
|
@ -5,7 +5,7 @@ import (
|
|||
"flag"
|
||||
"io"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
"code.icb4dc0.de/buildr/buildr/internal/execution"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/internal/rpc"
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
|
@ -43,8 +43,8 @@ func (c *VaultInitConfig) Flags() *flag.FlagSet {
|
|||
return fs
|
||||
}
|
||||
|
||||
type BuildrAccessor interface {
|
||||
BuildR() buildr.Buildr
|
||||
type ExecutionSpecAccessor interface {
|
||||
ExecutionSpec() execution.Spec
|
||||
}
|
||||
|
||||
type AppConfigAccessor interface {
|
||||
|
|
|
@ -33,8 +33,8 @@ import (
|
|||
"code.icb4dc0.de/buildr/buildr/internal/vault"
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/build"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/packaging"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/repo"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/task"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/tool"
|
||||
|
||||
|
@ -155,15 +155,17 @@ var (
|
|||
|
||||
type App struct {
|
||||
*services.Collection
|
||||
loggingCfg logging.Config
|
||||
appCfg AppConfig
|
||||
rootCmd *cobra.Command
|
||||
recorder *profiling.Recorder
|
||||
initializers map[InitLevel]AppInitializer
|
||||
buildrInstance *buildr.Buildr
|
||||
repo *modules.Repository
|
||||
pluginMgr *modules.PluginManager
|
||||
parsingState struct {
|
||||
loggingCfg logging.Config
|
||||
appCfg AppConfig
|
||||
rootCmd *cobra.Command
|
||||
recorder *profiling.Recorder
|
||||
initializers map[InitLevel]AppInitializer
|
||||
execSpec *execution.Spec
|
||||
vcs any
|
||||
repoDetails repo.Repo
|
||||
repo *modules.Repository
|
||||
pluginMgr *modules.PluginManager
|
||||
parsingState struct {
|
||||
parsingRemainder hcl2.Body
|
||||
currentEvalCtx *hcl2.EvalContext
|
||||
}
|
||||
|
@ -238,8 +240,8 @@ func (a *App) AppConfig() AppConfig {
|
|||
return a.appCfg
|
||||
}
|
||||
|
||||
func (a *App) BuildR() buildr.Buildr {
|
||||
return *a.buildrInstance
|
||||
func (a *App) ExecutionSpec() execution.Spec {
|
||||
return *a.execSpec
|
||||
}
|
||||
|
||||
func (a *App) BootstrapModule(cat modules.Category, typeName, moduleName string) error {
|
||||
|
@ -278,7 +280,7 @@ func (a *App) RunModule(ctx context.Context, cat modules.Category, name string)
|
|||
return err
|
||||
}
|
||||
|
||||
return plan.Execute(ctx, *a.buildrInstance)
|
||||
return plan.Execute(ctx, *a.execSpec)
|
||||
}
|
||||
|
||||
func (a *App) ArgProviderFor(cat modules.Category) ModuleArgsProvider {
|
||||
|
@ -326,7 +328,11 @@ func (a *App) basicParseConfig(ctx context.Context) (err error) {
|
|||
|
||||
_ = a.Collection.With(services.WithDiagnosticsWriter(parser.DiagsWriter()))
|
||||
|
||||
if a.buildrInstance, err = completeSpec.BuildrCfg.InitBuildr(a.appCfg.BuildRDirectory, a.appCfg.RepoRoot); err != nil {
|
||||
if a.vcs, a.repoDetails, err = a.appCfg.ParseVCSInfo(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if a.execSpec, err = completeSpec.BuildrCfg.PrepareExecutionSpec(a.appCfg.BuildRDirectory, a.appCfg.RepoRoot); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -335,12 +341,12 @@ func (a *App) basicParseConfig(ctx context.Context) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
a.pluginMgr = modules.NewPluginManager(a.StateStore(), a.buildrInstance.Config.CacheDirectory)
|
||||
a.pluginMgr = modules.NewPluginManager(a.StateStore(), a.execSpec.CacheDirectory)
|
||||
if err = a.pluginMgr.Add(ctx, pluginURLs...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if a.repo, err = completeSpec.ModulesSpec.Repository(evalCtx, a.DiagsWriter(), *a.buildrInstance, a.TypeRegistry()); err != nil {
|
||||
if a.repo, err = completeSpec.ModulesSpec.Repository(evalCtx, a.DiagsWriter(), a.TypeRegistry(), a.execSpec.OutDirectory); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -393,7 +399,11 @@ func (a *App) initBuildRConfig(ctx context.Context) (err error) {
|
|||
|
||||
_ = a.Collection.With(services.WithDiagnosticsWriter(parser.DiagsWriter()))
|
||||
|
||||
a.buildrInstance, err = buildrCfg.InitBuildr(a.appCfg.BuildRDirectory, a.appCfg.RepoRoot)
|
||||
if a.vcs, a.repoDetails, err = a.appCfg.ParseVCSInfo(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.execSpec, err = buildrCfg.PrepareExecutionSpec(a.appCfg.BuildRDirectory, a.appCfg.RepoRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -403,16 +413,12 @@ func (a *App) initBuildRConfig(ctx context.Context) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
a.pluginMgr = modules.NewPluginManager(a.StateStore(), a.buildrInstance.Config.CacheDirectory)
|
||||
a.pluginMgr = modules.NewPluginManager(a.StateStore(), a.execSpec.CacheDirectory)
|
||||
if err = a.pluginMgr.Add(ctx, pluginURLs...); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = a.Collection.With(services.WithGitHubTokenClient(ctx, a.buildrInstance.GitHub.APIToken)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = copyCurrentBinaryToBinariesDir(a.buildrInstance.Config.BinariesDirectory); err != nil {
|
||||
if err = copyCurrentBinaryToBinariesDir(a.execSpec.BinariesDirectory); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -434,7 +440,15 @@ func (a *App) initParseConfigs(ctx context.Context) (err error) {
|
|||
return errs.ErrAlreadyLogged
|
||||
}
|
||||
|
||||
if a.repo, err = rawSpec.Repository(evalCtx, a.DiagsWriter(), *a.buildrInstance, a.TypeRegistry()); err != nil {
|
||||
a.repo, err = rawSpec.Repository(
|
||||
evalCtx,
|
||||
a.DiagsWriter(),
|
||||
a.TypeRegistry(),
|
||||
a.execSpec.OutDirectory,
|
||||
hcl.WithGlobalVariable("vcs", a.vcs),
|
||||
hcl.WithGlobalVariable("repo", a.repoDetails),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -9,16 +9,16 @@ import (
|
|||
|
||||
var _ EnvCommander = (*EnvApp)(nil)
|
||||
|
||||
func NewEnvApp(initializer LevelInitializer, accessor BuildrAccessor) *EnvApp {
|
||||
func NewEnvApp(initializer LevelInitializer, accessor ExecutionSpecAccessor) *EnvApp {
|
||||
return &EnvApp{
|
||||
initializer: initializer,
|
||||
buildrAccessor: accessor,
|
||||
initializer: initializer,
|
||||
executionSpecAccessor: accessor,
|
||||
}
|
||||
}
|
||||
|
||||
type EnvApp struct {
|
||||
initializer LevelInitializer
|
||||
buildrAccessor BuildrAccessor
|
||||
initializer LevelInitializer
|
||||
executionSpecAccessor ExecutionSpecAccessor
|
||||
}
|
||||
|
||||
func (e EnvApp) PrintPath(writer io.Writer) (err error) {
|
||||
|
@ -26,14 +26,14 @@ func (e EnvApp) PrintPath(writer io.Writer) (err error) {
|
|||
return err
|
||||
}
|
||||
|
||||
buildr := e.buildrAccessor.BuildR()
|
||||
execSpec := e.executionSpecAccessor.ExecutionSpec()
|
||||
currentPath, ok := os.LookupEnv("PATH")
|
||||
if !ok {
|
||||
_, err = fmt.Fprintf(writer, "PATH=%s", buildr.Config.BinariesDirectory)
|
||||
_, err = fmt.Fprintf(writer, "PATH=%s", execSpec.BinariesDirectory)
|
||||
return err
|
||||
}
|
||||
|
||||
joinedPath := strings.Join([]string{buildr.Config.BinariesDirectory, currentPath}, string(os.PathListSeparator))
|
||||
joinedPath := strings.Join([]string{execSpec.BinariesDirectory, currentPath}, string(os.PathListSeparator))
|
||||
_, err = fmt.Fprintf(writer, "PATH=%s", joinedPath)
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -4,12 +4,16 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/internal/semver"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/repo"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/state"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/internal/config"
|
||||
|
@ -42,6 +46,30 @@ type AppConfig struct {
|
|||
}
|
||||
}
|
||||
|
||||
func (c *AppConfig) ParseVCSInfo() (vcsDetails any, repoDetails repo.Repo, err error) {
|
||||
repoDetails.Root = c.RepoRoot
|
||||
|
||||
switch c.VCSType {
|
||||
case vcs.TypeGit:
|
||||
gitInfo, err := vcs.ParseGitInfo(c.RepoRoot)
|
||||
if err != nil {
|
||||
return nil, repoDetails, err
|
||||
}
|
||||
|
||||
if tag := gitInfo.Tag; tag != "" && semver.IsValid(tag) {
|
||||
if repoDetails.Version, err = semver.ParseVersion(tag); err != nil {
|
||||
return nil, repoDetails, err
|
||||
} else {
|
||||
return gitInfo, repoDetails, nil
|
||||
}
|
||||
} else {
|
||||
return gitInfo, repoDetails, nil
|
||||
}
|
||||
default:
|
||||
return nil, repoDetails, fmt.Errorf("unsupported VCS type: %s", c.VCSType)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *AppConfig) RepoFS() fs.FS {
|
||||
return os.DirFS(c.RepoRoot)
|
||||
}
|
||||
|
|
|
@ -4,16 +4,23 @@ import (
|
|||
"context"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
)
|
||||
|
||||
type Spec struct {
|
||||
RepoRoot string
|
||||
BinariesDirectory string
|
||||
CacheDirectory string
|
||||
OutDirectory string
|
||||
LogsDirectory string
|
||||
LogToStdErr bool
|
||||
}
|
||||
|
||||
type TaskProvider interface {
|
||||
CanProvide(m modules.ModuleWithMeta) bool
|
||||
Create(m modules.ModuleWithMeta) (Task, error)
|
||||
}
|
||||
|
||||
type Task interface {
|
||||
Execute(ctx context.Context, b buildr.Buildr) error
|
||||
Execute(ctx context.Context, spec Spec) error
|
||||
AddDependentTask(other Task)
|
||||
}
|
||||
|
|
|
@ -3,8 +3,6 @@ package execution
|
|||
import (
|
||||
"context"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
|
@ -16,7 +14,7 @@ func (d *TaskDependencies) AddDependentTask(other Task) {
|
|||
*d = deps
|
||||
}
|
||||
|
||||
func (d *TaskDependencies) Execute(ctx context.Context, b buildr.Buildr) error {
|
||||
func (d *TaskDependencies) Execute(ctx context.Context, spec Spec) error {
|
||||
if len(*d) < 1 {
|
||||
return nil
|
||||
}
|
||||
|
@ -27,7 +25,7 @@ func (d *TaskDependencies) Execute(ctx context.Context, b buildr.Buildr) error {
|
|||
for i := range deps {
|
||||
dep := deps[i]
|
||||
grp.Go(func() error {
|
||||
return dep.Execute(grpCtx, b)
|
||||
return dep.Execute(grpCtx, spec)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ import (
|
|||
"code.icb4dc0.de/buildr/buildr/internal/ioutils"
|
||||
"code.icb4dc0.de/buildr/buildr/internal/logging"
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
)
|
||||
|
||||
type containerTask struct {
|
||||
|
@ -37,16 +36,16 @@ type containerTask struct {
|
|||
moduleWithMeta modules.ModuleWithMeta
|
||||
}
|
||||
|
||||
func (c *containerTask) Execute(ctx context.Context, b buildr.Buildr) (err error) {
|
||||
func (c *containerTask) Execute(ctx context.Context, spec execution.Spec) (err error) {
|
||||
c.once.Do(func() {
|
||||
err = c.doExecute(ctx, b)
|
||||
err = c.doExecute(ctx, spec)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *containerTask) doExecute(ctx context.Context, b buildr.Buildr) (err error) {
|
||||
if err = c.TaskDependencies.Execute(ctx, b); err != nil {
|
||||
func (c *containerTask) doExecute(ctx context.Context, spec execution.Spec) (err error) {
|
||||
if err = c.TaskDependencies.Execute(ctx, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -81,8 +80,8 @@ func (c *containerTask) doExecute(ctx context.Context, b buildr.Buildr) (err err
|
|||
}
|
||||
|
||||
outputSink, err := logging.NewTaskOutputSink(
|
||||
b.Config.Logging.LogsDirectory,
|
||||
b.Config.Logging.LogToStdErr,
|
||||
spec.LogsDirectory,
|
||||
spec.LogToStdErr,
|
||||
modules.LogFileNameFormatter(c.moduleWithMeta),
|
||||
)
|
||||
if err != nil {
|
||||
|
@ -96,25 +95,25 @@ func (c *containerTask) doExecute(ctx context.Context, b buildr.Buildr) (err err
|
|||
inputMappings := c.moduleWithMeta.InputMappings()
|
||||
|
||||
if len(inputMappings) == 0 {
|
||||
inputMappings[b.Repo.Root] = "."
|
||||
inputMappings[spec.RepoRoot] = "."
|
||||
}
|
||||
|
||||
containerSpec := c.moduleWithMeta.ContainerSpec()
|
||||
spec := containers.BuildRContainerSpec{
|
||||
buildrContainerSpec := containers.BuildRContainerSpec{
|
||||
ID: c.moduleWithMeta.ID(),
|
||||
ModuleName: c.moduleWithMeta.Name(),
|
||||
Image: containerSpec.Image,
|
||||
User: containerSpec.User,
|
||||
Privileged: containerSpec.Privileged,
|
||||
RepoRoot: b.Repo.Root,
|
||||
RepoRoot: spec.RepoRoot,
|
||||
Content: inputMappings,
|
||||
BinariesDir: b.Config.BinariesDirectory,
|
||||
BinariesDir: spec.BinariesDirectory,
|
||||
ExtraBinaries: extraBinaries,
|
||||
Mounts: containerSpec.Mounts(),
|
||||
}
|
||||
|
||||
logger.Debug("Preparing container")
|
||||
con, grpcConn, err := c.orchestrator.BuildRContainer(ctx, spec)
|
||||
con, grpcConn, err := c.orchestrator.BuildRContainer(ctx, buildrContainerSpec)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create container for task %s/%s: %w", c.moduleWithMeta.Type(), c.moduleWithMeta.Name(), err)
|
||||
}
|
||||
|
@ -195,7 +194,7 @@ func (c *containerTask) doExecute(ctx context.Context, b buildr.Buildr) (err err
|
|||
if msg.TaskResult.ModifiedFilesArchivePath != "" {
|
||||
outDir := c.moduleWithMeta.OutDir()
|
||||
if c.moduleWithMeta.Category() == modules.CategoryTool {
|
||||
outDir = b.Config.BinariesDirectory
|
||||
outDir = spec.BinariesDirectory
|
||||
}
|
||||
if err := c.handleModifiedFiles(ctx, con, msg.TaskResult.ModifiedFilesArchivePath, outDir); err != nil {
|
||||
return fmt.Errorf("failed to fetch modified files from execution container: %w", err)
|
||||
|
|
|
@ -13,8 +13,6 @@ import (
|
|||
"code.icb4dc0.de/buildr/buildr/internal/execution"
|
||||
"code.icb4dc0.de/buildr/buildr/internal/storage"
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
|
||||
"golang.org/x/exp/slog"
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
@ -28,16 +26,16 @@ type localTask struct {
|
|||
stateStore state.Store
|
||||
}
|
||||
|
||||
func (t *localTask) Execute(ctx context.Context, b buildr.Buildr) (err error) {
|
||||
func (t *localTask) Execute(ctx context.Context, spec execution.Spec) (err error) {
|
||||
t.once.Do(func() {
|
||||
err = t.doExecute(ctx, b)
|
||||
err = t.doExecute(ctx, spec)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (t *localTask) doExecute(ctx context.Context, b buildr.Buildr) (err error) {
|
||||
if err = t.TaskDependencies.Execute(ctx, b); err != nil {
|
||||
func (t *localTask) doExecute(ctx context.Context, spec execution.Spec) (err error) {
|
||||
if err = t.TaskDependencies.Execute(ctx, spec); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -52,17 +50,15 @@ func (t *localTask) doExecute(ctx context.Context, b buildr.Buildr) (err error)
|
|||
}
|
||||
|
||||
if mappings := t.module.InputMappings(); len(mappings) > 0 || t.module.Category() == modules.CategoryTool {
|
||||
return t.executeIsolated(ctx, b)
|
||||
return t.executeIsolated(ctx, spec)
|
||||
}
|
||||
|
||||
execCtx, err := t.executionContextFor(
|
||||
ctx,
|
||||
t.module,
|
||||
b.Repo.Root,
|
||||
spec,
|
||||
spec.RepoRoot,
|
||||
t.module.OutDir(),
|
||||
b.Config.BinariesDirectory,
|
||||
b.Config.Logging.LogsDirectory,
|
||||
b.Config.Logging.LogToStdErr,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to prepare execution context: %w", err)
|
||||
|
@ -80,7 +76,7 @@ func (t *localTask) doExecute(ctx context.Context, b buildr.Buildr) (err error)
|
|||
return t.module.Execute(execCtx)
|
||||
}
|
||||
|
||||
func (t *localTask) executeIsolated(ctx context.Context, b buildr.Buildr) error {
|
||||
func (t *localTask) executeIsolated(ctx context.Context, spec execution.Spec) error {
|
||||
workDir, err := os.MkdirTemp(os.TempDir(), "buildr-work-*")
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -92,7 +88,7 @@ func (t *localTask) executeIsolated(ctx context.Context, b buildr.Buildr) error
|
|||
|
||||
outDir := t.module.OutDir()
|
||||
if t.module.Category() == modules.CategoryTool {
|
||||
outDir = b.Config.BinariesDirectory
|
||||
outDir = spec.BinariesDirectory
|
||||
}
|
||||
|
||||
mappings := t.module.InputMappings()
|
||||
|
@ -106,7 +102,7 @@ func (t *localTask) executeIsolated(ctx context.Context, b buildr.Buildr) error
|
|||
}
|
||||
|
||||
if !filepath.IsAbs(outDir) {
|
||||
outDir = filepath.Join(b.Repo.Root, outDir)
|
||||
outDir = filepath.Join(spec.RepoRoot, outDir)
|
||||
}
|
||||
|
||||
ufs := storage.NewUnionFS(outDir)
|
||||
|
@ -136,16 +132,13 @@ func (t *localTask) executeIsolated(ctx context.Context, b buildr.Buildr) error
|
|||
defer func() {
|
||||
err = errors.Join(err, srv.Unmount())
|
||||
}()
|
||||
b.Repo.Root = workDir
|
||||
|
||||
execCtx, err := t.executionContextFor(
|
||||
grpcCtx,
|
||||
t.module,
|
||||
spec,
|
||||
workDir,
|
||||
outDir,
|
||||
b.Config.BinariesDirectory,
|
||||
b.Config.Logging.LogsDirectory,
|
||||
b.Config.Logging.LogToStdErr,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
|
@ -161,8 +154,8 @@ func (t *localTask) executeIsolated(ctx context.Context, b buildr.Buildr) error
|
|||
func (t *localTask) executionContextFor(
|
||||
ctx context.Context,
|
||||
m modules.ModuleWithMeta,
|
||||
workingDir, outDir, binDir, logsDir string,
|
||||
logToStdErr bool,
|
||||
spec execution.Spec,
|
||||
workingDir, outDir string,
|
||||
) (DefaultExecutionContext, error) {
|
||||
return NewDefaultExecutionContext(
|
||||
ctx,
|
||||
|
@ -170,9 +163,9 @@ func (t *localTask) executionContextFor(
|
|||
m,
|
||||
workingDir,
|
||||
outDir,
|
||||
binDir,
|
||||
logsDir,
|
||||
logToStdErr,
|
||||
spec.BinariesDirectory,
|
||||
spec.LogsDirectory,
|
||||
spec.LogToStdErr,
|
||||
WithLoggerFactory(func() *slog.Logger {
|
||||
return slog.Default().With(
|
||||
slog.String("module_name", m.Name()),
|
||||
|
|
|
@ -5,8 +5,6 @@ import (
|
|||
"fmt"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
)
|
||||
|
||||
func NewPlanFor(
|
||||
|
@ -34,6 +32,6 @@ type Plan struct {
|
|||
entryPoint Task
|
||||
}
|
||||
|
||||
func (p *Plan) Execute(ctx context.Context, b buildr.Buildr) error {
|
||||
return p.entryPoint.Execute(ctx, b)
|
||||
func (p *Plan) Execute(ctx context.Context, spec Spec) error {
|
||||
return p.entryPoint.Execute(ctx, spec)
|
||||
}
|
||||
|
|
|
@ -5,10 +5,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/internal/semver"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/vcs"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
"code.icb4dc0.de/buildr/buildr/internal/execution"
|
||||
)
|
||||
|
||||
const defaultDirectoryPermissions = 0o755
|
||||
|
@ -45,83 +42,65 @@ func (c BuildrConfig) PluginURLs() (pluginUrls []*url.URL, err error) {
|
|||
return pluginUrls, nil
|
||||
}
|
||||
|
||||
func (c BuildrConfig) InitBuildr(buildRDir, repoRoot string) (b *buildr.Buildr, err error) {
|
||||
b = &buildr.Buildr{
|
||||
Repo: buildr.Repo{
|
||||
Root: repoRoot,
|
||||
},
|
||||
}
|
||||
|
||||
if c.GitHub != nil {
|
||||
b.GitHub.APIToken = c.GitHub.APIToken
|
||||
}
|
||||
|
||||
if b.Repo.Git, err = vcs.ParseGitInfo(repoRoot); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if b.Repo.Git != nil {
|
||||
if tag := b.Repo.Git.Tag; tag != "" && semver.IsValid(tag) {
|
||||
if b.Repo.Version, err = semver.ParseVersion(tag); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
func (c BuildrConfig) PrepareExecutionSpec(buildRDir, repoRoot string) (s *execution.Spec, err error) {
|
||||
s = &execution.Spec{
|
||||
RepoRoot: repoRoot,
|
||||
}
|
||||
|
||||
if cacheDir, err := os.UserCacheDir(); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
b.Config.CacheDirectory = filepath.Join(cacheDir, "buildr")
|
||||
s.CacheDirectory = filepath.Join(cacheDir, "buildr")
|
||||
}
|
||||
|
||||
if err = c.createCleanDir(b.Config.CacheDirectory, false); err != nil {
|
||||
if err = c.createCleanDir(s.CacheDirectory, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if filepath.IsAbs(c.BinariesDirectory) {
|
||||
b.Config.BinariesDirectory = c.BinariesDirectory
|
||||
s.BinariesDirectory = c.BinariesDirectory
|
||||
} else if c.BinariesDirectory == "" {
|
||||
b.Config.BinariesDirectory = filepath.Join(buildRDir, "bin")
|
||||
s.BinariesDirectory = filepath.Join(buildRDir, "bin")
|
||||
} else {
|
||||
b.Config.BinariesDirectory = filepath.Join(b.Repo.Root, c.BinariesDirectory)
|
||||
s.BinariesDirectory = filepath.Join(repoRoot, c.BinariesDirectory)
|
||||
}
|
||||
|
||||
if err = c.createCleanDir(b.Config.BinariesDirectory, false); err != nil {
|
||||
if err = c.createCleanDir(s.BinariesDirectory, false); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if filepath.IsAbs(c.OutDirectory) {
|
||||
b.Config.OutDirectory = c.OutDirectory
|
||||
s.OutDirectory = c.OutDirectory
|
||||
} else if c.OutDirectory == "" {
|
||||
b.Config.OutDirectory = filepath.Join(buildRDir, "out")
|
||||
s.OutDirectory = filepath.Join(buildRDir, "out")
|
||||
} else {
|
||||
b.Config.OutDirectory = filepath.Join(b.Repo.Root, c.OutDirectory)
|
||||
s.OutDirectory = filepath.Join(repoRoot, c.OutDirectory)
|
||||
}
|
||||
|
||||
if err = c.createCleanDir(b.Config.OutDirectory, true); err != nil {
|
||||
if err = c.createCleanDir(s.OutDirectory, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
b.Config.Logging.LogToStdErr = c.LogToStderr
|
||||
s.LogToStdErr = c.LogToStderr
|
||||
|
||||
if c.LogToStderr {
|
||||
b.Config.Logging.LogToStdErr = c.LogToStderr
|
||||
return b, nil
|
||||
s.LogToStdErr = c.LogToStderr
|
||||
return s, nil
|
||||
}
|
||||
|
||||
if filepath.IsAbs(c.LogsDirectory) {
|
||||
b.Config.BinariesDirectory = c.LogsDirectory
|
||||
s.BinariesDirectory = c.LogsDirectory
|
||||
} else if c.LogsDirectory == "" {
|
||||
b.Config.Logging.LogsDirectory = filepath.Join(buildRDir, "logs")
|
||||
s.LogsDirectory = filepath.Join(buildRDir, "logs")
|
||||
} else {
|
||||
b.Config.Logging.LogsDirectory = filepath.Join(b.Repo.Root, c.LogsDirectory)
|
||||
s.LogsDirectory = filepath.Join(repoRoot, c.LogsDirectory)
|
||||
}
|
||||
|
||||
if err = c.createCleanDir(b.Config.Logging.LogsDirectory, true); err != nil {
|
||||
if err = c.createCleanDir(s.LogsDirectory, true); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return b, nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (c BuildrConfig) createCleanDir(dir string, clean bool) error {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package hcl
|
||||
|
||||
import (
|
||||
"code.icb4dc0.de/buildr/buildr/modules/helpers/paths"
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -28,8 +29,9 @@ func MockContext() *hcl.EvalContext {
|
|||
env.RegisterInContext(evalctx)
|
||||
string_helpers.RegisterInContext(evalctx)
|
||||
hclhelpers.RegisterInContext(evalctx)
|
||||
paths.RegisterInContext(evalctx)
|
||||
vaultHelpers.RegisterInContext(evalctx, vaultHelpers.MockGetter("<mocked>"))
|
||||
github.RegisterInContext(context.Background(), evalctx, nil, nil)
|
||||
github.RegisterInContext(context.Background(), evalctx, nil)
|
||||
|
||||
return evalctx
|
||||
}
|
||||
|
@ -45,6 +47,7 @@ func BasicContext(vaultGetter vaultHelpers.VaultGetter) *hcl.EvalContext {
|
|||
env.RegisterInContext(evalctx)
|
||||
string_helpers.RegisterInContext(evalctx)
|
||||
hclhelpers.RegisterInContext(evalctx)
|
||||
paths.RegisterInContext(evalctx)
|
||||
vaultHelpers.RegisterInContext(evalctx, vaultGetter)
|
||||
|
||||
return evalctx
|
||||
|
@ -65,7 +68,7 @@ func FullContext(ctx context.Context, parent *hcl.EvalContext, svc *services.Col
|
|||
evalctx.Variables = make(map[string]cty.Value)
|
||||
}
|
||||
|
||||
github.RegisterInContext(ctx, evalctx, svc.GitHubClient(), svc.Cache())
|
||||
github.RegisterInContext(ctx, evalctx, svc.Cache())
|
||||
|
||||
return evalctx
|
||||
}
|
||||
|
|
|
@ -9,14 +9,13 @@ import (
|
|||
"github.com/zclconf/go-cty/cty"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
)
|
||||
|
||||
func (s ModulesSpec) prepareBlockForParsing(
|
||||
block GenericBlock,
|
||||
modType modules.Category,
|
||||
evalCtx *hcl.EvalContext,
|
||||
buildrInstance buildr.Buildr,
|
||||
outDir string,
|
||||
) (blockPreparationResult, error) {
|
||||
syntaxBlock, ok := block.BlockBody.(*hclsyntax.Body)
|
||||
if !ok {
|
||||
|
@ -30,7 +29,7 @@ func (s ModulesSpec) prepareBlockForParsing(
|
|||
|
||||
forEachAttr, ok := syntaxBlock.Attributes["for_each"]
|
||||
if !ok {
|
||||
initBlock(syntaxBlock, modType, block.BlockName, buildrInstance.Config.OutDirectory)
|
||||
initBlock(syntaxBlock, modType, block.BlockName, outDir)
|
||||
bodyAsValue, _ := s.parseSyntaxBodyToObject(syntaxBlock, evalCtx, true)
|
||||
return blockPreparationResult{
|
||||
Specs: []blockParsingSpec{parsingSpecOf(modType, block, nil)},
|
||||
|
@ -98,7 +97,7 @@ func (s ModulesSpec) prepareBlockForParsing(
|
|||
gb := GenericBlock{
|
||||
ModuleName: block.ModuleName,
|
||||
BlockName: blockName,
|
||||
BlockBody: initBlock(blockCopy, modType, blockName, buildrInstance.Config.OutDirectory),
|
||||
BlockBody: initBlock(blockCopy, modType, blockName, outDir),
|
||||
}
|
||||
|
||||
result.Specs = append(result.Specs, parsingSpecOf(modType, gb, vals))
|
||||
|
|
|
@ -3,11 +3,29 @@ package hcl
|
|||
import (
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/gocty"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
)
|
||||
|
||||
type RepositoryOption func(evalCtx *hcl.EvalContext) error
|
||||
|
||||
func WithGlobalVariable(key string, value any) RepositoryOption {
|
||||
return func(evalCtx *hcl.EvalContext) error {
|
||||
ctyType, err := gocty.ImpliedType(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
mapped, err := gocty.ToCtyValue(value, ctyType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
evalCtx.Variables[key] = mapped
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type ModulesSpec struct {
|
||||
Locals []LocalsBlock `hcl:"locals,block"`
|
||||
Tools GenericBlocks `hcl:"tool,block"`
|
||||
|
@ -21,14 +39,17 @@ type ModulesSpec struct {
|
|||
func (s ModulesSpec) Repository(
|
||||
evalCtx *hcl.EvalContext,
|
||||
diagsWriter hcl.DiagnosticWriter,
|
||||
b buildr.Buildr,
|
||||
registry *modules.TypeRegistry,
|
||||
outDir string,
|
||||
opts ...RepositoryOption,
|
||||
) (repo *modules.Repository, err error) {
|
||||
repo = new(modules.Repository)
|
||||
s.diagsWriter = diagsWriter
|
||||
|
||||
if evalCtx.Variables["buildr"], err = mapToCtyVal(b, mappingCfg{}); err != nil {
|
||||
return nil, err
|
||||
for _, opt := range opts {
|
||||
if err := opt(evalCtx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = s.parseLocals(s.Locals, evalCtx); err != nil {
|
||||
|
@ -37,25 +58,25 @@ func (s ModulesSpec) Repository(
|
|||
|
||||
parsingSpecs := make([]blockParsingSpec, 0, len(s.Tools)+len(s.Tasks)+len(s.Builds))
|
||||
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryTool, s.Tools, evalCtx, b); err != nil {
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryTool, s.Tools, evalCtx, outDir); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
parsingSpecs = append(parsingSpecs, specs...)
|
||||
}
|
||||
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryTask, s.Tasks, evalCtx, b); err != nil {
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryTask, s.Tasks, evalCtx, outDir); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
parsingSpecs = append(parsingSpecs, specs...)
|
||||
}
|
||||
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryBuild, s.Builds, evalCtx, b); err != nil {
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryBuild, s.Builds, evalCtx, outDir); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
parsingSpecs = append(parsingSpecs, specs...)
|
||||
}
|
||||
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryPackage, s.Packages, evalCtx, b); err != nil {
|
||||
if specs, err := s.buildParsingInventory(modules.CategoryPackage, s.Packages, evalCtx, outDir); err != nil {
|
||||
return nil, err
|
||||
} else {
|
||||
parsingSpecs = append(parsingSpecs, specs...)
|
||||
|
@ -74,7 +95,7 @@ func (s ModulesSpec) buildParsingInventory(
|
|||
modType modules.Category,
|
||||
blocks []GenericBlock,
|
||||
evalCtx *hcl.EvalContext,
|
||||
buildrInstance buildr.Buildr,
|
||||
outDir string,
|
||||
) ([]blockParsingSpec, error) {
|
||||
if len(blocks) == 0 {
|
||||
return nil, nil
|
||||
|
@ -86,7 +107,7 @@ func (s ModulesSpec) buildParsingInventory(
|
|||
blockGroupParsingSpecs := make([]blockParsingSpec, 0)
|
||||
|
||||
for i := range blocks {
|
||||
result, err := s.prepareBlockForParsing(blocks[i], modType, evalCtx, buildrInstance)
|
||||
result, err := s.prepareBlockForParsing(blocks[i], modType, evalCtx, outDir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -8,8 +8,6 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/buildr"
|
||||
)
|
||||
|
||||
const FileName = ".buildrignore"
|
||||
|
@ -19,29 +17,6 @@ var (
|
|||
_ fs.ReadDirFS = (*Ignorer)(nil)
|
||||
)
|
||||
|
||||
// NewRootIgnorer returns a new Ignorer with the default ignore patterns included
|
||||
func NewRootIgnorer(b *buildr.Buildr, additionalPatterns ...string) (*Ignorer, error) {
|
||||
for i := range additionalPatterns {
|
||||
rel, err := filepath.Rel(b.Repo.Root, additionalPatterns[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
additionalPatterns[i] = rel
|
||||
}
|
||||
|
||||
ig, err := NewIgnorer(b.Repo.Root, additionalPatterns...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := defaultIgnorePatterns(b, ig); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return ig, nil
|
||||
}
|
||||
|
||||
func MustNewIgnorer(dir string, additionalPatterns ...string) *Ignorer {
|
||||
ig, err := NewIgnorer(dir, additionalPatterns...)
|
||||
if err != nil {
|
||||
|
@ -237,29 +212,3 @@ func readGitIgnore(content io.Reader) (patterns []string, err error) {
|
|||
}
|
||||
return patterns, scanner.Err()
|
||||
}
|
||||
|
||||
func defaultIgnorePatterns(b *buildr.Buildr, ig *Ignorer) error {
|
||||
appendRelBuildRDir := func(buildRDir string) error {
|
||||
if buildRDir == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
relDir, err := filepath.Rel(b.Repo.Root, buildRDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to make dir %s relative to Buildr repo root %s: %w", buildRDir, b.Repo.Root, err)
|
||||
}
|
||||
if !strings.HasSuffix(relDir, "/") {
|
||||
relDir += "/"
|
||||
}
|
||||
|
||||
return ig.AddPatterns(relDir)
|
||||
}
|
||||
|
||||
for _, d := range []string{b.Config.BinariesDirectory, b.Config.OutDirectory, b.Config.Logging.LogsDirectory} {
|
||||
if err := appendRelBuildRDir(d); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -49,9 +49,9 @@ func ParseVersion(version string) (v Version, err error) {
|
|||
}
|
||||
|
||||
type Version struct {
|
||||
Major int
|
||||
Minor int
|
||||
Patch int
|
||||
Prerelease string
|
||||
BuildMetadata string
|
||||
Major int `cty:"major"`
|
||||
Minor int `cty:"minor"`
|
||||
Patch int `cty:"patch"`
|
||||
Prerelease string `cty:"prerelease"`
|
||||
BuildMetadata string `cty:"build_metadata"`
|
||||
}
|
||||
|
|
|
@ -2,18 +2,15 @@ package services
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/state"
|
||||
|
||||
"github.com/docker/docker/client"
|
||||
gh "github.com/google/go-github/v50/github"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/internal/ignore"
|
||||
"code.icb4dc0.de/buildr/buildr/internal/vault"
|
||||
"code.icb4dc0.de/buildr/buildr/modules"
|
||||
"github.com/docker/docker/client"
|
||||
)
|
||||
|
||||
type CollectionOption interface {
|
||||
|
@ -87,20 +84,8 @@ func WithDockerClientFromEnv(ctx context.Context) CollectionOption {
|
|||
})
|
||||
}
|
||||
|
||||
func WithGitHubTokenClient(ctx context.Context, token string) CollectionOption {
|
||||
return collectionOptionFunc(func(svc *Collection) error {
|
||||
if token != "" {
|
||||
svc.ghClient = gh.NewTokenClient(ctx, token)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func NewCollection(opts ...CollectionOption) (*Collection, error) {
|
||||
svc := &Collection{
|
||||
ghClient: gh.NewClient(http.DefaultClient),
|
||||
}
|
||||
svc := new(Collection)
|
||||
|
||||
if err := svc.With(opts...); err != nil {
|
||||
return nil, err
|
||||
|
@ -111,7 +96,6 @@ func NewCollection(opts ...CollectionOption) (*Collection, error) {
|
|||
|
||||
type Collection struct {
|
||||
registry *modules.TypeRegistry
|
||||
ghClient *gh.Client
|
||||
vault *vault.Vault
|
||||
dockerClient *client.Client
|
||||
ignorer *ignore.Ignorer
|
||||
|
@ -138,10 +122,6 @@ func (c *Collection) Cache() state.Cache {
|
|||
return c.cache
|
||||
}
|
||||
|
||||
func (c *Collection) GitHubClient() *gh.Client {
|
||||
return c.ghClient
|
||||
}
|
||||
|
||||
func (c *Collection) TypeRegistry() *modules.TypeRegistry {
|
||||
return c.registry
|
||||
}
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
package buildr
|
||||
|
||||
import (
|
||||
"code.icb4dc0.de/buildr/buildr/internal/semver"
|
||||
"code.icb4dc0.de/buildr/buildr/modules/vcs"
|
||||
)
|
||||
|
||||
type Repo struct {
|
||||
Root string `hcl:"root"`
|
||||
Git *vcs.Git `hcl:"git"`
|
||||
Version semver.Version `hcl:"version"`
|
||||
}
|
||||
|
||||
type GitHub struct {
|
||||
APIToken string `hcl:"api_token"`
|
||||
}
|
||||
|
||||
type Buildr struct {
|
||||
Config Config `hcl:"config"`
|
||||
Repo Repo `hcl:"repo"`
|
||||
GitHub GitHub `hcl:"github"`
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
package buildr
|
||||
|
||||
type Config struct {
|
||||
OutDirectory string `hcl:"out_dir"`
|
||||
BinariesDirectory string `hcl:"bin_dir"`
|
||||
CacheDirectory string `hcl:"cache_dir"`
|
||||
Logging Logging `hcl:"logging"`
|
||||
}
|
||||
|
||||
type Logging struct {
|
||||
LogToStdErr bool `hcl:"log_to_stdout"`
|
||||
LogsDirectory string `hcl:"logs_dir"`
|
||||
}
|
|
@ -2,18 +2,20 @@ package github
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
gh "github.com/google/go-github/v50/github"
|
||||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/state"
|
||||
|
||||
"github.com/google/go-github/v50/github"
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
)
|
||||
|
||||
const DefaultAPITimeout = 30 * time.Second
|
||||
|
||||
func GetLatestReleaseTag(ctx context.Context, cli *github.Client, cache state.Cache) function.Function {
|
||||
func GetLatestReleaseTag(ctx context.Context, cache state.Cache) function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Description: "Get tag of latest release of Github project",
|
||||
Params: []function.Parameter{
|
||||
|
@ -28,6 +30,11 @@ func GetLatestReleaseTag(ctx context.Context, cli *github.Client, cache state.Ca
|
|||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
VarParam: &function.Parameter{
|
||||
Name: "token",
|
||||
Description: "GitHub API token",
|
||||
Type: cty.String,
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
owner := args[0].AsString()
|
||||
|
@ -42,6 +49,14 @@ func GetLatestReleaseTag(ctx context.Context, cli *github.Client, cache state.Ca
|
|||
}
|
||||
}
|
||||
|
||||
var cli *gh.Client
|
||||
|
||||
if len(args) >= 3 {
|
||||
cli = gh.NewTokenClient(ctx, args[2].AsString())
|
||||
} else {
|
||||
cli = gh.NewClient(http.DefaultClient)
|
||||
}
|
||||
|
||||
if cli == nil {
|
||||
return cty.StringVal("<mocked>"), nil
|
||||
}
|
||||
|
|
|
@ -5,10 +5,9 @@ import (
|
|||
|
||||
"code.icb4dc0.de/buildr/buildr/modules/state"
|
||||
|
||||
"github.com/google/go-github/v50/github"
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
)
|
||||
|
||||
func RegisterInContext(ctx context.Context, evalCtx *hcl.EvalContext, cli *github.Client, cache state.Cache) {
|
||||
evalCtx.Functions["gh_latest_release"] = GetLatestReleaseTag(ctx, cli, cache)
|
||||
func RegisterInContext(ctx context.Context, evalCtx *hcl.EvalContext, cache state.Cache) {
|
||||
evalCtx.Functions["gh_latest_release"] = GetLatestReleaseTag(ctx, cache)
|
||||
}
|
||||
|
|
23
modules/helpers/paths/dirname.go
Normal file
23
modules/helpers/paths/dirname.go
Normal file
|
@ -0,0 +1,23 @@
|
|||
package paths
|
||||
|
||||
import (
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func Dirname() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "dirname",
|
||||
Description: "Strip the filename from the path",
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(filepath.Dir(args[0].AsString())), nil
|
||||
},
|
||||
})
|
||||
}
|
22
modules/helpers/paths/file_ext.go
Normal file
22
modules/helpers/paths/file_ext.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package paths
|
||||
|
||||
import (
|
||||
"github.com/zclconf/go-cty/cty"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func FileExtension() function.Function {
|
||||
return function.New(&function.Spec{
|
||||
Params: []function.Parameter{
|
||||
{
|
||||
Name: "path",
|
||||
Type: cty.String,
|
||||
},
|
||||
},
|
||||
Type: function.StaticReturnType(cty.String),
|
||||
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
|
||||
return cty.StringVal(filepath.Ext(args[0].AsString())), nil
|
||||
},
|
||||
})
|
||||
}
|
8
modules/helpers/paths/registration.go
Normal file
8
modules/helpers/paths/registration.go
Normal file
|
@ -0,0 +1,8 @@
|
|||
package paths
|
||||
|
||||
import "github.com/hashicorp/hcl/v2"
|
||||
|
||||
func RegisterInContext(evalCtx *hcl.EvalContext) {
|
||||
evalCtx.Functions["dirname"] = Dirname()
|
||||
evalCtx.Functions["ext"] = FileExtension()
|
||||
}
|
10
modules/repo/repo.go
Normal file
10
modules/repo/repo.go
Normal file
|
@ -0,0 +1,10 @@
|
|||
package repo
|
||||
|
||||
import (
|
||||
"code.icb4dc0.de/buildr/buildr/internal/semver"
|
||||
)
|
||||
|
||||
type Repo struct {
|
||||
Root string `cty:"root"`
|
||||
Version semver.Version `cty:"version"`
|
||||
}
|
|
@ -1,19 +1,24 @@
|
|||
package vcs
|
||||
|
||||
type GitCommitAuthor struct {
|
||||
Name string `hcl:"name"`
|
||||
Email string `hcl:"email"`
|
||||
Name string `cty:"name"`
|
||||
Email string `cty:"email"`
|
||||
}
|
||||
|
||||
type GitCommit struct {
|
||||
Hash string `hcl:"commit_hash"`
|
||||
Author GitCommitAuthor `hcl:"author"`
|
||||
Message string `hcl:"message"`
|
||||
Hash string `cty:"commit_hash"`
|
||||
Author GitCommitAuthor `cty:"author"`
|
||||
Message string `cty:"message"`
|
||||
}
|
||||
|
||||
type Git struct {
|
||||
Commit GitCommit `hcl:"commit"`
|
||||
Branch string `hcl:"branch"`
|
||||
Tag string `hcl:"tag"`
|
||||
Reference string `hcl:"reference"`
|
||||
Dirty bool `cty:"dirty"`
|
||||
Commit GitCommit `cty:"commit"`
|
||||
Branch string `cty:"branch"`
|
||||
Tag string `cty:"tag"`
|
||||
Reference string `cty:"reference"`
|
||||
StagedFiles []string `cty:"staged_files"`
|
||||
UnstagedFiles []string `cty:"unstaged_files"`
|
||||
ModifiedFiles []string `cty:"modified_files"`
|
||||
UntrackedFiles []string `cty:"untracked_files"`
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package vcs
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"golang.org/x/exp/maps"
|
||||
|
||||
"github.com/go-git/go-git/v5"
|
||||
)
|
||||
|
||||
|
@ -14,6 +16,38 @@ func ParseGitInfo(root string) (*Git, error) {
|
|||
|
||||
g := new(Git)
|
||||
|
||||
workTree, err := repo.Worktree()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
stat, err := workTree.Status()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
g.Dirty = !stat.IsClean()
|
||||
|
||||
uniqueModifiedFiles := make(map[string]bool)
|
||||
|
||||
for p, s := range stat {
|
||||
switch s.Staging {
|
||||
case git.Added, git.Modified, git.Copied, git.Renamed:
|
||||
g.StagedFiles = append(g.StagedFiles, p)
|
||||
uniqueModifiedFiles[p] = true
|
||||
}
|
||||
|
||||
switch s.Worktree {
|
||||
case git.Added, git.Modified, git.Copied, git.Renamed:
|
||||
g.UnstagedFiles = append(g.UnstagedFiles, p)
|
||||
uniqueModifiedFiles[p] = true
|
||||
case git.Untracked:
|
||||
g.UntrackedFiles = append(g.UntrackedFiles, p)
|
||||
}
|
||||
}
|
||||
|
||||
g.ModifiedFiles = maps.Keys(uniqueModifiedFiles)
|
||||
|
||||
if head, err := repo.Head(); err != nil {
|
||||
return nil, fmt.Errorf("failed to read HEAD information: %w", err)
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue