Skip to content

Commit

Permalink
Extend command.Factory usage
Browse files Browse the repository at this point in the history
  • Loading branch information
adambabik committed May 21, 2024
1 parent 07cac7b commit 5ced265
Show file tree
Hide file tree
Showing 33 changed files with 916 additions and 1,102 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ jobs:
run: |
export SHELL=/bin/bash
export TZ=UTC
TAGS="test_with_docker" make test
TAGS="test_with_docker" make test/coverage
make test/coverage/func
if: ${{ matrix.os == 'ubuntu-latest' }}
- name: Test
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ test/coverage: PKGS ?= "./..."
test/coverage: RUN ?= .*
test/coverage: TAGS ?= "" # e.g. TAGS="test_with_docker"
test/coverage: build test/prep-git-project
TZ=UTC go test -ldflags="$(LDTESTFLAGS)" -run="$(RUN)" -tags="$(TAGS)" -timeout=90s -covermode=atomic -coverprofile=cover.out -coverpkg=./github.com/stateful/runme/v3 $(PKGS)
TZ=UTC go test -ldflags="$(LDTESTFLAGS)" -run="$(RUN)" -tags="$(TAGS)" -timeout=90s -covermode=atomic -coverprofile=cover.out -coverpkg=./... $(PKGS)

.PHONY: test/prep-git-project
test/prep-git-project:
Expand All @@ -56,6 +56,9 @@ test/clean-git-project:
.PHONY: test
test: test/prep-git-project test/execute test/clean-git-project

.PHONY: test-coverage
test-coverage: test/prep-git-project test/coverage test/clean-git-project

.PHONY: test/update-snapshots
test/update-snapshots:
@TZ=UTC UPDATE_SNAPSHOTS=true go test ./...
Expand Down
21 changes: 11 additions & 10 deletions internal/cmd/beta/run_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,7 @@ Run all blocks from the "setup" and "teardown" categories:
return errors.WithStack(err)
}

options := getCommandOptions(
cmd,
kernel,
session,
logger,
)
options := getCommandOptions(cmd, session)

for _, t := range tasks {
err := runCodeBlock(cmd.Context(), t.CodeBlock, cmdFactory, options)
Expand All @@ -91,13 +86,9 @@ Run all blocks from the "setup" and "teardown" categories:

func getCommandOptions(
cmd *cobra.Command,
kernel command.Kernel,
sess *command.Session,
logger *zap.Logger,
) command.Options {
return command.Options{
Kernel: kernel,
Logger: logger,
Session: sess,
Stdin: cmd.InOrStdin(),
Stdout: cmd.OutOrStdout(),
Expand All @@ -111,6 +102,16 @@ func runCodeBlock(
factory command.Factory,
options command.Options,
) error {
// TODO(adamb): [command.Config] is generated exclusively from the [document.CodeBlock].
// As we introduce some document- and block-related configs in runme.yaml (root but also nested),
// this [Command.Config] should be further extended.
//
// The way to do it is to use [config.Loader] and calling [config.Loader.FindConfigChain] with
// task's document path. It will produce all the configs that are relevant to the document.
// Next, they should be merged into a single [config.Config] in a correct order, starting from
// the last element of the returned config chain. Finally, [command.Config] should be updated.
// This algorithm should be likely encapsulated in the [internal/config] and [internal/command]
// packages.
cfg, err := command.NewProgramConfigFromCodeBlock(block)
if err != nil {
return err
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
healthgrpc "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/reflection"

"github.com/stateful/runme/v3/internal/command"
"github.com/stateful/runme/v3/internal/document/editor/editorservice"
"github.com/stateful/runme/v3/internal/project/projectservice"
"github.com/stateful/runme/v3/internal/runner"
Expand Down Expand Up @@ -110,7 +111,7 @@ The kernel is used to run long running processes like shells and interacting wit
}
runnerv1.RegisterRunnerServiceServer(server, runnerServicev1)

runnerServicev2, err := runnerv2service.NewRunnerService()
runnerServicev2, err := runnerv2service.NewRunnerService(command.NewFactory(nil, nil, logger), logger)
if err != nil {
return err
}
Expand Down
76 changes: 17 additions & 59 deletions internal/command/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,19 @@ import (
"strings"

"github.com/pkg/errors"
"go.uber.org/zap"
)

type Command interface {
IsInteractive() bool
Interactive() bool
Pid() int
Running() bool
Start(context.Context) error
Signal(os.Signal) error
Wait() error
}

type Options struct {
Kernel Kernel
Logger *zap.Logger
Session *Session
StdinWriter io.Writer
Stdin io.Reader
Stdout io.Writer
Stderr io.Writer
}

type internalCommand interface {
Command

type baseCommand interface {
Env() []string
Logger() *zap.Logger
ProgramConfig() *ProgramConfig
ProgramPath() (string, []string, error)
Session() *Session
Expand All @@ -44,45 +30,24 @@ type internalCommand interface {
Stderr() io.Writer
}

type internalCommand interface {
Command
baseCommand
}

type base struct {
cfg *ProgramConfig
kernel Kernel
logger *zap.Logger
session *Session
stdin io.Reader
stdinWriter io.Writer
stdout io.Writer
stderr io.Writer
}

func newBase(cfg *ProgramConfig, opts Options) *base {
if opts.Kernel == nil {
opts.Kernel = NewLocalKernel(nil)
}

if opts.Session == nil {
opts.Session = NewSession()
}

if opts.Logger == nil {
opts.Logger = zap.NewNop()
}

return &base{
cfg: cfg,
kernel: opts.Kernel,
logger: opts.Logger,
session: opts.Session,
stdin: opts.Stdin,
stdinWriter: opts.StdinWriter,
stdout: opts.Stdout,
stderr: opts.Stderr,
}
}

var _ internalCommand = (*base)(nil)

func (c *base) IsInteractive() bool {
func (c *base) Interactive() bool {
return c.cfg.Interactive
}

Expand All @@ -94,6 +59,13 @@ func (c *base) Running() bool {
return false
}

func (c *base) Session() *Session {
if c.session == nil {
c.session = NewSession()
}
return c.session
}

func (c *base) Start(context.Context) error {
return errors.New("not implemented")
}
Expand All @@ -117,13 +89,6 @@ func (c *base) Env() []string {
return env
}

func (c *base) Logger() *zap.Logger {
if c.logger == nil {
c.logger = zap.NewNop()
}
return c.logger
}

func (c *base) ProgramConfig() *ProgramConfig {
return c.cfg
}
Expand All @@ -135,7 +100,7 @@ func (c *base) ProgramPath() (string, []string, error) {

// If language ID is empty, interpreter lookup is futile.
if c.cfg.LanguageId != "" {
path, args, err := c.findProgramInKnownInterpretters(c.cfg.LanguageId, c.cfg.Arguments)
path, args, err := c.findProgramInKnownInterpreters(c.cfg.LanguageId, c.cfg.Arguments)
if err == nil {
return path, args, nil
}
Expand Down Expand Up @@ -172,7 +137,7 @@ func (c *base) findProgramInPath(name string, args []string) (string, []string,
return res, args, nil
}

func (c *base) findProgramInKnownInterpretters(programName string, args []string) (string, []string, error) {
func (c *base) findProgramInKnownInterpreters(programName string, args []string) (string, []string, error) {
interpreters := inferInterpreterFromLanguage(programName)
if len(interpreters) == 0 {
return "", nil, errors.Errorf("unsupported language %q", programName)
Expand All @@ -193,13 +158,6 @@ func (c *base) findProgramInKnownInterpretters(programName string, args []string
return "", nil, errors.Errorf("failed to find known interpreter out of %s", interpreters)
}

func (c *base) Session() *Session {
if c.session == nil {
c.session = NewSession()
}
return c.session
}

func (c *base) Stdin() io.Reader {
return c.stdin
}
Expand Down
Loading

0 comments on commit 5ced265

Please sign in to comment.