Skip to content

Commit

Permalink
Refactor config into kernel, project, etc
Browse files Browse the repository at this point in the history
  • Loading branch information
sourishkrout committed Apr 12, 2024
1 parent 357b31c commit 569a9f8
Show file tree
Hide file tree
Showing 20 changed files with 665 additions and 769 deletions.
77 changes: 38 additions & 39 deletions experimental/runme.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,45 @@
# You can test it with the "runme beta" commands.
version: v1alpha1

# config settings that often use default or a set at points of integration
kernel:
server:
# Also unix:///path/to/file.sock is supported.
address: localhost:7890
tls:
enabled: true
# If not specified, default paths will be used.
# cert_file: "/path/to/cert.pem"
# key_file: "/path/to/key.pem"

log:
enabled: true
path: "/var/tmp/runme.log"
verbose: true

# config settings that apply at the repo-level
repo:
project:
# Indicate the root of the runme project. "." means that
# the project root directory will be used.
root: "."
# If true, the project root will be searched upwards starting from "dir".
# If found, the repo root will be used as the project root.
find_repo_upward: true
ignore:
- "node_modules"
- ".venv"
disable_gitignore: false

# It's possible to point at a single file as well.
# filename: "README.md"

# List of dotenv files to load.
env:
use_system_env: true
sources:
- ".env"
- ".env.local"

# The list of filters to apply to blocks.
# "condition" must return a boolean value.
# You can learn about the syntax at https://expr-lang.org/docs/language-definition.
Expand All @@ -22,41 +59,3 @@ repo:
# Do not allow code blocks starting with "test".
- type: "FILTER_TYPE_BLOCK"
condition: "!hasPrefix(name, 'test')"

# config settings that often use default or a set at points of integration
core:
# Indicate the root of the runme project. "." means that
# the project root directory will be used.
project:
dir: "."
# If true, the project root will be searched upwards starting from "dir".
# If found, the repo root will be used as the project root.
find_repo_upward: true
ignore:
- "node_modules"
- ".venv"
disable_gitignore: false

# It's possible to point at a single file as well.
# filename: "README.md"

# List of dotenv files to load.
env:
use_system_env: true
sources:
- ".env"
- ".env.local"

server:
# Also unix:///path/to/file.sock is supported.
address: localhost:7890
tls:
enabled: true
# If not specified, default paths will be used.
# cert_file: "/path/to/cert.pem"
# key_file: "/path/to/key.pem"

log:
enabled: true
path: "/var/tmp/runme.log"
verbose: true
94 changes: 46 additions & 48 deletions internal/api/runme/config/v1alpha1/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,12 @@ import "buf/validate/validate.proto";

option go_package = "github.com/stateful/runme/internal/gen/proto/go/runme/config/v1alpha1;configv1alpha1";

// ConfigCore describes system-level configuration of the runme toolchain.
message ConfigCore {
// source is a source of Markdown files to look into.
oneof source {
option (buf.validate.oneof).required = true;

// project indicates a dir-based source typically including multiple Markdown files.
Project project = 1;

// filename indicates a single Markdown file.
string filename = 2;
}

// env is the environment variables configuration.
Env env = 3;

// Kernel describes system-level configuration of the runme toolchain.
message Kernel {
// log contains the log configuration.
Log log = 7;

Server server = 8;
Log log = 1;

message Project {
// dir is the directory to look for Markdown files.
string dir = 1;

// find_repo_upward indicates whether to find the nearest Git repository upward.
// This is useful to, for example, recognize .gitignore files.
bool find_repo_upward = 2;

// ignore_paths is a list of paths to ignore relative to dir.
repeated string ignore_paths = 3 [json_name = "ignore"];

// disable_gitignore indicates whether to disable the .gitignore file.
bool disable_gitignore = 4;
}

message Env {
// use_system_env indicates whether to use the system environment variables.
bool use_system_env = 1;

// sources is a list of files with env.
repeated string sources = 2;
}
Server server = 2;

message Log {
// enabled indicates whether to enable logging.
Expand All @@ -74,12 +37,44 @@ message ConfigCore {
}
}

// ConfigRepo describes repo-level configuration of the runme toolchain.
message ConfigRepo {
// Project describes repo-level configuration of the runme toolchain.
message Project {
// source is a source of Markdown files to look into.
oneof source {
option (buf.validate.oneof).required = true;

// root indicates a dir-based source typically including multiple Markdown files.
string root = 1;

// filename indicates a single Markdown file.
string filename = 2;
}

// env is the environment variables configuration.
Env env = 3;

// find_repo_upward indicates whether to find the nearest Git repository upward.
// This is useful to, for example, recognize .gitignore files.
bool find_repo_upward = 4;

// ignore_paths is a list of paths to ignore relative to dir.
repeated string ignore_paths = 5 [json_name = "ignore"];

// disable_gitignore indicates whether to disable the .gitignore file.
bool disable_gitignore = 6;

// filters is a list of filters to apply.
// Filters can be applied to documents or
// individual code blocks.
repeated Filter filters = 5;
repeated Filter filters = 7;

message Env {
// use_system_env indicates whether to use the system environment variables.
bool use_system_env = 1;

// sources is a list of files with env.
repeated string sources = 2;
}

message Filter {
// type is the type of the filter.
Expand All @@ -105,9 +100,12 @@ message ConfigRepo {

// Config describes the configuration of the runme toolchain, including CLI, server, and clients like VS Code extension.
message Config {
// core is the system-level configuration.
ConfigCore core = 1;
// kernel is the system-level configuration and config that's not specific to one single client
Kernel kernel = 1;

// project contains configuration applicable to the project inside a repo.
Project project = 2;

// repo is the repo-level configuration.
ConfigRepo repo = 2;
// will likely add document to overwrite frontmatter in documents per dir when nested
// Document document = 3;
}
2 changes: 1 addition & 1 deletion internal/cmd/beta/beta_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ All commands use the runme.yaml configuration file.`,
return autoconfig.Invoke(func(cfg *config.Config) error {
// Override the filename if provided.
if cFlags.filename != "" {
cfg.Core.Filename = cFlags.filename
cfg.Kernel.Filename = cFlags.filename
}

// Add a filter to run only tasks from the specified categories.
Expand Down
4 changes: 2 additions & 2 deletions internal/cmd/beta/server/grpcurl_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ func getDescriptorSource(ctx context.Context, cfg *config.Config) (grpcurl.Descr
}

func dialServer(ctx context.Context, cfg *config.Config) (*grpc.ClientConn, error) {
tlsConf, err := runmetls.LoadClientConfig(cfg.Core.ServerTLSCertFile, cfg.Core.ServerTLSKeyFile)
tlsConf, err := runmetls.LoadClientConfig(cfg.Kernel.ServerTLSCertFile, cfg.Kernel.ServerTLSKeyFile)
if err != nil {
return nil, err
}

creds := credentials.NewTLS(tlsConf)

network, addr := "tcp", cfg.Core.ServerAddress
network, addr := "tcp", cfg.Kernel.ServerAddress
if strings.HasPrefix(addr, "unix://") {
network, addr = "unix", strings.TrimPrefix(addr, "unix://")
}
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/beta/server/server_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func Cmd() *cobra.Command {
) error {
// For the server commands, we want to always log to stdout.
// TODO(adamb): there might be a need to separate client and server logs.
cfg.Core.LogPath = ""
cfg.Kernel.LogPath = ""
return nil
},
)
Expand Down
12 changes: 6 additions & 6 deletions internal/cmd/beta/server/server_start_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ func serverStartCmd() *cobra.Command {
defer logger.Sync()

serverCfg := &server.Config{
Address: cfg.Core.ServerAddress,
CertFile: cfg.Core.ServerTLSCertFile,
KeyFile: cfg.Core.ServerTLSKeyFile,
TLSEnabled: cfg.Core.ServerTLSEnabled,
Address: cfg.Kernel.ServerAddress,
CertFile: cfg.Kernel.ServerTLSCertFile,
KeyFile: cfg.Kernel.ServerTLSKeyFile,
TLSEnabled: cfg.Kernel.ServerTLSEnabled,
}

logger.Debug("server config", zap.Any("config", serverCfg))
Expand All @@ -39,12 +39,12 @@ func serverStartCmd() *cobra.Command {
}

// When using a unix socket, we want to create a file with server's PID.
if path := pidFileNameFromAddr(cfg.Core.ServerAddress); path != "" {
if path := pidFileNameFromAddr(cfg.Kernel.ServerAddress); path != "" {
logger.Debug("creating PID file", zap.String("path", path))
if err := createFileWithPID(path); err != nil {
return errors.WithStack(err)
}
defer os.Remove(cfg.Core.ServerAddress)
defer os.Remove(cfg.Kernel.ServerAddress)
}

return errors.WithStack(s.Serve())
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/beta/server/server_stop_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func serverStopCmd() *cobra.Command {

logger.Debug("stopping the server by looking for runme.pid")

path := pidFileNameFromAddr(cfg.Core.ServerAddress)
path := pidFileNameFromAddr(cfg.Kernel.ServerAddress)
if path == "" {
return errors.New("server address is not a unix socket")
}
Expand Down
36 changes: 18 additions & 18 deletions internal/config/autoconfig/autoconfig.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,20 +102,20 @@ func getConfig(userCfgDir UserConfigDir, viper *viper.Viper) (*config.Config, er
return nil, err
}

if cfg.Core.ServerTLSEnabled {
if cfg.Core.ServerTLSCertFile == "" {
cfg.Core.ServerTLSCertFile = filepath.Join(string(userCfgDir), "cert.pem")
if cfg.Kernel.ServerTLSEnabled {
if cfg.Kernel.ServerTLSCertFile == "" {
cfg.Kernel.ServerTLSCertFile = filepath.Join(string(userCfgDir), "cert.pem")
}
if cfg.Core.ServerTLSKeyFile == "" {
cfg.Core.ServerTLSKeyFile = filepath.Join(string(userCfgDir), "key.pem")
if cfg.Kernel.ServerTLSKeyFile == "" {
cfg.Kernel.ServerTLSKeyFile = filepath.Join(string(userCfgDir), "key.pem")
}
}

return cfg, nil
}

func getLogger(c *config.Config) (*zap.Logger, error) {
if c == nil || !c.Core.LogEnabled {
if c == nil || !c.Kernel.LogEnabled {
return zap.NewNop(), nil
}

Expand All @@ -132,16 +132,16 @@ func getLogger(c *config.Config) (*zap.Logger, error) {
ErrorOutputPaths: []string{"stderr"},
}

if c.Core.LogVerbose {
if c.Kernel.LogVerbose {
zapConfig.Level = zap.NewAtomicLevelAt(zap.DebugLevel)
zapConfig.Development = true
zapConfig.Encoding = "console"
zapConfig.EncoderConfig = zap.NewDevelopmentEncoderConfig()
}

if c.Core.LogPath != "" {
zapConfig.OutputPaths = []string{c.Core.LogPath}
zapConfig.ErrorOutputPaths = []string{c.Core.LogPath}
if c.Kernel.LogPath != "" {
zapConfig.OutputPaths = []string{c.Kernel.LogPath}
zapConfig.ErrorOutputPaths = []string{c.Kernel.LogPath}
}

l, err := zapConfig.Build()
Expand All @@ -153,24 +153,24 @@ func getProject(c *config.Config, logger *zap.Logger) (*project.Project, error)
project.WithLogger(logger),
}

if c.Core.Filename != "" {
return project.NewFileProject(c.Core.Filename, opts...)
if c.Kernel.Filename != "" {
return project.NewFileProject(c.Kernel.Filename, opts...)
}

projDir := c.Core.ProjectDir
projDir := c.Kernel.ProjectDir
// If no project directory is specified, use the current directory.
if projDir == "" {
projDir = "."
}

opts = append(
opts,
project.WithIgnoreFilePatterns(c.Core.IgnorePaths...),
project.WithRespectGitignore(!c.Core.DisableGitignore),
project.WithEnvFilesReadOrder(c.Core.EnvSourceFiles),
project.WithIgnoreFilePatterns(c.Kernel.IgnorePaths...),
project.WithRespectGitignore(!c.Kernel.DisableGitignore),
project.WithEnvFilesReadOrder(c.Kernel.EnvSourceFiles),
)

if c.Core.FindRepoUpward {
if c.Kernel.FindRepoUpward {
opts = append(opts, project.WithFindRepoUpward())
}

Expand Down Expand Up @@ -228,7 +228,7 @@ func getProjectFilters(c *config.Config) ([]project.Filter, error) {
func getSession(cfg *config.Config, proj *project.Project) (*command.Session, error) {
sess := command.NewSession()

if cfg.Core.UseSystemEnv {
if cfg.Kernel.UseSystemEnv {
if err := sess.SetEnv(os.Environ()...); err != nil {
return nil, err
}
Expand Down
4 changes: 1 addition & 3 deletions internal/config/autoconfig/autoconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ func TestInvokeAll(t *testing.T) {
// Create a runme.yaml using the README.md file from above.
// This won't work with the project as it requires the project
// to be a subdirectory of the current working directory.
configYAML := fmt.Sprintf("version: v1alpha1\ncore:\n filename: %s\n", readmeFilePath)

fmt.Println(string(configYAML))
configYAML := fmt.Sprintf("version: v1alpha1\nproject:\n filename: %s\n", readmeFilePath)

// Create a runme.yaml file in the temp directory.
err = os.WriteFile(filepath.Join(tempDir, "/runme.yaml"), []byte(configYAML), 0o600)
Expand Down
Loading

0 comments on commit 569a9f8

Please sign in to comment.