Remove 'prefix' and create autodetecting 'path' flag.
このコミットが含まれているのは:
コミット
ed1a715571
|
@ -4,6 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dave/jennifer/jen"
|
"github.com/dave/jennifer/jen"
|
||||||
"github.com/go-fed/activity/tools/exp/codegen"
|
"github.com/go-fed/activity/tools/exp/codegen"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -19,9 +20,11 @@ type PackageManager struct {
|
||||||
// NewPackageManager creates a package manager whose private implementation is
|
// NewPackageManager creates a package manager whose private implementation is
|
||||||
// in an "impl" subdirectory.
|
// in an "impl" subdirectory.
|
||||||
func NewPackageManager(prefix, root string) *PackageManager {
|
func NewPackageManager(prefix, root string) *PackageManager {
|
||||||
|
pathPrefix := strings.Replace(prefix, string(os.PathSeparator), "/", -1)
|
||||||
|
pathRoot := strings.Replace(root, string(os.PathSeparator), "/", -1)
|
||||||
return &PackageManager{
|
return &PackageManager{
|
||||||
prefix: prefix,
|
prefix: pathPrefix,
|
||||||
root: root,
|
root: pathRoot,
|
||||||
public: "",
|
public: "",
|
||||||
private: "impl",
|
private: "impl",
|
||||||
}
|
}
|
||||||
|
@ -84,9 +87,13 @@ func (p *PackageManager) SubPublic(name string) *PackageManager {
|
||||||
// toPackage returns the public or private Package managed by this
|
// toPackage returns the public or private Package managed by this
|
||||||
// PackageManager.
|
// PackageManager.
|
||||||
func (p *PackageManager) toPackage(suffix string, public bool) Package {
|
func (p *PackageManager) toPackage(suffix string, public bool) Package {
|
||||||
path := p.root
|
var path string
|
||||||
if len(suffix) > 0 {
|
if len(p.root) > 0 && len(suffix) > 0 {
|
||||||
path = strings.Join([]string{p.root, suffix}, "/")
|
path = strings.Join([]string{p.root, suffix}, "/")
|
||||||
|
} else if len(suffix) > 0 {
|
||||||
|
path = suffix
|
||||||
|
} else if len(p.root) > 0 {
|
||||||
|
path = p.root
|
||||||
}
|
}
|
||||||
s := strings.Split(path, "/")
|
s := strings.Split(path, "/")
|
||||||
name := s[len(s)-1]
|
name := s[len(s)-1]
|
||||||
|
@ -110,7 +117,11 @@ type Package struct {
|
||||||
|
|
||||||
// Path is the GOPATH or module path to this package.
|
// Path is the GOPATH or module path to this package.
|
||||||
func (p Package) Path() string {
|
func (p Package) Path() string {
|
||||||
return p.prefix + "/" + p.path
|
path := p.prefix
|
||||||
|
if len(p.path) > 0 {
|
||||||
|
path += "/" + p.path
|
||||||
|
}
|
||||||
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteDir obtains the relative directory this package should be written to,
|
// WriteDir obtains the relative directory this package should be written to,
|
||||||
|
|
|
@ -17,6 +17,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
pathFlag = "path"
|
||||||
|
specFlag = "spec"
|
||||||
|
)
|
||||||
|
|
||||||
// Global registry of "known" RDF ontologies. This manages the built-in
|
// Global registry of "known" RDF ontologies. This manages the built-in
|
||||||
// knowledge of how to parse specific linked data documents. It may be cloned
|
// knowledge of how to parse specific linked data documents. It may be cloned
|
||||||
// in the course of processing a JSON-LD document, due to "@context" dictating
|
// in the course of processing a JSON-LD document, due to "@context" dictating
|
||||||
|
@ -65,10 +70,37 @@ func (l *list) Set(v string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// settableString is a flag-friendly string that distinguishes an empty string
|
||||||
|
// due to not being set and explicitly being set as empty at the command line.
|
||||||
|
type settableString struct {
|
||||||
|
set bool
|
||||||
|
str string
|
||||||
|
}
|
||||||
|
|
||||||
|
// String simply returns the string value of this settableString.
|
||||||
|
func (s *settableString) String() string {
|
||||||
|
return s.str
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set will mark this settableString's set as true and store the value.
|
||||||
|
func (s *settableString) Set(v string) error {
|
||||||
|
s.set = true
|
||||||
|
s.str = v
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsSet returns true if this value was explicitly set as a flag value.
|
||||||
|
func (s settableString) IsSet() bool {
|
||||||
|
return s.set
|
||||||
|
}
|
||||||
|
|
||||||
// CommandLineFlags manages the flags defined by this tool.
|
// CommandLineFlags manages the flags defined by this tool.
|
||||||
type CommandLineFlags struct {
|
type CommandLineFlags struct {
|
||||||
specs list
|
// Flags
|
||||||
prefix string
|
specs list
|
||||||
|
path settableString
|
||||||
|
// Additional data
|
||||||
|
pathAutoDetected bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCommandLineFlags defines the flags expected to be used by this tool. Calls
|
// NewCommandLineFlags defines the flags expected to be used by this tool. Calls
|
||||||
|
@ -76,22 +108,55 @@ type CommandLineFlags struct {
|
||||||
// error if validation fails.
|
// error if validation fails.
|
||||||
func NewCommandLineFlags() (*CommandLineFlags, error) {
|
func NewCommandLineFlags() (*CommandLineFlags, error) {
|
||||||
c := &CommandLineFlags{}
|
c := &CommandLineFlags{}
|
||||||
// TODO: Be more rigorous when applying this. Also, clear the default value I am using for convenience.
|
flag.Var(
|
||||||
flag.StringVar(
|
&c.path,
|
||||||
&c.prefix,
|
pathFlag,
|
||||||
"prefix",
|
"Package path to use for all generated package paths. If using GOPATH, this is automatically detected as $GOPATH/<path>/ when generating in a subdirectory. Cannot be explicitly set to be empty.")
|
||||||
"github.com/go-fed/activity/tools/exp/tmp",
|
flag.Var(&(c.specs), specFlag, "Input JSON-LD specification used to generate Go code.")
|
||||||
"Package prefix to use for all generated package paths. This should be the prefix in the GOPATH directory if generating in a subdirectory.")
|
|
||||||
flag.Var(&(c.specs), "spec", "Input JSON-LD specification used to generate Go code.")
|
|
||||||
flag.Parse()
|
flag.Parse()
|
||||||
return c, c.Validate()
|
return c, c.Validate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// detectPath attempts to detect the path to use when generating the code. The
|
||||||
|
// path is only detected if the tool is running in a subdirectory of GOPATH,
|
||||||
|
// and will be set to $GOPATH/<path>/. After this method runs without errors,
|
||||||
|
// c.path.IsSet will always return true.
|
||||||
|
//
|
||||||
|
// When auto-detecting, if GOPATH is not set then will return an error.
|
||||||
|
//
|
||||||
|
// If the path has already been set at the command line, does nothing.
|
||||||
|
func (c *CommandLineFlags) detectPath() error {
|
||||||
|
if c.path.IsSet() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
gopath, isSet := os.LookupEnv("GOPATH")
|
||||||
|
if !isSet {
|
||||||
|
return fmt.Errorf("cannot detect %q because GOPATH environmental variable is not set and %q flag was not explicitly set", pathFlag, pathFlag)
|
||||||
|
}
|
||||||
|
pwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !strings.HasPrefix(pwd, gopath) {
|
||||||
|
return fmt.Errorf("cannot detect %q because current working directory is not under GOPATH and %q flag was not explicitly set", pathFlag, pathFlag)
|
||||||
|
}
|
||||||
|
c.pathAutoDetected = true
|
||||||
|
gopath = strings.Join([]string{gopath, "src", ""}, "/")
|
||||||
|
c.path.Set(strings.TrimPrefix(pwd, gopath))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Validate applies custom validation logic to flags and returns an error if any
|
// Validate applies custom validation logic to flags and returns an error if any
|
||||||
// flags violate these rules.
|
// flags violate these rules.
|
||||||
func (c *CommandLineFlags) Validate() error {
|
func (c *CommandLineFlags) Validate() error {
|
||||||
if len(c.specs) == 0 {
|
if len(c.specs) == 0 {
|
||||||
return fmt.Errorf("spec flag must not be empty")
|
return fmt.Errorf("%q flag must not be empty", specFlag)
|
||||||
|
}
|
||||||
|
if err := c.detectPath(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if len(c.path.String()) == 0 {
|
||||||
|
return fmt.Errorf("%q flag must not be empty", pathFlag)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -115,6 +180,16 @@ func (c *CommandLineFlags) ReadSpecs() (j []rdf.JSONLD, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AutoDetectedPath returns true if the path flag was auto-detected.
|
||||||
|
func (c *CommandLineFlags) AutoDetectedPath() bool {
|
||||||
|
return c.pathAutoDetected
|
||||||
|
}
|
||||||
|
|
||||||
|
// Path returns the path flag.
|
||||||
|
func (c *CommandLineFlags) Path() string {
|
||||||
|
return c.path.String()
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Read, Parse, and Validate command line flags
|
// Read, Parse, and Validate command line flags
|
||||||
cmd, err := NewCommandLineFlags()
|
cmd, err := NewCommandLineFlags()
|
||||||
|
@ -123,6 +198,11 @@ func main() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Print auto-determined values
|
||||||
|
if cmd.AutoDetectedPath() {
|
||||||
|
fmt.Printf("Auto-detected path: %s\n", cmd.Path())
|
||||||
|
}
|
||||||
|
|
||||||
// Read input specification files
|
// Read input specification files
|
||||||
fmt.Printf("Reading input specifications...\n")
|
fmt.Printf("Reading input specifications...\n")
|
||||||
inputJSONs, err := cmd.ReadSpecs()
|
inputJSONs, err := cmd.ReadSpecs()
|
||||||
|
@ -141,7 +221,7 @@ func main() {
|
||||||
// Convert to generated code
|
// Convert to generated code
|
||||||
fmt.Printf("Converting %d types, properties, and values...\n", p.Size())
|
fmt.Printf("Converting %d types, properties, and values...\n", p.Size())
|
||||||
c := &convert.Converter{
|
c := &convert.Converter{
|
||||||
GenRoot: gen.NewPackageManager(cmd.prefix, "gen"),
|
GenRoot: gen.NewPackageManager(cmd.Path(), ""),
|
||||||
PackagePolicy: convert.IndividualUnderRoot,
|
PackagePolicy: convert.IndividualUnderRoot,
|
||||||
}
|
}
|
||||||
f, err := c.Convert(p)
|
f, err := c.Convert(p)
|
||||||
|
|
読み込み中…
新しいイシューから参照