diff --git a/toys/README.md b/toys/README.md index e3d0f18..0629109 100644 --- a/toys/README.md +++ b/toys/README.md @@ -12,6 +12,7 @@ Specifically: * `/toys/release` provides the Ruby release system, including tools for controlling release-please, performing Rubygems releases, and building and publishing reference documentation. +* `/toys/tombstone-library` is a tool that replaces a library with a tombstone. * `/toys/yoshi` provides a set of utility classes for performing common steps such as interacting with GitHub and opening pull requests. diff --git a/toys/tombstone-library/.data/gemspec-template.erb b/toys/tombstone-library/.data/gemspec-template.erb new file mode 100644 index 0000000..c6a91e3 --- /dev/null +++ b/toys/tombstone-library/.data/gemspec-template.erb @@ -0,0 +1,27 @@ +require File.expand_path("<%= namespace_dir %>/version", __dir__) + +Gem::Specification.new do |gem| + gem.name = "<%= gem_name %>" + gem.version = <%= namespace %>::VERSION + gem.authors = ["Google LLC"] + gem.email = "googleapis-packages@google.com" + gem.description = + "This gem is obsolete because the related Google backend is turned down. " \ + "For more information, see <%= info_url %>." + gem.summary = "This gem is obsolete because the related backend is turned down." + gem.post_install_message = <<~MESSAGE + + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + The <%= gem_name %> gem is OBSOLETE. + For more information, see: + <%= info_url %> + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + MESSAGE + gem.homepage = "https://github.com/googleapis/google-cloud-ruby" + gem.license = "Apache-2.0" + gem.platform = Gem::Platform::RUBY + gem.files = ["README.md", "LICENSE.md", ".yardopts", "<%= namespace_dir %>/version.rb"] + gem.require_paths = ["lib"] + gem.required_ruby_version = ">= 3.0" +end diff --git a/toys/tombstone-library/.data/license-template.erb b/toys/tombstone-library/.data/license-template.erb new file mode 100644 index 0000000..c261857 --- /dev/null +++ b/toys/tombstone-library/.data/license-template.erb @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/toys/tombstone-library/.data/readme-template.erb b/toys/tombstone-library/.data/readme-template.erb new file mode 100644 index 0000000..dad48a0 --- /dev/null +++ b/toys/tombstone-library/.data/readme-template.erb @@ -0,0 +1,4 @@ +# Tombstone for Ruby gem <%= gem_name %> + +This gem is obsolete because the related Google backend is turned down. +For more information, see <%= info_url %>. diff --git a/toys/tombstone-library/.data/version-template.erb b/toys/tombstone-library/.data/version-template.erb new file mode 100644 index 0000000..b3dfc95 --- /dev/null +++ b/toys/tombstone-library/.data/version-template.erb @@ -0,0 +1,15 @@ +# Copyright <%= cur_year %> 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. + +<%= version_lines %> diff --git a/toys/tombstone-library/.data/yardopts-template.erb b/toys/tombstone-library/.data/yardopts-template.erb new file mode 100644 index 0000000..3754015 --- /dev/null +++ b/toys/tombstone-library/.data/yardopts-template.erb @@ -0,0 +1,9 @@ +--no-private +--title="Obsolete Gem <%= gem_name %>" +--markup markdown +--markup-provider redcarpet + +./lib/**/*.rb +- +README.md +LICENSE.md diff --git a/toys/tombstone-library/.toys.rb b/toys/tombstone-library/.toys.rb new file mode 100644 index 0000000..cd0967f --- /dev/null +++ b/toys/tombstone-library/.toys.rb @@ -0,0 +1,140 @@ +# frozen_string_literal: true + +# Copyright 2023 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. + +load File.join(File.dirname(__dir__), "yoshi") + +desc "Transform a gem into a tombstone after we think it's no longer useful" + +required_arg :gem_name do + desc "Name of the gem to tombstone" +end +optional_arg :gem_version do + desc "Gem version to use for the tombstone" +end +flag :info_url, "--info-url=URL" do + default "" + desc "URL to use for more information" +end +flag :gem_dir, "--dir=DIR" do + desc "Gem directory name, if different from the gem name" +end +flag :git_remote, "--remote=NAME" do + desc "The name of the git remote to use as the pull request head. If omitted, does not open a pull request." +end +flag :enable_fork, "--fork" do + desc "Use a fork to open the pull request" +end + +include :exec, e: true +include :terminal +include :fileutils +include "yoshi-pr-generator" + +DEFAULT_INFO_URL = "https://cloud.google.com/terms/deprecation" + +def run + setup + branch_name = "pr/tombstone/#{gem_name}" + message = "feat!: Replace #{gem_name} with a tombstone" + result = yoshi_pr_generator.capture enabled: !git_remote.nil?, + remote: git_remote, + branch_name: branch_name, + commit_message: message do + delete_files + generate_files + end + puts "Pull request creation: #{result}", :bold +end + +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 + set :gem_dir, gem_name if gem_dir.to_s.empty? + set :info_url, DEFAULT_INFO_URL if info_url.to_s.empty? + ensure_gem_version + require "erb" +end + +def ensure_gem_version + unless gem_version + require "json" + content = capture ["curl", "https://rubygems.org/api/v1/gems/#{gem_name}.json"], err: :null + last_version = JSON.parse(content)["version"] + logger.info "Last released version for #{gem_name} was #{last_version}" + last_version = last_version.split(".").first.to_i + set :gem_version, "#{last_version + 1}.0.0" + end + logger.info "Tombstone will be #{gem_name} version #{gem_version}" +end + +def delete_files + Dir.each_child gem_dir do |child| + rm_rf "#{gem_dir}/#{child}" + logger.info "Deleted #{child}" + end +end + +def generate_files + cd gem_dir do + generate_one "README.md", "readme-template.erb" + generate_one "LICENSE.md", "license-template.erb" + generate_one "#{gem_name}.gemspec", "gemspec-template.erb" + generate_one ".yardopts", "yardopts-template.erb" + mkdir_p "lib/#{namespace_dir}" + generate_one "lib/#{namespace_dir}/version.rb", "version-template.erb" + end +end + +def generate_one filename, template_name + template = File.read find_data template_name + File.write filename, ERB.new(template).result(binding) + logger.info "Generated #{filename} from #{template_name}" +end + +def cur_year + Time.now.year.to_s +end + +def namespace_modules + @namespace_modules ||= gem_name.split("-").map { |segment| segment.split("_").map(&:capitalize).join } +end + +def namespace + @namespace ||= namespace_modules.join "::" +end + +def namespace_dir + @namespace_dir ||= gem_name.tr "-", "/" +end + +def version_lines + lines = [] + indent = 0 + namespace_modules.each do |mod| + lines << "#{' ' * indent}module #{mod}" + indent += 2 + end + lines << "#{' ' * indent}VERSION = \"#{gem_version}\"" + while indent.positive? + indent -= 2 + lines << "#{' ' * indent}end" + end + lines.join "\n" +end