boil

package
v0.0.0-...-4064bea Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 17, 2024 License: MIT Imports: 19 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// ConfigDir is default Boil configuration directory name.
	ConfigDir = "boil"
	// ConfigFilename is defualt Boil configuration file name.
	ConfigFilename = "config.json"
	// RepositoryDir is default Boil repository irectory name.
	RepositoryDir = "repository"
)
View Source
const MetafileName = "boil.json"

MetafileName is the name of a file that defines a Boil template.

Variables

View Source
var StdVariables = []string{
	"TemplatePath",
	"ModulePath",
	"ProjectName",
	"WorkingDir",
	"OutputDir",
	"EditTarget",
	"AuthorName",
	"AuthorEmail",
	"AuthorHomepage",
}

StdVariables is a slice of standard variables.

Functions

func CreateBackup

func CreateBackup(dir string) (string, error)

CreateBackup creates a backup of a directory using config to determine backup location. Returns the backup id and nil on success or an empty string and an error otherwise.

func DefaultConfigDir

func DefaultConfigDir() string

DefaultConfigDir returns the absolute path of default config directory.

func DefaultConfigFilename

func DefaultConfigFilename() string

DefaultConfigFilename returns the absolute path of default config filename.

func DefaultRepositoryDir

func DefaultRepositoryDir() string

DefaultRepositoryDir returns the absolute path of default repository directory.

func ExecuteTemplateString

func ExecuteTemplateString(in string, data any) (out string, err error)

ExecuteTemplateString executes in as a text/template using data and returns it or an error. If data supports FuncMapper the functions are added to the template.

func IsRepoPath

func IsRepoPath(in string) bool

IsRepoPath returns truth is the path is a path relative to repository. This is true if the path has no relation prefix and is not rooted.

func RestoreBackup

func RestoreBackup(id string) error

Types

type Action

type Action struct {
	// Description is the description text of the Action. It's an optional text
	// that should describe the action purpose.
	Description string `json:"description,omitempty"`
	// Program is the path to executable to run.
	Program string `json:"program,omitempty"`
	// Arguments are the arguments to pass to the executable.
	Arguments []string `json:"arguments,omitempty"`
	// WorkDir is the working directory to run the Program from.
	WorkDir string `json:"workDir,omitempty"`
	// Environment is the additional values to set in the Program environment.
	Environment map[string]string `json:"environment,omitempty"`
	// NoFail, if true will not break the execution of the process that ran
	// the Action, but it will generate a warning in the output.
	NoFail bool `json:"noFail,omitempty"`
}

Action defines some external action to execute via command line. See Metafile.Actions for details on Action usage.

func NewAction

func NewAction() *Action

NewAction returns a new *Action.

func (*Action) Execute

func (self *Action) Execute(data *Data) (err error)

Execute executes the Action and returns nil on success or an error. It expands any template tokens in self definition using data.

type Actions

type Actions []*Action

Actions is a slice of Action with some utilities.

func (Actions) ExecuteAll

func (self Actions) ExecuteAll(data *Data) (err error)

ExecuteAll executes all actions in self. Returns the error of the first action that returns it and stops further execution or nil if no errors occur.

type Author

type Author struct {
	// Name is the author name in an arbitrary format.
	Name string `json:"name,omitempty"`
	// Email is the author Email address.
	Email string `json:"email,omitempty"`
	// Homepage is the author's homepage URL.
	Homepage string `json:"homepage,omitempty"`
	// ModulePrefix is the authors default module prefix, your repo home.
	ModulePrefix string `json:"modulePrefix,omitempty"`
}

Author defines an author of a Template or a Repository.

func NewAuthor

func NewAuthor() *Author

NewAuthor returns a new *Author.

type Config

type Config struct {
	// Author is the default template author info.
	Author Author `json:"author,omitempty"`
	// RepositoryPath is the absolute path to the default repository.
	RepositoryPath string `json:"repositoryPath"`

	// DisableBackup, if true disables output directory backup before
	// Template execution.
	//
	// If backup is disabled, if errors occur during template execution
	// the output directory might contain an incomplete and invalid output.
	DisableBackup bool `json:"disableBackup"`

	// Editor defines the action to execute for the "edit" command, i.e.
	// an external application to edit the template files and metafile.
	//
	// If no editor is defined Boil opens the Template directory in the default
	// system file explorer.
	Editor Action `json:"editor,omitempty"`

	// Overrides are the configuration overrides specified on command line.
	// They exist at runtime only and are not serialized with Config.
	Overrides struct {
		// ConfigFile is the absolute path of loaded config file.
		ConfigFile string
		// RepositoryPath is the absolute path of loaded repository.
		RepositoryPath string
		// DisableBackup overrides the Configuration.DisableBackup.
		DisableBackup bool
		// NoRepository if true does not use a repository when interpreting template
		// paths. Relative paths will be treated as relative to current working
		// directory.
		NoRepository bool
		// Verbose specifies wether to enable verbose output.
		Verbose bool
	} `json:"-"`

	// Runtime holds the runtime variables.
	// They are set by Command Run functions.
	// They exist at runtime only and are not serialized with Config.
	Runtime struct {
		// LoadedConfigFile is the name of the configuration file last loaded
		// into self using self.LoadFromFile.
		LoadedConfigFile string
	} `json:"-"`
}

Config represents Boil configuration file.

func DefaultConfig

func DefaultConfig() (config *Config, err error)

DefaultConfig returns a config set to "sane" defaults or an error. Sane as in: * Author name from user account. * ModulePrefix assumed on github with author name suffix. * Editor defaults to vs code in a new window.

func (*Config) GetRepositoryPath

func (self *Config) GetRepositoryPath() string

GetRepositoryPath returns the RepositoryPath considering override values.

func (*Config) LoadFromFile

func (self *Config) LoadFromFile(filename string) (err error)

LoadFromFile loads self from filename or returns an error.

func (*Config) LoadOrCreate

func (self *Config) LoadOrCreate() (err error)

Load loads self from a config file. If Self.Overrides.ConfigFile is set, that path is used, otherwise the config is loaded from the default config file. If the function fails it returns an error.

TODO: Try loading first from program directory on Windows.

func (*Config) Print

func (self *Config) Print()

Print prints self to stdout.

func (*Config) SaveToFile

func (self *Config) SaveToFile(filename string) (err error)

SaveToFile saves self to a file specified by filename or returns an error.

func (*Config) ShouldBackup

func (self *Config) ShouldBackup() (should bool)

ShouldBackup returns true if self says that a backups should be performed.

type Data

type Data struct {
	Vars Variables
	Bast *bast.Bast
	Json map[string]any
}

func DataFromInputs

func DataFromInputs(vars Variables, goInput, jsonInput []string) (out *Data, err error)

func NewData

func NewData() *Data

func (*Data) StringVar

func (self *Data) StringVar(name string) string

StringVar returns a variable value if it exists and its value is a string.

type DiskRepository

type DiskRepository struct {
	// contains filtered or unexported fields
}

DiskRepository is a repository that works with a local fileystem. It is initialized from an absolute filesystem path or a path relative to the current working directory.

func NewDiskRepository

func NewDiskRepository(root string) *DiskRepository

NewDiskRepository returns a new DiskRepository rooted at root.

func (*DiskRepository) Exists

func (self *DiskRepository) Exists(path string) (exists bool, err error)

func (*DiskRepository) HasMeta

func (self *DiskRepository) HasMeta(path string) (exists bool, err error)

func (DiskRepository) LoadMetamap

func (self DiskRepository) LoadMetamap() (metamap Metamap, err error)

LoadMetamap implements Repository.LoadMetamap.

func (DiskRepository) Location

func (self DiskRepository) Location() string

func (*DiskRepository) Mkdir

func (self *DiskRepository) Mkdir(path string) error

func (*DiskRepository) OpenMeta

func (self *DiskRepository) OpenMeta(path string) (meta *Metafile, err error)

func (*DiskRepository) ReadFile

func (self *DiskRepository) ReadFile(name string) ([]byte, error)

func (*DiskRepository) Remove

func (self *DiskRepository) Remove(path string) error

func (*DiskRepository) SaveMeta

func (self *DiskRepository) SaveMeta(meta *Metafile) (err error)

func (*DiskRepository) WalkDir

func (self *DiskRepository) WalkDir(root string, f fs.WalkDirFunc) (err error)

func (*DiskRepository) WriteFile

func (self *DiskRepository) WriteFile(name string, data []byte) error

type Editor

type Editor struct {
	*Interrogator
	// contains filtered or unexported fields
}

Editor is a metafile editor that defines or edits metafiles using stdio for user interaction.

func NewEditor

func NewEditor(config *Config, metafile *Metafile) *Editor

NewEditor returns a new metafile *Editor configured by config.

func (*Editor) EditAll

func (self *Editor) EditAll() (err error)

func (*Editor) EditDirs

func (self *Editor) EditDirs() error

func (*Editor) EditFiles

func (self *Editor) EditFiles() error

func (*Editor) EditGroups

func (self *Editor) EditGroups() error

func (*Editor) EditInfo

func (self *Editor) EditInfo() (err error)

func (*Editor) EditPostExec

func (self *Editor) EditPostExec() error

func (*Editor) EditPreExec

func (self *Editor) EditPreExec() error

func (*Editor) EditPreParse

func (self *Editor) EditPreParse() error

func (*Editor) EditPrompt

func (self *Editor) EditPrompt(prompt *Prompt) (err error)

func (*Editor) EditPrompts

func (self *Editor) EditPrompts() (err error)

func (*Editor) Wizard

func (self *Editor) Wizard() (err error)

Wizard executes a wizard that completely defines the loaded metafile.

type FuncMapper

type FuncMapper interface {
	FuncMap() template.FuncMap
}

FuncMapper can return a template.FuncMap.

type Group

type Group struct {
	// Name is the name of the Template Group.
	Name string `json:"name,omitempty"`
	// Description is the Group description text.
	Description string `json:"description,omitempty"`
	// Templates is a slice of Template names contained in this Group.
	Templates []string `json:"templates,omitempty"`
}

Group defines a group of templates. See Metafile.Groups for details on Group usage.

type Interrogator

type Interrogator struct {
	// contains filtered or unexported fields
}

Interrogator interrogates the user via some reader and writer.

func NewInterrogator

func NewInterrogator(r io.Reader, w io.Writer) *Interrogator

NewInterrogator returns a new *Interrogator that reads from r and writes to w.

func (*Interrogator) AskChoice

func (self *Interrogator) AskChoice(def string, choices ...string) (result string, err error)

AskChoice asks for one of the specified choices and returns it and nil on success or an empty result and an error if one occured.

If an empty value is entered the function returns def. There may be no empty strings in choices otherwise an error is returned.

The choice string may be a single word that must be repeated on input to select a choice. If a non empty value is entered but does not match any of the choices the prompt is repeated.

A choice string may also be a tab delimited string where left of the first tab is the choice word that must be repeated and right of first tab is the short description text displayed next to the choice.

func (*Interrogator) AskList

func (self *Interrogator) AskList() (result []string, err error)

AskList asks for a list of values by repeatedly asking for a value until an empty string is entered then returns the result and a nil error or an empty result and an error if one occured.

func (*Interrogator) AskValue

func (self *Interrogator) AskValue(title, def, regex string) (result string, err error)

AskValue asks for a value and returns def if empty string was entered. If regex is not empty entered value is matched against it and prompt is repeated if the match failed. If an error occurs it is returned with an empty result, nil otherwise.

func (*Interrogator) AskVariable

func (self *Interrogator) AskVariable() (key, value string, err error)

AskVariable asks for a key=value pair and returns them with a nil error. If an empty key is entered the function aborts and returns empty key and value and a nil error. Caller should check validity of returned values, If any other error occurs returns empty key and value and the occured error.

func (*Interrogator) AskYesNo

func (self *Interrogator) AskYesNo(def bool) (result bool, err error)

AskYesNo asks for a choice between "yes" or a "no" using AskChoice. If an empty string is entered the function returns def. If a word other than "yes" and "no" is entered the prompt is repeated. The value of def must be "yes" or "no" or an error is returned. If an error occurs returns empty result and an error or nil otherwise.

func (*Interrogator) Flush

func (self *Interrogator) Flush() error

Flush flushes self and returns any errors.

func (*Interrogator) Printf

func (self *Interrogator) Printf(format string, arguments ...any) (err error)

Printf printfs to self and flushes. Returns an error if one occured.

type Metafile

type Metafile struct {
	// Name is the Template name.
	// It is the last element of the template path when addressing it.
	// For example 'apps/<name>'
	Name string `json:"name,omitempty"`

	// Description is the Template description.
	// It is presented to the user when asking for template information.
	Description string `json:"description,omitempty"`

	// Author is the template author details.
	// This information is optional and is generated from the values set in
	// Configuration when generating a Template.
	Author *Author `json:"author,omitempty"`

	// Version is the template version, set manually used to help keep track of
	// Template changes. SemVer will be understood if this becomes important to
	// machine; currently just a meta field possibly useful to user.
	// By default the version is set at '1.0.0' when generating a Template.
	Version string `json:"version,omitempty"`

	// URL is an optional template url. Like Version, it has no meaning to the
	// machine but is just an additional meta field. It is empty by default.
	URL string `json:"url,omitempty"`

	// Files is a list of paths to files inside the Template directory that
	// will get executed and written to the output target directory retaining
	// its path relative to the Template directory.
	//
	// Paths must be relative to the Template directory and may not be rooted.
	// Files must point to existing files inside the Template directory.
	//
	// Directories for files will be created as needed, regardless of wether
	// they are defined in Directories.
	//
	// Paths of files defined in Files may contain placeholder values which will
	// get expended to actual values during Template execution.
	// A placeholder is defined with a "$" prefix, immediately followed by the
	// name of a Variable.
	Files []string `json:"files"`

	// Directories is a list of directories to create in the target directory.
	// Placeholders are supported like with Files. Directories defined in this
	// list will be created regardless of wether they contain any of the
	// files defined by Files or if they exist phisically in the Template
	// directory. They will be created in the template however when creating a
	// Template with the "snap" command.
	Directories []string `json:"directories"`

	// Prompts is a list of prompts to present to the user before Template
	// execution via stdin to input values for variables the prompts define.
	//
	// Along with manually defining variables with the --var flag, a Template
	// can prompt the user for specific variables that the Template file needs.
	//
	// Prompts can each define a regular expression to use for input validation.
	// A failed validation will then re-prompt the user for value.
	Prompts Prompts `json:"prompts,imitempty"`

	// Actions are groups of definitions of external actions to perform at
	// various stages of Template execution. In each Action group
	// (PreParse, PreExecute,...) the name of the Action must be unique and not
	// empty.
	Actions struct {
		// PreParse is a slice of actions to perform before any input variables
		// were parsed from any of sources defined on command line, in the
		// order they are defined. This is useful for a template setup like
		// temporary file generation, data input to variables, etc.
		//
		// No placeholders are available to expand in PerParse action
		// definition and any placeholder values found in the Action definition
		// will be unchanged and passed as defined, without raising an error.
		PreParse Actions `json:"preParse,omitempty"`
		// PreExecute is a slice of actions to perform before the template is
		// executed in the order they are defined. It is called after the
		// variables were defined by parsing command line input, files given as
		// variable data on command line and all other input methods and are
		// available as expandable placeholders in action definition.
		//
		// This useful to execute some Template setup commands that depend on
		// Template variables.
		PreExecute Actions `json:"preExecute,omitempty"`

		// PostExecute is a slice of actions to perform after the template was
		// executed, in order they are defined. This is useful for performing
		// cleanup operations. Variables will be available for expansion in the
		// action definition via placeholders.
		PostExecute Actions `json:"postExecute,omitempty"`
	} `json:"actions,omitempty"`

	// Groups is a slice of Template Group definitions that may be executed
	// with the Template the metafile describes, as part of that Template.
	//
	// If the Template that this metafile describes contains other Templates
	// in any of its subdirectories, at any depths, one or more of those child
	// Templates may be combined into a named Group and addressed from it by a
	// path relative to this template.
	//
	// A Group can be executed along with the Template that defines it as part
	// of that template. This allows for defining segmented and multilayered
	// permutations of templates organized in a parent-child manner.
	//
	// A Group template is addressed by its path in a manner that the last
	// element of the path that matches Metafile.Name is instead replaced with
	// the name of the Group. So for instance, if a template 'apps/versatileapp'
	// defines groups 'base', and 'complete', to execute the 'base' Group the
	// path would be 'apps/base'.
	Groups []*Group `json:"groups,omitempty"`

	// Path is where metafile resides, relative to the repository root.
	// it is equal to template Path minus the optional group name.
	//
	// Path is not stored with the template, it's runtime only.
	Path string `json:"-"`
}

Metafile is the Boil Template metadata. A directory with a valid Metafile defines a Template.

If a Template contains other Templates in some of its subdirectories it can define one or more Group definitions with various combinations of theese child templates to be executed as part of the parent Template.

func NewMetafile

func NewMetafile(config *Config) *Metafile

NewMetafile returns a new metfile initialized to defaults from config.

func (Metafile) ExecPostExecuteActions

func (self Metafile) ExecPostExecuteActions(data *Data) error

ExecPostExecuteActions executes all PostExecute Actions defined in the Metafile. It returns the error of the first Action that failed and stops execution. If no error occurs nil is returned.

func (Metafile) ExecPreExecuteActions

func (self Metafile) ExecPreExecuteActions(data *Data) error

ExecPreExecuteActions executes all PreExecute Actions defined in the Metafile. It returns the error of the first Action that failed and stops execution. If no error occurs nil is returned.

func (Metafile) ExecPreParseActions

func (self Metafile) ExecPreParseActions() error

ExecPreParseActions executes all PreParse Actions defined in the Metafile. It returns the error of the first Action that failed and stops execution. If no error occurs nil is returned.

func (*Metafile) Print

func (self *Metafile) Print(wr io.Writer)

Print prints self to stdout. TODO: better layout.

func (Metafile) Validate

func (self Metafile) Validate(repo Repository) error

Validate validates that metadata is properly formatted. It checks that multis point to valid Templates in the repo. It checks for duplicate template definitions.

type Metamap

type Metamap map[string]*Metafile

Metamap maps a path to a template to its *Metafile.

func (Metamap) Print

func (self Metamap) Print(wr io.Writer)

Print prints self to stdout.

type Printer

type Printer struct {
	// contains filtered or unexported fields
}

Printer is a boil preset TabWriter.

func NewPrinter

func NewPrinter(w io.Writer) *Printer

NewPrinter returns a new *Printer that writes to w. If w is nil Printer prints to stdout.

func (*Printer) Printf

func (self *Printer) Printf(format string, args ...any)

func (*Printer) Write

func (self *Printer) Write(p []byte) (n int, err error)

type Prompt

type Prompt struct {
	// Variable is the name of the Variable this prompt will ask value for.
	Variable string `json:"variable,omitempty"`
	// Description is the prompt text presented to the user when asking for value.
	//
	// On stdin the format will be: "Enter a value for <Description>".
	Description string `json:"description,omitempty"`
	// RegEx is the regular expression to use to validate the input string.
	// If RegEx is not set no validation will be performed on input in addition
	// to an empty value being accepted as a value.
	RegExp string `json:"regexp,omitempty"`
	// Optional if true will not trigger an error if the variable was assigned
	// an empty value.
	Optional bool `json:"optional,omitempty"`
}

Prompt defines a prompt to the user for input of variable values. See Metafile.Prompts for details on Prompt usage.

type Prompts

type Prompts []*Prompt

Prompts is a slice of *Prompt.

func (Prompts) FindByVariable

func (self Prompts) FindByVariable(variable string) *Prompt

FindByVariable returns a Prompt that defines variable or nil if not found.

type Repository

type Repository interface {
	// Location returns the repository location in a format specific to
	// Repository backend.
	Location() string

	// LoadMetamap loads metadata from repository walking all child
	// subdirectories and returns it or returns a descriptive error.
	//
	// The resulting Metamap will contain a *Metadata for each subdirectory at
	// any level in the Repository that contains a Metafile, i.e. defines a
	// Template, under a key that will be a path relative to Repository.
	//
	// If the root of the Repository contains Metafile i.e. is a Template
	// itself an entry for it will be set under current directory dot ".".
	//
	// Any groups defined in a template will be added under the same path as the
	// template that defines them but with a group name suffix prefixed with a
	// "#". For example if a template 'go/app' defines a 'config' group it would
	// be addressed as 'go/app#config'.
	LoadMetamap() (Metamap, error)
	// HasMeta returns true if path contains a metafile or an error.
	HasMeta(path string) (bool, error)
	// OpenMeta returns a *Metafile at path or an error if it does not exist or
	// some other error occurs.
	OpenMeta(path string) (*Metafile, error)
	// SaveMeta saves the Metafile into repository according to its Path or
	// returns an error. It overwrites the target if it exists or creates it if
	// it does not. Creates required directories along the path.
	SaveMeta(meta *Metafile) error

	// Exists returns true if file or dir exists at path or an error.
	Exists(path string) (bool, error)
	// GetFile gets contents of the file at path. It must exist and be
	// referenced in meta.
	ReadFile(path string) ([]byte, error)
	// WriteFile writes data as contents of the file at path into repository.
	// File may exists and if it does will be truncated and overwritten.
	// Path must be referenced in meta. Directories will be created as needed
	// if the file is referenced in meta.
	WriteFile(path string, data []byte) error
	// Mkdir creates all directories along the path or returns an error.
	Mkdir(path string) error
	// Remove removes file at path if path points to a file or recusrsively
	// deletes all content in the directory at path, recusrively. Returns an
	// error if one occured.
	Remove(path string) error

	// WalkDir walks the repository depth first and calls f for each file or
	// directory found in the repository. Behaves exactly like filepath.WalkDir
	// except that the path given to f will be a path relative to the repository
	// root.
	WalkDir(root string, f fs.WalkDirFunc) error
}

Repository defines a location where Templates are stored.

Templates inside a Repository are addressed by a path relative to the Repository root, i.e. 'apps/cliapp'.

func OpenRepository

func OpenRepository(path string) (repo Repository, err error)

OpenRepository opens a repository at the specified path. It returns an implementation that handles the specific path format.

Currently supported backends: * local filesystem (DiskRepository)

If an error occurs it is returned with a nil repository.

type Variable

type Variable int

Variable defines a known variable. A known variable is a variable that oil sets or manipulates but it can be set ot overriden by the user in various situations. Each one has its magic described.

const (
	// VarTemplatePath is exec command template-path.
	VarTemplatePath Variable = iota

	VarModulePath

	// VarProjectName is used in the context of a project generation by the
	// exec command. It is by default determined from the base of the OutputDir.
	VarProjectName
	// VarWorkingDir is always available.
	VarWorkingDir
	// VarOutputDir is exec command output-dir.
	// It can be set via prompt to override value giveon on command line.
	VarOutputDir

	// VarEditTarget is set by a command.
	VarEditTarget

	// VarAuthor holds the author name.
	VarAuthorName

	VarAuthorEmail

	VarAuthorHomepage
)

func (Variable) String

func (self Variable) String() string

String reurns string representation of Variable.

type Variables

type Variables map[string]any

Variables defines a map of variables keying variable names to their values.

A variable is a value that is available to Template files on execution either as data for a Template file being executed with text/template or as values when expending placeholders in Template file names.

Variables can be extracted from files, generated by an external command or defined by the user on Template execution via command line.

func (Variables) AddNew

func (self Variables) AddNew(variables Variables) Variables

AddNew adds variables that do not exist in self to self and returns self.

func (Variables) Exists

func (self Variables) Exists(name string) (exists bool)

Exists returns true if variable under name exists.

func (Variables) MaybeSetString

func (self Variables) MaybeSetString(key Variable, out *string)

MaybeSetString sets the value of out to the value of the Variable under key if it exists in self and is of type string. Otherwise, out is unmodified.

func (Variables) Print

func (self Variables) Print(wr io.Writer)

func (Variables) ReplacePlaceholders

func (self Variables) ReplacePlaceholders(in string) (out string)

ReplacePlaceholders replaces all known variable placeholders in input string with actual values and returns it.

A placeholder is a case sensitive variable name prefixed with "$".

func (Variables) SetAssignments

func (self Variables) SetAssignments(assignments ...string) (err error)

SetAssignments adds assignments to self overwriting any existing entries where an assignment is a string in a "key=value" format.

Value is unquoted if quoted. If an entry is found that is not in proper format an error is returned that describes the offending entry and no variables are added to self or in case of any other error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL