Skip to content

Commit

Permalink
cmd: add install command
Browse files Browse the repository at this point in the history
  • Loading branch information
dobarx committed Mar 3, 2024
1 parent 0413e5a commit 2d52f87
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 44 deletions.
7 changes: 5 additions & 2 deletions cmd/data.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,15 +97,18 @@ var dataCmd = &cobra.Command{
Long: `Execute the data block and print out prettified JSON to stdout`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
var diags diagnostics.Diag
eval := NewEvaluator(cliArgs.pluginsDir)
eval := NewEvaluator()
defer func() {
err = eval.Cleanup(diags)
}()
diags = eval.ParseFabricFiles(os.DirFS(cliArgs.sourceDir))
if diags.HasErrors() {
return
}
if diags.Extend(eval.LoadRunner()) {
if diags.Extend(eval.LoadPluginResolver(false)) {
return
}
if diags.Extend(eval.LoadPluginRunner()) {
return
}

Expand Down
91 changes: 70 additions & 21 deletions cmd/evaluator.go
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
package cmd

import (
"context"
"fmt"
"io/fs"
"log/slog"
"os"
"path/filepath"

"github.com/hashicorp/hcl/v2"

"github.com/blackstork-io/fabric/internal/builtin"
"github.com/blackstork-io/fabric/parser"
"github.com/blackstork-io/fabric/parser/definitions"
"github.com/blackstork-io/fabric/pkg/diagnostics"
"github.com/blackstork-io/fabric/plugin/resolver"
"github.com/blackstork-io/fabric/plugin/runner"
)

const (
defaultLockFile = ".fabric-lock.json"
)

type Evaluator struct {
PluginsDir string
Blocks *parser.DefinedBlocks
Runner *runner.Runner
FileMap map[string]*hcl.File
Config *definitions.GlobalConfig
Blocks *parser.DefinedBlocks
Runner *runner.Runner
LockFile *resolver.LockFile
Resolver *resolver.Resolver
FileMap map[string]*hcl.File
}

func NewEvaluator(pluginsDir string) *Evaluator {
func NewEvaluator() *Evaluator {
return &Evaluator{
PluginsDir: pluginsDir,
Config: &definitions.GlobalConfig{
PluginRegistry: &definitions.PluginRegistry{
BaseURL: "http://localhost:8080",
MirrorDir: "",
},
CacheDir: ".fabric",
},
}
}

Expand All @@ -44,28 +62,59 @@ func (e *Evaluator) ParseFabricFiles(sourceDir fs.FS) (diags diagnostics.Diag) {
if diags.HasErrors() {
return
}
if e.PluginsDir == "" && e.Blocks.GlobalConfig != nil && e.Blocks.GlobalConfig.PluginRegistry != nil {
// use pluginsDir from config, unless overridden by cli arg
e.PluginsDir = e.Blocks.GlobalConfig.PluginRegistry.MirrorDir
if e.Blocks.GlobalConfig != nil {
e.Config.Merge(e.Blocks.GlobalConfig)
}
return
}

func (e *Evaluator) LoadRunner() diagnostics.Diag {
var pluginVersions runner.VersionMap
if e.Blocks.GlobalConfig != nil {
pluginVersions = e.Blocks.GlobalConfig.PluginVersions
func (e *Evaluator) LoadPluginRunner() diagnostics.Diag {
var diag diagnostics.Diag
binaryMap, diags := e.Resolver.Resolve(context.Background(), e.LockFile)
if diag.ExtendHcl(diags) {
return diag
}
var stdDiag hcl.Diagnostics
e.Runner, diags = runner.Load(binaryMap, builtin.Plugin(version), slog.Default())
diag.ExtendHcl(diags)
return diag
}

e.Runner, stdDiag = runner.Load(
runner.WithBuiltIn(
builtin.Plugin(version),
),
runner.WithPluginDir(e.PluginsDir),
runner.WithPluginVersions(pluginVersions),
func (e *Evaluator) LoadPluginResolver(includeRemote bool) diagnostics.Diag {
pluginDir := filepath.Join(e.Config.CacheDir, "plugins")
sources := []resolver.Source{
resolver.LocalSource{
Path: pluginDir,
},
}
if e.Config.PluginRegistry != nil {
if e.Config.PluginRegistry.MirrorDir != "" {
sources = append(sources, resolver.LocalSource{
Path: e.Config.PluginRegistry.MirrorDir,
})
}
if includeRemote && e.Config.PluginRegistry.BaseURL != "" {
sources = append(sources, resolver.RemoteSource{
BaseURL: e.Config.PluginRegistry.BaseURL,
DownloadDir: pluginDir,
UserAgent: fmt.Sprintf("fabric/%s", version),
})
}
}
var err error
e.LockFile, err = resolver.ReadLockFileFrom(defaultLockFile)
if err != nil {
return diagnostics.Diag{{
Severity: hcl.DiagError,
Summary: "Failed to read lock file",
Detail: err.Error(),
}}
}
var diags hcl.Diagnostics
e.Resolver, diags = resolver.NewResolver(e.Config.PluginVersions,
resolver.WithLogger(slog.Default()),
resolver.WithSources(sources...),
)
return diagnostics.Diag(stdDiag)
return diagnostics.Diag(diags)
}

func (e *Evaluator) PluginCaller() *parser.Caller {
Expand Down
43 changes: 43 additions & 0 deletions cmd/install.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package cmd

import (
"context"
"os"

"github.com/spf13/cobra"

"github.com/blackstork-io/fabric/pkg/diagnostics"
"github.com/blackstork-io/fabric/plugin/resolver"
)

var installUpgrade bool

var installCmd = &cobra.Command{
Use: "install",
Short: "Install plugins",
Long: "Install Fabric plugins",
RunE: func(cmd *cobra.Command, args []string) (err error) {
var diags diagnostics.Diag
eval := NewEvaluator()
defer func() {
err = eval.Cleanup(diags)
}()
diags = eval.ParseFabricFiles(os.DirFS(cliArgs.sourceDir))
if diags.HasErrors() {
return
}
if diags.Extend(eval.LoadPluginResolver(true)) {
return
}
lockFile, stdDiags := eval.Resolver.Install(context.Background(), eval.LockFile, installUpgrade)
if diags.ExtendHcl(stdDiags) {
return
}
return resolver.SaveLockFileTo(defaultLockFile, lockFile)
},
}

func init() {
rootCmd.AddCommand(installCmd)
installCmd.Flags().BoolVarP(&installUpgrade, "upgrade", "u", false, "Upgrade plugin versions")
}
8 changes: 5 additions & 3 deletions cmd/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,18 @@ var renderCmd = &cobra.Command{
}

var diags diagnostics.Diag
eval := NewEvaluator(cliArgs.pluginsDir)
eval := NewEvaluator()
defer func() {
err = eval.Cleanup(diags)
}()
diags = eval.ParseFabricFiles(os.DirFS(cliArgs.sourceDir))
if diags.HasErrors() {
return
}
diag := eval.LoadRunner()
if diags.Extend(diag) {
if diags.Extend(eval.LoadPluginResolver(false)) {
return
}
if diags.Extend(eval.LoadPluginRunner()) {
return
}
res, diag := Render(cmd.Context(), eval.Blocks, eval.PluginCaller(), target)
Expand Down
21 changes: 7 additions & 14 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,6 @@ var rootCmd = &cobra.Command{
}
cliArgs.sourceDir = rawArgs.sourceDir

cliArgs.pluginsDir = rawArgs.pluginsDir

cliArgs.colorize = rawArgs.colorize && term.IsTerminal(int(os.Stderr.Fd()))

var level slog.Level
Expand Down Expand Up @@ -157,18 +155,16 @@ func Execute() {
}

var cliArgs = struct {
sourceDir string
pluginsDir string
colorize bool
sourceDir string
colorize bool
}{}

var rawArgs = struct {
sourceDir string
logOutput string
logLevel string
pluginsDir string
verbose bool
colorize bool
sourceDir string
logOutput string
logLevel string
verbose bool
colorize bool
}{}

func init() {
Expand All @@ -180,7 +176,4 @@ func init() {
)
rootCmd.PersistentFlags().BoolVar(&rawArgs.colorize, "color", true, "enables colorizing the logs and diagnostics (if supported by the terminal and log format)")
rootCmd.PersistentFlags().BoolVarP(&rawArgs.verbose, "verbose", "v", false, "a shortcut to --log-level debug")
rootCmd.PersistentFlags().StringVar(
&rawArgs.pluginsDir, "plugins-dir", "", "override for plugins dir from fabric configuration",
)
}
4 changes: 2 additions & 2 deletions test/e2e/data_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,15 @@ func dataTest(t *testing.T, testName string, files []string, target string, expe
Mode: 0o777,
}
}
eval := cmd.NewEvaluator("")
eval := cmd.NewEvaluator()
defer func() {
eval.Cleanup(nil)
}()

var res plugin.Data
diags := eval.ParseFabricFiles(sourceDir)
if !diags.HasErrors() {
if !diags.Extend(eval.LoadRunner()) {
if !diags.Extend(eval.LoadPluginResolver(false)) && !diags.Extend(eval.LoadPluginRunner()) {
var diag diagnostics.Diag
res, diag = cmd.Data(context.Background(), eval.Blocks, eval.PluginCaller(), target)
diags.Extend(diag)
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ func renderTest(t *testing.T, testName string, files []string, docName string, e
Mode: 0o777,
}
}
eval := cmd.NewEvaluator("")
eval := cmd.NewEvaluator()
defer func() {
eval.Cleanup(nil)
}()

var res []string
diags := eval.ParseFabricFiles(sourceDir)
if !diags.HasErrors() {
if !diags.Extend(eval.LoadRunner()) {
if !diags.Extend(eval.LoadPluginResolver(false)) && !diags.Extend(eval.LoadPluginRunner()) {
var diag diagnostics.Diag
res, diag = cmd.Render(context.Background(), eval.Blocks, eval.PluginCaller(), docName)
diags.Extend(diag)
Expand Down

0 comments on commit 2d52f87

Please sign in to comment.