Skip to content

Commit b7e5fad

Browse files
authored
chore: Add synth scripts for client generation (googleapis#912)
1 parent 586c96f commit b7e5fad

File tree

6 files changed

+151
-22
lines changed

6 files changed

+151
-22
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ tmp/
1919
*.iml
2020
atlassian*
2121

22+
__pycache__/
23+
/vendor/

api_list_config.yaml

+8
Original file line numberDiff line numberDiff line change
@@ -1 +1,9 @@
1+
include:
2+
- name: appsmarket
3+
version: v2
4+
discovery_rest_url: https://content.googleapis.com/discovery/v1/apis/appsmarket/v2/rest
5+
- name: youtubePartner
6+
version: v1
7+
discovery_rest_url: https://content.googleapis.com/discovery/v1/apis/youtubePartner/v1/rest
18
exclude: []
9+
pause: []

bin/generate-api

+77-15
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,34 @@ module Google
2828

2929
desc 'gen OUTDIR', 'Generate ruby API from an API description'
3030
method_options url: :array, file: :array, from_discovery: :boolean, preferred_only: :boolean,
31-
verbose: :boolean, names: :string, names_out: :string
31+
verbose: :boolean, names: :string, names_out: :string, api: :string, clean: :boolean
3232
def gen(dir)
3333
ensure_active_support
3434
require 'google/apis/generator'
3535

3636
self.destination_root = dir
3737
Google::Apis.logger.level = Logger::DEBUG if options[:verbose]
38-
generate_from_url(options[:url]) if options[:url]
39-
generate_from_file(options[:file]) if options[:file]
40-
generate_from_discovery(preferred_only: options[:preferred_only]) if options[:from_discovery]
41-
create_file(options[:names_out]) { |*| generator.dump_api_names } if options[:names_out]
38+
count = 0
39+
count += generate_from_url(options[:url]) if options[:url]
40+
count += generate_from_file(options[:file]) if options[:file]
41+
count += generate_specific_apis(options[:api]) if options[:api]
42+
count += generate_from_discovery(preferred_only: options[:preferred_only]) if options[:from_discovery]
43+
count += clean_from_discovery if options[:clean]
44+
create_file(options[:names_out]) { |*| generator.dump_api_names } if count > 0 && options[:names_out]
4245
end
4346

4447
desc 'list', 'List public APIs'
4548
method_options verbose: :boolean, preferred_only: :boolean
4649
def list
4750
Google::Apis.logger.level = Logger::DEBUG if options[:verbose]
48-
discovery = Discovery::DiscoveryService.new
49-
apis = discovery.list_apis
50-
apis.items.each do |api|
51+
discovery_api_list.each do |api|
5152
say sprintf('%s - %s', api.id, api.description).strip unless options[:preferred_only] && !api.preferred?
5253
end
5354
end
5455

5556
no_commands do
56-
def generate_from_url(urls)
57+
def generate_from_url(urls, first_only: false)
58+
count = 0
5759
Array(urls).each do |url|
5860
begin
5961
json = discovery.http(:get, url)
@@ -62,7 +64,10 @@ module Google
6264
next
6365
end
6466
generate_api(json)
67+
return 1 if first_only
68+
count += 1
6569
end
70+
count
6671
end
6772

6873
def generate_from_file(files)
@@ -71,15 +76,38 @@ module Google
7176
generate_api(f.read)
7277
end
7378
end
79+
Array(files).size
80+
end
81+
82+
def generate_specific_apis(apis)
83+
discovery_apis = discovery_api_list.each_with_object({}) do |api, hash|
84+
hash["#{api.name}.#{api.version}"] = api
85+
end
86+
paused_apis = Array(api_list_config["pause"])
87+
count = 0
88+
Array(apis).each do |name_version|
89+
api = discovery_apis[name_version]
90+
if api.nil?
91+
say "API #{api} is not in the discovery list."
92+
elsif paused_apis.include? name_version
93+
say "Ignoring paused API #{api.name} #{api.version}"
94+
else
95+
discovery_rest_url = "https://raw.githubusercontent.com/googleapis/discovery-artifact-manager/master/discoveries/#{api.name}.#{api.version}.json"
96+
say sprintf('Loading %s, version %s from %s', api.name, api.version, discovery_rest_url)
97+
generate_from_url([discovery_rest_url, api.discovery_rest_url], first_only: true)
98+
count += 1
99+
end
100+
end
101+
count
74102
end
75103

76104
def generate_from_discovery(preferred_only: false)
77105
say 'Fetching API list'
78-
apis = discovery.list_apis
79-
exclude_apis = api_list_config["exclude"] || []
80-
apis.items.each do |api|
81-
if exclude_apis.include? "#{api.name}.#{api.version}"
82-
say "Ignoring excluded API #{api.name} #{api.version}"
106+
paused_apis = Array(api_list_config["pause"])
107+
count = 0
108+
discovery_api_list.each do |api|
109+
if paused_apis.include? "#{api.name}.#{api.version}"
110+
say "Ignoring paused API #{api.name} #{api.version}"
83111
elsif (preferred_only && !api.preferred?)
84112
say sprintf('Ignoring disoverable API %s', api.id)
85113
else
@@ -91,9 +119,27 @@ module Google
91119
# by the Discovery index.
92120
discovery_rest_url = "https://raw.githubusercontent.com/googleapis/discovery-artifact-manager/master/discoveries/#{api.name}.#{api.version}.json"
93121
say sprintf('Loading %s, version %s from %s', api.name, api.version, discovery_rest_url)
94-
generate_from_url(discovery_rest_url)
122+
generate_from_url([discovery_rest_url, api.discovery_rest_url], first_only: true)
123+
count += 1
95124
end
96125
end
126+
count
127+
end
128+
129+
def clean_from_discovery
130+
count = 0
131+
apis = discovery_api_list.map { |api| "#{api.name.underscore}_#{api.version.tr '.', '_'}" }
132+
Dir.chdir("#{destination_root}/google/apis") do
133+
Dir.glob("*.rb").each do |filename|
134+
filename = File.basename(filename, ".rb")
135+
unless apis.include? filename
136+
FileUtils.rm_r filename
137+
FileUtils.rm "#{filename}.rb"
138+
count += 1
139+
end
140+
end
141+
end
142+
count
97143
end
98144

99145
def generate_api(json)
@@ -107,6 +153,20 @@ module Google
107153
@discovery ||= Discovery::DiscoveryService.new
108154
end
109155

156+
def discovery_api_list
157+
@discovery_api_list ||= begin
158+
items = discovery.list_apis.items
159+
excluded = Array(api_list_config["exclude"])
160+
items.delete_if { |item| excluded.include? "#{item.name}.#{item.version}" }
161+
Array(api_list_config["include"]).each do |include_hash|
162+
include_hash.symbolize_keys!
163+
include_item = Discovery::DirectoryList::Item.new(**include_hash)
164+
items << include_item unless items.any? { |item| item.name == include_item.name && item.version == include_item.version }
165+
end
166+
items
167+
end
168+
end
169+
110170
def generator
111171
@generator ||= Google::Apis::Generator.new(api_names: options[:names], api_names_out: options[:names_out])
112172
end
@@ -117,7 +177,9 @@ module Google
117177

118178
def ensure_active_support
119179
begin
180+
require 'active_support'
120181
require 'active_support/inflector'
182+
require 'active_support/core_ext'
121183
rescue LoadError => e
122184
error 'ActiveSupport is required, please run:'
123185
error 'gem install activesupport'

script/generate

+1-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,4 @@
44

55
DIR=$(dirname $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ))
66

7-
URLS=(https://content.googleapis.com/discovery/v1/apis/appsmarket/v2/rest \
8-
https://content.googleapis.com/discovery/v1/apis/youtubePartner/v1/rest \
9-
https://content.googleapis.com/discovery/v1/apis/compute/beta/rest \
10-
https://monitoring.googleapis.com/\$discovery/rest?version=v3
11-
)
12-
13-
echo 'a' | bundle exec bin/generate-api gen generated --from-discovery --no-preferred-only --names-out=$DIR/api_names_out.yaml --url=${URLS[*]}
7+
echo 'a' | bundle exec bin/generate-api gen generated --from-discovery --no-preferred-only --names-out=$DIR/api_names_out.yaml

script/synth.rb

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env ruby
2+
3+
require "fileutils"
4+
5+
DIR = File.dirname __dir__
6+
7+
def execute cmd
8+
puts cmd
9+
abort unless system cmd
10+
end
11+
12+
execute "bundle install"
13+
14+
if ARGV.empty?
15+
execute "echo a | bundle exec bin/generate-api gen generated --from-discovery --no-preferred-only --names-out=#{DIR}/api_names_out.yaml"
16+
elsif ARGV == ["--clean"]
17+
execute "bundle exec bin/generate-api gen generated --clean"
18+
elsif ARGV.size == 2
19+
api, version = ARGV
20+
execute "echo a | bundle exec bin/generate-api gen generated --api=#{api}.#{version} --names-out=#{DIR}/api_names_out.yaml"
21+
else
22+
abort "Bad arguments: #{ARGV}"
23+
end

synth.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
"""This script is used to synthesize generated parts of this library."""
16+
17+
from synthtool.__main__ import extra_args
18+
import synthtool as s
19+
import synthtool.log as log
20+
import synthtool.shell as shell
21+
import logging
22+
import os
23+
24+
logging.basicConfig(level=logging.DEBUG)
25+
s.metadata.set_track_obsolete_files(False) # TODO: enable again.
26+
27+
command = [
28+
"docker",
29+
"run",
30+
"--rm",
31+
f"-v{os.getcwd()}:/workspace",
32+
"-v/var/run/docker.sock:/var/run/docker.sock",
33+
"-w", "/workspace",
34+
"--entrypoint", "script/synth.rb",
35+
"gcr.io/cloud-devrel-kokoro-resources/yoshi-ruby/autosynth"]
36+
if extra_args():
37+
command.extend(extra_args())
38+
39+
log.debug(f"Running: {' '.join(command)}")
40+
shell.run(command, hide_output=False)

0 commit comments

Comments
 (0)