1414# See the License for the specific language governing permissions and
1515# limitations under the License.
1616
17- desc "A tool that generates a new client library "
17+ desc "A tool that generates new client libraries "
1818
1919required_arg :proto_namespace
2020
21+ remaining_args :additional_proto_namespaces do
22+ desc "Additional proto namespaces to generate"
23+ end
24+
2125flag :piper_client , "--piper-client=NAME" do
2226 desc "Name of the piper client"
2327end
7175def run
7276 setup
7377 set :branch_name , "gen/#{ gem_name } " unless branch_name
74- commit_message = "feat: Initial generation of #{ gem_name } "
78+ commit_message = "feat: Initial generation of #{ gem_names . join ', ' } "
7579 yoshi_pr_generator . capture enabled : !git_remote . nil? ,
7680 remote : git_remote ,
7781 branch_name : branch_name ,
7882 commit_message : commit_message do
79- write_owlbot_config
80- write_owlbot_script
81- call_owlbot
82- create_release_please_configs if bootstrap_releases
83- test_library if enable_tests
83+ all_proto_namespaces . zip ( gem_names ) . each do |namespace , gem_name |
84+ generate_library namespace , gem_name
85+ end
8486 end
8587end
8688
8789def setup
8890 require "erb"
8991
9092 Dir . chdir context_directory
91- error "#{ owlbot_config_path } already exists" if File . file? owlbot_config_path
93+ gem_names . each do |gem_name |
94+ config_path = owlbot_config_path_for gem_name
95+ error "#{ config_path } already exists" if File . file? config_path
96+ end
9297 yoshi_utils . git_ensure_identity
9398 if enable_fork
9499 set :git_remote , "pull-request-fork" unless git_remote
95100 yoshi_utils . gh_ensure_fork remote : git_remote
96101 end
97- mkdir_p gem_name
102+ gem_names . each { |gem_name | mkdir_p gem_name }
103+ end
104+
105+ def generate_library namespace , gem_name
106+ write_owlbot_config namespace , gem_name
107+ write_owlbot_script gem_name
108+ call_owlbot gem_name
109+ create_release_please_configs gem_name if bootstrap_releases
110+ test_library gem_name if enable_tests
98111end
99112
100113def ensure_docker
@@ -103,26 +116,27 @@ def ensure_docker
103116 logger . info "Verified docker present"
104117end
105118
106- def write_owlbot_config
119+ def write_owlbot_config proto_namespace , gem_name
107120 template = File . read find_data "owlbot-config-template.erb"
108- File . write owlbot_config_path , ERB . new ( template ) . result ( binding )
121+ File . write owlbot_config_path_for ( gem_name ) , ERB . new ( template ) . result ( binding )
109122end
110123
111- def write_owlbot_script
124+ def write_owlbot_script gem_name
112125 return unless interactive
113126 error "No EDITOR set" unless editor
114127 template = File . read find_data "owlbot-script-template.erb"
115- File . write owlbot_script_path , ERB . new ( template ) . result ( binding )
116- exec [ editor , owlbot_script_path ]
117- new_content = File . read owlbot_script_path
128+ script_path = owlbot_script_path_for gem_name
129+ File . write script_path , ERB . new ( template ) . result ( binding )
130+ exec [ editor , script_path ]
131+ new_content = File . read script_path
118132 error "Aborted" if new_content . to_s . strip . empty?
119133 lines = new_content . split "\n "
120134 return unless lines . all? { |line | line . strip . empty? || line . start_with? ( "#" ) || line . strip == "OwlBot.move_files" }
121135 puts "Omitting .owlbot.rb"
122- rm owlbot_script_path
136+ rm script_path
123137end
124138
125- def call_owlbot
139+ def call_owlbot gem_name
126140 cmd = [ "owlbot" , gem_name ]
127141 cmd << "--pull" if pull
128142 cmd << "--protos-path" << protos_path if protos_path
@@ -138,7 +152,7 @@ def call_owlbot
138152 exec_tool cmd
139153end
140154
141- def create_release_please_configs
155+ def create_release_please_configs gem_name
142156 manifest = JSON . parse File . read manifest_name
143157 manifest [ gem_name ] = "0.0.1"
144158 manifest = add_fillers ( manifest ) . sort . to_h
@@ -147,21 +161,18 @@ def create_release_please_configs
147161 config = JSON . parse File . read config_name
148162 config [ "packages" ] [ gem_name ] = {
149163 "component" => gem_name ,
150- "version_file" => gem_version_file ,
164+ "version_file" => gem_version_file_for ( gem_name ) ,
151165 }
152166 config [ "packages" ] = config [ "packages" ] . sort . to_h
153167 File . write config_name , "#{ JSON . pretty_generate config } \n "
154168end
155169
156- def gem_version_file
157- @gem_version_file ||= begin
158- version_path = gem_name . tr "-" , "/"
159- version_file = File . join "lib" , version_path , "version.rb"
160- version_file_full = File . join gem_name , version_file
161- raise "Unable to find #{ version_file_full } " unless File . file? version_file_full
162- version_file
163- end
164- @gem_version_file
170+ def gem_version_file_for gem_name
171+ version_path = gem_name . tr "-" , "/"
172+ version_file = File . join "lib" , version_path , "version.rb"
173+ version_file_full = File . join gem_name , version_file
174+ raise "Unable to find #{ version_file_full } " unless File . file? version_file_full
175+ version_file
165176end
166177
167178def add_fillers manifest
@@ -172,18 +183,18 @@ def add_fillers manifest
172183 manifest
173184end
174185
175- def test_library
186+ def test_library gem_name
176187 Dir . chdir gem_name do
177188 exec [ "bundle" , "install" ]
178189 exec [ "toys" , "ci" , "--rubocop" , "--yard" , "--test" ]
179190 end
180191end
181192
182- def owlbot_config_path
193+ def owlbot_config_path_for gem_name
183194 File . join gem_name , ".OwlBot.yaml"
184195end
185196
186- def owlbot_script_path
197+ def owlbot_script_path_for gem_name
187198 File . join gem_name , ".owlbot.rb"
188199end
189200
@@ -199,18 +210,34 @@ def bazel_base_dir
199210 end
200211end
201212
202- def gem_name
203- @gem_name ||= begin
204- build_file_path = File . join bazel_base_dir , proto_namespace , "BUILD.bazel"
205- bazel_rules_content = File . read build_file_path
206- if bazel_rules_content =~ /"ruby-cloud-gem-name=([\w -]+)"/
207- Regexp . last_match [ 1 ]
208- else
209- error "Unable to find gem name rule in #{ build_file_path } "
210- end
213+ def gem_name_for namespace
214+ build_file_path = File . join bazel_base_dir , namespace , "BUILD.bazel"
215+ bazel_rules_content = File . read build_file_path
216+ if bazel_rules_content =~ /"ruby-cloud-gem-name=([\w -]+)"/
217+ Regexp . last_match [ 1 ]
218+ else
219+ error "Unable to find gem name rule in #{ build_file_path } "
211220 end
212221end
213222
223+ def gem_names
224+ @gem_names ||= all_proto_namespaces . map { |namespace | gem_name_for namespace }
225+ end
226+
227+ def all_proto_namespaces
228+ @all_proto_namespaces ||= begin
229+ raw_list = [ proto_namespace ] + additional_proto_namespaces
230+ namespaces = raw_list . flat_map { |namespace | namespace . split ( /[\s ,]+/ ) } . reject ( &:empty? )
231+ # Sort versioned namespaces (e.g. ending in v1) first so that wrappers (e.g. without v1)
232+ # can find them in the repository directories when the wrapper is generated.
233+ namespaces . sort_by { |namespace | namespace =~ %r{/v\d } ? 0 : 1 }
234+ end
235+ end
236+
237+ def gem_name
238+ @gem_name ||= gem_names . first
239+ end
240+
214241def copyright_year
215242 Time . now . year
216243end
0 commit comments