| 
									
										
										
										
											2024-06-30 19:25:19 +01:00
										 |  |  | # typed: strict | 
					
						
							| 
									
										
										
										
											2019-04-19 15:38:03 +09:00
										 |  |  | # frozen_string_literal: true | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | require "abstract_command" | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  | require "erb" | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | require "fileutils" | 
					
						
							| 
									
										
										
										
											2018-04-01 16:47:30 +05:30
										 |  |  | require "tap" | 
					
						
							| 
									
										
										
										
											2024-12-10 05:24:10 +00:00
										 |  |  | require "utils/uid" | 
					
						
							| 
									
										
										
										
											2018-04-01 16:47:30 +05:30
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-13 13:41:53 +01:00
										 |  |  | module Homebrew | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |   module DevCmd | 
					
						
							|  |  |  |     class TapNew < AbstractCommand | 
					
						
							|  |  |  |       include FileUtils | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       cmd_args do | 
					
						
							|  |  |  |         usage_banner "`tap-new` [<options>] <user>`/`<repo>" | 
					
						
							|  |  |  |         description <<~EOS | 
					
						
							|  |  |  |           Generate the template files for a new tap. | 
					
						
							|  |  |  |         EOS | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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." | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         named_args :tap, number: 1
 | 
					
						
							| 
									
										
										
										
											2020-09-18 13:02:40 +02:00
										 |  |  |       end | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |       sig { override.void } | 
					
						
							|  |  |  |       def run | 
					
						
							|  |  |  |         label = args.pull_label || "pr-pull" | 
					
						
							|  |  |  |         branch = args.branch || "main" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         tap = args.named.to_taps.fetch(0) | 
					
						
							|  |  |  |         odie "Invalid tap name '#{tap}'" unless tap.path.to_s.match?(HOMEBREW_TAP_PATH_REGEX) | 
					
						
							| 
									
										
										
										
											2023-05-11 01:29:57 +08:00
										 |  |  |         odie "Tap is already installed!" if tap.installed? | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         titleized_user = tap.user.dup | 
					
						
							| 
									
										
										
										
											2024-09-24 10:15:34 +01:00
										 |  |  |         titleized_repository = tap.repository.dup | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |         titleized_user[0] = titleized_user[0].upcase | 
					
						
							| 
									
										
										
										
											2024-09-24 10:15:34 +01:00
										 |  |  |         titleized_repository[0] = titleized_repository[0].upcase | 
					
						
							| 
									
										
										
										
											2025-06-13 08:32:56 -04:00
										 |  |  |         # Duplicate assignment to silence `assigned but unused variable` warning | 
					
						
							|  |  |  |         root_url = root_url = GitHubPackages.root_url(tap.user, "homebrew-#{tap.repository}") if args.github_packages? | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         (tap.path/"Formula").mkpath | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         readme = <<~MARKDOWN | 
					
						
							| 
									
										
										
										
											2024-09-24 10:15:34 +01:00
										 |  |  |           # #{titleized_user} #{titleized_repository} | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |           ## How do I install these formulae? | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           `brew install #{tap}/<formula>` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           Or `brew tap #{tap}` and then `brew install <formula>`. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-03-19 09:51:39 +00:00
										 |  |  |           Or, in a `brew bundle` `Brewfile`: | 
					
						
							| 
									
										
										
										
											2024-05-08 14:20:51 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  |           ```ruby
 | 
					
						
							|  |  |  |           tap "#{tap}" | 
					
						
							|  |  |  |           brew "<formula>" | 
					
						
							|  |  |  |           ```
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           ## Documentation | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |           `brew help`, `man brew` or check [Homebrew's documentation](https://docs.brew.sh). | 
					
						
							|  |  |  |         MARKDOWN | 
					
						
							|  |  |  |         write_path(tap, "README.md", readme) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |         tests_yml = <<~ERB | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           name: brew test-bot | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           on: | 
					
						
							|  |  |  |             push: | 
					
						
							|  |  |  |               branches: | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |                 - <%= branch %> | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |             pull_request: | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           jobs: | 
					
						
							|  |  |  |             test-bot: | 
					
						
							|  |  |  |               strategy: | 
					
						
							|  |  |  |                 matrix: | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |                   os: [ ubuntu-22.04, macos-13, macos-15 ] | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |               runs-on: ${{ matrix.os }} | 
					
						
							| 
									
										
										
										
											2025-04-27 22:53:06 +01:00
										 |  |  |               permissions: | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |                 actions: read | 
					
						
							|  |  |  |                 checks: read | 
					
						
							|  |  |  |                 contents: read | 
					
						
							|  |  |  |           <% if  args.github_packages? -%> | 
					
						
							|  |  |  |                 packages: read | 
					
						
							|  |  |  |           <% end  -%> | 
					
						
							|  |  |  |                 pull-requests: read | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |               steps: | 
					
						
							|  |  |  |                 - name: Set up Homebrew | 
					
						
							|  |  |  |                   id: set-up-homebrew | 
					
						
							| 
									
										
										
										
											2025-06-13 14:22:09 +01:00
										 |  |  |                   uses: Homebrew/actions/setup-homebrew@main | 
					
						
							| 
									
										
										
										
											2025-04-27 22:53:06 +01:00
										 |  |  |                   with: | 
					
						
							| 
									
										
										
										
											2025-07-10 16:43:38 +09:00
										 |  |  |                     token: ${{ secrets.GITHUB_TOKEN }} | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - name: Cache Homebrew Bundler RubyGems | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  |                   uses: actions/cache@v4 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |                   with: | 
					
						
							|  |  |  |                     path: ${{ steps.set-up-homebrew.outputs.gems-path }} | 
					
						
							| 
									
										
										
										
											2024-06-22 20:55:13 +01:00
										 |  |  |                     key: ${{ matrix.os }}-rubygems-${{ steps.set-up-homebrew.outputs.gems-hash }} | 
					
						
							|  |  |  |                     restore-keys: ${{ matrix.os }}-rubygems- | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - run: brew test-bot --only-cleanup-before | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 - run: brew test-bot --only-setup | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 - run: brew test-bot --only-tap-syntax | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |           <% if  args.github_packages? -%> | 
					
						
							|  |  |  |                 - name: Base64-encode GITHUB_TOKEN for HOMEBREW_DOCKER_REGISTRY_TOKEN | 
					
						
							| 
									
										
										
										
											2025-04-27 22:53:06 +01:00
										 |  |  |                   id: base64-encode | 
					
						
							|  |  |  |                   if: github.event_name == 'pull_request' | 
					
						
							|  |  |  |                   env: | 
					
						
							| 
									
										
										
										
											2025-07-10 16:43:38 +09:00
										 |  |  |                     TOKEN: ${{ secrets.GITHUB_TOKEN }} | 
					
						
							| 
									
										
										
										
											2025-04-27 22:53:06 +01:00
										 |  |  |                   run: | | 
					
						
							|  |  |  |                     base64_token=$(echo -n "${TOKEN}" | base64 | tr -d "\\n") | 
					
						
							|  |  |  |                     echo "::add-mask::${base64_token}" | 
					
						
							|  |  |  |                     echo "token=${base64_token}" >> "${GITHUB_OUTPUT}" | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |           <% end  -%> | 
					
						
							| 
									
										
										
										
											2025-05-21 13:19:11 +01:00
										 |  |  |                 - run: brew test-bot --only-formulae#{" --root-url=#{root_url}" if root_url} | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |                   if: github.event_name == 'pull_request' | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |           <% if  args.github_packages? -%> | 
					
						
							| 
									
										
										
										
											2025-04-27 22:53:06 +01:00
										 |  |  |                   env: | 
					
						
							|  |  |  |                     HOMEBREW_DOCKER_REGISTRY_TOKEN: ${{ steps.base64-encode.outputs.token }} | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |           <% end  -%> | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - name: Upload bottles as artifact | 
					
						
							|  |  |  |                   if: always() && github.event_name == 'pull_request' | 
					
						
							| 
									
										
										
										
											2024-04-19 10:43:41 +08:00
										 |  |  |                   uses: actions/upload-artifact@v4 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |                   with: | 
					
						
							| 
									
										
										
										
											2024-04-19 10:43:41 +08:00
										 |  |  |                     name: bottles_${{ matrix.os }} | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |                     path: '*.bottle.*' | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |         ERB | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         publish_yml = <<~ERB | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           name: brew pr-pull | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           on: | 
					
						
							|  |  |  |             pull_request_target: | 
					
						
							|  |  |  |               types: | 
					
						
							|  |  |  |                 - labeled | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           jobs: | 
					
						
							|  |  |  |             pr-pull: | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |               if: contains(github.event.pull_request.labels.*.name, '<%= label %>') | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |               runs-on: ubuntu-22.04
 | 
					
						
							|  |  |  |               permissions: | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |                 actions: read | 
					
						
							|  |  |  |                 checks: read | 
					
						
							|  |  |  |                 contents: write | 
					
						
							|  |  |  |                 issues: read | 
					
						
							|  |  |  |           <% if  args.github_packages? -%> | 
					
						
							|  |  |  |                 packages: write | 
					
						
							|  |  |  |           <% end  -%> | 
					
						
							|  |  |  |                 pull-requests: write | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |               steps: | 
					
						
							|  |  |  |                 - name: Set up Homebrew | 
					
						
							| 
									
										
										
										
											2025-06-13 14:22:09 +01:00
										 |  |  |                   uses: Homebrew/actions/setup-homebrew@main | 
					
						
							| 
									
										
										
										
											2025-04-27 22:53:06 +01:00
										 |  |  |                   with: | 
					
						
							| 
									
										
										
										
											2025-07-10 16:43:38 +09:00
										 |  |  |                     token: ${{ secrets.GITHUB_TOKEN }} | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - name: Set up git | 
					
						
							| 
									
										
										
										
											2025-06-13 14:22:09 +01:00
										 |  |  |                   uses: Homebrew/actions/git-user-config@main | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - name: Pull bottles | 
					
						
							|  |  |  |                   env: | 
					
						
							| 
									
										
										
										
											2025-07-10 16:43:38 +09:00
										 |  |  |                     HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }} | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |           <% if  args.github_packages? -%> | 
					
						
							| 
									
										
										
										
											2025-07-10 16:43:38 +09:00
										 |  |  |                     HOMEBREW_GITHUB_PACKAGES_TOKEN: ${{ secrets.GITHUB_TOKEN }} | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |                     HOMEBREW_GITHUB_PACKAGES_USER: ${{ github.repository_owner }} | 
					
						
							|  |  |  |           <% end  -%> | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |                     PULL_REQUEST: ${{ github.event.pull_request.number }} | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  |                   run: brew pr-pull --debug --tap="$GITHUB_REPOSITORY" "$PULL_REQUEST" | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - name: Push commits | 
					
						
							| 
									
										
										
										
											2025-06-13 14:22:09 +01:00
										 |  |  |                   uses: Homebrew/actions/git-try-push@main | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |                   with: | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |                     branch: <%= branch %> | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |                 - name: Delete branch | 
					
						
							|  |  |  |                   if: github.event.pull_request.head.repo.fork == false | 
					
						
							|  |  |  |                   env: | 
					
						
							|  |  |  |                     BRANCH: ${{ github.event.pull_request.head.ref }} | 
					
						
							| 
									
										
										
										
											2024-04-19 11:05:39 +08:00
										 |  |  |                   run: git push --delete origin "$BRANCH" | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |         ERB | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         (tap.path/".github/workflows").mkpath | 
					
						
							| 
									
										
										
										
											2025-04-28 23:57:44 +01:00
										 |  |  |         write_path(tap, ".github/workflows/tests.yml", ERB.new(tests_yml, trim_mode: "-").result(binding)) | 
					
						
							|  |  |  |         write_path(tap, ".github/workflows/publish.yml", ERB.new(publish_yml, trim_mode: "-").result(binding)) | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  |         unless args.no_git? | 
					
						
							| 
									
										
										
										
											2024-12-10 05:24:10 +00:00
										 |  |  |           cd tap.path do |path| | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |             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" | 
					
						
							| 
									
										
										
										
											2024-12-10 05:24:10 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |             args = [] | 
					
						
							|  |  |  |             git_owner = File.stat(File.join(path, ".git")).uid | 
					
						
							|  |  |  |             if git_owner != Process.uid && git_owner == Process.euid | 
					
						
							|  |  |  |               # Under Homebrew user model, EUID is permitted to execute commands under the UID. | 
					
						
							|  |  |  |               # Root users are never allowed (see brew.sh). | 
					
						
							|  |  |  |               args << "-c" << "safe.directory=#{path}" | 
					
						
							|  |  |  |             end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Use the configuration of the original user, which will have author information and signing keys. | 
					
						
							|  |  |  |             Utils::UID.drop_euid do | 
					
						
							|  |  |  |               env = { HOME: Utils::UID.uid_home }.compact | 
					
						
							|  |  |  |               env[:TMPDIR] = nil if (tmpdir = ENV.fetch("TMPDIR", nil)) && !File.writable?(tmpdir) | 
					
						
							|  |  |  |               with_env(env) do | 
					
						
							|  |  |  |                 safe_system "git", *args, "add", "--all" | 
					
						
							|  |  |  |                 safe_system "git", *args, "commit", "-m", "Create #{tap} tap" | 
					
						
							|  |  |  |                 safe_system "git", *args, "branch", "-m", branch | 
					
						
							|  |  |  |               end | 
					
						
							|  |  |  |             end | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |           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 | 
					
						
							| 
									
										
										
										
											2020-09-18 13:02:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |       private | 
					
						
							| 
									
										
										
										
											2018-10-08 22:49:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-06-30 19:25:19 +01:00
										 |  |  |       sig { params(tap: Tap, filename: T.any(String, Pathname), content: String).void } | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |       def write_path(tap, filename, content) | 
					
						
							|  |  |  |         path = tap.path/filename | 
					
						
							|  |  |  |         tap.path.mkpath | 
					
						
							|  |  |  |         odie "#{path} already exists" if path.exist? | 
					
						
							| 
									
										
										
										
											2018-10-08 22:49:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-03-21 21:47:55 -07:00
										 |  |  |         path.write content | 
					
						
							|  |  |  |       end | 
					
						
							|  |  |  |     end | 
					
						
							| 
									
										
										
										
											2018-10-08 22:49:03 -04:00
										 |  |  |   end | 
					
						
							| 
									
										
										
										
											2016-10-13 13:41:53 +01:00
										 |  |  | end |