diff --git a/Library/Homebrew/cask/artifact.rb b/Library/Homebrew/cask/artifact.rb index 98ccf9d66c..278d0c4442 100644 --- a/Library/Homebrew/cask/artifact.rb +++ b/Library/Homebrew/cask/artifact.rb @@ -23,6 +23,7 @@ require "cask/artifact/stage_only" require "cask/artifact/suite" require "cask/artifact/uninstall" require "cask/artifact/zap" +require "cask/artifact/manpage" module Cask module Artifact diff --git a/Library/Homebrew/cask/artifact/manpage.rb b/Library/Homebrew/cask/artifact/manpage.rb new file mode 100644 index 0000000000..d7957c625d --- /dev/null +++ b/Library/Homebrew/cask/artifact/manpage.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require "cask/artifact/moved" + +require "extend/hash_validator" +using HashValidator + +module Cask + module Artifact + class Manpage < Moved + def self.from_args(cask, *args) + source_string, section_hash = args + section = nil + + if section_hash + raise CaskInvalidError unless section_hash.respond_to?(:keys) + + section_hash.assert_valid_keys!(:section) + + section = section_hash[:section] + else + section = source_string.split(".").last + end + + raise CaskInvalidError, "section should be a positive number" unless section.to_i.positive? + + section_hash ||= {} + + new(cask, source_string, **section_hash) + end + + def resolve_target(_target) + config.manpagedir.join("man#{section}", target_name) + end + + def initialize(cask, source, section: nil) + @source_section = section + + super(cask, source) + end + + def extension + @source.extname.downcase[1..-1].to_s + end + + def section + (@source_section || extension).to_i + end + + def target_name + "#{@source.basename(@source.extname)}.#{section}" + end + end + end +end diff --git a/Library/Homebrew/cask/config.rb b/Library/Homebrew/cask/config.rb index 8c2aa3da68..41fba64514 100644 --- a/Library/Homebrew/cask/config.rb +++ b/Library/Homebrew/cask/config.rb @@ -93,6 +93,10 @@ module Cask @binarydir ||= HOMEBREW_PREFIX/"bin" end + def manpagedir + @manpagedir ||= HOMEBREW_PREFIX/"share/man" + end + DEFAULT_DIRS.keys.each do |dir| define_method(dir) do explicit.fetch(dir, env.fetch(dir, default.fetch(dir))) diff --git a/Library/Homebrew/cask/dsl.rb b/Library/Homebrew/cask/dsl.rb index 9ed09b4bb7..9e6c2a29eb 100644 --- a/Library/Homebrew/cask/dsl.rb +++ b/Library/Homebrew/cask/dsl.rb @@ -46,6 +46,7 @@ module Cask Artifact::Vst3Plugin, Artifact::Uninstall, Artifact::Zap, + Artifact::Manpage, ].freeze ACTIVATABLE_ARTIFACT_CLASSES = (ORDINARY_ARTIFACT_CLASSES - [Artifact::StageOnly]).freeze diff --git a/Library/Homebrew/rubocops/cask/constants/stanza.rb b/Library/Homebrew/rubocops/cask/constants/stanza.rb index ad7b41ce46..3684eef095 100644 --- a/Library/Homebrew/rubocops/cask/constants/stanza.rb +++ b/Library/Homebrew/rubocops/cask/constants/stanza.rb @@ -32,6 +32,7 @@ module RuboCop :vst_plugin, :artifact, :stage_only, + :manpage, ], [:preflight], [:postflight], diff --git a/Library/Homebrew/test/cask/artifact/manpage_spec.rb b/Library/Homebrew/test/cask/artifact/manpage_spec.rb new file mode 100644 index 0000000000..e4e0a8d04e --- /dev/null +++ b/Library/Homebrew/test/cask/artifact/manpage_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +describe Cask::Artifact::Manpage, :cask do + let(:cask_token) { "" } + let(:cask) { Cask::CaskLoader.load(cask_path(cask_token)) } + + context "without section" do + let(:cask_token) { "invalid/invalid-manpage-no-section" } + + it "fails to load a cask without section" do + expect { cask }.to raise_error(Cask::CaskInvalidError, /section should be a positive number/) + end + end + + context "with install" do + let(:install_phase) { + lambda do + cask.artifacts.select { |a| a.is_a?(described_class) }.each do |artifact| + artifact.install_phase(command: NeverSudoSystemCommand, force: false) + end + end + } + + let(:source_path) { cask.staged_path.join("manpage.1") } + let(:expected_section) { "" } + let(:target_path) { cask.config.manpagedir.join("man#{expected_section}/manpage.#{expected_section}") } + + before do + InstallHelper.install_without_artifacts(cask) + end + + context "with autodetected section" do + let(:cask_token) { "with-autodetected-manpage-section" } + let(:expected_section) { 1 } + + it "moves the manpage to the proper directory" do + install_phase.call + + expect(target_path).to exist + expect(source_path).not_to exist + end + end + + context "with explicit section" do + let(:cask_token) { "with-explicit-manpage-section" } + let(:expected_section) { 3 } + + it "moves the manpage to the proper directory" do + install_phase.call + + expect(target_path).to exist + expect(source_path).not_to exist + end + end + end +end diff --git a/Library/Homebrew/test/support/fixtures/cask/AppWithManpage.zip b/Library/Homebrew/test/support/fixtures/cask/AppWithManpage.zip new file mode 100644 index 0000000000..938933a1ca Binary files /dev/null and b/Library/Homebrew/test/support/fixtures/cask/AppWithManpage.zip differ diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/invalid/invalid-manpage-no-section.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/invalid/invalid-manpage-no-section.rb new file mode 100644 index 0000000000..6dd3148756 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/invalid/invalid-manpage-no-section.rb @@ -0,0 +1,9 @@ +cask 'invalid-manpage-no-section' do + version '1.2.3' + sha256 '67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94' + + url "file://#{TEST_FIXTURE_DIR}/cask/AppWithManpage.zip" + homepage 'https://brew.sh/with-generic-artifact' + + manpage 'manpage' +end diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-autodetected-manpage-section.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-autodetected-manpage-section.rb new file mode 100644 index 0000000000..a92b9be233 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-autodetected-manpage-section.rb @@ -0,0 +1,9 @@ +cask 'with-autodetected-manpage-section' do + version '1.2.3' + sha256 '67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94' + + url "file://#{TEST_FIXTURE_DIR}/cask/AppWithManpage.zip" + homepage 'https://brew.sh/with-autodetected-manpage-section' + + manpage 'manpage.1' +end diff --git a/Library/Homebrew/test/support/fixtures/cask/Casks/with-explicit-manpage-section.rb b/Library/Homebrew/test/support/fixtures/cask/Casks/with-explicit-manpage-section.rb new file mode 100644 index 0000000000..ce01e051a5 --- /dev/null +++ b/Library/Homebrew/test/support/fixtures/cask/Casks/with-explicit-manpage-section.rb @@ -0,0 +1,9 @@ +cask 'with-explicit-manpage-section' do + version '1.2.3' + sha256 '67cdb8a02803ef37fdbf7e0be205863172e41a561ca446cd84f0d7ab35a99d94' + + url "file://#{TEST_FIXTURE_DIR}/cask/AppWithManpage.zip" + homepage 'https://brew.sh/with-explicit-manpage-section' + + manpage 'manpage.1', section: 3 +end