goa_model_gen 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55c211e5cded1ceaad2db67152473f68f80db81ee97d83f8ea453ce08ee07cf8
4
- data.tar.gz: 2a752f9dcd6daa746f7e8364ca9ca972e73a78e8dfd497eb08783da6ebb8ecc8
3
+ metadata.gz: 721bb2c0d07817d9853be4f1dae801b682b51d636416880e464b29ace1477949
4
+ data.tar.gz: 2a5c2e05448fd86fb2b3bef0d5b3693589fd325c45830763ea82f29a1e924f39
5
5
  SHA512:
6
- metadata.gz: 7197c6ef9959172c9d32f533fe8cacd72ed94f1b9f5a7eacbbed21622e39a5226cd9a2a765f25bed15e206cba6b8bb85a3e93e519596d6f667d7c22d9c5ada6a
7
- data.tar.gz: bc4dfd74fd8cc1b0d7362218da8e51039614dcc008b074d95fab2fc5e6214f629be95a5917f3660621f655b65dbd864b50b0d58779345b18240d8e40a46fbde3
6
+ metadata.gz: bd7b88d3471523df596f2b07ad5cb974c5ca6a127ed75cca19a5615d8b432a5edf812341047c554a7988358f0dfa6ef9548ecf5857d435b8b17cd0ded2f60ece
7
+ data.tar.gz: d1cb7ccfbe6dd50baeede29910cdcafbdace04d8b55d2fbf322143fb76f42017b5bf8c9dbfb23a20be748bb827765a95c5eb1841834b6c5df83b4450de62f56f
@@ -32,22 +32,22 @@ module GoaModelGen
32
32
  desc "show FILE1...", "Show model info from definition files"
33
33
  def show(*paths)
34
34
  show_version_if_required
35
- load_types_for(paths) do |path, types|
36
- puts "types in #{path}"
37
- puts YAML.dump(types)
35
+ load_types_for(paths) do |source_file|
36
+ puts "types in #{source_file.yaml_path}"
37
+ puts YAML.dump(source_file.types)
38
38
  end
39
39
  end
40
40
 
41
41
  desc "model FILE1...", "Generate model files from definition files"
42
42
  def model(*paths)
43
43
  show_version_if_required
44
- load_types_for(paths) do |path, types|
45
- generator = new_generator.tap{|g| g.types = types }
44
+ load_types_for(paths) do |source_file|
45
+ generator = new_generator.tap{|g| g.source_file = source_file }
46
46
  [
47
47
  {path: 'templates/model.go.erb', suffix: '.go', overwrite: true},
48
48
  {path: 'templates/model_validation.go.erb', suffix: '_validation.go', overwrite: false},
49
49
  ].each do |d|
50
- dest = File.join(cfg.model_dir, File.basename(path, ".*") + d[:suffix])
50
+ dest = File.join(cfg.model_dir, File.basename(source_file.path, ".*") + d[:suffix])
51
51
  generator.run(d[:path], dest, overwrite: d[:overwrite])
52
52
  end
53
53
  end
@@ -56,10 +56,10 @@ module GoaModelGen
56
56
  desc "converter FILE1...", "Generate converter files from definition files and swagger.yaml"
57
57
  def converter(*paths)
58
58
  show_version_if_required
59
- load_types_for(paths) do |path, types|
60
- generator = new_generator.tap{|g| g.types = types }
61
- dest = File.join(cfg.controller_dir, File.basename(path, ".*") + "_conv.go")
62
- if types.any?{|t| !!t.payload || !!t.media_type}
59
+ load_types_for(paths) do |source_file|
60
+ generator = new_generator.tap{|g| g.types = source_file.types }
61
+ dest = File.join(cfg.controller_dir, File.basename(source_file.yaml_path, ".*") + "_conv.go")
62
+ if source_file.types.any?{|t| !!t.payload || !!t.media_type}
63
63
  generator.run('templates/converter.go.erb', dest, overwrite: true)
64
64
  end
65
65
  end
@@ -88,24 +88,12 @@ module GoaModelGen
88
88
  end
89
89
 
90
90
  def load_types_for(paths)
91
- swagger_loader = GoaModelGen::SwaggerLoader.new(cfg.swagger_yaml)
92
- path_to_types = {}
93
- defined_types = {}
94
- paths.each do |path|
95
- types = GoaModelGen::ModelLoader.new(path).load_types
96
- types.each{|t| t.assign_swagger_types(swagger_loader) }
97
- types.each{|t| defined_types[t.name] = t }
98
- path_to_types[path] = types
99
- end
100
- paths.each do |path|
101
- types = path_to_types[path]
102
- types.each{|t| t.assign_field_type_base(defined_types) }
103
- end
104
- paths.each do |path|
105
- yield(path, path_to_types[path])
91
+ loader = GoaModelGen::Loader.new(cfg)
92
+ source_files = loader.load(paths)
93
+ source_files.each do |source_file|
94
+ yield(source_file)
106
95
  end
107
96
  end
108
-
109
97
  end
110
98
 
111
99
  end
@@ -17,7 +17,7 @@ module GoaModelGen
17
17
  controller_dir
18
18
  ].freeze
19
19
 
20
- attr_reader *ATTRIBUTES
20
+ attr_accessor *ATTRIBUTES
21
21
 
22
22
  def fulfill
23
23
  @go_package ||= default_go_package
@@ -62,6 +62,10 @@ module GoaModelGen
62
62
  ].map{|k,v| v ? "#{k}:\"#{v}\"" : nil}.compact.join(' ')
63
63
  end
64
64
 
65
+ def definition
66
+ "#{ name } #{ type } `#{ tag }`"
67
+ end
68
+
65
69
  # https://swagger.io/docs/specification/data-models/data-types/
66
70
  # https://tour.golang.org/basics/11
67
71
  # https://golang.org/pkg/go/types/#pkg-variables
@@ -1,4 +1,5 @@
1
1
  require "goa_model_gen"
2
+ require "goa_model_gen/golang_helper"
2
3
 
3
4
  require "erb"
4
5
 
@@ -9,23 +10,30 @@ module GoaModelGen
9
10
  class Generator
10
11
  # These are used in templates
11
12
  attr_reader :config
12
- attr_accessor :types
13
+ attr_accessor :source_file
13
14
 
14
15
  def initialize(config)
15
16
  @config = config
16
17
  end
17
18
 
18
- def run(rel_path, path, overwrite: false)
19
- return if File.exist?(path) && !overwrite
20
- abs_path = File.expand_path('../' + rel_path, __FILE__)
19
+ def golang_helper
20
+ @golang_helper ||= GolangHelper.new
21
+ end
22
+
23
+ def generate(template_path)
24
+ abs_path = File.expand_path('../' + template_path, __FILE__)
21
25
  erb = ERB.new(File.read(abs_path), nil, "-")
22
26
  erb.filename = abs_path
23
27
  content = erb.result(binding)
24
- open(path, 'w'){|f| f.puts(content) }
25
- if (File.extname(path) == '.go') && !config.gofmt_disabled
26
- system("gofmt -w #{path}")
27
- end
28
28
  end
29
29
 
30
+ def run(template_path, output_path, overwrite: false)
31
+ return if File.exist?(output_path) && !overwrite
32
+ content = generate(template_path)
33
+ open(output_path, 'w'){|f| f.puts(content) }
34
+ if (File.extname(output_path) == '.go') && !config.gofmt_disabled
35
+ system("gofmt -w #{output_path}")
36
+ end
37
+ end
30
38
  end
31
39
  end
@@ -0,0 +1,19 @@
1
+ module GoaModelGen
2
+ class GolangHelper
3
+
4
+ PARTITION_PATTERNS = [
5
+ /\A[^\.\/]+(?:\/.+)?\z/,
6
+ /\Agopkg\.in\//,
7
+ /\Agolang\.org\//,
8
+ /\Agoogle\.golang\.org\//,
9
+ /\Agithub\.com\//,
10
+ ]
11
+
12
+ def partition(paths)
13
+ groups = paths.group_by do |path|
14
+ PARTITION_PATTERNS.index{|ptn| ptn =~ path} || PARTITION_PATTERNS.length
15
+ end
16
+ groups.keys.sort.map{|k| groups[k].sort }
17
+ end
18
+ end
19
+ end
@@ -4,6 +4,7 @@ require "yaml"
4
4
 
5
5
  require "goa_model_gen/type"
6
6
  require "goa_model_gen/field"
7
+ require "goa_model_gen/source_file"
7
8
 
8
9
  module GoaModelGen
9
10
  class BaseLoader
@@ -16,12 +17,6 @@ module GoaModelGen
16
17
  @raw = YAML.load_file(path)
17
18
  end
18
19
 
19
- def load_types
20
- raw[types_key].map do |name, definition|
21
- build_type(name, definition)
22
- end
23
- end
24
-
25
20
  def build_type(name, d)
26
21
  kind.new(name, d).tap do |t|
27
22
  if d[fields_key]
@@ -35,19 +30,6 @@ module GoaModelGen
35
30
  def build_field(name, f)
36
31
  Field.new(name, f)
37
32
  end
38
-
39
- def dig(path)
40
- dig_into(raw, path.split('/'), [])
41
- end
42
-
43
- def dig_into(hash, keys, footprints)
44
- # puts "dig_into(hash, #{keys.inspect}, #{footprints.inspect})"
45
- key = keys.shift
46
- value = hash[key]
47
- return value if keys.empty?
48
- raise "No data for #{key} in #{footprints.join('/')}" if value.nil?
49
- return dig_into(value, keys, footprints + [key])
50
- end
51
33
  end
52
34
 
53
35
  class ModelLoader < BaseLoader
@@ -55,6 +37,13 @@ module GoaModelGen
55
37
  super(path, Model, 'types', 'fields')
56
38
  end
57
39
 
40
+ def load_file
41
+ types = raw[types_key].map do |name, definition|
42
+ build_type(name, definition)
43
+ end
44
+ SourceFile.new(path, types)
45
+ end
46
+
58
47
  def build_field(name, f)
59
48
  fd = f.is_a?(Hash) ? f : {'type' => f.to_s}
60
49
  fd['type'] ||= 'string'
@@ -94,5 +83,40 @@ module GoaModelGen
94
83
  raise "#{name} not found in #{path}" unless r
95
84
  r
96
85
  end
86
+
87
+ def dig(path)
88
+ dig_into(raw, path.split('/'), [])
89
+ end
90
+
91
+ def dig_into(hash, keys, footprints)
92
+ # puts "dig_into(hash, #{keys.inspect}, #{footprints.inspect})"
93
+ key = keys.shift
94
+ value = hash[key]
95
+ return value if keys.empty?
96
+ raise "No data for #{key} in #{footprints.join('/')}" if value.nil?
97
+ return dig_into(value, keys, footprints + [key])
98
+ end
99
+ end
100
+
101
+ class Loader
102
+ attr_reader :config
103
+ def initialize(config)
104
+ @config = config
105
+ end
106
+
107
+ def load_types(paths)
108
+ swagger_loader = GoaModelGen::SwaggerLoader.new(config.swagger_yaml)
109
+ defined_types = {}
110
+ files = paths.map do |path|
111
+ GoaModelGen::ModelLoader.new(path).load_file.tap do |f|
112
+ f.types.each{|t| t.assign_swagger_types(swagger_loader) }
113
+ f.types.each{|t| defined_types[t.name] = t }
114
+ end
115
+ end
116
+ files.each do |f|
117
+ f.types.each{|t| t.assign_field_type_base(defined_types) }
118
+ end
119
+ return files
120
+ end
97
121
  end
98
122
  end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ require 'goa_model_gen'
3
+ require 'goa_model_gen/type'
4
+
5
+ require "active_support/core_ext/string"
6
+
7
+ module GoaModelGen
8
+ class SourceFile
9
+ attr_reader :yaml_path, :types
10
+ def initialize(yaml_path, types)
11
+ @yaml_path, @types = yaml_path, types
12
+ end
13
+
14
+ def model_dependencies
15
+ @model_dependencies ||= calc_model_dependencies
16
+ end
17
+
18
+ def calc_model_dependencies
19
+ r = []
20
+ r << "github.com/goadesign/goa/uuid" if types.any?(&:use_uuid?)
21
+ if types.any?(&:store?)
22
+ r << "fmt"
23
+ r << "golang.org/x/net/context"
24
+ r << "google.golang.org/appengine/datastore"
25
+ r << "google.golang.org/appengine/log"
26
+ end
27
+ r << "time" if types.any?(&:has_time_field?)
28
+ r.uniq
29
+ end
30
+ end
31
+ end
@@ -1,29 +1,27 @@
1
1
  package model
2
2
 
3
+ <%- unless source_file.model_dependencies.empty? -%>
3
4
  import (
4
- "fmt"
5
- "time"
6
-
7
- "golang.org/x/net/context"
8
- "google.golang.org/appengine/datastore"
9
- "google.golang.org/appengine/log"
5
+ <%- golang_helper.partition(source_file.model_dependencies).each do |group| -%>
6
+ <%- group.each do |path| -%>
7
+ "<%= path %>"
8
+ <%- end -%>
10
9
 
11
- <%- if types.select(&:store?).any?{|m| m.goon['id_type'] == 'UUID'} -%>
12
- "github.com/goadesign/goa/uuid"
13
10
  <%- end -%>
14
11
  )
12
+ <%- end -%>
15
13
 
16
- <%- types.each do |type| -%>
14
+ <%- source_file.types.each do |type| -%>
17
15
  <%- if !type.fields.empty? -%>
18
16
  type <%= type.name %> struct {
19
17
  <%- if type.goon -%>
20
- <%= type.id_name %> <%= type.id_golang_type %> `datastore:"-" goon:"id" json:"<%= type.id_name.underscore %>"`
18
+ <%= type.id_definition %>
21
19
  <%- if type.parent -%>
22
20
  ParentKey *datastore.Key `datastore:"-" goon:"parent" json:"-"`
23
21
  <%- end -%>
24
22
  <%- end -%>
25
23
  <%- type.fields.each do |field| -%>
26
- <%= field.name %> <%= field.type %> `<%= field.tag %>`
24
+ <%= field.definition %>
27
25
  <%- end -%>
28
26
  }
29
27
  <%- elsif type.base -%>
@@ -40,7 +38,7 @@ const (
40
38
 
41
39
  <%- end -%>
42
40
 
43
- <%- types.select(&:store?).each do |model| -%>
41
+ <%- source_file.types.select(&:store?).each do |model| -%>
44
42
  func (m *<%= model.name %>) PrepareToCreate() error {
45
43
  <%- if model.fields.any?{|f| f.name == "CreatedAt"} -%>
46
44
  if m.CreatedAt.IsZero() {
@@ -71,7 +69,7 @@ func (m *<%= model.name %>) Parent(ctx context.Context) (*<%= model.parent %>, e
71
69
 
72
70
  <%- end -%>
73
71
 
74
- <%- types.select(&:store?).each do |model| -%>
72
+ <%- source_file.types.select(&:store?).each do |model| -%>
75
73
  <%- store_name = "#{model.name}Store" -%>
76
74
  type <%= store_name %> struct{
77
75
  <%- if model.parent -%>
@@ -4,7 +4,7 @@ import (
4
4
  "gopkg.in/go-playground/validator.v9"
5
5
  )
6
6
 
7
- <%- types.select(&:store?).each do |model| -%>
7
+ <%- source_file.types.select(&:store?).each do |model| -%>
8
8
  func (m *<%= model.name %>) Validate() error {
9
9
  validator := validator.New()
10
10
  return validator.Struct(m)
@@ -16,6 +16,15 @@ module GoaModelGen
16
16
  def assign_field_type_base(types)
17
17
  self.fields.each{|f| f.assign_type_base(types) }
18
18
  end
19
+
20
+ def use_uuid?
21
+ false
22
+ end
23
+
24
+ TIME_TYPE_PATTERN = /\Atime\./
25
+ def has_time_field?
26
+ fields.any?{|f| f.type =~ TIME_TYPE_PATTERN}
27
+ end
19
28
  end
20
29
 
21
30
  class Model < Type
@@ -58,6 +67,10 @@ module GoaModelGen
58
67
  s.blank? ? nil : s[0].downcase + s[1..-1]
59
68
  end
60
69
 
70
+ def id_definition
71
+ goon && "#{id_name} #{id_golang_type } `datastore:\"-\" goon:\"id\" json:\"#{ id_name.underscore }\"`"
72
+ end
73
+
61
74
  def parent
62
75
  goon && goon['parent']
63
76
  end
@@ -66,6 +79,11 @@ module GoaModelGen
66
79
  !!goon
67
80
  end
68
81
 
82
+ # @override
83
+ def use_uuid?
84
+ goon && (goon['id_type'] == 'UUID')
85
+ end
86
+
69
87
  def key_id_method
70
88
  case id_golang_type
71
89
  when 'int64' then 'IntID'
@@ -110,6 +128,9 @@ module GoaModelGen
110
128
  end
111
129
  end
112
130
 
131
+ def field_by(name)
132
+ fields.detect{|f| f.name == name}
133
+ end
113
134
  end
114
135
 
115
136
  class SwaggerDef < Type
@@ -1,3 +1,3 @@
1
1
  module GoaModelGen
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: goa_model_gen
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - akm
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-08-24 00:00:00.000000000 Z
11
+ date: 2018-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thor
@@ -120,7 +120,9 @@ files:
120
120
  - lib/goa_model_gen/field.rb
121
121
  - lib/goa_model_gen/generator.rb
122
122
  - lib/goa_model_gen/goa.rb
123
+ - lib/goa_model_gen/golang_helper.rb
123
124
  - lib/goa_model_gen/loader.rb
125
+ - lib/goa_model_gen/source_file.rb
124
126
  - lib/goa_model_gen/templates/converter.go.erb
125
127
  - lib/goa_model_gen/templates/converter_base.go.erb
126
128
  - lib/goa_model_gen/templates/goon.go.erb
@@ -148,7 +150,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
148
150
  version: '0'
149
151
  requirements: []
150
152
  rubyforge_project:
151
- rubygems_version: 2.7.3
153
+ rubygems_version: 2.7.6
152
154
  signing_key:
153
155
  specification_version: 4
154
156
  summary: Generate model files for goa in golang