diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 287e95b03a..cfa55d26e6 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,10 +1,10 @@ **Please note we will close your issue without comment if you delete, do not read or do not fill out the issue checklist below and provide ALL the requested information. If you repeatedly fail to use the issue template, we will block you from ever submitting issues to Homebrew again.** -# Please always follow these steps: -- [ ] Confirmed this is a problem with running a `brew` command and not `brew install`ing or the post-install behaviour of one or more formulae? If it's a formulae-specific problem please file this issue at the relevant tap e.g. for Homebrew/homebrew-core https://github.com/Homebrew/homebrew-core/issues/new -- [ ] Ran `brew update` and retried your prior step? -- [ ] Ran `brew doctor`, fixed all issues and retried your prior step? -- [ ] Ran `brew config` and `brew doctor` and included their output with your issue? +- [ ] are reporting a bug others will be able to reproduce and not asking a question. If you're not sure or want to ask a question do so on our Discourse: https://discourse.brew.sh +- [ ] ran a `brew` command and reproduced the problem with multiple formulae? If it's a problem with a single, official formula (not cask) please file this issue at Homebrew/homebrew-core: https://github.com/Homebrew/homebrew-core/issues/new. If it's a `brew cask` problem please file this issue at https://github.com/caskroom/homebrew-cask/issues/new. If it's a tap (e.g. Homebrew/homebrew-php) problem please file this issue at the tap. +- [ ] ran `brew update` and can still reproduce the problem? +- [ ] ran `brew doctor`, fixed all issues and can still reproduce the problem? +- [ ] ran `brew config` and `brew doctor` and included their output with your issue? To help us debug your issue please explain: - What you were trying to do (and why) @@ -16,7 +16,7 @@ To help us debug your issue please explain: Please replace this section with: - a detailed description of your proposed feature - the motivation for the feature -- how the feature would be relevant to at least 90% of Homebrew users +- how the feature would be relevant to at least 90% of Homebrew users (if it's not: do not open a feature request) - what alternatives to the feature you have considered -We will close this issue or ask you to create a pull-request if it's something we're not actively planning to work on. +We will close this issue or ask you to create a pull-request if it's something the maintainers are not actively planning to work on. diff --git a/.travis.yml b/.travis.yml index fd43e39420..fef0f91cad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ cache: directories: - $HOME/Library/Caches/Homebrew/style - $HOME/Library/Caches/Homebrew/tests - - $HOME/Library/Homebrew/vendor/bundle + - Library/Homebrew/vendor/bundle branches: only: - master @@ -36,22 +36,8 @@ before_install: mv "$HOMEBREW_REPOSITORY/Library/Taps" "$PWD/Library"; sudo rm -rf "$HOMEBREW_REPOSITORY"; sudo ln -s "$PWD" "$HOMEBREW_REPOSITORY"; - else - HOMEBREW_CORE_TAP_DIR="$(brew --repo "homebrew/core")"; - mkdir -p "$HOMEBREW_CORE_TAP_DIR"; - fi - - if [ "$MACOS" ]; then - travis_retry git -C Library/Taps/homebrew/homebrew-core fetch --depth=1 origin; fi - travis_retry git clone --depth=1 https://github.com/Homebrew/homebrew-test-bot Library/Taps/homebrew/homebrew-test-bot - - if [ "$LINUX" ]; then - HOMEBREW_TEST_BOT_TAP_DIR="$(brew --repo "homebrew/test-bot")"; - ln -s "$HOMEBREW_TEST_BOT_TAP_DIR/.git" "$HOMEBREW_TEST_BOT_TAP_DIR/Formula" "$HOMEBREW_CORE_TAP_DIR"; - fi - # can be removed after 1.5.3 is tagged - - if [ "$LINUX" ]; then - export HOMEBREW_FORCE_VENDOR_RUBY=1; - fi script: - brew test-bot diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0cf37b85de..7ba6830c03 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,7 +5,7 @@ First time contributing to Homebrew? Read our [Code of Conduct](https://github.c * Run `brew update` (twice). * Run and read `brew doctor`. -* Read [the Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting.html). +* Read [the Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting). * Open an issue on the formula's repository or on Homebrew/brew if it's not a formula-specific issue. ### Propose a feature diff --git a/Library/Homebrew/README.md b/Library/Homebrew/README.md index 681bb92880..e0e9613734 100644 --- a/Library/Homebrew/README.md +++ b/Library/Homebrew/README.md @@ -3,6 +3,6 @@ This is the (partially) documented public API for Homebrew. The main class you should look at is the {Formula} class (and classes linked from there). That's the class that's used to create Homebrew formulae (i.e. package descriptions). Assume anything else you stumble upon is private. -You may also find the [Formula Cookbook](https://docs.brew.sh/Formula-Cookbook.html) and [Ruby Style Guide](https://github.com/styleguide/ruby) helpful in creating formulae. +You may also find the [Formula Cookbook](https://docs.brew.sh/Formula-Cookbook) and [Ruby Style Guide](https://github.com/styleguide/ruby) helpful in creating formulae. Good luck! diff --git a/Library/Homebrew/brew.sh b/Library/Homebrew/brew.sh index 60952c7fed..590dde3632 100644 --- a/Library/Homebrew/brew.sh +++ b/Library/Homebrew/brew.sh @@ -75,7 +75,6 @@ case "$HOMEBREW_SYSTEM" in Linux) HOMEBREW_LINUX="1" ;; esac -HOMEBREW_CURL="curl" if [[ -n "$HOMEBREW_MACOS" ]] then HOMEBREW_PROCESSOR="$(uname -p)" @@ -97,11 +96,12 @@ then HOMEBREW_FORCE_BREWED_CURL="1" fi - if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" && - -x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]] && - "$HOMEBREW_PREFIX/opt/curl/bin/curl" --version >/dev/null + # The system Git is too old for some GitHub's SSL ciphers on older + # macOS versions. + # https://github.com/blog/2507-weak-cryptographic-standards-removed + if [[ "$HOMEBREW_MACOS_VERSION_NUMERIC" -lt "100900" ]] then - HOMEBREW_CURL="$HOMEBREW_PREFIX/opt/curl/bin/curl" + HOMEBREW_SYSTEM_GIT_TOO_OLD="1" fi if [[ -z "$HOMEBREW_CACHE" ]] @@ -125,6 +125,16 @@ else fi fi fi + +if [[ -n "$HOMEBREW_FORCE_BREWED_CURL" && + -x "$HOMEBREW_PREFIX/opt/curl/bin/curl" ]] && + "$HOMEBREW_PREFIX/opt/curl/bin/curl" --version >/dev/null +then + HOMEBREW_CURL="$HOMEBREW_PREFIX/opt/curl/bin/curl" +else + HOMEBREW_CURL="curl" +fi + HOMEBREW_USER_AGENT="$HOMEBREW_PRODUCT/$HOMEBREW_USER_AGENT_VERSION ($HOMEBREW_SYSTEM; $HOMEBREW_PROCESSOR $HOMEBREW_OS_USER_AGENT_VERSION)" HOMEBREW_CURL_VERSION="$("$HOMEBREW_CURL" --version 2>/dev/null | head -n1 | awk '{print $1"/"$2}')" HOMEBREW_USER_AGENT_CURL="$HOMEBREW_USER_AGENT $HOMEBREW_CURL_VERSION" @@ -224,6 +234,15 @@ case "$HOMEBREW_COMMAND" in --config) HOMEBREW_COMMAND="config" ;; esac +if [[ "$HOMEBREW_COMMAND" = "cask" ]] +then + HOMEBREW_CASK_COMMAND="$1" + + case "$HOMEBREW_CASK_COMMAND" in + instal) HOMEBREW_CASK_COMMAND="install" ;; # gem does the same + esac +fi + # Set HOMEBREW_DEV_CMD_RUN for users who have run a development command. # This makes them behave like HOMEBREW_DEVELOPERs for brew update. if [[ -z "$HOMEBREW_DEVELOPER" ]] @@ -234,6 +253,14 @@ then then export HOMEBREW_DEV_CMD_RUN="1" fi + + # Don't allow non-developers to customise Ruby warnings. + unset HOMEBREW_RUBY_WARNINGS +fi + +if [[ -z "$HOMEBREW_RUBY_WARNINGS" ]] +then + export HOMEBREW_RUBY_WARNINGS="-W0" fi if [[ -f "$HOMEBREW_LIBRARY/Homebrew/cmd/$HOMEBREW_COMMAND.sh" ]] @@ -297,7 +324,8 @@ update-preinstall() { [[ -z "$HOMEBREW_AUTO_UPDATE_CHECKED" ]] || return [[ -z "$HOMEBREW_UPDATE_PREINSTALL" ]] || return - if [[ "$HOMEBREW_COMMAND" = "install" || "$HOMEBREW_COMMAND" = "upgrade" || "$HOMEBREW_COMMAND" = "tap" ]] + if [[ "$HOMEBREW_COMMAND" = "install" || "$HOMEBREW_COMMAND" = "upgrade" || "$HOMEBREW_COMMAND" = "tap" || + "$HOMEBREW_CASK_COMMAND" = "install" || "$HOMEBREW_CASK_COMMAND" = "upgrade" ]] then if [[ -z "$HOMEBREW_VERBOSE" ]] then @@ -351,5 +379,5 @@ else # Unshift command back into argument list (unless argument list was empty). [[ "$HOMEBREW_ARG_COUNT" -gt 0 ]] && set -- "$HOMEBREW_COMMAND" "$@" - { update-preinstall; exec "$HOMEBREW_RUBY_PATH" -W0 "$HOMEBREW_LIBRARY/Homebrew/brew.rb" "$@"; } + { update-preinstall; exec "$HOMEBREW_RUBY_PATH" $HOMEBREW_RUBY_WARNINGS "$HOMEBREW_LIBRARY/Homebrew/brew.rb" "$@"; } fi diff --git a/Library/Homebrew/cask/lib/hbc/artifact/installer.rb b/Library/Homebrew/cask/lib/hbc/artifact/installer.rb index 5cd388c7fe..8fa54c01ec 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/installer.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/installer.rb @@ -23,7 +23,7 @@ module Hbc def install_phase(command: nil, **_) ohai "Running #{self.class.dsl_key} script '#{path.relative_path_from(cask.staged_path)}'" FileUtils.chmod "+x", path unless path.executable? - command.run(path, **args) + command.run(path, **args, path: PATH.new(HOMEBREW_PREFIX/"bin", HOMEBREW_PREFIX/"sbin", ENV["PATH"])) end end diff --git a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb index 856ab2766f..31cede71a9 100644 --- a/Library/Homebrew/cask/lib/hbc/artifact/moved.rb +++ b/Library/Homebrew/cask/lib/hbc/artifact/moved.rb @@ -62,14 +62,16 @@ module Hbc raise CaskError, "It seems the #{self.class.english_name} source '#{target}' is not there." end - ohai "Moving #{self.class.english_name} '#{target.basename}' back to '#{source}'." + ohai "Backing #{self.class.english_name} '#{target.basename}' up to '#{source}'." source.dirname.mkpath if target.parent.writable? - FileUtils.move(target, source) + FileUtils.cp_r(target, source) else - command.run("/bin/mv", args: [target, source], sudo: true) + command.run("/bin/cp", args: ["-r", target, source], sudo: true) end + + delete(target, force: force, command: command, **options) end def delete(target, force: false, command: nil, **_) diff --git a/Library/Homebrew/cask/lib/hbc/cask_loader.rb b/Library/Homebrew/cask/lib/hbc/cask_loader.rb index c32b355847..74c39176d3 100644 --- a/Library/Homebrew/cask/lib/hbc/cask_loader.rb +++ b/Library/Homebrew/cask/lib/hbc/cask_loader.rb @@ -16,11 +16,11 @@ module Hbc end def initialize(content) - @content = content + @content = content.force_encoding("UTF-8") end def load - instance_eval(content.force_encoding("UTF-8"), __FILE__, __LINE__) + instance_eval(content, __FILE__, __LINE__) end private @@ -52,7 +52,7 @@ module Hbc @content = IO.read(path) - super + instance_eval(content, path) end private diff --git a/Library/Homebrew/cask/lib/hbc/cli/doctor.rb b/Library/Homebrew/cask/lib/hbc/cli/doctor.rb index a586a00ab1..32b927218b 100644 --- a/Library/Homebrew/cask/lib/hbc/cli/doctor.rb +++ b/Library/Homebrew/cask/lib/hbc/cli/doctor.rb @@ -24,6 +24,7 @@ module Hbc check_software_versions check_install_location check_staging_location + check_cached_downloads check_taps check_load_path check_environment_variables diff --git a/Library/Homebrew/cask/lib/hbc/system_command.rb b/Library/Homebrew/cask/lib/hbc/system_command.rb index a890c42e41..e5a7d9202b 100644 --- a/Library/Homebrew/cask/lib/hbc/system_command.rb +++ b/Library/Homebrew/cask/lib/hbc/system_command.rb @@ -37,7 +37,7 @@ module Hbc result end - def initialize(executable, args: [], sudo: false, input: [], print_stdout: false, print_stderr: true, must_succeed: false, **options) + def initialize(executable, args: [], sudo: false, input: [], print_stdout: false, print_stderr: true, must_succeed: false, path: ENV["PATH"], **options) @executable = executable @args = args @sudo = sudo @@ -47,6 +47,7 @@ module Hbc @must_succeed = must_succeed options.extend(HashValidator).assert_valid_keys(:chdir) @options = options + @path = path end def command @@ -55,7 +56,7 @@ module Hbc private - attr_reader :executable, :args, :input, :options, :processed_output, :processed_status + attr_reader :executable, :args, :input, :options, :processed_output, :processed_status, :path attr_predicate :sudo?, :print_stdout?, :print_stderr?, :must_succeed? @@ -83,12 +84,8 @@ module Hbc def each_output_line(&b) executable, *args = expanded_command - unless File.exist?(executable) - executable = which(executable, PATH.new(ENV["PATH"], HOMEBREW_PREFIX/"bin")) - end - raw_stdin, raw_stdout, raw_stderr, raw_wait_thr = - Open3.popen3([executable, executable], *args, **options) + Open3.popen3({ "PATH" => path }, [executable, executable], *args, **options) write_input_to(raw_stdin) raw_stdin.close_write diff --git a/Library/Homebrew/cmd/analytics.rb b/Library/Homebrew/cmd/analytics.rb index 0985f00b84..0f56cd675f 100644 --- a/Library/Homebrew/cmd/analytics.rb +++ b/Library/Homebrew/cmd/analytics.rb @@ -1,6 +1,6 @@ #: * `analytics` [`state`]: #: Display anonymous user behaviour analytics state. -#: Read more at . +#: Read more at . #: #: * `analytics` (`on`|`off`): #: Turn on/off Homebrew's analytics. diff --git a/Library/Homebrew/cmd/gist-logs.rb b/Library/Homebrew/cmd/gist-logs.rb index 630361ca2b..ab81a017e2 100644 --- a/Library/Homebrew/cmd/gist-logs.rb +++ b/Library/Homebrew/cmd/gist-logs.rb @@ -39,6 +39,16 @@ module Homebrew files["00.tap.out"] = { content: tap } end + if GitHub.api_credentials_type == :none + puts <<~EOS + You can create a new personal access token: + #{GitHub::ALL_SCOPES_URL} + and then set the new HOMEBREW_GITHUB_API_TOKEN as the authentication method. + + EOS + login! + end + # Description formatted to work well as page title when viewing gist if f.core_formula? descr = "#{f.name} on #{OS_VERSION} - Homebrew build logs" @@ -48,16 +58,6 @@ module Homebrew url = create_gist(files, descr) if ARGV.include?("--new-issue") || ARGV.switch?("n") - if GitHub.api_credentials_type == :none - puts <<~EOS - You can create a new personal access token: - #{GitHub::ALL_SCOPES_URL} - and then set the new HOMEBREW_GITHUB_API_TOKEN as the authentication method. - - EOS - login! - end - url = create_issue(f.tap, "#{f.name} failed to build on #{MacOS.full_version}", url) end diff --git a/Library/Homebrew/cmd/help.rb b/Library/Homebrew/cmd/help.rb index c85916f9b9..c85b92124a 100644 --- a/Library/Homebrew/cmd/help.rb +++ b/Library/Homebrew/cmd/help.rb @@ -16,7 +16,7 @@ HOMEBREW_HELP = <<~EOS.freeze Developers: brew create [URL [--no-fetch]] brew edit [FORMULA...] - https://docs.brew.sh/Formula-Cookbook.html + https://docs.brew.sh/Formula-Cookbook Further help: man brew diff --git a/Library/Homebrew/cmd/info.rb b/Library/Homebrew/cmd/info.rb index 1eb9fe9fed..a0e1cd4756 100644 --- a/Library/Homebrew/cmd/info.rb +++ b/Library/Homebrew/cmd/info.rb @@ -17,7 +17,7 @@ #: information on all installed formulae. #: #: See the docs for examples of using the JSON output: -#: +#: require "missing_formula" require "caveats" @@ -137,7 +137,12 @@ module Homebrew EOS end - kegs = f.installed_kegs.sort_by(&:version) + kegs = f.installed_kegs + heads, versioned = kegs.partition { |k| k.version.head? } + kegs = [ + *heads.sort_by { |k| -Tab.for_keg(k).time.to_i }, + *versioned.sort_by(&:version), + ] if kegs.empty? puts "Not installed" else diff --git a/Library/Homebrew/cmd/tap-info.rb b/Library/Homebrew/cmd/tap-info.rb index 3d995f4bcb..26daa1a8ae 100644 --- a/Library/Homebrew/cmd/tap-info.rb +++ b/Library/Homebrew/cmd/tap-info.rb @@ -13,7 +13,7 @@ #: Pass `--installed` to get information on installed taps. #: #: See the docs for examples of using the JSON output: -#: +#: require "tap" diff --git a/Library/Homebrew/cmd/update-report.rb b/Library/Homebrew/cmd/update-report.rb index 055c55a84f..2c4d3de0c5 100644 --- a/Library/Homebrew/cmd/update-report.rb +++ b/Library/Homebrew/cmd/update-report.rb @@ -35,7 +35,7 @@ module Homebrew ohai "Homebrew has enabled anonymous aggregate user behaviour analytics." puts <<~EOS #{Tty.bold}Read the analytics documentation (and how to opt-out) here: - #{Formatter.url("https://docs.brew.sh/Analytics.html")}#{Tty.reset} + #{Formatter.url("https://docs.brew.sh/Analytics")}#{Tty.reset} EOS diff --git a/Library/Homebrew/cmd/update.sh b/Library/Homebrew/cmd/update.sh index 7477845274..3f287340ff 100644 --- a/Library/Homebrew/cmd/update.sh +++ b/Library/Homebrew/cmd/update.sh @@ -390,12 +390,14 @@ EOS brew install curl fi - if ! git --version >/dev/null 2>&1 + if ! git --version &>/dev/null || + [[ -n "$HOMEBREW_SYSTEM_GIT_TOO_OLD" && + ! -x "$HOMEBREW_PREFIX/opt/git/bin/git" ]] then # we cannot install brewed git if homebrew/core is unavailable. [[ -d "$HOMEBREW_LIBRARY/Taps/homebrew/homebrew-core" ]] && brew install git unset GIT_EXECUTABLE - if ! git --version >/dev/null 2>&1 + if ! git --version &>/dev/null then odie "Git must be installed and in your PATH!" fi diff --git a/Library/Homebrew/cmd/upgrade.rb b/Library/Homebrew/cmd/upgrade.rb index debd5eea2c..1446025805 100644 --- a/Library/Homebrew/cmd/upgrade.rb +++ b/Library/Homebrew/cmd/upgrade.rb @@ -118,7 +118,7 @@ module Homebrew fi = FormulaInstaller.new(f) fi.options = options - fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.build_bottle?) + fi.build_bottle = ARGV.build_bottle? || (!f.bottled? && f.build.bottle?) fi.installed_on_request = !ARGV.named.empty? fi.link_keg ||= keg_was_linked if keg_had_linked_opt if tab diff --git a/Library/Homebrew/compat/dependency_collector.rb b/Library/Homebrew/compat/dependency_collector.rb index 84d5431f3e..8bea8a5aa9 100644 --- a/Library/Homebrew/compat/dependency_collector.rb +++ b/Library/Homebrew/compat/dependency_collector.rb @@ -52,14 +52,14 @@ class DependencyCollector output_deprecation(spec, "open-mpi") Dependency.new("open-mpi", tags) when :python, :python2 + output_deprecation(spec, "python@2") + Dependency.new("python@2", tags) + when :python3 output_deprecation(spec, "python") Dependency.new("python", tags) - when :python3 - output_deprecation(spec, "python3") - Dependency.new("python3", tags) when :emacs, :mysql, :perl, :postgresql, :rbenv, :ruby output_deprecation(spec) - Dependency.new(spec, tags) + Dependency.new(spec.to_s, tags) else super end diff --git a/Library/Homebrew/compat/requirements.rb b/Library/Homebrew/compat/requirements.rb index 38344c1fcd..3dd5c74795 100644 --- a/Library/Homebrew/compat/requirements.rb +++ b/Library/Homebrew/compat/requirements.rb @@ -84,16 +84,16 @@ end class PythonRequirement < Requirement fatal true satisfy do - odeprecated("PythonRequirement", "'depends_on \"python\"'") - which "python" + odeprecated("PythonRequirement", "'depends_on \"python@2\"'") + which "python2" end end class Python3Requirement < Requirement fatal true satisfy do - odeprecated("Python3Requirement", "'depends_on \"python3\"'") - which "python3" + odeprecated("Python3Requirement", "'depends_on \"python\"'") + which "python" end end diff --git a/Library/Homebrew/compat/requirements/language_module_requirement.rb b/Library/Homebrew/compat/requirements/language_module_requirement.rb index 5ddce7a66b..fc9dcc4428 100644 --- a/Library/Homebrew/compat/requirements/language_module_requirement.rb +++ b/Library/Homebrew/compat/requirements/language_module_requirement.rb @@ -38,9 +38,9 @@ class LanguageModuleRequirement < Requirement when :perl ["/usr/bin/env", "perl", "-e", "use #{@import_name}"] when :python - ["/usr/bin/env", "python", "-c", "import #{@import_name}"] + ["/usr/bin/env", "python2", "-c", "import #{@import_name}"] when :python3 - ["/usr/bin/env", "python3", "-c", "import #{@import_name}"] + ["/usr/bin/env", "python", "-c", "import #{@import_name}"] when :ruby ["/usr/bin/env", "ruby", "-rubygems", "-e", "require '#{@import_name}'"] end @@ -51,8 +51,8 @@ class LanguageModuleRequirement < Requirement when :lua then "luarocks-5.2 install" when :lua51 then "luarocks-5.1 install" when :perl then "cpan -i" - when :python then "pip install" - when :python3 then "pip3 install" + when :python then "pip3 install" + when :python3 then "pip install" when :ruby then "gem install" end end diff --git a/Library/Homebrew/dependency_collector.rb b/Library/Homebrew/dependency_collector.rb index 03a86d661e..74f42a6aaf 100644 --- a/Library/Homebrew/dependency_collector.rb +++ b/Library/Homebrew/dependency_collector.rb @@ -63,11 +63,19 @@ class DependencyCollector end def cvs_dep_if_needed(tags) - Dependency.new("cvs", tags) + Dependency.new("cvs", tags) unless which("cvs") end def xz_dep_if_needed(tags) - Dependency.new("xz", tags) + Dependency.new("xz", tags) unless which("xz") + end + + def unzip_dep_if_needed(tags) + Dependency.new("unzip", tags) unless which("unzip") + end + + def bzip2_dep_if_needed(tags) + Dependency.new("bzip2", tags) unless which("bzip2") end def ld64_dep_if_needed(*); end @@ -158,6 +166,8 @@ class DependencyCollector def parse_url_spec(url, tags) case File.extname(url) when ".xz" then xz_dep_if_needed(tags) + when ".zip" then unzip_dep_if_needed(tags) + when ".bz2" then bzip2_dep_if_needed(tags) when ".lha", ".lzh" then Dependency.new("lha", tags) when ".lz" then Dependency.new("lzip", tags) when ".rar" then Dependency.new("unrar", tags) diff --git a/Library/Homebrew/dev-cmd/create.rb b/Library/Homebrew/dev-cmd/create.rb index 122be25938..3963e5a7bc 100644 --- a/Library/Homebrew/dev-cmd/create.rb +++ b/Library/Homebrew/dev-cmd/create.rb @@ -167,7 +167,7 @@ class FormulaCreator def template <<~EOS - # Documentation: https://docs.brew.sh/Formula-Cookbook.html + # Documentation: https://docs.brew.sh/Formula-Cookbook # http://www.rubydoc.info/github/Homebrew/brew/master/Formula # PLEASE REMOVE ALL GENERATED COMMENTS BEFORE SUBMITTING YOUR PULL REQUEST! class #{Formulary.class_s(name)} < Formula diff --git a/Library/Homebrew/cmd/irb.rb b/Library/Homebrew/dev-cmd/irb.rb similarity index 57% rename from Library/Homebrew/cmd/irb.rb rename to Library/Homebrew/dev-cmd/irb.rb index 4cd3d4c9ec..700cbe0097 100644 --- a/Library/Homebrew/cmd/irb.rb +++ b/Library/Homebrew/dev-cmd/irb.rb @@ -1,11 +1,9 @@ -#: * `irb` [`--examples`]: +#: * `irb` [`--examples`] [`--pry`]: #: Enter the interactive Homebrew Ruby shell. #: #: If `--examples` is passed, several examples will be shown. - -require "formula" -require "keg" -require "irb" +#: If `--pry` is passed or HOMEBREW_PRY is set, pry will be +#: used instead of irb. class Symbol def f(*args) @@ -23,17 +21,33 @@ module Homebrew module_function def irb - $LOAD_PATH.unshift("#{HOMEBREW_LIBRARY_PATH}/cask/lib") - require "hbc" - if ARGV.include? "--examples" puts "'v8'.f # => instance of the v8 formula" puts ":hub.f.installed?" puts ":lua.f.methods - 1.methods" puts ":mpd.f.recursive_dependencies.reject(&:installed?)" + return + end + + if ARGV.pry? + Homebrew.install_gem_setup_path! "pry" + require "pry" + Pry.config.prompt_name = "brew" + else + require "irb" + end + + require "formula" + require "keg" + + $LOAD_PATH.unshift("#{HOMEBREW_LIBRARY_PATH}/cask/lib") + require "hbc" + + ohai "Interactive Homebrew Shell" + puts "Example commands available with: brew irb --examples" + if ARGV.pry? + Pry.start else - ohai "Interactive Homebrew Shell" - puts "Example commands available with: brew irb --examples" IRB.start end end diff --git a/Library/Homebrew/dev-cmd/linkage.rb b/Library/Homebrew/dev-cmd/linkage.rb index c3c87e30df..391a129365 100644 --- a/Library/Homebrew/dev-cmd/linkage.rb +++ b/Library/Homebrew/dev-cmd/linkage.rb @@ -14,7 +14,7 @@ #: 'keg.name' and forces a check on the dylibs. require "cache_store" -require "os/mac/linkage_checker" +require "linkage_checker" module Homebrew module_function diff --git a/Library/Homebrew/dev-cmd/prof.rb b/Library/Homebrew/dev-cmd/prof.rb new file mode 100755 index 0000000000..c7121f6e85 --- /dev/null +++ b/Library/Homebrew/dev-cmd/prof.rb @@ -0,0 +1,15 @@ +#: * `prof` []: +#: Run Homebrew with the Ruby profiler. +#: For example: +# brew prof readall + +module Homebrew + module_function + + def prof + Homebrew.install_gem_setup_path! "ruby-prof" + FileUtils.mkdir_p "prof" + brew_rb = (HOMEBREW_LIBRARY_PATH/"brew.rb").resolved_path + exec "ruby-prof", "--printer=multi", "--file=prof", brew_rb, "--", *ARGV + end +end diff --git a/Library/Homebrew/dev-cmd/ruby.rb b/Library/Homebrew/dev-cmd/ruby.rb new file mode 100755 index 0000000000..c5696d6bba --- /dev/null +++ b/Library/Homebrew/dev-cmd/ruby.rb @@ -0,0 +1,13 @@ +#: * `ruby` []: +#: Run a Ruby instance with Homebrew's libraries loaded. +#: For example: +# brew ruby -e "puts :gcc.f.deps" +# brew ruby script.rb + +module Homebrew + module_function + + def ruby + exec ENV["HOMEBREW_RUBY_PATH"], "-I#{HOMEBREW_LIBRARY_PATH}", "-rglobal", "-rdev-cmd/irb", *ARGV + end +end diff --git a/Library/Homebrew/dev-cmd/tap-new.rb b/Library/Homebrew/dev-cmd/tap-new.rb index 38cdb1c2e7..31299d2b0b 100644 --- a/Library/Homebrew/dev-cmd/tap-new.rb +++ b/Library/Homebrew/dev-cmd/tap-new.rb @@ -50,8 +50,7 @@ module Homebrew osx_image: xcode9.2 cache: directories: - - $HOME/.gem/ruby - - Library/Homebrew/vendor/bundle + - /usr/local/Homebrew/Library/Homebrew/vendor/bundle branches: only: - master diff --git a/Library/Homebrew/diagnostic.rb b/Library/Homebrew/diagnostic.rb index 8516f2b634..79f5b2f1d0 100644 --- a/Library/Homebrew/diagnostic.rb +++ b/Library/Homebrew/diagnostic.rb @@ -788,7 +788,7 @@ module Homebrew EOS end - return if ENV["CI"] || ENV["JENKINS_HOME"] + return if ENV["CI"] branch = coretap_path.git_branch return if branch.nil? || branch =~ /master/ @@ -822,7 +822,7 @@ module Homebrew return if linked.empty? inject_file_list linked.map(&:full_name), <<~EOS - Some keg-only formula are linked into the Cellar. + Some keg-only formulae are linked into the Cellar. Linking a keg-only formula, such as gettext, into the cellar with `brew link ` will cause other formulae to detect them during the `./configure` step. This may cause problems when compiling those @@ -835,18 +835,6 @@ module Homebrew EOS end - def check_for_large_cache - return unless HOMEBREW_CACHE.exist? - # CI can be expected to have a large cache. - return if ENV["CI"] || ENV["JENKINS_HOME"] - cache_size = HOMEBREW_CACHE.disk_usage - return unless cache_size > 2_147_483_648 - <<~EOS - Your HOMEBREW_CACHE is using #{disk_usage_readable(cache_size)} of disk space. - You may wish to consider running `brew cleanup`. - EOS - end - def check_for_other_frameworks # Other frameworks that are known to cause problems when present frameworks_to_check = %w[ @@ -884,7 +872,7 @@ module Homebrew return if missing.empty? <<~EOS - Some installed formula are missing dependencies. + Some installed formulae are missing dependencies. You should `brew install` the missing dependencies: brew install #{missing.sort_by(&:full_name) * " "} @@ -946,7 +934,7 @@ module Homebrew from your PATH variable. Python scripts will now install into #{HOMEBREW_PREFIX}/bin. You can delete anything, except 'Extras', from the #{HOMEBREW_PREFIX}/share/python - (and #{HOMEBREW_PREFIX}/share/python3) dir and install affected Python packages + (and #{HOMEBREW_PREFIX}/share/python@2) dir and install affected Python packages anew with `pip install --upgrade`. EOS end diff --git a/Library/Homebrew/download_strategy.rb b/Library/Homebrew/download_strategy.rb index feb518057f..e85661d76d 100644 --- a/Library/Homebrew/download_strategy.rb +++ b/Library/Homebrew/download_strategy.rb @@ -303,7 +303,11 @@ class AbstractFileDownloadStrategy < AbstractDownloadStrategy # We can't use basename_without_params, because given a URL like # https://example.com/download.php?file=foo-1.0.tar.gz # the extension we want is ".tar.gz", not ".php". - Pathname.new(@url).extname[/[^?]+/] + Pathname.new(@url).ascend do |path| + ext = path.extname[/[^?]+/] + return ext if ext + end + nil end end diff --git a/Library/Homebrew/exceptions.rb b/Library/Homebrew/exceptions.rb index 42c62338a8..20ad2a3788 100644 --- a/Library/Homebrew/exceptions.rb +++ b/Library/Homebrew/exceptions.rb @@ -343,8 +343,8 @@ class FormulaAmbiguousPythonError < RuntimeError def initialize(formula) super <<~EOS The version of python to use with the virtualenv in the `#{formula.full_name}` formula - cannot be guessed automatically. If the simultaneous use of python and python3 - is intentional, please add `:using => "python"` or `:using => "python3"` to + cannot be guessed automatically. If the simultaneous use of python and python@2 + is intentional, please add `:using => "python"` or `:using => "python@2"` to `virtualenv_install_with_resources` to resolve the ambiguity manually. EOS end diff --git a/Library/Homebrew/extend/ARGV.rb b/Library/Homebrew/extend/ARGV.rb index d9da014f05..2bc84620a4 100644 --- a/Library/Homebrew/extend/ARGV.rb +++ b/Library/Homebrew/extend/ARGV.rb @@ -267,6 +267,10 @@ module HomebrewArgvExtension include? "--fetch-HEAD" end + def pry? + include?("--pry") || !ENV["HOMEBREW_PRY"].nil? + end + # eg. `foo -ns -i --bar` has three switches, n, s and i def switch?(char) return false if char.length > 1 diff --git a/Library/Homebrew/extend/ENV.rb b/Library/Homebrew/extend/ENV.rb index 374be49b92..002220764a 100644 --- a/Library/Homebrew/extend/ENV.rb +++ b/Library/Homebrew/extend/ENV.rb @@ -28,9 +28,9 @@ module EnvActivation end def clear_sensitive_environment! - ENV.each_key do |key| + each_key do |key| next unless /(cookie|key|token|password)/i =~ key - ENV.delete key + delete key end end end diff --git a/Library/Homebrew/extend/os/mac/dependency_collector.rb b/Library/Homebrew/extend/os/mac/dependency_collector.rb index 108b6ccb2b..a7e5d7ffc8 100644 --- a/Library/Homebrew/extend/os/mac/dependency_collector.rb +++ b/Library/Homebrew/extend/os/mac/dependency_collector.rb @@ -18,6 +18,10 @@ class DependencyCollector Dependency.new("xz", tags) end + def zip_dep_if_needed(tags); end + + def bzip2_dep_if_needed(tags); end + def ld64_dep_if_needed(*) # Tiger's ld is too old to properly link some software return if MacOS.version > :tiger diff --git a/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb b/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb index d381aa7eaf..14be2f3b7e 100644 --- a/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb +++ b/Library/Homebrew/extend/os/mac/formula_cellar_checks.rb @@ -1,5 +1,5 @@ require "cache_store" -require "os/mac/linkage_checker" +require "linkage_checker" module FormulaCellarChecks def check_shadowed_headers diff --git a/Library/Homebrew/extend/os/mac/system_config.rb b/Library/Homebrew/extend/os/mac/system_config.rb index 7961347810..c0a28d3e95 100644 --- a/Library/Homebrew/extend/os/mac/system_config.rb +++ b/Library/Homebrew/extend/os/mac/system_config.rb @@ -23,6 +23,19 @@ class SystemConfig @ponk.join(", ") unless @ponk.empty? end + def describe_java + # java_home doesn't exist on all macOSs; it might be missing on older versions. + return "N/A" unless File.executable? "/usr/libexec/java_home" + + java_xml = Utils.popen_read("/usr/libexec/java_home", "--xml", "--failfast", err: :close) + return "N/A" unless $CHILD_STATUS.success? + javas = [] + REXML::XPath.each(REXML::Document.new(java_xml), "//key[text()='JVMVersion']/following-sibling::string") do |item| + javas << item.text + end + javas.uniq.join(", ") + end + def describe_xquartz return "N/A" unless MacOS::XQuartz.installed? "#{MacOS::XQuartz.version} => #{describe_path(MacOS::XQuartz.prefix)}" diff --git a/Library/Homebrew/formula.rb b/Library/Homebrew/formula.rb index 1355e5945c..521c626374 100644 --- a/Library/Homebrew/formula.rb +++ b/Library/Homebrew/formula.rb @@ -28,7 +28,7 @@ require "language/python" # @see SharedEnvExtension # @see FileUtils # @see Pathname -# @see https://docs.brew.sh/Formula-Cookbook.html Formula Cookbook +# @see https://docs.brew.sh/Formula-Cookbook Formula Cookbook # @see https://github.com/styleguide/ruby Ruby Style Guide # #
class Wget < Formula
@@ -2057,7 +2057,7 @@ class Formula
     # and you haven't passed or previously used any options on this formula.
     #
     # If you maintain your own repository, you can add your own bottle links.
-    # https://docs.brew.sh/Bottles.html
+    # https://docs.brew.sh/Bottles
     # You can ignore this block entirely if submitting to Homebrew/homebrew-core.
     # It'll be handled for you by the Brew Test Bot.
     #
@@ -2201,12 +2201,12 @@ class Formula
     # # `build.with?` or `build.without? "another_formula"`:
     # depends_on "postgresql" if build.without? "sqlite"
     #
-    # 
# Python 2.7:
-    # depends_on "python"
- #
# Python 2.7 but use system Python where possible
-    # depends_on "python" if MacOS.version <= :snow_leopard
- #
# Python 3.x if the `--with-python3` is given to `brew install example`
+    # 
# Python 3.x if the `--with-python` is given to `brew install example`
     # depends_on "python3" => :optional
+ #
# Python 2.7:
+    # depends_on "python@2"
+ #
# Python 2.7 but use system Python where possible
+    # depends_on "python@2" if MacOS.version <= :snow_leopard
def depends_on(dep) specs.each { |spec| spec.depends_on(dep) } end diff --git a/Library/Homebrew/formula_installer.rb b/Library/Homebrew/formula_installer.rb index a89da9ae9e..8d7f0aae1c 100644 --- a/Library/Homebrew/formula_installer.rb +++ b/Library/Homebrew/formula_installer.rb @@ -566,7 +566,7 @@ class FormulaInstaller def caveats return if only_deps? - audit_installed if ARGV.homebrew_developer? && !formula.keg_only? + audit_installed if ARGV.homebrew_developer? caveats = Caveats.new(formula) @@ -882,8 +882,10 @@ class FormulaInstaller end def audit_installed - problem_if_output(check_env_path(formula.bin)) - problem_if_output(check_env_path(formula.sbin)) + unless formula.keg_only? + problem_if_output(check_env_path(formula.bin)) + problem_if_output(check_env_path(formula.sbin)) + end super end diff --git a/Library/Homebrew/language/python.rb b/Library/Homebrew/language/python.rb index 3908f4b8f4..c41e22b5ce 100644 --- a/Library/Homebrew/language/python.rb +++ b/Library/Homebrew/language/python.rb @@ -9,16 +9,17 @@ module Language Version.create(version.to_s) end - def self.homebrew_site_packages(version = "2.7") + def self.homebrew_site_packages(version = "3.6") HOMEBREW_PREFIX/"lib/python#{version}/site-packages" end def self.each_python(build, &block) original_pythonpath = ENV["PYTHONPATH"] - ["python", "python3"].each do |python| - next if build.without? python + { "python@3" => "python3", "python@2" => "python2.7" }.each do |python_formula, python| + python_formula = Formulary.factory(python_formula) + next if build.without? python_formula.to_s version = major_minor_version python - ENV["PYTHONPATH"] = if Formulary.factory(python).installed? + ENV["PYTHONPATH"] = if python_formula.installed? nil else homebrew_site_packages(version) @@ -88,7 +89,7 @@ module Language # @param venv_root [Pathname, String] the path to the root of the virtualenv # (often `libexec/"venv"`) # @param python [String] which interpreter to use (e.g. "python" - # or "python3") + # or "python2") # @param formula [Formula] the active Formula # @return [Virtualenv] a {Virtualenv} instance def virtualenv_create(venv_root, python = "python", formula = self) @@ -114,8 +115,8 @@ module Language # Returns true if a formula option for the specified python is currently # active or if the specified python is required by the formula. Valid - # inputs are "python", "python3", :python, and :python3. Note that - # "with-python", "without-python", "with-python3", and "without-python3" + # inputs are "python", "python2", :python, and :python2. Note that + # "with-python", "without-python", "with-python@2", and "without-python@2" # formula options are handled correctly even if not associated with any # corresponding depends_on statement. # @api private @@ -127,16 +128,16 @@ module Language # Helper method for the common case of installing a Python application. # Creates a virtualenv in `libexec`, installs all `resource`s defined # on the formula, and then installs the formula. An options hash may be - # passed (e.g., :using => "python3") to override the default, guessed - # formula preference for python or python3, or to resolve an ambiguous - # case where it's not clear whether python or python3 should be the + # passed (e.g., :using => "python") to override the default, guessed + # formula preference for python or python2, or to resolve an ambiguous + # case where it's not clear whether python or python2 should be the # default guess. def virtualenv_install_with_resources(options = {}) python = options[:using] if python.nil? - wanted = %w[python python@2 python@3 python3].select { |py| needs_python?(py) } + wanted = %w[python python@2 python2 python3].select { |py| needs_python?(py) } raise FormulaAmbiguousPythonError, self if wanted.size > 1 - python = wanted.first || "python2.7" + python = wanted.first || "python" end venv = virtualenv_create(libexec, python.delete("@")) venv.pip_install resources @@ -153,7 +154,7 @@ module Language # @param venv_root [Pathname, String] the path to the root of the # virtualenv # @param python [String] which interpreter to use; i.e. "python" or - # "python3" + # "python2" def initialize(formula, venv_root, python) @formula = formula @venv_root = Pathname.new(venv_root) @@ -179,11 +180,11 @@ module Language end end - # Robustify symlinks to survive python3 patch upgrades + # Robustify symlinks to survive python patch upgrades @venv_root.find do |f| next unless f.symlink? next unless (rp = f.realpath.to_s).start_with? HOMEBREW_CELLAR - python = rp.include?("python3") ? "python3" : "python" + python = rp.include?("python2") ? "python2" : "python" new_target = rp.sub %r{#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix f.unlink f.make_symlink new_target @@ -191,7 +192,7 @@ module Language Pathname.glob(@venv_root/"lib/python*/orig-prefix.txt").each do |prefix_file| prefix_path = prefix_file.read - python = prefix_path.include?("python3") ? "python3" : "python" + python = prefix_path.include?("python2") ? "python2" : "python" prefix_path.sub! %r{^#{HOMEBREW_CELLAR}/#{python}/[^/]+}, Formula[python].opt_prefix prefix_file.atomic_write prefix_path end diff --git a/Library/Homebrew/os/mac/linkage_checker.rb b/Library/Homebrew/linkage_checker.rb similarity index 99% rename from Library/Homebrew/os/mac/linkage_checker.rb rename to Library/Homebrew/linkage_checker.rb index d2da4e5055..9b04dbc79a 100644 --- a/Library/Homebrew/os/mac/linkage_checker.rb +++ b/Library/Homebrew/linkage_checker.rb @@ -94,7 +94,7 @@ class LinkageChecker formula.build.without?(dep) end declared_deps = formula.deps.reject { |dep| filter_out.call(dep) }.map(&:name) - recursive_deps = keg.to_formula.runtime_dependencies.map { |dep| dep.to_formula.full_name } + recursive_deps = keg.to_formula.runtime_dependencies.map { |dep| dep.to_formula.name } declared_dep_names = declared_deps.map { |dep| dep.split("/").last } indirect_deps = [] undeclared_deps = [] diff --git a/Library/Homebrew/manpages/brew.1.md.erb b/Library/Homebrew/manpages/brew.1.md.erb index 508c90f2d4..618e050f63 100644 --- a/Library/Homebrew/manpages/brew.1.md.erb +++ b/Library/Homebrew/manpages/brew.1.md.erb @@ -76,7 +76,7 @@ scripts that reside somewhere in the `PATH`, named `brew-` or to create your own commands without modifying Homebrew's internals. Instructions for creating your own commands can be found in the docs: - + ## SPECIFYING FORMULAE @@ -183,6 +183,10 @@ can take several different forms: *Note:* Homebrew doesn't require permissions for any of the scopes. + * `HOMEBREW_INSTALL_BADGE`: + Text printed before the installation summary of each successful build. + Defaults to the beer emoji. + * `HOMEBREW_LOGS`: If set, Homebrew will use the given directory to store log files. @@ -193,12 +197,15 @@ can take several different forms: *Default:* the number of available CPU cores. * `HOMEBREW_NO_ANALYTICS`: - If set, Homebrew will not send analytics. See: + If set, Homebrew will not send analytics. See: * `HOMEBREW_NO_AUTO_UPDATE`: If set, Homebrew will not auto-update before running `brew install`, `brew upgrade` or `brew tap`. + * `HOMEBREW_NO_COLOR`: + If set, Homebrew will not print text with color added. + * `HOMEBREW_NO_EMOJI`: If set, Homebrew will not print the `HOMEBREW_INSTALL_BADGE` on a successful build. @@ -217,9 +224,8 @@ can take several different forms: If set, Homebrew will not use the GitHub API for e.g searches or fetching relevant issues on a failed install. - * `HOMEBREW_INSTALL_BADGE`: - Text printed before the installation summary of each successful build. - Defaults to the beer emoji. + * `HOMEBREW_PRY`: + If set, Homebrew will use `pry` for the `brew irb` command. * `HOMEBREW_SVN`: When exporting from Subversion, Homebrew will use `HOMEBREW_SVN` if set, diff --git a/Library/Homebrew/migrator.rb b/Library/Homebrew/migrator.rb index 8664d474be..503f889852 100644 --- a/Library/Homebrew/migrator.rb +++ b/Library/Homebrew/migrator.rb @@ -183,7 +183,7 @@ class Migrator end def migrate - oh1 "Migrating #{Formatter.identifier(oldname)} to #{Formatter.identifier(newname)}" + oh1 "Processing #{Formatter.identifier(oldname)} formula rename to #{Formatter.identifier(newname)}" lock unlink_oldname unlink_newname if new_cellar.exist? @@ -193,6 +193,14 @@ class Migrator link_oldname_opt link_newname unless old_linked_keg.nil? update_tabs + return unless formula.outdated? + opoo <<~EOS + #{Formatter.identifier(newname)} is outdated! + To avoid broken installations, as soon as possible please run: + brew upgrade + Or, if you're OK with a less reliable fix: + brew upgrade #{newname} + EOS rescue Interrupt ignore_interrupts { backup_oldname } rescue Exception => e # rubocop:disable Lint/RescueException @@ -226,7 +234,7 @@ class Migrator end end - oh1 "Moving #{Formatter.identifier(oldname)} children" + oh1 "Moving #{Formatter.identifier(oldname)} versions to #{new_cellar}" if new_cellar.exist? FileUtils.mv(old_cellar.children, new_cellar) else @@ -261,7 +269,7 @@ class Migrator end def unlink_newname - oh1 "Unlinking #{Formatter.identifier(newname)}" + oh1 "Temporarily unlinking #{Formatter.identifier(newname)}" new_cellar.subdirs.each do |d| keg = Keg.new(d) keg.unlink @@ -269,7 +277,7 @@ class Migrator end def link_newname - oh1 "Linking #{Formatter.identifier(newname)}" + oh1 "Relinking #{Formatter.identifier(newname)}" new_keg = Keg.new(new_linked_keg_record) # If old_keg wasn't linked then we just optlink a keg. @@ -288,7 +296,8 @@ class Migrator new_keg.remove_linked_keg_record if new_keg.linked? begin - new_keg.link + mode = OpenStruct.new(overwrite: true) + new_keg.link(mode) rescue Keg::ConflictError => e onoe "Error while executing `brew link` step on #{newname}" puts e diff --git a/Library/Homebrew/missing_formula.rb b/Library/Homebrew/missing_formula.rb index 146c3e984e..31dfa94efa 100644 --- a/Library/Homebrew/missing_formula.rb +++ b/Library/Homebrew/missing_formula.rb @@ -155,7 +155,7 @@ module Homebrew git -C "$(brew --repo #{tap})" show #{short_hash}^:#{relative_path} If you still use this formula consider creating your own tap: - https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap.html + https://docs.brew.sh/How-to-Create-and-Maintain-a-Tap EOS end end diff --git a/Library/Homebrew/os.rb b/Library/Homebrew/os.rb index d35a49dd7b..cc6c865375 100644 --- a/Library/Homebrew/os.rb +++ b/Library/Homebrew/os.rb @@ -17,10 +17,11 @@ module OS require "os/mac" # Don't tell people to report issues on unsupported versions of macOS. if !OS::Mac.prerelease? && !OS::Mac.outdated_release? - ISSUES_URL = "https://docs.brew.sh/Troubleshooting.html".freeze + ISSUES_URL = "https://docs.brew.sh/Troubleshooting".freeze end PATH_OPEN = "/usr/bin/open".freeze elsif OS.linux? + require "os/linux" ISSUES_URL = "https://github.com/Linuxbrew/brew/wiki/troubleshooting".freeze PATH_OPEN = "xdg-open".freeze end diff --git a/Library/Homebrew/os/linux.rb b/Library/Homebrew/os/linux.rb new file mode 100644 index 0000000000..e5af301b2f --- /dev/null +++ b/Library/Homebrew/os/linux.rb @@ -0,0 +1,28 @@ +module OS + # Define OS::Mac on Linux for formula API compatibility. + module Mac + module_function + + ::MacOS = self # rubocop:disable Naming/ConstantName + + def prefer_64_bit? + Hardware::CPU.is_64_bit? + end + + def version + Version::NULL + end + + def full_version + Version::NULL + end + + module Xcode + module_function + + def version + Version::NULL + end + end + end +end diff --git a/Library/Homebrew/os/mac/xcode.rb b/Library/Homebrew/os/mac/xcode.rb index f977a066da..2e4ec63819 100644 --- a/Library/Homebrew/os/mac/xcode.rb +++ b/Library/Homebrew/os/mac/xcode.rb @@ -131,7 +131,7 @@ module OS xcodebuild_output = Utils.popen_read(xcodebuild_path, "-version") next unless $CHILD_STATUS.success? - xcode_version = xcodebuild_output[/Xcode (\d(\.\d)*)/, 1] + xcode_version = xcodebuild_output[/Xcode (\d+(\.\d+)*)/, 1] return xcode_version if xcode_version # Xcode 2.x's xcodebuild has a different version string diff --git a/Library/Homebrew/rubocops.rb b/Library/Homebrew/rubocops.rb index 8dc49bb459..f1923ee654 100644 --- a/Library/Homebrew/rubocops.rb +++ b/Library/Homebrew/rubocops.rb @@ -2,6 +2,7 @@ require_relative "./rubocops/bottle_block_cop" require_relative "./rubocops/formula_desc_cop" require_relative "./rubocops/components_order_cop" require_relative "./rubocops/components_redundancy_cop" +require_relative "./rubocops/dependency_order_cop" require_relative "./rubocops/homepage_cop" require_relative "./rubocops/text_cop" require_relative "./rubocops/caveats_cop" diff --git a/Library/Homebrew/rubocops/dependency_order_cop.rb b/Library/Homebrew/rubocops/dependency_order_cop.rb new file mode 100644 index 0000000000..1d1481f280 --- /dev/null +++ b/Library/Homebrew/rubocops/dependency_order_cop.rb @@ -0,0 +1,166 @@ +require_relative "./extend/formula_cop" + +module RuboCop + module Cop + module NewFormulaAudit + # This cop checks for correct order of `depends_on` in a Formula + # + # precedence order: + # build-time > run-time > normal > recommended > optional + class DependencyOrder < FormulaCop + def audit_formula(_node, _class_node, _parent_class_node, body_node) + check_dependency_nodes_order(body_node) + [:devel, :head, :stable].each do |block_name| + block = find_block(body_node, block_name) + next unless block + check_dependency_nodes_order(block.body) + end + end + + def check_dependency_nodes_order(parent_node) + return if parent_node.nil? + dependency_nodes = fetch_depends_on_nodes(parent_node) + ordered = dependency_nodes.sort { |a, b| sort_by_dependency_name(a, b) } + ordered = sort_dependencies_by_type(ordered) + sort_conditional_dependencies!(ordered) + verify_order_in_source(ordered) + end + + # Match all `depends_on` nodes among childnodes of given parent node + def fetch_depends_on_nodes(parent_node) + parent_node.each_child_node.select { |x| depends_on_node?(x) } + end + + def sort_by_dependency_name(a, b) + a_name = dependency_name(a) + b_name = dependency_name(b) + if a_name < b_name + -1 + elsif a_name > b_name + 1 + else + 0 + end + end + + # Separate dependencies according to precedence order: + # build-time > run-time > normal > recommended > optional + def sort_dependencies_by_type(dependency_nodes) + ordered = [] + ordered.concat(dependency_nodes.select { |dep| buildtime_dependency? dep }.to_a) + ordered.concat(dependency_nodes.select { |dep| runtime_dependency? dep }.to_a) + ordered.concat(dependency_nodes.reject { |dep| negate_normal_dependency? dep }.to_a) + ordered.concat(dependency_nodes.select { |dep| recommended_dependency? dep }.to_a) + ordered.concat(dependency_nodes.select { |dep| optional_dependency? dep }.to_a) + end + + # `depends_on :apple if build.with? "foo"` should always be defined + # after `depends_on :foo` + # This method reorders dependencies array according to above rule + def sort_conditional_dependencies!(ordered) + length = ordered.size + idx = 0 + while idx < length + idx1, idx2 = nil + ordered.each_with_index do |dep, pos| + idx = pos+1 + match_nodes = build_with_dependency_name(dep) + idx1 = pos if match_nodes && !match_nodes.empty? + next unless idx1 + idx2 = nil + ordered.drop(idx1+1).each_with_index do |dep2, pos2| + next unless match_nodes.index(dependency_name(dep2)) + idx2 = pos2 if idx2.nil? || pos2 > idx2 + end + break if idx2 + end + insert_after!(ordered, idx1, idx2+idx1) if idx2 + end + ordered + end + + # Verify actual order of sorted `depends_on` nodes in source code + # Else raise RuboCop problem + def verify_order_in_source(ordered) + ordered.each_with_index do |dependency_node_1, idx| + l1 = line_number(dependency_node_1) + dependency_node_2 = nil + ordered.drop(idx+1).each do |node2| + l2 = line_number(node2) + dependency_node_2 = node2 if l2 < l1 + end + next unless dependency_node_2 + @offensive_nodes = [dependency_node_1, dependency_node_2] + component_problem dependency_node_1, dependency_node_2 + end + end + + # Node pattern method to match + # `depends_on` variants + def_node_matcher :depends_on_node?, <<~EOS + {(if _ (send nil? :depends_on ...) nil?) + (send nil? :depends_on ...)} + EOS + + def_node_search :buildtime_dependency?, "(sym :build)" + + def_node_search :recommended_dependency?, "(sym :recommended)" + + def_node_search :runtime_dependency?, "(sym :run)" + + def_node_search :optional_dependency?, "(sym :optional)" + + def_node_search :negate_normal_dependency?, "(sym {:build :recommended :run :optional})" + + # Node pattern method to extract `name` in `depends_on :name` + def_node_search :dependency_name_node, <<~EOS + {(send nil? :depends_on {(hash (pair $_ _)) $({str sym} _)}) + (if _ (send nil? :depends_on {(hash (pair $_ _)) $({str sym} _)}) nil?)} + EOS + + # Node pattern method to extract `name` in `build.with? :name` + def_node_search :build_with_dependency_node, <<~EOS + (send (send nil? :build) :with? $({str sym} _)) + EOS + + def insert_after!(arr, idx1, idx2) + arr.insert(idx2+1, arr.delete_at(idx1)) + end + + def build_with_dependency_name(node) + match_nodes = build_with_dependency_node(node) + match_nodes = match_nodes.to_a.delete_if(&:nil?) + match_nodes.map { |n| string_content(n) } unless match_nodes.empty? + end + + def dependency_name(dependency_node) + match_node = dependency_name_node(dependency_node).to_a.first + string_content(match_node) if match_node + end + + def autocorrect(_node) + succeeding_node = @offensive_nodes[0] + preceding_node = @offensive_nodes[1] + lambda do |corrector| + reorder_components(corrector, succeeding_node, preceding_node) + end + end + + private + + def component_problem(c1, c2) + offending_node(c1) + problem "dependency \"#{dependency_name(c1)}\" (line #{line_number(c1)}) should be put before dependency \"#{dependency_name(c2)}\" (line #{line_number(c2)})" + end + + # Reorder two nodes in the source, using the corrector instance in autocorrect method + def reorder_components(corrector, node1, node2) + indentation = " " * (start_column(node2) - line_start_column(node2)) + line_breaks = "\n" + corrector.insert_before(node2.source_range, node1.source + line_breaks + indentation) + corrector.remove(range_with_surrounding_space(range: node1.source_range, side: :left)) + end + end + end + end +end diff --git a/Library/Homebrew/system_config.rb b/Library/Homebrew/system_config.rb index 28eecf951f..63e162075e 100644 --- a/Library/Homebrew/system_config.rb +++ b/Library/Homebrew/system_config.rb @@ -131,16 +131,10 @@ class SystemConfig end def describe_java - # java_home doesn't exist on all macOSs; it might be missing on older versions. - return "N/A" unless File.executable? "/usr/libexec/java_home" - - java_xml = Utils.popen_read("/usr/libexec/java_home", "--xml", "--failfast", err: :close) + return "N/A" unless which "java" + java_version = Utils.popen_read("java", "-version") return "N/A" unless $CHILD_STATUS.success? - javas = [] - REXML::XPath.each(REXML::Document.new(java_xml), "//key[text()='JVMVersion']/following-sibling::string") do |item| - javas << item.text - end - javas.uniq.join(", ") + java_version[/java version "([\d\._]+)"/, 1] || "N/A" end def describe_git diff --git a/Library/Homebrew/test/ENV_spec.rb b/Library/Homebrew/test/ENV_spec.rb index 07f6cdb6b0..8b39e52d78 100644 --- a/Library/Homebrew/test/ENV_spec.rb +++ b/Library/Homebrew/test/ENV_spec.rb @@ -141,6 +141,20 @@ shared_examples EnvActivation do expect(subject["MAKEFLAGS"]).to eq("-j4") end + + describe "#clear_sensitive_environment!" do + it "removes sensitive environment variables" do + subject["SECRET_TOKEN"] = "password" + subject.clear_sensitive_environment! + expect(subject).not_to include("SECRET_TOKEN") + end + + it "leaves non-sensitive environment variables alone" do + subject["FOO"] = "bar" + subject.clear_sensitive_environment! + expect(subject["FOO"]).to eq "bar" + end + end end describe Stdenv do diff --git a/Library/Homebrew/test/Gemfile b/Library/Homebrew/test/Gemfile index b6d1405ff6..34ba794a89 100644 --- a/Library/Homebrew/test/Gemfile +++ b/Library/Homebrew/test/Gemfile @@ -5,6 +5,7 @@ require_relative "../constants" gem "parallel_tests" gem "rspec" gem "rspec-its", require: false +gem "rspec-retry", require: false gem "rspec-wait", require: false gem "rubocop", HOMEBREW_RUBOCOP_VERSION diff --git a/Library/Homebrew/test/Gemfile.lock b/Library/Homebrew/test/Gemfile.lock index 47f51e56bb..0d43174e98 100644 --- a/Library/Homebrew/test/Gemfile.lock +++ b/Library/Homebrew/test/Gemfile.lock @@ -1,7 +1,7 @@ GEM remote: https://rubygems.org/ specs: - ast (2.3.0) + ast (2.4.0) codecov (0.1.10) json simplecov @@ -9,29 +9,31 @@ GEM diff-lcs (1.3) docile (1.1.5) json (2.1.0) - parallel (1.12.0) - parallel_tests (2.17.0) + parallel (1.12.1) + parallel_tests (2.21.2) parallel - parser (2.4.0.2) - ast (~> 2.3) + parser (2.5.0.2) + ast (~> 2.4.0) powerpack (0.1.1) rainbow (3.0.0) - rspec (3.6.0) - rspec-core (~> 3.6.0) - rspec-expectations (~> 3.6.0) - rspec-mocks (~> 3.6.0) - rspec-core (3.6.0) - rspec-support (~> 3.6.0) - rspec-expectations (3.6.0) + rspec (3.7.0) + rspec-core (~> 3.7.0) + rspec-expectations (~> 3.7.0) + rspec-mocks (~> 3.7.0) + rspec-core (3.7.1) + rspec-support (~> 3.7.0) + rspec-expectations (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) + rspec-support (~> 3.7.0) rspec-its (1.2.0) rspec-core (>= 3.0.0) rspec-expectations (>= 3.0.0) - rspec-mocks (3.6.0) + rspec-mocks (3.7.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.6.0) - rspec-support (3.6.0) + rspec-support (~> 3.7.0) + rspec-retry (0.5.6) + rspec-core (> 3.3, < 3.8) + rspec-support (3.7.1) rspec-wait (0.0.9) rspec (>= 3, < 4) rubocop (0.52.1) @@ -58,9 +60,10 @@ DEPENDENCIES parallel_tests rspec rspec-its + rspec-retry rspec-wait rubocop (= 0.52.1) simplecov BUNDLED WITH - 1.16.0 + 1.16.1 diff --git a/Library/Homebrew/test/cask/cli/reinstall_spec.rb b/Library/Homebrew/test/cask/cli/reinstall_spec.rb index 3737a7a701..f2d1322ad5 100644 --- a/Library/Homebrew/test/cask/cli/reinstall_spec.rb +++ b/Library/Homebrew/test/cask/cli/reinstall_spec.rb @@ -13,7 +13,8 @@ describe Hbc::CLI::Reinstall, :cask do Already downloaded: .*local-caffeine--1.2.3.zip ==> Verifying checksum for Cask local-caffeine ==> Uninstalling Cask local-caffeine - ==> Moving App 'Caffeine.app' back to '.*Caffeine.app'. + ==> Backing App 'Caffeine.app' up to '.*Caffeine.app'. + ==> Removing App '.*Caffeine.app'. ==> Purging files for version 1.2.3 of Cask local-caffeine ==> Installing Cask local-caffeine ==> Moving App 'Caffeine.app' to '.*Caffeine.app'. diff --git a/Library/Homebrew/test/cask/cli/uninstall_spec.rb b/Library/Homebrew/test/cask/cli/uninstall_spec.rb index 322394de4c..38ee1bb73a 100644 --- a/Library/Homebrew/test/cask/cli/uninstall_spec.rb +++ b/Library/Homebrew/test/cask/cli/uninstall_spec.rb @@ -12,7 +12,8 @@ describe Hbc::CLI::Uninstall, :cask do output = Regexp.new <<~EOS ==> Uninstalling Cask local-caffeine - ==> Moving App 'Caffeine.app' back to '.*Caffeine.app'. + ==> Backing App 'Caffeine.app' up to '.*Caffeine.app'. + ==> Removing App '.*Caffeine.app'. ==> Purging files for version 1.2.3 of Cask local-caffeine EOS diff --git a/Library/Homebrew/test/cask/dsl_spec.rb b/Library/Homebrew/test/cask/dsl_spec.rb index d3bb462642..993c03bac8 100644 --- a/Library/Homebrew/test/cask/dsl_spec.rb +++ b/Library/Homebrew/test/cask/dsl_spec.rb @@ -75,6 +75,7 @@ describe Hbc::DSL, :cask do it "may use deprecated DSL version hash syntax" do allow(ENV).to receive(:[]).with("HOMEBREW_DEVELOPER").and_return(nil) + allow(ENV).to receive(:[]).with("HOMEBREW_NO_COLOR").and_return(nil) expect(cask.token).to eq("with-dsl-version") expect(cask.url.to_s).to eq("http://example.com/TestCask.dmg") diff --git a/Library/Homebrew/test/cmd/migrate_spec.rb b/Library/Homebrew/test/cmd/migrate_spec.rb index 18c94fa018..83dee0cb65 100644 --- a/Library/Homebrew/test/cmd/migrate_spec.rb +++ b/Library/Homebrew/test/cmd/migrate_spec.rb @@ -29,7 +29,7 @@ describe "brew migrate", :integration_test do install_and_rename_coretap_formula "testball1", "testball2" expect { brew "migrate", "testball1" } - .to output(/Migrating testball1 to testball2/).to_stdout + .to output(/Processing testball1 formula rename to testball2/).to_stdout .and not_to_output.to_stderr .and be_a_success end diff --git a/Library/Homebrew/test/cmd/search_spec.rb b/Library/Homebrew/test/cmd/search_spec.rb index 36ddde3e1d..aec23ae4c1 100644 --- a/Library/Homebrew/test/cmd/search_spec.rb +++ b/Library/Homebrew/test/cmd/search_spec.rb @@ -25,7 +25,7 @@ describe "brew search", :integration_test do .and be_a_success end - it "falls back to a GitHub tap search when no formula is found", :needs_network do + it "falls back to a GitHub tap search when no formula is found", :needs_network, retry: 3 do expect { brew "search", "caskroom/cask/firefox" } .to output(/firefox/).to_stdout .and output(/Searching/).to_stderr diff --git a/Library/Homebrew/test/cmd/services_spec.rb b/Library/Homebrew/test/cmd/services_spec.rb index 669e84e5f8..fb40ce0b21 100644 --- a/Library/Homebrew/test/cmd/services_spec.rb +++ b/Library/Homebrew/test/cmd/services_spec.rb @@ -1,4 +1,4 @@ -describe "brew services", :integration_test, :needs_macos, :needs_network do +describe "brew services", :integration_test, :needs_macos, :needs_network, retry: 3 do it "allows controlling services" do setup_remote_tap "homebrew/services" diff --git a/Library/Homebrew/test/dev-cmd/pull_spec.rb b/Library/Homebrew/test/dev-cmd/pull_spec.rb index 984ac08439..cc66df7830 100644 --- a/Library/Homebrew/test/dev-cmd/pull_spec.rb +++ b/Library/Homebrew/test/dev-cmd/pull_spec.rb @@ -6,7 +6,7 @@ describe "brew pull", :integration_test do .and be_a_failure end - it "fetches a patch from a GitHub commit or pull request and applies it", :needs_network do + it "fetches a patch from a GitHub commit or pull request and applies it", :needs_network, retry: 3 do CoreTap.instance.path.cd do system "git", "init" system "git", "checkout", "-b", "new-branch" diff --git a/Library/Homebrew/test/dev-cmd/ruby_spec.rb b/Library/Homebrew/test/dev-cmd/ruby_spec.rb new file mode 100644 index 0000000000..e05bccc833 --- /dev/null +++ b/Library/Homebrew/test/dev-cmd/ruby_spec.rb @@ -0,0 +1,13 @@ +describe "brew ruby", :integration_test do + it "executes ruby code with Homebrew's libraries loaded" do + expect { brew "ruby", "-e", "exit 0" } + .to be_a_success + .and not_to_output.to_stdout + .and not_to_output.to_stderr + + expect { brew "ruby", "-e", "exit 1" } + .to be_a_failure + .and not_to_output.to_stdout + .and not_to_output.to_stderr + end +end diff --git a/Library/Homebrew/test/download_strategies_spec.rb b/Library/Homebrew/test/download_strategies_spec.rb index 06d6fa855c..7ad070fc44 100644 --- a/Library/Homebrew/test/download_strategies_spec.rb +++ b/Library/Homebrew/test/download_strategies_spec.rb @@ -209,6 +209,19 @@ describe CurlDownloadStrategy do it "parses the opts and sets the corresponding args" do expect(subject.send(:_curl_opts)).to eq(["--user", "download:123456"]) end + + describe "#tarball_path" do + subject { described_class.new(name, resource).tarball_path } + + context "when URL ends with file" do + it { is_expected.to eq(HOMEBREW_CACHE/"foo-.tar.gz") } + end + + context "when URL file is in middle" do + let(:url) { "http://example.com/foo.tar.gz/from/this/mirror" } + it { is_expected.to eq(HOMEBREW_CACHE/"foo-.tar.gz") } + end + end end describe DownloadStrategyDetector do diff --git a/Library/Homebrew/test/language_module_requirement_spec.rb b/Library/Homebrew/test/language_module_requirement_spec.rb index 6ca8cbd0e8..74d092bac9 100644 --- a/Library/Homebrew/test/language_module_requirement_spec.rb +++ b/Library/Homebrew/test/language_module_requirement_spec.rb @@ -31,10 +31,6 @@ describe LanguageModuleRequirement, :needs_compat do it "does not satisfy invalid dependencies" do expect(described_class.new(:python, "notapackage")).not_to be_satisfied end - - it "satisfies valid dependencies" do - expect(described_class.new(:python, "datetime")).to be_satisfied - end end context "when the language is Ruby" do diff --git a/Library/Homebrew/test/os/linux/dependency_collector_spec.rb b/Library/Homebrew/test/os/linux/dependency_collector_spec.rb new file mode 100644 index 0000000000..a8f85b4cac --- /dev/null +++ b/Library/Homebrew/test/os/linux/dependency_collector_spec.rb @@ -0,0 +1,53 @@ +require "dependency_collector" + +describe DependencyCollector do + alias_matcher :be_a_build_requirement, :be_build + + after(:each) do + described_class.clear_cache + end + + describe "#add" do + resource = Resource.new + + context "when xz, unzip, and bzip2 are not available" do + it "creates a resource dependency from a '.xz' URL" do + resource.url("http://example.com/foo.xz") + allow_any_instance_of(Object).to receive(:which).with("xz") + expect(subject.add(resource)).to eq(Dependency.new("xz", [:build])) + end + + it "creates a resource dependency from a '.zip' URL" do + resource.url("http://example.com/foo.zip") + allow_any_instance_of(Object).to receive(:which).with("unzip") + expect(subject.add(resource)).to eq(Dependency.new("unzip", [:build])) + end + + it "creates a resource dependency from a '.bz2' URL" do + resource.url("http://example.com/foo.tar.bz2") + allow_any_instance_of(Object).to receive(:which).with("bzip2") + expect(subject.add(resource)).to eq(Dependency.new("bzip2", [:build])) + end + end + + context "when xz, zip, and bzip2 are available" do + it "does not create a resource dependency from a '.xz' URL" do + resource.url("http://example.com/foo.xz") + allow_any_instance_of(Object).to receive(:which).with("xz").and_return(Pathname.new("foo")) + expect(subject.add(resource)).to be nil + end + + it "does not create a resource dependency from a '.zip' URL" do + resource.url("http://example.com/foo.zip") + allow_any_instance_of(Object).to receive(:which).with("unzip").and_return(Pathname.new("foo")) + expect(subject.add(resource)).to be nil + end + + it "does not create a resource dependency from a '.bz2' URL" do + resource.url("http://example.com/foo.tar.bz2") + allow_any_instance_of(Object).to receive(:which).with("bzip2").and_return(Pathname.new("foo")) + expect(subject.add(resource)).to be nil + end + end + end +end diff --git a/Library/Homebrew/test/os/mac/dependency_collector_spec.rb b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb index 5d260ebf71..a8fe8ba54c 100644 --- a/Library/Homebrew/test/os/mac/dependency_collector_spec.rb +++ b/Library/Homebrew/test/os/mac/dependency_collector_spec.rb @@ -36,6 +36,18 @@ describe DependencyCollector do expect(subject.add(resource)).to be nil end + specify "Resource dependency from a '.zip' URL" do + resource = Resource.new + resource.url("http://example.com/foo.zip") + expect(subject.add(resource)).to be nil + end + + specify "Resource dependency from a '.bz2' URL" do + resource = Resource.new + resource.url("http://example.com/foo.tar.bz2") + expect(subject.add(resource)).to be nil + end + specify "Resource dependency from a '.git' URL" do resource = Resource.new resource.url("git://example.com/foo/bar.git") diff --git a/Library/Homebrew/test/rubocops/dependency_order_cop_spec.rb b/Library/Homebrew/test/rubocops/dependency_order_cop_spec.rb new file mode 100644 index 0000000000..92ca724750 --- /dev/null +++ b/Library/Homebrew/test/rubocops/dependency_order_cop_spec.rb @@ -0,0 +1,75 @@ +require_relative "../../rubocops/dependency_order_cop" + +describe RuboCop::Cop::NewFormulaAudit::DependencyOrder do + subject(:cop) { described_class.new } + + context "depends_on" do + it "wrong conditional depends_on order" do + expect_offense(<<~RUBY) + class Foo < Formula + homepage "http://example.com" + url "http://example.com/foo-1.0.tgz" + depends_on "apple" if build.with? "foo" + depends_on "foo" => :optional + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 5) should be put before dependency "apple" (line 4) + end + RUBY + end + + it "wrong alphabetical depends_on order" do + expect_offense(<<~RUBY) + class Foo < Formula + homepage "http://example.com" + url "http://example.com/foo-1.0.tgz" + depends_on "foo" + depends_on "bar" + ^^^^^^^^^^^^^^^^ dependency "bar" (line 5) should be put before dependency "foo" (line 4) + end + RUBY + end + + it "wrong conditional depends_on order" do + expect_offense(<<~RUBY) + class Foo < Formula + homepage "http://example.com" + url "http://example.com/foo-1.0.tgz" + head do + depends_on "apple" if build.with? "foo" + depends_on "bar" + ^^^^^^^^^^^^^^^^ dependency "bar" (line 6) should be put before dependency "apple" (line 5) + depends_on "foo" => :optional + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 7) should be put before dependency "apple" (line 5) + end + depends_on "apple" if build.with? "foo" + depends_on "foo" => :optional + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dependency "foo" (line 10) should be put before dependency "apple" (line 9) + end + RUBY + end + end + + context "autocorrect" do + it "wrong conditional depends_on order" do + source = <<~EOS + class Foo < Formula + homepage "http://example.com" + url "http://example.com/foo-1.0.tgz" + depends_on "apple" if build.with? "foo" + depends_on "foo" => :optional + end + EOS + + correct_source = <<~EOS + class Foo < Formula + homepage "http://example.com" + url "http://example.com/foo-1.0.tgz" + depends_on "foo" => :optional + depends_on "apple" if build.with? "foo" + end + EOS + + corrected_source = autocorrect_source(source) + expect(corrected_source).to eq(correct_source) + end + end +end diff --git a/Library/Homebrew/test/spec_helper.rb b/Library/Homebrew/test/spec_helper.rb index be184b6e09..cba530736a 100644 --- a/Library/Homebrew/test/spec_helper.rb +++ b/Library/Homebrew/test/spec_helper.rb @@ -2,6 +2,7 @@ require "find" require "pathname" require "rspec/its" require "rspec/wait" +require "rspec/retry" require "rubocop" require "rubocop/rspec/support" require "set" @@ -74,6 +75,10 @@ RSpec.configure do |config| skip "Requires network connection." unless ENV["HOMEBREW_TEST_ONLINE"] end + config.before(:each, :needs_svn) do + skip "Requires subversion." unless which "svn" + end + config.around(:each) do |example| def find_files Find.find(TEST_TMPDIR) diff --git a/Library/Homebrew/test/utils/svn_spec.rb b/Library/Homebrew/test/utils/svn_spec.rb index 503d285f3e..f527a614f2 100644 --- a/Library/Homebrew/test/utils/svn_spec.rb +++ b/Library/Homebrew/test/utils/svn_spec.rb @@ -30,7 +30,7 @@ describe Utils do expect(described_class.svn_remote_exists(HOMEBREW_CACHE/"install")).to be_falsey end - it "returns true when remote exists", :needs_network do + it "returns true when remote exists", :needs_network, :needs_svn do remote = "http://github.com/Homebrew/install" svn = HOMEBREW_SHIMS_PATH/"scm/svn" diff --git a/Library/Homebrew/test/utils/tty_spec.rb b/Library/Homebrew/test/utils/tty_spec.rb index 3ba89b6fdb..e6c9168f31 100644 --- a/Library/Homebrew/test/utils/tty_spec.rb +++ b/Library/Homebrew/test/utils/tty_spec.rb @@ -53,7 +53,7 @@ describe Tty do allow($stdout).to receive(:tty?).and_return(true) end - it "returns an empty string for all colors" do + it "returns ANSI escape codes for colors" do expect(subject.to_s).to eq("") expect(subject.red.to_s).to eq("\033[31m") expect(subject.green.to_s).to eq("\033[32m") @@ -63,5 +63,17 @@ describe Tty do expect(subject.cyan.to_s).to eq("\033[36m") expect(subject.default.to_s).to eq("\033[39m") end + + it "returns an empty string for all colors when HOMEBREW_NO_COLOR is set" do + ENV["HOMEBREW_NO_COLOR"] = "1" + expect(subject.to_s).to eq("") + expect(subject.red.to_s).to eq("") + expect(subject.green.to_s).to eq("") + expect(subject.yellow.to_s).to eq("") + expect(subject.blue.to_s).to eq("") + expect(subject.magenta.to_s).to eq("") + expect(subject.cyan.to_s).to eq("") + expect(subject.default.to_s).to eq("") + end end end diff --git a/Library/Homebrew/utils/analytics.rb b/Library/Homebrew/utils/analytics.rb index 9766c14db3..adef3e811d 100644 --- a/Library/Homebrew/utils/analytics.rb +++ b/Library/Homebrew/utils/analytics.rb @@ -40,7 +40,7 @@ module Utils end # Send analytics. Don't send or store any personally identifiable information. - # https://docs.brew.sh/Analytics.html + # https://docs.brew.sh/Analytics # https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide # https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters if ENV["HOMEBREW_ANALYTICS_DEBUG"] diff --git a/Library/Homebrew/utils/tty.rb b/Library/Homebrew/utils/tty.rb index e872e64601..81d5f00d7b 100644 --- a/Library/Homebrew/utils/tty.rb +++ b/Library/Homebrew/utils/tty.rb @@ -59,7 +59,9 @@ module Tty end def to_s - return "" unless $stdout.tty? + if ENV["HOMEBREW_NO_COLOR"] || !$stdout.tty? + return "" + end current_escape_sequence ensure reset_escape_sequence! diff --git a/README.md b/README.md index 5513089690..240774ed2e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Homebrew [![GitHub release](https://img.shields.io/github/release/Homebrew/brew.svg)](https://github.com/Homebrew/brew/releases) -Features, usage and installation instructions are [summarised on the homepage](https://brew.sh). Terminology (e.g. the difference between a Cellar, Tap, Cask and so forth) is [explained here](docs/Formula-Cookbook.md#homebrew-terminology). +Features, usage and installation instructions are [summarised on the homepage](https://brew.sh). Terminology (e.g. the difference between a Cellar, Tap, Cask and so forth) is [explained here](https://docs.brew.sh/Formula-Cookbook#homebrew-terminology). ## What Packages Are Available? 1. Type `brew search` for a list. @@ -14,7 +14,7 @@ Features, usage and installation instructions are [summarised on the homepage](h ## Troubleshooting First, please run `brew update` and `brew doctor`. -Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting.html). +Second, read the [Troubleshooting Checklist](https://docs.brew.sh/Troubleshooting). **If you don't read these it will take us far longer to help you with your problem.** @@ -26,7 +26,7 @@ We'd love you to contribute to Homebrew. First, please read our [Contribution Gu We explicitly welcome contributions from people who have never contributed to open-source before: we were all beginners once! We can help build on a partially working pull request with the aim of getting it merged. We are also actively seeking to diversify our contributors and especially welcome contributions from women from all backgrounds and people of colour. -A good starting point for contributing is running `brew audit --strict` with some of the packages you use (e.g. `brew audit --strict wget` if you use `wget`) and then read through the warnings, try to fix them until `brew audit --strict` shows no results and [submit a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request.html). If no formulae you use have warnings you can run `brew audit --strict` without arguments to have it run on all packages and pick one. +A good starting point for contributing is running `brew audit --strict` with some of the packages you use (e.g. `brew audit --strict wget` if you use `wget`) and then read through the warnings, try to fix them until `brew audit --strict` shows no results and [submit a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request). If no formulae you use have warnings you can run `brew audit --strict` without arguments to have it run on all packages and pick one. Alternatively, for something more substantial, check out one of the issues labeled `help wanted` in [Homebrew/brew](https://github.com/homebrew/brew/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22) or [Homebrew/homebrew-core](https://github.com/homebrew/homebrew-core/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22). diff --git a/bin/brew b/bin/brew index 881ace1ec1..b3a4d62720 100755 --- a/bin/brew +++ b/bin/brew @@ -47,7 +47,7 @@ HOMEBREW_LIBRARY="$HOMEBREW_REPOSITORY/Library" # Whitelist and copy to HOMEBREW_* all variables previously mentioned in # manpage or used elsewhere by Homebrew. for VAR in AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY BINTRAY_USER BINTRAY_KEY \ - BROWSER EDITOR GIT PATH VISUAL \ + BROWSER EDITOR GIT NO_COLOR PATH VISUAL \ GITHUB_USER GITHUB_PASSWORD GITHUB_TOKEN do # Skip if variable value is empty. @@ -66,9 +66,9 @@ then FILTERED_ENV=() # Filter all but the specific variables. - for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS SSH_AUTH_SOCK SUDO_ASKPASS \ + for VAR in HOME SHELL PATH TERM LOGNAME USER CI TRAVIS TRAVIS_SUDO SSH_AUTH_SOCK SUDO_ASKPASS \ http_proxy https_proxy ftp_proxy no_proxy all_proxy HTTPS_PROXY FTP_PROXY ALL_PROXY \ - "${!HOMEBREW_@}" "${!TRAVIS_@}" "${!JENKINS_@}" + "${!HOMEBREW_@}" do # Skip if variable value is empty. [[ -z "${!VAR}" ]] && continue diff --git a/docs/.well-known/acme-challenge/CgQNmjNTd6fUriinp4XpuRI5PBGp7zEXbEEsQceSD0k b/docs/.well-known/acme-challenge/CgQNmjNTd6fUriinp4XpuRI5PBGp7zEXbEEsQceSD0k deleted file mode 100644 index d3ba42ff4b..0000000000 --- a/docs/.well-known/acme-challenge/CgQNmjNTd6fUriinp4XpuRI5PBGp7zEXbEEsQceSD0k +++ /dev/null @@ -1 +0,0 @@ -CgQNmjNTd6fUriinp4XpuRI5PBGp7zEXbEEsQceSD0k.unNjkXuFqjKx4BO8gem4nzeMm1tSZxPPeBjNqQhFCqQ diff --git a/docs/Acceptable-Formulae.md b/docs/Acceptable-Formulae.md index df799bb1a7..5f6e6fcc62 100644 --- a/docs/Acceptable-Formulae.md +++ b/docs/Acceptable-Formulae.md @@ -38,15 +38,6 @@ tarballs should include the version in the filename whenever possible. We don’t accept software without a tagged version because they regularly break due to upstream changes and we can’t provide [bottles](Bottles.md) for them. -### Bindings -First check that there is not already a binding available via -[`gem`](https://rubygems.org/) or [`pip`](http://www.pip-installer.org/) -etc. - -If not, then put bindings in the formula they bind to. This is more -useful to people. Just install the stuff! Having to faff around with -foo-ruby, foo-perl etc. is a bad user experience. - ### Niche (or self-submitted) stuff The software in question must: diff --git a/docs/Common-Issues.md b/docs/Common-Issues.md index 01ab4e8065..a3a31ce80b 100644 --- a/docs/Common-Issues.md +++ b/docs/Common-Issues.md @@ -80,7 +80,7 @@ When running `brew upgrade`, you see something like this: $ brew upgrade Error: undefined method `include?' for nil:NilClass Please report this bug: - https://docs.brew.sh/Troubleshooting.html + https://docs.brew.sh/Troubleshooting /usr/local/Library/Homebrew/formula.rb:393:in `canonical_name' /usr/local/Library/Homebrew/formula.rb:425:in `factory' /usr/local/Library/Contributions/examples/brew-upgrade.rb:7 diff --git a/docs/Formula-Cookbook.md b/docs/Formula-Cookbook.md index c4db9e9f8b..1f2b2e89e2 100644 --- a/docs/Formula-Cookbook.md +++ b/docs/Formula-Cookbook.md @@ -344,7 +344,7 @@ If you have already forked Homebrew on GitHub, then you can manually push (just git push https://github.com/myname/homebrew-core/ ``` -Now, [open a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request.html) for your changes. +Now, [open a pull request](https://docs.brew.sh/How-To-Open-a-Homebrew-Pull-Request) for your changes. * One formula per commit; one commit per formula * Keep merge commits out of the pull request diff --git a/docs/Gems,-Eggs-and-Perl-Modules.md b/docs/Gems,-Eggs-and-Perl-Modules.md index 4a1b1ba44b..14d38003b3 100644 --- a/docs/Gems,-Eggs-and-Perl-Modules.md +++ b/docs/Gems,-Eggs-and-Perl-Modules.md @@ -11,8 +11,8 @@ Starting with OS X Lion (10.7), you need `sudo` to install to these like so: `sudo gem install`, `sudo easy_install` or `sudo cpan -i`. An option to avoid sudo is to use an access control list: -`chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/2.7/site-packages`, -for example, will let you add packages to Python 2.7 as yourself. That +`chmod +a 'user:YOUR_NAME_HERE allow add_subdirectory,add_file,delete_child,directory_inherit' /Library/Python/3.6/site-packages`, +for example, will let you add packages to Python 3.6 as yourself. That is probably safer than changing the group ownership of the directory. ### So why was I using sudo? @@ -29,14 +29,14 @@ Rather than changing the rights on `/Library/Python`, we recommend the following options: ### With a brewed Python -Note, `easy_install` is deprecated. We install `pip` (or `pip3` for -Python 3) along with python/python3. +Note, `easy_install` is deprecated. We install `pip` (or `pip2` for +Python 2) along with python/python2. We set up distutils such that `pip install` will always put modules in `$(brew --prefix)/lib/pythonX.Y/site-packages` and scripts in `$(brew --prefix)/share/python`. Therefore, you won’t need sudo! -Do `brew info python` or `brew info python3` for precise information +Do `brew info python` or `brew info python@2` for precise information about the paths. Note, a brewed Python still searches for modules in `/Library/Python/X.Y/site-packages` and also in `~/Library/Python/X.Y/lib/python/site-packages`. diff --git a/docs/Homebrew-and-Python.md b/docs/Homebrew-and-Python.md index eb96e57583..3a4c0052ae 100644 --- a/docs/Homebrew-and-Python.md +++ b/docs/Homebrew-and-Python.md @@ -4,33 +4,34 @@ This page describes how Python is handled in Homebrew for users. See [Python for Homebrew should work with any [CPython](https://stackoverflow.com/questions/2324208/is-there-any-difference-between-cpython-and-python) and defaults to the macOS system Python. -Homebrew provides formulae to brew a more up-to-date Python 2.7.x and 3.x. +Homebrew provides formulae to brew 3.x and a more up-to-date Python 2.7.x. -**Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team can only provide limited support. +**Important:** If you choose to install a Python which isn't either of these two (system Python or brewed Python), the Homebrew team cannot support any breakage that may occur. -## Python 2.x or Python 3.x -Homebrew provides one formula for Python 2.7.x and another for Python 3.x. The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict: -* `python` points to the macOS system Python (with no manual PATH modification) +## Python 3.x or Python 2.x +Homebrew provides one formula for Python 3.x (`python`) and another for Python 2.7.x (`python@2`). + +The executables are organized as follows so that Python 2 and Python 3 can both be installed without conflict: +* `python` and `python3` point to Homebrew's Python 3.x (if installed) otherwise the macOS system Python * `python2` points to Homebrew's Python 2.7.x (if installed) -* `python3` points to Homebrew's Python 3.x (if installed) +* `pip` and `pip3` point to Homebrew's Python 3.x's pip (if installed) * `pip2` points to Homebrew's Python 2.7.x's pip (if installed) -* `pip3` points to Homebrew's Python 3.x's pip (if installed) ([Wondering which one to choose?](https://wiki.python.org/moin/Python2orPython3)) ## Setuptools, Pip, etc. -The Python formulae install [pip](http://www.pip-installer.org) (as `pip2` or `pip3`) and [Setuptools](https://pypi.python.org/pypi/setuptools). +The Python formulae install [pip](http://www.pip-installer.org) (as `pip` or `pip2`) and [Setuptools](https://pypi.python.org/pypi/setuptools). Setuptools can be updated via pip, without having to re-brew Python: ```sh -python2 -m pip install --upgrade setuptools +python -m pip install --upgrade setuptools ``` Similarly, pip can be used to upgrade itself via: ```sh -python2 -m pip install --upgrade pip +python -m pip install --upgrade pip ``` ### Note on `pip install --user` @@ -39,7 +40,7 @@ The normal `pip install --user` is disabled for brewed Python. This is because o A possible workaround (which puts executable scripts in `~/Library/Python/./bin`) is: ```sh -python2 -m pip install --user --install-option="--prefix=" +python -m pip install --user --install-option="--prefix=" ``` ## `site-packages` and the `PYTHONPATH` @@ -49,12 +50,12 @@ The `site-packages` is a directory that contains Python modules (especially bind $(brew --prefix)/lib/pythonX.Y/site-packages ``` -So, for Python 2.7.x, you'll find it at `/usr/local/lib/python2.7/site-packages`. +So, for Python 3.6.x, you'll find it at `/usr/local/lib/python3.6/site-packages`. -Python 2.7 also searches for modules in: +Python 3.6 also searches for modules in: -- `/Library/Python/2.7/site-packages` -- `~/Library/Python/2.7/lib/python/site-packages` +- `/Library/Python/3.6/site-packages` +- `~/Library/Python/3.6/lib/python/site-packages` Homebrew's `site-packages` directory is first created if (1) any Homebrew formula with Python bindings are installed, or (2) upon `brew install python`. @@ -62,9 +63,7 @@ Homebrew's `site-packages` directory is first created if (1) any Homebrew formul The reasoning for this location is to preserve your modules between (minor) upgrades or re-installations of Python. Additionally, Homebrew has a strict policy never to write stuff outside of the `brew --prefix`, so we don't spam your system. ## Homebrew-provided Python bindings -Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python3` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options `.) - -Homebrew builds bindings against the first `python` (and `python-config`) in your `PATH`. (Check with `which python`). +Some formulae provide Python bindings. Sometimes a `--with-python` or `--with-python@2` option has to be passed to `brew install` in order to build the Python bindings. (Check with `brew options `.) **Warning!** Python may crash (see [Common Issues](Common-Issues.md)) if you `import ` from a brewed Python if you ran `brew install ` against the system Python. If you decide to switch to the brewed Python, then reinstall all formulae with Python bindings (e.g. `pyside`, `wxwidgets`, `pygtk`, `pygobject`, `opencv`, `vtk` and `boost-python`). @@ -89,4 +88,4 @@ Homebrew will still install Python modules into Homebrew's `site-packages` and * Virtualenv has a `--system-site-packages` switch to allow "global" (i.e. Homebrew's) `site-packages` to be accessible from within the virtualenv. ## Why is Homebrew's Python being installed as a dependency? -Formulae that declare an unconditional dependency on the `"python"` or `"python3"` formulae are bottled against Homebrew's Python 2.7.x or 3.x and require it to be installed. +Formulae that declare an unconditional dependency on the `"python"` or `"python@2"` formulae are bottled against Homebrew's Python 3.x or 2.7.x and require it to be installed. diff --git a/docs/Manpage.md b/docs/Manpage.md index 9205183767..ff33466856 100644 --- a/docs/Manpage.md +++ b/docs/Manpage.md @@ -39,7 +39,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `analytics` [`state`]: Display anonymous user behaviour analytics state. - Read more at . + Read more at . * `analytics` (`on`|`off`): Turn on/off Homebrew's analytics. @@ -212,7 +212,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note information on all installed formulae. See the docs for examples of using the JSON output: - + * `install` [`--debug`] [`--env=`(`std`|`super`)] [`--ignore-dependencies`|`--only-dependencies`] [`--cc=``compiler`] [`--build-from-source`|`--force-bottle`] [`--devel`|`--HEAD`] [`--keep-tmp`] [`--build-bottle`] [`--force`] [`--verbose`] `formula` [`options` ...]: Install `formula`. @@ -280,11 +280,6 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--git` (or `-g`) is passed, Homebrew will create a Git repository, useful for creating patches to the software. - * `irb` [`--examples`]: - Enter the interactive Homebrew Ruby shell. - - If `--examples` is passed, several examples will be shown. - * `leaves`: Show installed formulae that are not dependencies of another installed formula. @@ -493,7 +488,7 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note Pass `--installed` to get information on installed taps. See the docs for examples of using the JSON output: - + * `tap-pin` `tap`: Pin `tap`, prioritizing its formulae over core when formula names are supplied @@ -761,6 +756,13 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note * `formula` `formula`: Display the path where `formula` is located. + * `irb` [`--examples`] [`--pry`]: + Enter the interactive Homebrew Ruby shell. + + If `--examples` is passed, several examples will be shown. + If `--pry` is passed or HOMEBREW_PRY is set, pry will be + used instead of irb. + * `linkage` [`--test`] [`--reverse`] `formula`: Checks the library links of an installed formula. @@ -782,6 +784,10 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note Additionally, the date used in new manpages will match those in the existing manpages (to allow comparison without factoring in the date). + * `prof` [`ruby options`]: + Run Homebrew with the Ruby profiler. + For example: + * `pull` [`--bottle`] [`--bump`] [`--clean`] [`--ignore-whitespace`] [`--resolve`] [`--branch-okay`] [`--no-pbcopy`] [`--no-publish`] [`--warn-on-publish-failure`] [`--bintray-org=``bintray-org`] [`--test-bot-user=``test-bot-user`] `patch-source` [`patch-source`]: Gets a patch from a GitHub commit or pull request and applies it to Homebrew. @@ -839,6 +845,10 @@ With `--verbose` or `-v`, many commands print extra debugging information. Note If `--markdown` is passed, output as a Markdown list. + * `ruby` [`ruby options`]: + Run a Ruby instance with Homebrew's libraries loaded. + For example: + * `tap-new` `user``/``repo`: Generate the template files for a new tap. @@ -914,7 +924,7 @@ scripts that reside somewhere in the `PATH`, named `brew-``cmdname` or to create your own commands without modifying Homebrew's internals. Instructions for creating your own commands can be found in the docs: - + ## SPECIFYING FORMULAE @@ -1021,6 +1031,10 @@ can take several different forms: *Note:* Homebrew doesn't require permissions for any of the scopes. + * `HOMEBREW_INSTALL_BADGE`: + Text printed before the installation summary of each successful build. + Defaults to the beer emoji. + * `HOMEBREW_LOGS`: If set, Homebrew will use the given directory to store log files. @@ -1031,12 +1045,15 @@ can take several different forms: *Default:* the number of available CPU cores. * `HOMEBREW_NO_ANALYTICS`: - If set, Homebrew will not send analytics. See: + If set, Homebrew will not send analytics. See: * `HOMEBREW_NO_AUTO_UPDATE`: If set, Homebrew will not auto-update before running `brew install`, `brew upgrade` or `brew tap`. + * `HOMEBREW_NO_COLOR`: + If set, Homebrew will not print text with color added. + * `HOMEBREW_NO_EMOJI`: If set, Homebrew will not print the `HOMEBREW_INSTALL_BADGE` on a successful build. @@ -1055,9 +1072,8 @@ can take several different forms: If set, Homebrew will not use the GitHub API for e.g searches or fetching relevant issues on a failed install. - * `HOMEBREW_INSTALL_BADGE`: - Text printed before the installation summary of each successful build. - Defaults to the beer emoji. + * `HOMEBREW_PRY`: + If set, Homebrew will use `pry` for the `brew irb` command. * `HOMEBREW_SVN`: When exporting from Subversion, Homebrew will use `HOMEBREW_SVN` if set, diff --git a/docs/New-Maintainer-Checklist.md b/docs/New-Maintainer-Checklist.md index 72abf2ddb8..cb4919d697 100644 --- a/docs/New-Maintainer-Checklist.md +++ b/docs/New-Maintainer-Checklist.md @@ -39,8 +39,8 @@ A few requests: own fork. - if still in doubt please ask for help and we'll help you out - please read: - - https://docs.brew.sh/Brew-Test-Bot-For-Core-Contributors.html - - https://docs.brew.sh/Maintainer-Guidelines.html + - https://docs.brew.sh/Brew-Test-Bot-For-Core-Contributors + - https://docs.brew.sh/Maintainer-Guidelines - anything else you haven't read on https://docs.brew.sh How does that sound? diff --git a/docs/Python-for-Formula-Authors.md b/docs/Python-for-Formula-Authors.md index a530dbef7d..e4d50e5246 100644 --- a/docs/Python-for-Formula-Authors.md +++ b/docs/Python-for-Formula-Authors.md @@ -16,16 +16,16 @@ Applications should unconditionally bundle all of their Python-language dependen ### Python declarations +Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python"`. These apps **must** work with the current Homebrew Python 3.x formula. + Applications that are compatible with Python 2 **should** use the Apple-provided system Python in `/usr/bin` on systems that provide Python 2.7. To do this, declare: ```ruby -depends_on "python" if MacOS.version <= :snow_leopard +depends_on "python@2" if MacOS.version <= :snow_leopard ``` No explicit Python dependency is needed on recent OS versions since `/usr/bin` is always in `PATH` for Homebrew formulae; on Leopard and older, the `python` in `PATH` is used if it's at least version 2.7, or else Homebrew's Python 2.7.x is installed. -Formulae for apps that require Python 3 **should** declare an unconditional dependency on `"python3"`. These apps **must** work with the current Homebrew Python 3.x formula. - ### Installing Applications should be installed into a Python [virtualenv](https://virtualenv.pypa.io/en/stable/) environment rooted in `libexec`. This prevents the app's Python modules from contaminating the system site-packages and vice versa. @@ -66,7 +66,7 @@ This is exactly the same as writing: ```ruby def install # Create a virtualenv in `libexec`. If your app needs Python 3, make sure that - # `depends_on "python3"` is declared, and use `virtualenv_create(libexec, "python3")`. + # `depends_on "python"` is declared, and use `virtualenv_create(libexec, "python")`. venv = virtualenv_create(libexec) # Install all of the resources declared on the formula into the virtualenv. venv.pip_install resources @@ -121,9 +121,9 @@ in case you need to do different things for different resources. ## Bindings -Build bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). +To add bindings for Python 3, please add `depends_on "python"`. -To add bindings for Python 3, please add `depends_on "python3" => :optional` and make the bindings conditional on `build.with?("python3")`. +Build Python 2 bindings with the system Python by default (don't add an option) and they should be usable with any binary-compatible Python. If that isn't the case, it's an upstream bug; [here's some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). ### Dependencies @@ -153,7 +153,9 @@ Sometimes we have to `inreplace` a `Makefile` to use our prefix for the Python b ### Python declarations -Python 2 libraries do not need a `depends_on "python"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). Libraries built for Python 3 should include `depends_on "python3"`, which will bottle against Homebrew's Python 3.x. If a library supports both Python 2.x and Python 3.x, the `"python3"` dependency should be `:optional`. Python 2.x libraries must function when they are installed against either the system Python or brewed Python. +Libraries built for Python 3 should include `depends_on "python"`, which will bottle against Homebrew's Python 3.x. Python 2.x libraries must function when they are installed against either the system Python or brewed Python. + +Python 2 libraries do not need a `depends_on "python@2"` declaration; they will be built with the system Python, but should still be usable with any other Python 2.7. If this is not the case, it is an upstream bug; [here is some advice for resolving it](http://blog.tim-smith.us/2015/09/python-extension-modules-os-x/). ### Installing diff --git a/docs/Versions.md b/docs/Versions.md index 282640a1f0..2fa3f563f5 100644 --- a/docs/Versions.md +++ b/docs/Versions.md @@ -11,8 +11,11 @@ Versioned formulae we include in [homebrew/core](https://github.com/homebrew/hom * Versioned formulae should differ in major/minor (not patch) versions from the current stable release. This is because patch versions indicate bug or security updates and we want to ensure you apply security updates. * Upstream should have a release branch for the versioned formulae version and still make security updates for that version, when necessary. For example, [PHP 5.5 was not a supported version but PHP 7.2 was](http://php.net/supported-versions.php) in January 2018 * Formulae that depend on versioned formulae must not depend on the same formulae at two different versions twice in their recursive dependencies. For example, if you depend on `openssl@1.0` and `foo`, and `foo` depends on `openssl` then you must instead use `openssl`. -* Versioned formulae should only be linkable at the same time as their non-versioned counterpart if the upstream project provides support for it, e.g. using suffixed binaries. If this is not possible, use `keg_only :versioned_formula` to allow users to have multiple versions installed at once. Note `keg_only :versioned_formula` should not `post_install` anything in the `HOMEBREW_PREFIX` that conflicts with or duplicates the non-versioned counterpart (or other versioned formulae). For example, a `node@6` formula should not install its `npm` into `HOMEBREW_PREFIX` like the `node` formula does. +* Versioned formulae should only be linkable at the same time as their non-versioned counterpart if the upstream project provides support for it, e.g. using suffixed binaries. If this is not possible, use `keg_only :versioned_formula` to allow users to have multiple versions installed at once. +* A `keg_only :versioned_formula` should not `post_install` anything in the `HOMEBREW_PREFIX` that conflicts with or duplicates the non-versioned counterpart (or other versioned formulae). For example, a `node@6` formula should not install its `npm` into `HOMEBREW_PREFIX` like the `node` formula does. * Versioned formulae submitted should be expected to be used by a large number of people. If this ceases to be the case: they will be removed. We will aim not to remove those in the [top 1000 `install_on_request` formulae](https://brew.sh/analytics/install-on-request/). +* Versioned formulae should not have `resource`s that require security updates. For example, a `node@6` formula should not have an `npm` resource but instead rely on the `npm` provided by the upstream tarball. +* Versioned formulae should be as similar as possible and sensible to the unversioned formulae. Creating or updating a versioned formula should be a chance to ask questions of the unversioned formula e.g. can some unused or useless options be removed or made default? * No more than five versions of a formula (including the non-versioned one) will be supported at any given time, regardless of usage. When removing formulae that violate this we will aim to do so based on usage and support status rather than age. Homebrew's versions are not intended to be used for any old versions you personally require for your project. You should create your own [tap](How-to-Create-and-Maintain-a-Tap.md) for formulae you or your organisation wish to control the versioning of or those that do not meet the above standards. Software that has regular API or ABI breaking releases still needs to meet all the above requirements; that a `brew upgrade` has broken something for you is not an argument for us to add and maintain a formula for you. diff --git a/docs/_config.yml b/docs/_config.yml index 210d0b0d40..93518c6c55 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -1,17 +1,32 @@ -include: [.well-known] -exclude: [bin, vendor, CNAME, Gemfile, Gemfile.lock] +title: Homebrew Documentation +description: Documentation for the missing package manager for macOS. -# Same as GitHub Pages -# https://help.github.com/articles/using-jekyll-with-pages#troubleshooting -# Disable despite enabled on GitHub Pages for supported plugins to work. -# safe: true -kramdown: - input: GFM - hard_wrap: false -lsi: false -highlighter: rouge +exclude: + - bin + - CNAME + - Gemfile* + - vendor -gems: +plugins: - jekyll-feed - jekyll-sitemap - jekyll-seo-tag + +permalink: :title + +defaults: + - scope: + path: "" + values: + image: /img/homebrew-256x256.png + +logo: /img/homebrew-256x256.png + +github: + repository_nwo: Homebrew/brew + +twitter: + username: MacHomebrew + +facebook: + publisher: https://www.facebook.com/machomebrew/ diff --git a/docs/_layouts/analytics.html b/docs/_layouts/analytics.html new file mode 100644 index 0000000000..b62e424c58 --- /dev/null +++ b/docs/_layouts/analytics.html @@ -0,0 +1,22 @@ +--- +layout: base +--- +{% assign json = site.data.analytics[page.category] %} +

{{ page.category_pretty }} Events

+

{{ json.start_date }} - {{ json.end_date }}

+ + + + + + + +{% for item in json.items %} + + + + + + +{% endfor %} +
{% if page.category == "os-version" %}Version{% else %}Formula{% endif %}Events%
#{{ item.number }}{% if page.category == "os-version" %}{{ item.os_version }}{% else %}{{ item.formula }}{% endif %}{{ item.count }}{{ item.percent }}%
diff --git a/docs/_layouts/base.html b/docs/_layouts/base.html index ee631bda54..422e98bed8 100644 --- a/docs/_layouts/base.html +++ b/docs/_layouts/base.html @@ -1,21 +1,29 @@ +{% assign t = site.data.locales[page.lang][page.lang] %} {% if page.title %} - {{ page.title }} — Homebrew - {% elsif page.direction == "rtl" %} - {{ page.subtitle }} — Homebrew + {{ page.title }} — {{ site.title }} + {% elsif t.subtitle %} + {% if page.direction == "rtl" %} + {{ site.title }} — {{ t.subtitle }} {% else %} - Homebrew — {{ page.subtitle }} + {{ t.subtitle }} — {{ t.subtitle }} + {% endif %} + {% else %} + {{ site.title }} {% endif %} {% seo title=false %} {% feed_meta %} - + + {% if site.url == "http://localhost:4000" %} + + {% endif %} - {% for lang in site.langs %} - {% if lang.langcode == "en" %} + {% if site.data.locales %} + {% assign locales = site.data.locales | sort %} + {% for locale in locales %} + {% assign lang = locale[0] %} + {% if lang == "en" %} {% else %} - + {% endif %} {% endfor %} + {% endif %}