github.com/furusax0621/goa-v1@v1.4.3/goagen/codegen/helpers.go (about)

     1  package codegen
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"go/build"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  	"unicode"
    11  
    12  	"github.com/goadesign/goa/design"
    13  	"github.com/goadesign/goa/version"
    14  )
    15  
    16  // CheckVersion returns an error if the ver is empty, contains an incorrect value or
    17  // a version number that is not compatible with the version of this repo.
    18  func CheckVersion(ver string) error {
    19  	compat, err := version.Compatible(ver)
    20  	if err != nil {
    21  		return err
    22  	}
    23  	if !compat {
    24  		return fmt.Errorf("version mismatch: using goagen %s to generate code that compiles with goa %s",
    25  			ver, version.String())
    26  	}
    27  	return nil
    28  }
    29  
    30  // CommandLine return the command used to run this process.
    31  func CommandLine() string {
    32  	// We don't use the full path to the tool so that running goagen multiple times doesn't
    33  	// end up creating different command line comments (because of the temporary directory it
    34  	// runs in).
    35  	var param string
    36  
    37  	if len(os.Args) > 1 {
    38  		args := make([]string, len(os.Args)-1)
    39  		gopaths := filepath.SplitList(envOr("GOPATH", build.Default.GOPATH))
    40  		for i, a := range os.Args[1:] {
    41  			for _, p := range gopaths {
    42  				p = "=" + p
    43  				if strings.Contains(a, p) {
    44  					args[i] = strings.Replace(a, p, "=$(GOPATH)", 1)
    45  					break
    46  				}
    47  			}
    48  			if args[i] == "" {
    49  				args[i] = a
    50  			}
    51  		}
    52  		param = strings.Join(args, " ")
    53  	}
    54  	rawcmd := filepath.Base(os.Args[0])
    55  	// Remove possible .exe suffix to not create different ouptut just because
    56  	// you ran goagen on Windows.
    57  	rawcmd = strings.TrimSuffix(rawcmd, ".exe")
    58  
    59  	cmd := fmt.Sprintf("$ %s %s", rawcmd, param)
    60  	return strings.Replace(cmd, " --", "\n\t--", -1)
    61  }
    62  
    63  // Copied from go/build/build.go
    64  func envOr(name, def string) string {
    65  	s := os.Getenv(name)
    66  	if s == "" {
    67  		return def
    68  	}
    69  	return s
    70  }
    71  
    72  // Comment produces line comments by concatenating the given strings and producing 80 characters
    73  // long lines starting with "//"
    74  func Comment(elems ...string) string {
    75  	var lines []string
    76  	for _, e := range elems {
    77  		lines = append(lines, strings.Split(e, "\n")...)
    78  	}
    79  	var trimmed = make([]string, len(lines))
    80  	for i, l := range lines {
    81  		trimmed[i] = strings.TrimLeft(l, " \t")
    82  	}
    83  	t := strings.Join(trimmed, "\n")
    84  
    85  	return Indent(t, "// ")
    86  }
    87  
    88  // Indent inserts prefix at the beginning of each non-empty line of s. The
    89  // end-of-line marker is NL.
    90  func Indent(s, prefix string) string {
    91  	return string(IndentBytes([]byte(s), []byte(prefix)))
    92  }
    93  
    94  // IndentBytes inserts prefix at the beginning of each non-empty line of b.
    95  // The end-of-line marker is NL.
    96  func IndentBytes(b, prefix []byte) []byte {
    97  	var res []byte
    98  	bol := true
    99  	for _, c := range b {
   100  		if bol && c != '\n' {
   101  			res = append(res, prefix...)
   102  		}
   103  		res = append(res, c)
   104  		bol = c == '\n'
   105  	}
   106  	return res
   107  }
   108  
   109  // Tabs returns a string made of depth tab characters.
   110  func Tabs(depth int) string {
   111  	var tabs string
   112  	for i := 0; i < depth; i++ {
   113  		tabs += "\t"
   114  	}
   115  	//	return fmt.Sprintf("%d%s", depth, tabs)
   116  	return tabs
   117  }
   118  
   119  // Add adds two integers and returns the sum of the two.
   120  func Add(a, b int) int { return a + b }
   121  
   122  // CanonicalTemplate returns the resource URI template as a format string suitable for use in the
   123  // fmt.Printf function family.
   124  func CanonicalTemplate(r *design.ResourceDefinition) string {
   125  	return design.WildcardRegex.ReplaceAllLiteralString(r.URITemplate(), "/%v")
   126  }
   127  
   128  // CanonicalParams returns the list of parameter names needed to build the canonical href to the
   129  // resource. It returns nil if the resource does not have a canonical action.
   130  func CanonicalParams(r *design.ResourceDefinition) []string {
   131  	var params []string
   132  	if ca := r.CanonicalAction(); ca != nil {
   133  		if len(ca.Routes) > 0 {
   134  			params = ca.Routes[0].Params()
   135  		}
   136  		for i, p := range params {
   137  			params[i] = Goify(p, false)
   138  		}
   139  	}
   140  	return params
   141  }
   142  
   143  // Casing exceptions
   144  var toLower = map[string]string{"OAuth": "oauth"}
   145  
   146  // SnakeCase produces the snake_case version of the given CamelCase string.
   147  func SnakeCase(name string) string {
   148  	for u, l := range toLower {
   149  		name = strings.Replace(name, u, l, -1)
   150  	}
   151  	var b bytes.Buffer
   152  	var lastUnderscore bool
   153  	ln := len(name)
   154  	if ln == 0 {
   155  		return ""
   156  	}
   157  	b.WriteRune(unicode.ToLower(rune(name[0])))
   158  	for i := 1; i < ln; i++ {
   159  		r := rune(name[i])
   160  		nextIsLower := false
   161  		if i < ln-1 {
   162  			n := rune(name[i+1])
   163  			nextIsLower = unicode.IsLower(n) && unicode.IsLetter(n)
   164  		}
   165  		if unicode.IsUpper(r) {
   166  			if !lastUnderscore && nextIsLower {
   167  				b.WriteRune('_')
   168  				lastUnderscore = true
   169  			}
   170  			b.WriteRune(unicode.ToLower(r))
   171  		} else {
   172  			b.WriteRune(r)
   173  			lastUnderscore = false
   174  		}
   175  	}
   176  	return b.String()
   177  }
   178  
   179  // KebabCase produces the kebab-case version of the given CamelCase string.
   180  func KebabCase(name string) string {
   181  	name = SnakeCase(name)
   182  	return strings.Replace(name, "_", "-", -1)
   183  }