From e0519d736a9a69b5ed154b7370fd040008c91e23 Mon Sep 17 00:00:00 2001 From: Douglas Eichelberger Date: Thu, 21 Mar 2024 21:47:55 -0700 Subject: [PATCH] Port Homebrew::DevCmd::TapNew --- Library/Homebrew/dev-cmd/tap-new.rb | 292 +++++++++--------- Library/Homebrew/test/dev-cmd/tap-new_spec.rb | 3 +- 2 files changed, 151 insertions(+), 144 deletions(-) diff --git a/Library/Homebrew/dev-cmd/tap-new.rb b/Library/Homebrew/dev-cmd/tap-new.rb index ffe01a144c..1c36553ec0 100644 --- a/Library/Homebrew/dev-cmd/tap-new.rb +++ b/Library/Homebrew/dev-cmd/tap-new.rb @@ -1,182 +1,188 @@ # typed: true # frozen_string_literal: true +require "abstract_command" +require "fileutils" require "tap" require "cli/parser" module Homebrew - sig { returns(CLI::Parser) } - def self.tap_new_args - Homebrew::CLI::Parser.new do - usage_banner "`tap-new` [] `/`" - description <<~EOS - Generate the template files for a new tap. - EOS + module DevCmd + class TapNew < AbstractCommand + include FileUtils - switch "--no-git", - description: "Don't initialize a Git repository for the tap." - flag "--pull-label=", - description: "Label name for pull requests ready to be pulled (default: `pr-pull`)." - flag "--branch=", - description: "Initialize Git repository and setup GitHub Actions workflows with the " \ - "specified branch name (default: `main`)." - switch "--github-packages", - description: "Upload bottles to GitHub Packages." + cmd_args do + usage_banner "`tap-new` [] `/`" + description <<~EOS + Generate the template files for a new tap. + EOS - named_args :tap, number: 1 - end - end + switch "--no-git", + description: "Don't initialize a Git repository for the tap." + flag "--pull-label=", + description: "Label name for pull requests ready to be pulled (default: `pr-pull`)." + flag "--branch=", + description: "Initialize Git repository and setup GitHub Actions workflows with the " \ + "specified branch name (default: `main`)." + switch "--github-packages", + description: "Upload bottles to GitHub Packages." - def self.tap_new - args = tap_new_args.parse + named_args :tap, number: 1 + end - label = args.pull_label || "pr-pull" - branch = args.branch || "main" + sig { override.void } + def run + label = args.pull_label || "pr-pull" + branch = args.branch || "main" - tap = args.named.to_taps.first - odie "Invalid tap name '#{tap}'" unless tap.path.to_s.match?(HOMEBREW_TAP_PATH_REGEX) + tap = args.named.to_taps.fetch(0) + odie "Invalid tap name '#{tap}'" unless tap.path.to_s.match?(HOMEBREW_TAP_PATH_REGEX) - titleized_user = tap.user.dup - titleized_repo = tap.repo.dup - titleized_user[0] = titleized_user[0].upcase - titleized_repo[0] = titleized_repo[0].upcase - root_url = GitHubPackages.root_url(tap.user, "homebrew-#{tap.repo}") if args.github_packages? + titleized_user = tap.user.dup + titleized_repo = tap.repo.dup + titleized_user[0] = titleized_user[0].upcase + titleized_repo[0] = titleized_repo[0].upcase + root_url = GitHubPackages.root_url(tap.user, "homebrew-#{tap.repo}") if args.github_packages? - (tap.path/"Formula").mkpath + (tap.path/"Formula").mkpath - readme = <<~MARKDOWN - # #{titleized_user} #{titleized_repo} + readme = <<~MARKDOWN + # #{titleized_user} #{titleized_repo} - ## How do I install these formulae? + ## How do I install these formulae? - `brew install #{tap}/` + `brew install #{tap}/` - Or `brew tap #{tap}` and then `brew install `. + Or `brew tap #{tap}` and then `brew install `. - ## Documentation + ## Documentation - `brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh). - MARKDOWN - write_path(tap, "README.md", readme) + `brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh). + MARKDOWN + write_path(tap, "README.md", readme) - actions_main = <<~YAML - name: brew test-bot - on: - push: - branches: - - #{branch} - pull_request: - jobs: - test-bot: - strategy: - matrix: - os: [ubuntu-22.04, macos-13] - runs-on: ${{ matrix.os }} - steps: - - name: Set up Homebrew - id: set-up-homebrew - uses: Homebrew/actions/setup-homebrew@master + actions_main = <<~YAML + name: brew test-bot + on: + push: + branches: + - #{branch} + pull_request: + jobs: + test-bot: + strategy: + matrix: + os: [ubuntu-22.04, macos-13] + runs-on: ${{ matrix.os }} + steps: + - name: Set up Homebrew + id: set-up-homebrew + uses: Homebrew/actions/setup-homebrew@master - - name: Cache Homebrew Bundler RubyGems - id: cache - uses: actions/cache@v3 - with: - path: ${{ steps.set-up-homebrew.outputs.gems-path }} - key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }} - restore-keys: ${{ runner.os }}-rubygems- + - name: Cache Homebrew Bundler RubyGems + id: cache + uses: actions/cache@v3 + with: + path: ${{ steps.set-up-homebrew.outputs.gems-path }} + key: ${{ runner.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }} + restore-keys: ${{ runner.os }}-rubygems- - - run: brew test-bot --only-cleanup-before + - run: brew test-bot --only-cleanup-before - - run: brew test-bot --only-setup + - run: brew test-bot --only-setup - - run: brew test-bot --only-tap-syntax + - run: brew test-bot --only-tap-syntax - - run: brew test-bot --only-formulae#{" --root-url=#{root_url}" if root_url} - if: github.event_name == 'pull_request' + - run: brew test-bot --only-formulae#{" --root-url=#{root_url}" if root_url} + if: github.event_name == 'pull_request' - - name: Upload bottles as artifact - if: always() && github.event_name == 'pull_request' - uses: actions/upload-artifact@v3 - with: - name: bottles - path: '*.bottle.*' - YAML + - name: Upload bottles as artifact + if: always() && github.event_name == 'pull_request' + uses: actions/upload-artifact@v3 + with: + name: bottles + path: '*.bottle.*' + YAML - actions_publish = <<~YAML - name: brew pr-pull - on: - pull_request_target: - types: - - labeled - jobs: - pr-pull: - if: contains(github.event.pull_request.labels.*.name, '#{label}') - runs-on: ubuntu-22.04 - permissions: - contents: write - packages: #{args.github_packages? ? "write" : "none"} - pull-requests: write - steps: - - name: Set up Homebrew - uses: Homebrew/actions/setup-homebrew@master + actions_publish = <<~YAML + name: brew pr-pull + on: + pull_request_target: + types: + - labeled + jobs: + pr-pull: + if: contains(github.event.pull_request.labels.*.name, '#{label}') + runs-on: ubuntu-22.04 + permissions: + contents: write + packages: #{args.github_packages? ? "write" : "none"} + pull-requests: write + steps: + - name: Set up Homebrew + uses: Homebrew/actions/setup-homebrew@master - - name: Set up git - uses: Homebrew/actions/git-user-config@master + - name: Set up git + uses: Homebrew/actions/git-user-config@master - - name: Pull bottles - env: - HOMEBREW_GITHUB_API_TOKEN: ${{ github.token }} - HOMEBREW_GITHUB_PACKAGES_TOKEN: ${{ github.token }} - HOMEBREW_GITHUB_PACKAGES_USER: ${{ github.actor }} - PULL_REQUEST: ${{ github.event.pull_request.number }} - run: brew pr-pull --debug --tap=$GITHUB_REPOSITORY $PULL_REQUEST + - name: Pull bottles + env: + HOMEBREW_GITHUB_API_TOKEN: ${{ github.token }} + HOMEBREW_GITHUB_PACKAGES_TOKEN: ${{ github.token }} + HOMEBREW_GITHUB_PACKAGES_USER: ${{ github.actor }} + PULL_REQUEST: ${{ github.event.pull_request.number }} + run: brew pr-pull --debug --tap=$GITHUB_REPOSITORY $PULL_REQUEST - - name: Push commits - uses: Homebrew/actions/git-try-push@master - with: - token: ${{ github.token }} - branch: #{branch} + - name: Push commits + uses: Homebrew/actions/git-try-push@master + with: + token: ${{ github.token }} + branch: #{branch} - - name: Delete branch - if: github.event.pull_request.head.repo.fork == false - env: - BRANCH: ${{ github.event.pull_request.head.ref }} - run: git push --delete origin $BRANCH - YAML + - name: Delete branch + if: github.event.pull_request.head.repo.fork == false + env: + BRANCH: ${{ github.event.pull_request.head.ref }} + run: git push --delete origin $BRANCH + YAML - (tap.path/".github/workflows").mkpath - write_path(tap, ".github/workflows/tests.yml", actions_main) - write_path(tap, ".github/workflows/publish.yml", actions_publish) + (tap.path/".github/workflows").mkpath + write_path(tap, ".github/workflows/tests.yml", actions_main) + write_path(tap, ".github/workflows/publish.yml", actions_publish) - unless args.no_git? - cd tap.path do - Utils::Git.set_name_email! - Utils::Git.setup_gpg! + unless args.no_git? + cd tap.path do + Utils::Git.set_name_email! + Utils::Git.setup_gpg! - # Would be nice to use --initial-branch here but it's not available in - # older versions of Git that we support. - safe_system "git", "-c", "init.defaultBranch=#{branch}", "init" - safe_system "git", "add", "--all" - safe_system "git", "commit", "-m", "Create #{tap} tap" - safe_system "git", "branch", "-m", branch + # Would be nice to use --initial-branch here but it's not available in + # older versions of Git that we support. + safe_system "git", "-c", "init.defaultBranch=#{branch}", "init" + safe_system "git", "add", "--all" + safe_system "git", "commit", "-m", "Create #{tap} tap" + safe_system "git", "branch", "-m", branch + end + end + + ohai "Created #{tap}" + puts <<~EOS + #{tap.path} + + When a pull request making changes to a formula (or formulae) becomes green + (all checks passed), then you can publish the built bottles. + To do so, label your PR as `#{label}` and the workflow will be triggered. + EOS + end + + private + + def write_path(tap, filename, content) + path = tap.path/filename + tap.path.mkpath + odie "#{path} already exists" if path.exist? + + path.write content end end - - ohai "Created #{tap}" - puts <<~EOS - #{tap.path} - - When a pull request making changes to a formula (or formulae) becomes green - (all checks passed), then you can publish the built bottles. - To do so, label your PR as `#{label}` and the workflow will be triggered. - EOS - end - - def self.write_path(tap, filename, content) - path = tap.path/filename - tap.path.mkpath - odie "#{path} already exists" if path.exist? - - path.write content end end diff --git a/Library/Homebrew/test/dev-cmd/tap-new_spec.rb b/Library/Homebrew/test/dev-cmd/tap-new_spec.rb index a79d356507..fe2d1f5827 100644 --- a/Library/Homebrew/test/dev-cmd/tap-new_spec.rb +++ b/Library/Homebrew/test/dev-cmd/tap-new_spec.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true require "cmd/shared_examples/args_parse" +require "dev-cmd/tap-new" -RSpec.describe "brew tap-new" do +RSpec.describe Homebrew::DevCmd::TapNew do it_behaves_like "parseable arguments" it "initializes a new tap with a README file and GitHub Actions CI", :integration_test do