- Global options -v/-vv/-vvv, -q, --ansi/--no-ansi, -n and --env on every command; PeekGlobals reads them before config loads, OnGlobals hooks re-apply them after parsing (diary.ApplyGlobals in the generated main) - Bare binary, --help and list print the Artisan list with the version header from BuildVersion and namespace blocks - Execute runs the root through fang (no version, man page or completions) and returns 0, 1 or 2; Fail renders errors before the root exists - NewRoot rejects duplicate command names (ErrDuplicateCommand) and flags that reuse a global option (ErrReservedFlag) - Generated main and summer use PeekGlobals, compass.Open with --env, diary.FromGlobals and bonfire.Execute; docs checker knows the globals
74 lines
2.1 KiB
Go
74 lines
2.1 KiB
Go
package bonfire
|
|
|
|
import (
|
|
"runtime/debug"
|
|
)
|
|
|
|
// frameworkModule is the module path of the SummerCMS framework.
|
|
const frameworkModule = "git.golem15.com/golem15/summercms"
|
|
|
|
// Version is the version line of a binary: the application's own version and
|
|
// the framework version it was built against.
|
|
type Version struct {
|
|
// App is the application module version ("devel" for an untagged
|
|
// local build).
|
|
App string
|
|
// Framework is the framework module version; it equals App when the
|
|
// binary is the framework's own summer tool.
|
|
Framework string
|
|
// Local is true when the framework comes from a replace directive
|
|
// (a local checkout) rather than the module proxy.
|
|
Local bool
|
|
}
|
|
|
|
// BuildVersion reads the versions from the binary's build information
|
|
// (runtime/debug.ReadBuildInfo): App is the main module version and Framework
|
|
// the version of the git.golem15.com/golem15/summercms dependency, or App
|
|
// when the main module is the framework itself. "(devel)" reads as "devel".
|
|
func BuildVersion() Version {
|
|
info, ok := debug.ReadBuildInfo()
|
|
if !ok {
|
|
return Version{App: "devel", Framework: "devel"}
|
|
}
|
|
v := Version{App: cleanVersion(info.Main.Version)}
|
|
if info.Main.Path == frameworkModule {
|
|
v.Framework = v.App
|
|
return v
|
|
}
|
|
v.Framework = "devel"
|
|
for _, dep := range info.Deps {
|
|
if dep.Path != frameworkModule {
|
|
continue
|
|
}
|
|
v.Framework = cleanVersion(dep.Version)
|
|
v.Local = dep.Replace != nil
|
|
break
|
|
}
|
|
return v
|
|
}
|
|
|
|
func cleanVersion(s string) string {
|
|
if s == "" || s == "(devel)" {
|
|
return "devel"
|
|
}
|
|
return s
|
|
}
|
|
|
|
// Header is the first line of the command list: "SummerCMS acme v1.4.0
|
|
// (framework v0.3.2)", with ", local" added inside the parentheses when the
|
|
// framework is a local checkout, and "SummerCMS summer v0.3.2" when App and
|
|
// Framework are the same build.
|
|
func (v Version) Header(name string) string {
|
|
app := cleanVersion(v.App)
|
|
line := "SummerCMS " + name + " " + app
|
|
fw := v.Framework
|
|
if fw == "" || (fw == v.App && !v.Local) {
|
|
return line
|
|
}
|
|
fw = "framework " + cleanVersion(fw)
|
|
if v.Local {
|
|
fw += ", local"
|
|
}
|
|
return line + " (" + fw + ")"
|
|
}
|