goa_model_gen 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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