From 3666546304edc14895bf1f701fe4533090185882 Mon Sep 17 00:00:00 2001 From: Daniel Azuma Date: Tue, 18 Jul 2023 04:46:34 -0700 Subject: [PATCH] chore: run rubocop on .toys directory (#22533) --- .github/workflows/ci.yml | 3 + .rubocop_root.yml | 30 ++++++++- .toys/analyze-clients.rb | 14 ++-- .toys/batch-review.rb | 72 ++++++++++---------- .toys/ci.rb | 109 ++++++++++++++++++------------- .toys/fix-release-manifest.rb | 4 +- .toys/gen-wrapper-bazel.rb | 36 ++++++---- .toys/new-library.rb | 24 +++---- .toys/obsolete-library.rb | 7 +- .toys/owlbot.rb | 40 ++++++++---- .toys/rad/backfill.rb | 22 +++++-- .toys/rad/delete-blob.rb | 18 ++++- .toys/rad/list-built-versions.rb | 18 ++++- .toys/rad/local.rb | 33 +++++++--- .toys/rad/restrict-access.rb | 26 ++++++-- .toys/release.rb | 19 +++--- .toys/sample.rb | 39 ++++++----- .toys/update-pr.rb | 18 +++-- .toys/update-release-levels.rb | 12 ++-- 19 files changed, 340 insertions(+), 204 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 68ea15d523fe..d720965d2a94 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -50,6 +50,9 @@ jobs: - os: windows-latest ruby: "3.2" task: "--test" + - os: ubuntu-latest + ruby: "3.2" + task: "--rubocop-toplevel" fail-fast: false runs-on: ${{ matrix.os }} steps: diff --git a/.rubocop_root.yml b/.rubocop_root.yml index dab7ed2bd008..66cfd51a036f 100644 --- a/.rubocop_root.yml +++ b/.rubocop_root.yml @@ -2,10 +2,36 @@ inherit_gem: google-style: google-style.yml AllCops: + Exclude: + - "integration/**/*" Include: - - "NOTHING.rb" -# - ".toys/**/*.rb" + - ".toys/**/*.rb" +Lint/NonLocalExitFromIterator: + Enabled: false +Metrics/AbcSize: + Max: 40 Metrics/BlockLength: Exclude: - ".toys/**/*.rb" +Metrics/CyclomaticComplexity: + Max: 20 +Metrics/MethodLength: + Max: 50 +Metrics/PerceivedComplexity: + Max: 20 +Naming/AccessorMethodName: + Enabled: false +Naming/FileName: + Exclude: + - ".toys/**/*.rb" +Style/GuardClause: + AllowConsecutiveConditionals: true +Style/MultilineBlockChain: + Enabled: false +Style/StderrPuts: + Enabled: false +Style/TrailingCommaInArrayLiteral: + EnforcedStyleForMultiline: comma +Style/TrailingCommaInHashLiteral: + EnforcedStyleForMultiline: comma diff --git a/.toys/analyze-clients.rb b/.toys/analyze-clients.rb index 4261384a4bbf..d59b57d0b003 100644 --- a/.toys/analyze-clients.rb +++ b/.toys/analyze-clients.rb @@ -24,8 +24,8 @@ outdated_wrappers: "List wrapper gems prioritizing an outdated gapic", incomplete_bazel: "List incomplete Ruby bazel configs", wrapper_bazel: "List missing Ruby wrapper bazel configs", - gapic_ready: "List complete Ruby bazel configs that haven't yet been generated" -} + gapic_ready: "List complete Ruby bazel configs that haven't yet been generated", +}.freeze at_least_one desc: "Analyses" do flag :all, desc: "Run all analyses except those explicitly disabled" @@ -91,7 +91,7 @@ def gem_version gem_name func = proc do Dir.chdir gem_name do spec = Gem::Specification.load "#{gem_name}.gemspec" - puts spec.version.to_s + puts spec.version end end capture_proc(func).strip @@ -164,7 +164,7 @@ def outdated_wrappers_analysis match = /^#{gem_name}-(v\d+)$/.match versioned_name ga_versions << match[1] if match end - expected_version = (ga_versions.empty? ? pre_versions : ga_versions).sort.last + expected_version = (ga_versions.empty? ? pre_versions : ga_versions).max unless expected_version puts "#{gem_name}: No expected version" next @@ -189,7 +189,7 @@ def incomplete_bazel_analysis count = 0 puts "Results:", :cyan Dir.chdir googleapis_path do - Dir.glob("**/BUILD.bazel") do |build_file| + Dir.glob "**/BUILD.bazel" do |build_file| content = File.read build_file next unless content.include? "ruby_cloud_gapic_library" unless content.include?("ruby-cloud-api-id=") && @@ -208,7 +208,7 @@ def wrapper_bazel_analysis count = 0 puts "Results:", :cyan Dir.chdir googleapis_path do - Dir.glob("**/BUILD.bazel") do |build_file| + Dir.glob "**/BUILD.bazel" do |build_file| dir = File.dirname build_file if dir =~ /v\d\w+$/ wrapper_bazel_path = File.join File.dirname(dir), "BUILD.bazel" @@ -226,7 +226,7 @@ def gapic_ready_analysis count = 0 puts "Results:", :cyan Dir.chdir googleapis_path do - Dir.glob("**/BUILD.bazel") do |build_file| + Dir.glob "**/BUILD.bazel" do |build_file| content = File.read build_file next unless content.include?("ruby_cloud_gapic_library") && content.include?("ruby-cloud-api-id=") && diff --git a/.toys/batch-review.rb b/.toys/batch-review.rb index c5cfa0b0e4e2..cc9cfa593ad5 100644 --- a/.toys/batch-review.rb +++ b/.toys/batch-review.rb @@ -41,7 +41,7 @@ /\.release-please-manifest\.json$/, /\/CHANGELOG\.md$/, /\/version\.rb$/, - /\/snippets\/snippet_metadata_[\w\.]+\.json$/ + /\/snippets\/snippet_metadata_[\w\.]+\.json$/, ], }, "releases-wrappers" => { @@ -62,18 +62,18 @@ /\.release-please-manifest\.json$/, /\/CHANGELOG\.md$/, /\/version\.rb$/, - /\/snippets\/snippet_metadata_[\w\.]+\.json$/ + /\/snippets\/snippet_metadata_[\w\.]+\.json$/, ], }, -} +}.freeze REPO = "googleapis/google-cloud-ruby" BOT_USERS = [ "yoshi-code-bot", "yoshi-automation", "gcf-owl-bot[bot]", - "release-please[bot]" -] + "release-please[bot]", +].freeze desc "Interactive mass code review" @@ -153,8 +153,8 @@ def find_prs def check_automerge pr_data if !@automerge_enabled || - @automerge_count_max.positive? && @automerge_count >= @automerge_count_max || - !pr_data.diff_files.all? { |file| @omits.any? { |omit| omit.call file } } + (@automerge_count_max.positive? && @automerge_count >= @automerge_count_max) || + !pr_data.diff_files.all? { |file| @omits.any? { |omit| omit.call file } } @automerge_count = 1 return false end @@ -208,7 +208,7 @@ def handle_input pr_data def handle_merge pr_data get_commit_message pr_data - get_commit_detail pr_data if detail_type + get_commit_detail if detail_type do_approve pr_data do_merge pr_data end @@ -259,7 +259,7 @@ def handle_display arg, pr_data end end -def handle_omit arg, *extra_args +def handle_omit arg, *extra_args # rubocop:disable Metrics/AbcSize case arg when /^x/ @omits = [] @@ -301,9 +301,7 @@ def handle_omit arg, *extra_args puts "... added omit for deleted file paths: #{regexp}" end when /^i/ - omit = Omit.new "All changes affect indentation only" do |file| - file.only_indentation - end + omit = Omit.new "All changes affect indentation only", &:only_indentation @omits << omit puts "... added omit for indentation-only diffs" else @@ -324,7 +322,7 @@ def handle_suppress *args omit = Omit.new "All changes match given regexes" do |file| file.reduce_hunks true do |val, hunk| val && hunk.all? do |line| - line_without_mark = line[1..-1] + line_without_mark = line[1..] if line.start_with? "+" adds.any? { |regex| regex.match? line_without_mark } elsif line.start_with? "-" @@ -360,7 +358,7 @@ def display_pr_title pr_data def display_filenames pr_data pr_data.diff_files.each_with_index do |file, index| - write "%3d " % index + write format("%3d ", index) write file.type, :bold, :yellow write " " puts file.path @@ -370,7 +368,7 @@ def display_filenames pr_data def display_all_diffs pr_data, force_all: false files = pr_data.diff_files unless force_all - disp_files, omit_files = files.partition { |file| !@omits.any? { |omit| omit.call file } } + disp_files, omit_files = files.partition { |file| @omits.none? { |omit| omit.call file } } end omit_files.each do |file| puts "Omitting display of #{file.path}" @@ -403,11 +401,11 @@ def get_commit_message pr_data @commit_message = ask("Message: ", default: @commit_message) if @edit_enabled end -def get_commit_detail pr_data +def get_commit_detail return unless @edit_enabled case detail_type when :shared - file = Tempfile.new("commit-default") + file = Tempfile.new "commit-default" begin file.write @commit_detail file.rewind @@ -478,10 +476,11 @@ def paged_api path end def error *messages - messages.each { |msg| STDERR.puts msg } + messages.each { |msg| $stderr.puts msg } exit 1 end +# Represents a diff output class DiffFile def initialize text @text = text @@ -528,7 +527,6 @@ def initial_analysis def analyze_changes hunk = nil - from_path = to_path = nil @lines.each do |line| if line.start_with? "@@" yield hunk if hunk && !hunk.empty? @@ -551,7 +549,7 @@ def analyze_only_indentation hunk if pos == minuses.length minuses = [line] pos = 0 - elsif pos == 0 + elsif pos.zero? minuses << line else throw :fail @@ -570,6 +568,7 @@ def analyze_only_indentation hunk end end +# Represents an omit rule class Omit def initialize desc, &block raise "Block required" unless block @@ -584,6 +583,7 @@ def call pr_file end end +# Represents information about a pull request class PrData def initialize context, pr_resource @context = context @@ -595,7 +595,10 @@ def initialize context, pr_resource attr_reader :title def raw_diff_data - @raw_diff_data ||= @context.capture(["curl", "-s", "https://patch-diff.githubusercontent.com/raw/#{REPO}/pull/#{id}.diff"], e: true) + @raw_diff_data ||= begin + cmd = ["curl", "-s", "https://patch-diff.githubusercontent.com/raw/#{REPO}/pull/#{id}.diff"] + @context.capture cmd, e: true + end end def diff_files @@ -603,22 +606,22 @@ def diff_files "\n#{raw_diff_data.chomp}" .split("\ndiff --git ") .slice(1..-1) - .map{ |text| DiffFile.new("diff --git #{text}\n") } + .map { |text| DiffFile.new "diff --git #{text}\n" } end end def diff_line_count - @diff_line_count ||= raw_diff_data.count("\n") + @diff_line_count ||= raw_diff_data.count "\n" end def lib_name unless defined? @lib_name @lib_name = case title - when /^\[CHANGE ME\] Re-generated google-cloud-([\w-]+) to pick up changes in the API or client/ - Regexp.last_match[1] - when /^\[CHANGE ME\] Re-generated ([\w-]+) to pick up changes in the API or client/ - Regexp.last_match[1] + when /^\[CHANGE ME\] Re-generated google-cloud-(?[\w-]+) to pick up changes in the API or client/ + Regexp.last_match[:basename] + when /^\[CHANGE ME\] Re-generated (?[\w-]+) to pick up changes in the API or client/ + Regexp.last_match[:fullname] else interpret_lib_name end @@ -628,7 +631,7 @@ def lib_name def custom_message message if lib_name && message =~ /^(\w+):\s+(\S.*)$/ - "#{$1}(#{lib_name}): #{$2}" + "#{Regexp.last_match[1]}(#{lib_name}): #{Regexp.last_match[2]}" else message end @@ -639,14 +642,11 @@ def custom_message message def interpret_lib_name name = nil diff_files.each do |diff_file| - if %r{^([^/]+)/} =~ diff_file.path - possible_name = Regexp.last_match[1] - if name.nil? - name = possible_name - elsif name != possible_name - return nil - end - else + return nil unless %r{^([^/]+)/} =~ diff_file.path + possible_name = Regexp.last_match[1] + if name.nil? + name = possible_name + elsif name != possible_name return nil end end diff --git a/.toys/ci.rb b/.toys/ci.rb index 2db0b28eb48c..72196b2b89c5 100644 --- a/.toys/ci.rb +++ b/.toys/ci.rb @@ -14,8 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -TASKS = ["test", "rubocop", "build", "yard", "linkinator", "acceptance", "samples-master", "samples-latest"] -ISSUE_TASKS = ["bundle", "test", "rubocop", "build", "yard", "linkinator"] +TASKS = ["test", "rubocop", "build", "yard", "linkinator", "acceptance", "samples-master", "samples-latest"].freeze +ISSUE_TASKS = ["bundle", "test", "rubocop", "build", "yard", "linkinator"].freeze FAILURES_REPORT_PATH = "tmp/ci-failures.json" desc "Run CI tasks." @@ -65,9 +65,10 @@ end at_least_one_required desc: "Tasks" do + flag :task_rubocop_toplevel, "--[no-]rubocop-toplevel", desc: "Run the toplevel rubocop task" flag :do_bundle, "--[no-]bundle" do |f| - f.desc "Normally bundle install is performed prior to any other task. Use --no-bundle to disable this, or" \ - " use --bundle to force a bundle install even if no other tasks are run." + f.desc "Normally bundle install is performed prior to any other task. Use --no-bundle to disable this, or " \ + "use --bundle to force a bundle install even if no other tasks are run." end flag :bundle_update do |f| f.desc "Update rather than install gem bundles." @@ -105,7 +106,8 @@ def run Dir.chdir context_directory dirs = determine_dirs - if max_gem_count > 0 && dirs.size > max_gem_count + run_toplevel + if max_gem_count.positive? && dirs.size > max_gem_count puts "CI skipped because the limit of #{max_gem_count} libraries was exceeded.", :bold, :yellow puts "Modified libraries found:" dirs.each { |dir| puts " #{dir}" } @@ -126,7 +128,7 @@ def setup_auth_env "GCLOUD_TEST_PROJECT" => final_project, "GOOGLE_CLOUD_PROJECT" => final_project, "GCLOUD_TEST_KEYFILE" => final_keyfile, - "GOOGLE_APPLICATION_CREDENTIALS" => ENV["GOOGLE_APPLICATION_CREDENTIALS"] + "GOOGLE_APPLICATION_CREDENTIALS" => ENV["GOOGLE_APPLICATION_CREDENTIALS"], } end @@ -136,16 +138,17 @@ def determine_tasks do_task = get "task_#{task_underscore}" do_task.nil? ? all_tasks : do_task end - bundle_task = if bundle_update - logger.info "Will update bundles for tested libraries" - "update" - elsif do_bundle == false - logger.info "Will not install bundles for tested libraries" - nil - else - logger.info "Will install bundles for tested libraries" - "install" - end + bundle_task = + if bundle_update + logger.info "Will update bundles for tested libraries" + "update" + elsif do_bundle == false + logger.info "Will not install bundles for tested libraries" + nil + else + logger.info "Will install bundles for tested libraries" + "install" + end logger.info "Running the following tasks: #{run_tasks.inspect}" [run_tasks, bundle_task] end @@ -158,7 +161,7 @@ def determine_dirs def all_gem_dirs which_files dirs = Dir.glob("*/*.gemspec").map { |file| File.dirname file } - if which_files == true || which_files == "" + if [true, ""].include? which_files puts "Running for all gems", :bold else puts "Running for all gems with the following files: #{which_files}", :bold @@ -207,7 +210,7 @@ def gem_dirs_from_changes end def interpret_github_event - payload = JSON.load File.read github_event_payload unless github_event_payload.empty? + payload = JSON.parse File.read github_event_payload unless github_event_payload.empty? base_ref, head_ref = case github_event_name when "pull_request" @@ -236,7 +239,7 @@ def ensure_checkout head_ref logger.info "Already at head SHA: #{head_sha}" else logger.info "Checking out head SHA: #{head_sha}" - exec(["git", "checkout", head_sha], e: true) + exec ["git", "checkout", head_sha], e: true end end @@ -252,17 +255,17 @@ def find_changed_files base_ref end def ensure_fetched ref - result = exec(["git", "show", "--no-patch", "--format=%H", ref], out: :capture, err: :capture) + result = exec ["git", "show", "--no-patch", "--format=%H", ref], out: :capture, err: :capture if result.success? result.captured_out.strip elsif ref == "HEAD^" # Common special case current_sha = capture(["git", "rev-parse", "HEAD"], e: true).strip - exec(["git", "fetch", "--depth=2", "origin", current_sha], e: true) + exec ["git", "fetch", "--depth=2", "origin", current_sha], e: true capture(["git", "rev-parse", "HEAD^"], e: true).strip else logger.info "Fetching ref: #{ref}" - exec(["git", "fetch", "--depth=1", "origin", "#{ref}:refs/temp/#{ref}"], e: true) + exec ["git", "fetch", "--depth=1", "origin", "#{ref}:refs/temp/#{ref}"], e: true capture(["git", "show", "--no-patch", "--format=%H", "refs/temp/#{ref}"], e: true).strip end end @@ -270,24 +273,21 @@ def ensure_fetched ref def find_changed_directories files dirs = Set.new files.each do |file| - if file =~ %r{^([^/]+)/.+$} - dir = Regexp.last_match[1] - dirs << dir - if dir =~ %r{^(.+)-v\d[^-]*$} - wrapper_dir = Regexp.last_match[1] - if Dir.exist? wrapper_dir - dirs << wrapper_dir - end - end - end + next unless file =~ %r{^([^/]+)/.+$} + dir = Regexp.last_match[1] + dirs << dir + next unless dir =~ %r{^(.+)-v\d[^-]*$} + wrapper_dir = Regexp.last_match[1] + next unless Dir.exist? wrapper_dir + dirs << wrapper_dir end filter_gem_dirs dirs.to_a end def filter_gem_dirs dirs dirs.find_all do |dir| - if ["Rakefile", "Gemfile", "#{dir}.gemspec"].all? { |file| File.file?(File.join(dir, file)) } - result = capture_ruby([], in: :controller) do |controller| + if ["Rakefile", "Gemfile", "#{dir}.gemspec"].all? { |file| File.file? File.join(dir, file) } + result = capture_ruby [], in: :controller do |controller| controller.in.puts "spec = Gem::Specification.load '#{dir}/#{dir}.gemspec'" controller.in.puts "puts spec.required_ruby_version.satisfied_by? Gem::Version.new(#{RUBY_VERSION.inspect})" end @@ -298,6 +298,24 @@ def filter_gem_dirs dirs end.sort end +def run_toplevel + if @bundle_task + puts + puts "toplevel: bundle ...", :bold, :cyan + result = exec ["bundle", @bundle_task, "--retry=#{bundle_retry}"] + unless result.success? + @errors << [dir, "bundle"] + return + end + end + if task_rubocop_toplevel + puts + puts "toplevel: rubocop ...", :bold, :cyan + result = exec ["bundle", "exec", "rubocop", "-c", ".rubocop_root.yml"] + @errors << ["toplevel", "rubocop"] unless result.success? + end +end + def run_in_dir dir Dir.chdir dir do if @bundle_task @@ -312,11 +330,12 @@ def run_in_dir dir @run_tasks.each do |task| puts puts "#{dir}: #{task} ...", :bold, :cyan - success = if task == "linkinator" - run_linkinator dir - else - exec(["bundle", "exec", "rake", task.tr("-", ":")], env: @auth_env).success? - end + success = + if task == "linkinator" + run_linkinator dir + else + exec(["bundle", "exec", "rake", task.tr("-", ":")], env: @auth_env).success? + end @errors << [dir, task] unless success end end @@ -329,7 +348,7 @@ def run_linkinator dir "\\w+\\.md$", "^https://rubygems\\.org/gems/#{dir_without_version}", "^https://cloud\\.google\\.com/ruby/docs/reference/#{dir}/latest$", - "^https://rubydoc\\.info/gems/#{dir}" + "^https://rubydoc\\.info/gems/#{dir}", ] if dir == dir_without_version skip_regexes << "^https://cloud\\.google\\.com/ruby/docs/reference/#{dir}-v\\d\\w*/latest$" @@ -409,7 +428,7 @@ def find_existing_issue dir result = JSON.parse result rescue [] result.first["number"] unless result.empty? end - + def update_issue issue_id, dir, tasks body = create_body dir, tasks exec [ @@ -419,7 +438,7 @@ def update_issue issue_id, dir, tasks ] puts "Added to issue #{issue_id}: reported #{dir}: #{tasks.join ', '}", :yellow end - + def create_new_issue dir, tasks body = "#{create_body dir, tasks}\n\n#{encode_str dir}" exec [ @@ -427,15 +446,15 @@ def create_new_issue dir, tasks "--repo", "googleapis/google-cloud-ruby", "--title", "[Nightly CI Failures] Failures detected for #{dir}", "--label", "type: bug,priority: p1,nightly failure", - "--body", body, + "--body", body ] puts "Created new issue for #{dir}: #{tasks.join ', '}", :yellow end - + def encode_str str "report_key_#{Digest::MD5.hexdigest str}" end - + def create_body dir, tasks now = Time.now.utc.strftime "%Y-%m-%d %H:%M:%S" messages = [] diff --git a/.toys/fix-release-manifest.rb b/.toys/fix-release-manifest.rb index 272143479a3b..f5a25fdf77eb 100644 --- a/.toys/fix-release-manifest.rb +++ b/.toys/fix-release-manifest.rb @@ -53,7 +53,7 @@ def read_canonical_versions_file def write_canonical_versions_file return unless write_versions - File.write write_versions, "#{JSON.pretty_generate(@canonical_versions)}\n" + File.write write_versions, "#{JSON.pretty_generate @canonical_versions}\n" end def load_data @@ -64,7 +64,7 @@ def load_data config = JSON.parse File.read "release-please-config.json" config["packages"].each do |package, info| next if !input_packages.empty? && !input_packages.include?(package) - version_path = "#{package}/#{info["version_file"]}" + version_path = "#{package}/#{info['version_file']}" declared_version = load_declared_version version_path canonical_version = load_canonical_version package existing_tags = load_existing_tags all_tags, package diff --git a/.toys/gen-wrapper-bazel.rb b/.toys/gen-wrapper-bazel.rb index c7a86f12d119..7164309b810e 100644 --- a/.toys/gen-wrapper-bazel.rb +++ b/.toys/gen-wrapper-bazel.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + include :exec, e: true include :fileutils @@ -12,23 +28,20 @@ def run each_library do |library_data| erb = ERB.new template content = erb.result library_data.erb_binding - unless dry_run - File.open library_data.bazel_path, "w" do |file| - file.write content - end - end + next if dry_run + File.write library_data.bazel_path, content end end def each_library piper_client_dir = capture("p4 g4d #{piper_client}").strip LibraryData.googleapis_base_dir = File.join piper_client_dir, "third_party", "googleapis", "stable" - Dir.glob("*/synth.py") do |path| + Dir.glob "*/synth.py" do |path| full_path = File.expand_path path, context_directory library_data = LibraryData.new full_path errors = library_data.errors unless errors.empty? - errors.each { |msg| logger.warn "#{msg} in #{path}"} + errors.each { |msg| logger.warn "#{msg} in #{path}" } next end logger.info "Handling #{path}..." @@ -36,6 +49,7 @@ def each_library end end +# Represents a bunch of information about the library class LibraryData class << self attr_accessor :googleapis_base_dir @@ -124,9 +138,9 @@ def interpret_generator_args content end def interpret_versioned_bazel content - @proto_with_info_target = nil - if content =~ /:(\w+_proto_with_info)/ - @proto_with_info_target = Regexp.last_match[1] - end + @proto_with_info_target = + if content =~ /:(\w+_proto_with_info)/ + Regexp.last_match[1] + end end end diff --git a/.toys/new-library.rb b/.toys/new-library.rb index b37b8de6302b..9bc5827a69f1 100644 --- a/.toys/new-library.rb +++ b/.toys/new-library.rb @@ -99,36 +99,30 @@ def ensure_docker def write_owlbot_config template = File.read find_data "owlbot-config-template.erb" - File.open owlbot_config_path, "w" do |file| - file.write ERB.new(template).result(binding) - end + File.write owlbot_config_path, ERB.new(template).result(binding) end def write_owlbot_script return unless interactive error "No EDITOR set" unless editor template = File.read find_data "owlbot-script-template.erb" - File.open owlbot_script_path, "w" do |file| - file.write ERB.new(template).result(binding) - end + File.write owlbot_script_path, ERB.new(template).result(binding) exec [editor, owlbot_script_path] new_content = File.read owlbot_script_path error "Aborted" if new_content.to_s.strip.empty? - lines = new_content.split("\n") - if lines.all? { |line| line.strip.empty? || line.start_with?("#") || line.strip == "OwlBot.move_files" } - puts "Omitting .owlbot.rb" - rm owlbot_script_path - end + lines = new_content.split "\n" + return unless lines.all? { |line| line.strip.empty? || line.start_with?("#") || line.strip == "OwlBot.move_files" } + puts "Omitting .owlbot.rb" + rm owlbot_script_path end def call_owlbot cmd = ["owlbot", gem_name] cmd << "--pull" if pull - cmd << "-#{'v' * verbosity}" if verbosity > 0 - cmd << "-#{'q' * (-verbosity)}" if verbosity < 0 cmd << "--protos-path" << protos_path if protos_path cmd << "--source-path" << source_path if source_path cmd << "--piper-client" << piper_client if piper_client + cmd += verbosity_flags exec_tool cmd end @@ -141,7 +135,7 @@ def create_release_please_configs config = JSON.parse File.read config_name config["packages"][gem_name] = { "component" => gem_name, - "version_file" => gem_version_file + "version_file" => gem_version_file, } config["packages"] = config["packages"].sort.to_h File.write config_name, "#{JSON.pretty_generate config}\n" @@ -159,7 +153,7 @@ def gem_version_file end def add_fillers manifest - manifest.keys.each do |key| + manifest.each_key do |key| manifest["#{key}+FILLER"] = "0.0.0" unless key.end_with? "+FILLER" end manifest diff --git a/.toys/obsolete-library.rb b/.toys/obsolete-library.rb index f5406ef1faee..74c516ae4a9d 100644 --- a/.toys/obsolete-library.rb +++ b/.toys/obsolete-library.rb @@ -48,10 +48,9 @@ def run def setup cd context_directory yoshi_utils.git_ensure_identity - if enable_fork - set :git_remote, "pull-request-fork" unless git_remote - yoshi_utils.gh_ensure_fork remote: git_remote - end + return unless enable_fork + set :git_remote, "pull-request-fork" unless git_remote + yoshi_utils.gh_ensure_fork remote: git_remote end def remove_release_manifest diff --git a/.toys/owlbot.rb b/.toys/owlbot.rb index 9bcd574c9bbb..e32b4387844f 100644 --- a/.toys/owlbot.rb +++ b/.toys/owlbot.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + desc "Runs OwlBot for one or more gems." long_desc \ @@ -96,10 +112,9 @@ def run def setup_git yoshi_utils.git_ensure_identity - if enable_fork - set :git_remote, "pull-request-fork" unless git_remote - yoshi_utils.gh_ensure_fork remote: git_remote - end + return unless enable_fork + set :git_remote, "pull-request-fork" unless git_remote + yoshi_utils.gh_ensure_fork remote: git_remote end def ensure_docker @@ -178,7 +193,7 @@ def determine_bazel_target library_path end def run_bazel gem_info - gem_info.each do |name, info| + gem_info.each_value do |info| info[:bazel_targets].each do |library_path, bazel_target| exec ["bazel", "build", "//#{library_path}:#{bazel_target}"], chdir: bazel_base_dir end @@ -217,7 +232,7 @@ def run_owlbot gem_info, use_bazel_bin: temp_config = File.join TMP_DIR_NAME, OWLBOT_CONFIG_FILE_NAME rm_f temp_config combined_deep_copy_regex = gem_info.values.map { |info| info[:deep_copy_regexes] }.flatten - combined_config = {"deep-copy-regex" => combined_deep_copy_regex} + combined_config = { "deep-copy-regex" => combined_deep_copy_regex } File.open temp_config, "w" do |file| file.puts Psych.dump combined_config end @@ -254,7 +269,7 @@ def process_gems gems def process_gems_separate_prs gems, temp_staging_dir results = {} gems.each_with_index do |name, index| - timestamp = Time.now.utc.strftime("%Y%m%d-%H%M%S") + timestamp = Time.now.utc.strftime "%Y%m%d-%H%M%S" branch_name = "owlbot/#{name}-#{timestamp}" message = build_commit_message name result = yoshi_pr_generator.capture enabled: !git_remote.nil?, @@ -270,7 +285,7 @@ def process_gems_separate_prs gems, temp_staging_dir end def process_gems_combined_pr gems, temp_staging_dir - timestamp = Time.now.utc.strftime("%Y%m%d-%H%M%S") + timestamp = Time.now.utc.strftime "%Y%m%d-%H%M%S" branch_name = "owlbot/all-#{timestamp}" message = build_commit_message "all gems" result = yoshi_pr_generator.capture enabled: !git_remote.nil?, @@ -297,11 +312,10 @@ def process_single_gem name, temp_staging_dir mkdir_p STAGING_DIR_NAME mv File.join(temp_staging_dir, name), File.join(STAGING_DIR_NAME, name) docker_run "#{POSTPROCESSOR_IMAGE}:#{postprocessor_tag}", "--gem", name - if enable_tests - cd name do - exec ["bundle", "install"] - exec ["bundle", "exec", "rake", "ci"] - end + return unless enable_tests + cd name do + exec ["bundle", "install"] + exec ["bundle", "exec", "rake", "ci"] end end diff --git a/.toys/rad/backfill.rb b/.toys/rad/backfill.rb index b95ca741db8f..fc75c5259750 100644 --- a/.toys/rad/backfill.rb +++ b/.toys/rad/backfill.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + desc "Backfill reference documentation upload" remaining_args :specified_releases @@ -29,15 +45,13 @@ def analyze_git_info next unless match (@releases[match[1]] ||= []) << ::Gem::Version.new(match[2]) end - @releases.each_value do |versions| - versions.sort! - end + @releases.each_value(&:sort!) end def interpret_releases @jobs = [] specified_releases.each do |release_spec| - segments = release_spec.split /[:,;]/ + segments = release_spec.split(/[:,;]/) gem_name = segments.shift existing_versions = @releases[gem_name] error "No such gem #{gem_name}" unless existing_versions diff --git a/.toys/rad/delete-blob.rb b/.toys/rad/delete-blob.rb index fbf1f594ef7d..01c23b21af49 100644 --- a/.toys/rad/delete-blob.rb +++ b/.toys/rad/delete-blob.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + desc "Delete cloud-rad blobs" include :exec, e: true @@ -53,5 +69,5 @@ def delete_blob blob value: "#{blob}" } PAYLOAD - exec(["stubby", "call", "blade:kokoro-api", "KokoroApi.Build"], in: [:string, payload]) + exec ["stubby", "call", "blade:kokoro-api", "KokoroApi.Build"], in: [:string, payload] end diff --git a/.toys/rad/list-built-versions.rb b/.toys/rad/list-built-versions.rb index 7b12ccf5c8b0..9f1edf66ad8e 100644 --- a/.toys/rad/list-built-versions.rb +++ b/.toys/rad/list-built-versions.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + desc "List built versions" flag :latest_only @@ -12,7 +28,7 @@ def run (data[Regexp.last_match[1]] ||= []) << Gem::Version.new(Regexp.last_match[2]) end end - data.transform_values! { |versions| versions.sort } + data.transform_values!(&:sort) data.transform_values! { |versions| [versions.last] } if latest_only output = [] data.keys.sort.each do |gem_name| diff --git a/.toys/rad/local.rb b/.toys/rad/local.rb index 445b64bb28da..4acd1be84d97 100644 --- a/.toys/rad/local.rb +++ b/.toys/rad/local.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + desc "Run cloud-rad locally for testing" remaining_args :gem_names @@ -28,10 +44,7 @@ def run_yard gem_name Dir.chdir gem_name do rm_rf "doc" rm_rf ".yardoc" - cmd = ["release", "build-rad", "--gem-name", gem_name] - cmd << "-#{'q' * (-verbosity)}" if verbosity < 0 - cmd << "-#{'v' * verbosity}" if verbosity > 0 - exec_tool cmd + exec_tool ["release", "build-rad", "--gem-name", gem_name] + verbosity_flags end end @@ -53,15 +66,13 @@ def run_docfx gem_name def update_docfx_json gem_name require "json" content = File.read doc_templates_json_path - orig_data = JSON.parse! content data = JSON.parse! content global_metadata = data["build"]["globalMetadata"] global_metadata["_appTitle"] = gem_name global_metadata["_rootPath"] = "/ruby/docs/reference/#{gem_name}/latest" - unless content == data - File.open doc_templates_json_path, "w" do |file| - file.puts JSON.pretty_generate data - end + return if content == data + File.open doc_templates_json_path, "w" do |file| + file.puts JSON.pretty_generate data end end @@ -86,7 +97,9 @@ def update_piper def output_piper_results puts "Stage:", :bold - paths = effective_gem_names.map { |gem_name| "googledata/devsite/site-cloud/en/ruby/docs/reference/#{gem_name}/latest" } + paths = effective_gem_names.map do |gem_name| + "googledata/devsite/site-cloud/en/ruby/docs/reference/#{gem_name}/latest" + end paths << "googledata/devsite/site-cloud/en/ruby/_book.yaml" paths = paths.join ", " puts "PATHS: #{paths}" diff --git a/.toys/rad/restrict-access.rb b/.toys/rad/restrict-access.rb index 1f05e6cb905d..6f5d81c79856 100644 --- a/.toys/rad/restrict-access.rb +++ b/.toys/rad/restrict-access.rb @@ -1,3 +1,19 @@ +# frozen_string_literal: true + +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + desc "Create _access.yaml files" required_arg :piper_client @@ -19,7 +35,7 @@ def run end end -def each_gem +def each_gem &block omit_list = [ "gcloud", "google-cloud", @@ -31,15 +47,13 @@ def each_gem "google-cloud-ids", "google-cloud-ids-v1", "google-cloud-vmmigration", - "google-cloud-vmmigration-v1" + "google-cloud-vmmigration-v1", ] - Dir.glob("*/*.gemspec") do |path| + Dir.glob "*/*.gemspec" do |path| name = File.dirname path yield name unless omit_list.include? name end - extra_list.each do |name| - yield name - end + extra_list.each(&block) end def piper_client_dir diff --git a/.toys/release.rb b/.toys/release.rb index 404c21e64d2e..9ce6f51a5f45 100644 --- a/.toys/release.rb +++ b/.toys/release.rb @@ -43,7 +43,7 @@ flag :enable_fork, "--fork" do desc "Use a fork to open the pull request" end - + include :exec, e: true include :terminal include "yoshi-pr-generator" @@ -61,7 +61,7 @@ def run setup_git - date = Time.now.utc.strftime("%Y%m%d-%H%M%S") + date = Time.now.utc.strftime "%Y%m%d-%H%M%S" set :branch_name, "gen/bootstrap-release-#{date}" unless branch_name commit_message = "chore: Bootstrap release manifest for new packages" yoshi_pr_generator.capture enabled: !git_remote.nil?, @@ -74,10 +74,9 @@ def run def setup_git yoshi_utils.git_ensure_identity - if enable_fork - set :git_remote, "pull-request-fork" unless git_remote - yoshi_utils.gh_ensure_fork remote: git_remote - end + return unless enable_fork + set :git_remote, "pull-request-fork" unless git_remote + yoshi_utils.gh_ensure_fork remote: git_remote end def update_manifest_files @@ -97,7 +96,7 @@ def update_manifest_files manifest[package] = package_info[package][:version] config_packages[package] = { "component" => package, - "version_file" => package_info[package][:version_file] + "version_file" => package_info[package][:version_file], } end end @@ -114,7 +113,7 @@ def update_manifest_files end def add_fillers manifest - manifest.keys.each do |key| + manifest.each_key do |key| manifest["#{key}+FILLER"] = "0.0.0" unless key.end_with? "+FILLER" end manifest @@ -131,7 +130,7 @@ def get_package_info logger.info "Getting info for #{package}..." package_info[package] = { version_file: gem_version_file(package), - version: gem_version(package) + version: gem_version(package), } end package_info @@ -149,7 +148,7 @@ def gem_version package func = proc do Dir.chdir package do spec = Gem::Specification.load "#{package}.gemspec" - puts spec.version.to_s + puts spec.version end end capture_proc(func, log_level: false).strip diff --git a/.toys/sample.rb b/.toys/sample.rb index e2da2c352381..107bbfe8ba9b 100644 --- a/.toys/sample.rb +++ b/.toys/sample.rb @@ -20,29 +20,28 @@ SampleLoader.list.each do |filename| sample = SampleLoader.load filename + next unless sample.well_formed? - if sample.well_formed? - tool_name = sample.name_segments.map { |seg| seg.tr "_", "-" } - tool tool_name do - desc "Run the \"#{sample.file_name}\" sample" + tool_name = sample.name_segments.map { |seg| seg.tr "_", "-" } + tool tool_name do + desc "Run the \"#{sample.file_name}\" sample" - sample.param_names.each do |param| - accepted_type = - case sample.param_type(param) - when "Integer" - Integer - when "Array" - Array - else - String - end - flag param, accept: accepted_type, desc: sample.param_desc(param) - end + sample.param_names.each do |param| + accepted_type = + case sample.param_type param + when "Integer" + Integer + when "Array" + Array + else + String + end + flag param, accept: accepted_type, desc: sample.param_desc(param) + end - to_run do - params = sample.param_names.to_h { |param| [param, get(param)] } - sample.run(**params) - end + to_run do + params = sample.param_names.to_h { |param| [param, get(param)] } + sample.run(**params) end end end diff --git a/.toys/update-pr.rb b/.toys/update-pr.rb index 5c38df125707..d4a39c818578 100644 --- a/.toys/update-pr.rb +++ b/.toys/update-pr.rb @@ -60,7 +60,7 @@ def cleanup def setup_branch branch shallow = capture(["git", "rev-parse", "--is-shallow-repository"]).strip == "true" fetch_options = shallow ? ["--unshallow"] : [] - exec(["git", "fetch"] + fetch_options + [remote, branch]) + exec ["git", "fetch"] + fetch_options + [remote, branch] exec ["git", "switch", branch] exec ["git", "pull", remote, branch] end @@ -68,26 +68,24 @@ def setup_branch branch def merge_branches exec ["git", "switch", head_branch] result = exec ["git", "merge", "-m", "Merge the latest #{base_branch} branch", base_branch], e: false - unless result.success? - exec ["git", "merge", "--abort"] - error "Merge failed" - end + return if result.success? + exec ["git", "merge", "--abort"] + error "Merge failed" end def rebase_branches exec ["git", "switch", head_branch] result = exec ["git", "rebase", base_branch], e: false - unless result.success? - exec ["git", "rebase", "--abort"] - error "Rebase failed" - end + return if result.success? + exec ["git", "rebase", "--abort"] + error "Rebase failed" end def push_branch return if no_push exec ["git", "switch", head_branch] push_options = rebase ? ["-f"] : [] - exec(["git", "push"] + push_options + [remote, head_branch]) + exec ["git", "push"] + push_options + [remote, head_branch] end def base_branch diff --git a/.toys/update-release-levels.rb b/.toys/update-release-levels.rb index 98a503a89a95..681bb1a52d21 100644 --- a/.toys/update-release-levels.rb +++ b/.toys/update-release-levels.rb @@ -40,7 +40,7 @@ def run end def update_release_levels - timestamp = Time.now.utc.strftime("%Y%m%d-%H%M%S") + timestamp = Time.now.utc.strftime "%Y%m%d-%H%M%S" branch_name = "pr/update-release-levels-#{timestamp}" updated = [] pr_result = yoshi_pr_generator.capture enabled: !git_remote.nil?, @@ -69,9 +69,9 @@ def output_result updated, pr_result, *style def selected_gems Dir.chdir context_directory Dir.glob("*/.repo-metadata.json") - .map { |path| File.dirname path } - .find_all { |gem_name| File.file? "#{gem_name}/#{gem_name}.gemspec" } - .sort + .map { |path| File.dirname path } + .find_all { |gem_name| File.file? "#{gem_name}/#{gem_name}.gemspec" } + .sort end def update_gem gem_name @@ -83,9 +83,7 @@ def update_gem gem_name return false end logger.info "Updated repo-metadata for #{gem_name}" - File.open "#{gem_name}/.repo-metadata.json", "w" do |file| - file.write updated_metadata - end + File.write "#{gem_name}/.repo-metadata.json", updated_metadata true end