Documentation
¶
Overview ¶
Package parser provides a bunch of functions to be wrapped with generate.Parser function signature.
Examples:
type config struct { ... }
func ParserNode(ctx context.Context, destdir string, c *config) error {
var jsonfile parser.PackageJSON
jsonpath := filepath.Join(destdir, parser.FilePackageJSON)
if err := files.ReadJSON(jsonpath, &jsonfile, os.ReadFile); err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return fmt.Errorf("read json: %w", err)
}
engine.GetLogger().Infof("node detected, a '%s' is present and valid", parser.FilePackageJSON)
if err := jsonfile.Validate(); err != nil {
return fmt.Errorf("validate '%s': %w", parser.FilePackageJSON, err)
}
// do something with parsed jsonfile (e.g. update config since it's a pointer)
return nil
}
var _ generate.Parser[config] = ParserNode // ensure interface is implemented
// single parser call
func main() {
var c config
err := parser.ParserNode(ctx, "path/to/dir", &c)
// handle err
}
// fully used with engine.Generate
func main() {
destdir, _ := os.Getwd()
var c config
err := engine.Generate(ctx, destdir, c, []engine.Parser[config]{ParserNode}, ...)
// handle err
}
Index ¶
Constants ¶
const ( // FolderCMD represents the cmd folder where go main.go should be placed according to go layout. FolderCMD = "cmd" // FileGomod represents the go.mod filename. FileGomod = "go.mod" // FileMain represents the main.go filename. FileMain = "main.go" )
const ( // Bitbucket is just the bitbucket constant. Bitbucket = "bitbucket" // Gitea is just the gitea constant. Gitea = "gitea" // GitHub is just the github constant. GitHub = "github" // GitLab is just the gitlab constant. GitLab = "gitlab" )
const FilePackageJSON = "package.json"
FilePackageJSON represents package.json filename.
Variables ¶
var ( // ErrMissingModuleStatement is the error returned when module statement is missing from go.mod. ErrMissingModuleStatement = errors.New("invalid go.mod, module statement is missing") // ErrMissingGoStatement is the error returned when go statement is missing from go.mod. ErrMissingGoStatement = errors.New("invalid go.mod, go statement is missing") )
var ( // ErrMissingPackageName is the error returned when package.json name is missing. ErrMissingPackageName = errors.New("package.json 'name' is missing") // ErrInvalidPackageManager is the error returned when packageManager is missing or invalid in package.json. ErrInvalidPackageManager = errors.New("package.json 'packageManager' is missing or isn't valid") )
Functions ¶
func MergeValues ¶
MergeValues merges all input values files into one and only map.
It also takes an input values struct / map that could have been read beforehand and marshals it with JSON as base values.
All successive merges are made with override strategy, meaning that a value can be overridden by the next values file. See mergo.Merge for more details.
In case of error, merges stops on the first error and returns it.
It can be used as a simple function, calling it directly, but can also be used as its expected usage with engine.Generate:
type config struct { ... }
func ParserChart(ctx context.Context, destdir string, c *config) error {
chartdir := filepath.Join(destdir, "chart")
if config.CI != nil && config.CI.Deployment != nil && config.CI.Deployment.Helm {
engine.GetLogger().Infof("skipping helm chart, configuration has 'exclude' key with 'chart' in it")
if err := os.RemoveAll(chartdir); err != nil {
return fmt.Errorf("remove chart dir: %w", err)
}
return nil
}
engine.GetLogger().Infof("helm chart detected, configuration doesn't have 'exclude' key or 'chart' isn't present in it")
values, err := parser.MergeValues(c,
filepath.Join(chartdir, "values.custom1.yaml"),
filepath.Join(chartdir, "values.custom2.yaml"))
if err != nil {
return fmt.Errorf("merge values: %w", err)
}
// do something with values (e.g. update config since it's a pointer)
return nil
}
Types ¶
type Executables ¶
type Executables struct {
// Clis is a map of CLI names without value (empty struct).
Clis map[string]struct{} `json:"clis,omitempty"`
// Crons is a map of cronjob names without value (empty struct).
Crons map[string]struct{} `json:"crons,omitempty"`
// Jobs is a map of job names without value (empty struct).
Jobs map[string]struct{} `json:"jobs,omitempty"`
// Workers is a map of workers names without value (empty struct).
Workers map[string]struct{} `json:"workers,omitempty"`
}
Executables represents a collection of executables (clis, cronjobs, jobs, workers).
func ReadGoCmd ¶
func ReadGoCmd(destdir string) (Executables, error)
ReadGoCmd reads cmd folder at destdir and returns all executables found.
An executable is a main.go present in a subfolder of cmd. For instance cmd/<name>/main.go.
Executables are categorized as CLI, Cron, Job and Worker. The prefix of <name> indicates in which category the executable belongs:
- <name> for CLI executables
- cron-<name> for cron executables
- job-<name> for job executables
- worker-<name> for worker executables
It can be used as a simple function, calling it directly, but can also be used as its expected usage with engine.Generate:
type config struct { ... }
func ParserGolang(ctx context.Context, destdir string, c *config) error {
gomod, err := parser.ReadGomod(destdir)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return fmt.Errorf("read go.mod: %w", err)
}
engine.GetLogger().Infof("golang detected, file '%s' is present and valid", parser.FileGomod)
// do something with gomod (e.g. update config since it's a pointer)
executables, err := parser.ReadGoCmd(destdir)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return fmt.Errorf("read cmd: %w", err)
}
// do something with executables (e.g. update config since it's a pointer)
return nil
}
func (*Executables) AddCLI ¶
func (g *Executables) AddCLI(name string)
AddCLI sets a CLI with its name. In case a CLI with the name same already exists, it is replaced.
func (*Executables) AddCron ¶
func (g *Executables) AddCron(name string)
AddCron sets a cronjob with its name. In case a cronjob with the name same already exists, it is replaced.
func (*Executables) AddJob ¶
func (g *Executables) AddJob(name string)
AddJob sets a job with its name. In case a job with the name same already exists, it is replaced.
func (*Executables) AddWorker ¶
func (g *Executables) AddWorker(name string)
AddWorker sets a worker with its name. In case a worker with the name same already exists, it is replaced.
func (Executables) Binaries ¶
func (g Executables) Binaries() int
Binaries returns the sum of all executables (clis, cronjobs, jobs, workers).
type Gomod ¶
type Gomod struct {
// Go is the go statement,
// i.e. "go 1.23.4" without "go" (and space) part.
Go string
// Module is the module statement,
// i.e. "module github.com/kilianpaquier/craft" without "module" (and space) part.
Module string
// Toolchain is the toolchain statement,
// i.e. "toolchain go1.23.4" without "toolchain go" part.
Toolchain string
// Tools is the slice of tools present in go.mod file.
// Nothing is done on it like formatting, as such the path of each tool is the full path given in go.mod.
Tools []string
}
Gomod represents the parsed struct for go.mod file.
func ReadGomod ¶
ReadGomod reads the go.mod file at destdir and returns its representation.
It will return an error if the go.mod file is missing the following properties:
- module statement
- go statement
It can be used as a simple function, calling it directly, but can also be used as its expected usage with engine.Generate:
type config struct { ... }
func Golang(ctx context.Context, destdir string, c *config) error {
gomod, err := parser.ReadGomod(destdir)
if err != nil {
if errors.Is(err, fs.ErrNotExist) {
return nil
}
return fmt.Errorf("read go.mod: %w", err)
}
engine.GetLogger().Infof("golang detected, file '%s' is present and valid", parser.FileGomod)
// do something with gomod (e.g. update config since it's a pointer)
return nil
}
type HugoConfig ¶
type HugoConfig struct {
// IsTheme expresses whether a theme.* configuration is present,
// meaning current hugo repository is a theme one.
IsTheme bool
}
HugoConfig represents the parse'd hugo.* or theme.* file associated to hugo configuration file.
func Hugo ¶
func Hugo(destdir string) (HugoConfig, bool)
Hugo detects if the project is a Hugo project.
Detection consists of looking for hugo.* or theme.* files in the given destdir.
It can be used as a simple function, calling it directly, but can also be used as its expected usage with engine.Generate:
type config struct { ... }
func ParserHugo(ctx context.Context, destdir string, c *config) error {
hugoc, ok := parser.Hugo(destdir)
if !ok {
return nil
}
engine.GetLogger().Infof("hugo detected, theme or hugo files are present")
// do something with hugo config (e.g. update config since it's a pointer)
return nil
}
type PackageJSON ¶
type PackageJSON struct {
Author *string `json:"author,omitempty"`
Description *string `json:"description,omitempty"`
Files []string `json:"files,omitempty"`
Keywords []string `json:"keywords,omitempty"`
License *string `json:"license,omitempty"`
Main *string `json:"main,omitempty"`
Module string `json:"module,omitempty"`
Name string `json:"name,omitempty"`
PackageManager string `json:"packageManager,omitempty"`
Private bool `json:"private,omitempty"`
PublishConfig struct {
Access string `json:"access,omitempty"`
Provenance bool `json:"provenance,omitempty"`
Registry string `json:"registry,omitempty"`
Tag string `json:"tag,omitempty"`
} `json:"publishConfig,omitzero"`
Repository *struct {
URL string `json:"url,omitempty"`
} `json:"repository,omitempty"`
Scripts map[string]string `json:"scripts,omitempty"`
Version string `json:"version,omitempty"`
}
PackageJSON represents the node package json file.
func (*PackageJSON) Validate ¶
func (p *PackageJSON) Validate() error
Validate validates the given PackageJSON struct.
type VCS ¶
type VCS struct {
// Name is the version control system name.
Name string `json:"name,omitempty" yaml:"-"`
// Platform represents the vcs platform hosting the project.
Platform string `json:"-" yaml:"platform,omitempty"`
// ProjectHost represents the host where the project is hosted.
ProjectHost string `json:"projectHost,omitempty" yaml:"-"`
// ProjectName is the project name being generated.
ProjectName string `json:"projectName,omitempty" yaml:"-"`
// ProjectPath is the project path.
ProjectPath string `json:"projectPath,omitempty" yaml:"-"`
}
VCS structure contains all properties related to VCS (Version Control System).
func Git ¶
Git reads the input destdir directory remote.origin.url to retrieve various project information (git host, project name, etc.).
It can be used as a simple function, calling it directly, but can also be used as its expected usage with engine.Generate:
type config struct { ... }
func ParserGit(ctx context.Context, destdir string, c *config) error {
vcs, err := parser.Git(destdir)
if err != nil {
engine.GetLogger().Warnf("failed to retrieve git vcs configuration: %v", err)
return nil // a repository may not be a git repository
}
engine.GetLogger().Infof("git repository detected")
// do something with vcs (e.g. update config since it's a pointer)
return nil
}