diff --git a/.rubocop.yml b/.rubocop.yml index 9232ccd..2dc853f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,9 @@ require: 'rubocop-cask' AllCops: TargetRubyVersion: 2.0 + Exclude: + - 'Casks/**/*.rb' + - 'Formula/**/*.rb' Metrics/AbcSize: Enabled: false @@ -20,10 +23,6 @@ Metrics/PerceivedComplexity: Metrics/ModuleLength: CountComments: false - Exclude: - - 'lib/hbc/locations.rb' - - 'lib/hbc/macos.rb' - - 'lib/hbc/utils.rb' Style/ClassAndModuleChildren: EnforcedStyle: compact diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..b8d52f5 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,41 @@ +language: ruby + +sudo: false + +env: + global: + - LANG=en_US.UTF-8 + - LANGUAGE=en_US.UTF-8 + - LC_ALL=en_US.UTF-8 + +matrix: + include: + - env: OSX=10.11 HOMEBREW_RUBY=2.0.0 + os: osx + osx_image: xcode7.3 + rvm: system + - env: OSX=10.10 HOMEBREW_RUBY=2.0.0 + os: osx + osx_image: xcode7.1 + rvm: system + fast_finish: true + +branches: + only: + - master + +cache: + directories: + - $HOME/.gem + +before_install: + - . ci/travis/before_install.sh + +install: + - . ci/travis/install.sh + +before_script: + - . ci/travis/before_script.sh + +script: + - . ci/travis/script.sh diff --git a/Casks/.rubocop.yml b/Casks/.rubocop.yml deleted file mode 100644 index 90d78bc..0000000 --- a/Casks/.rubocop.yml +++ /dev/null @@ -1 +0,0 @@ -require: rubocop-cask diff --git a/Gemfile b/Gemfile old mode 100644 new mode 100755 diff --git a/Gemfile.lock b/Gemfile.lock old mode 100644 new mode 100755 index 913838f..f407fc0 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -14,19 +14,19 @@ GEM powerpack (0.1.1) public_suffix (2.0.2) rainbow (2.1.0) - rake (11.2.2) + rake (10.0.4) rspec (3.0.0) rspec-core (~> 3.0.0) rspec-expectations (~> 3.0.0) rspec-mocks (~> 3.0.0) - rspec-core (3.0.4) + rspec-core (3.0.2) rspec-support (~> 3.0.0) - rspec-expectations (3.0.4) + rspec-expectations (3.0.2) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.0.0) - rspec-mocks (3.0.4) + rspec-mocks (3.0.2) rspec-support (~> 3.0.0) - rspec-support (3.0.4) + rspec-support (3.0.2) rubocop (0.41.2) parser (>= 2.3.1.1, < 3.0) powerpack (~> 0.1) diff --git a/readme.md b/README.md similarity index 100% rename from readme.md rename to README.md diff --git a/Rakefile b/Rakefile old mode 100644 new mode 100755 index d72046d..a30bc15 --- a/Rakefile +++ b/Rakefile @@ -1,13 +1,8 @@ require "rake/testtask" -require "rubocop/rake_task" Rake::TestTask.new do |t| t.pattern = "test/**/*_test.rb" t.libs << "test" end -RuboCop::RakeTask.new(:rubocop) do |t| - t.options = ["--force-exclusion"] -end - -task default: [:test, :rubocop] +task default: :test diff --git a/ci/travis/README.md b/ci/travis/README.md new file mode 100755 index 0000000..9c1050b --- /dev/null +++ b/ci/travis/README.md @@ -0,0 +1,5 @@ +## Travis-CI Scripts + +The bash scripts in this directory are run only in Travis-CI, and are placed here to help simplify the [`.travis.yml`](../../.travis.yml) configuration file. + +These scripts are not meant to be run locally by users or developers of Homebrew-Cask. diff --git a/ci/travis/before_install.sh b/ci/travis/before_install.sh new file mode 100755 index 0000000..69fc05c --- /dev/null +++ b/ci/travis/before_install.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# +# before_install.sh +# +# This file is meant to be sourced during the `before_install` phase of the +# Travis build. Do not attempt to source or run it locally. +# +# shellcheck disable=SC1090 +. "${TRAVIS_BUILD_DIR}/ci/travis/helpers.sh" + +header 'Running before_install.sh...' + +# https://github.com/rvm/rvm/pull/3627 +run rvm get head + +# unset rvm hook functions +run unset -f cd gem + +# print all travis-defined environment variables +run 'env | sort' + +# see https://github.com/travis-ci/travis-ci/issues/2666 +run export BRANCH_COMMIT="${TRAVIS_COMMIT_RANGE##*.}" +run export TARGET_COMMIT="${TRAVIS_COMMIT_RANGE%%.*}" +# shellcheck disable=SC2016 +if ! run 'MERGE_BASE="$(git merge-base "${BRANCH_COMMIT}" "${TARGET_COMMIT}")"'; then + run git fetch --unshallow + run 'MERGE_BASE="$(git merge-base "${BRANCH_COMMIT}" "${TARGET_COMMIT}")"' +fi +run export MERGE_BASE="${MERGE_BASE}" +run export TRAVIS_COMMIT_RANGE="${MERGE_BASE}...${BRANCH_COMMIT}" + +# print detailed macOS version info +run sw_vers + +# capture system ruby and gem locations +run export SYSTEM_RUBY_HOME="/System/Library/Frameworks/Ruby.framework/Versions/${HOMEBREW_RUBY%.*}" +run export SYSTEM_RUBY_BINDIR="${SYSTEM_RUBY_HOME}/usr/bin" +run export SYSTEM_GEM_HOME="${SYSTEM_RUBY_HOME}/usr/lib/ruby/gems/${HOMEBREW_RUBY}" +run export SYSTEM_GEM_BINDIR="${SYSTEM_GEM_HOME}/bin" + +# capture user gem locations +run export GEM_HOME="$HOME/.gem/ruby/${HOMEBREW_RUBY}" +run export GEM_BINDIR="${GEM_HOME}/bin" + +# ensure that the gems we install are used before system gems +run export GEM_PATH="${GEM_HOME}:${SYSTEM_GEM_HOME}" +run export PATH="${GEM_BINDIR}:${SYSTEM_GEM_BINDIR}:${SYSTEM_RUBY_BINDIR}:$PATH" + +# ensure that brew uses the ruby we want it to +run export HOMEBREW_RUBY_PATH="${SYSTEM_RUBY_BINDIR}/ruby" + +run which ruby +run ruby --version + +run which gem +run gem --version + +run brew update + +# ensure that we are the only brew-cask available +run brew uninstall --force brew-cask + +# mirror the repo as a tap, then run the build from there +run export CASK_TAP_DIR='/usr/local/Library/Taps/reitermarkus/homebrew-tap' +run mkdir -p "${CASK_TAP_DIR}" +run rsync -az --delete "${TRAVIS_BUILD_DIR}/" "${CASK_TAP_DIR}/" +run export TRAVIS_BUILD_DIR="${CASK_TAP_DIR}" +run cd "${CASK_TAP_DIR}" || exit 1 diff --git a/ci/travis/before_script.sh b/ci/travis/before_script.sh new file mode 100755 index 0000000..e84c1b0 --- /dev/null +++ b/ci/travis/before_script.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# before_script.sh +# +# This file is meant to be sourced during the `before_script` phase of the +# Travis build. Do not attempt to source or run it locally. +# +# shellcheck disable=SC1090 +. "${TRAVIS_BUILD_DIR}/ci/travis/helpers.sh" + +header 'Running before_script.sh...' + +run which bundle +run bundle --version + +run which rake +run rake --version diff --git a/ci/travis/helpers.sh b/ci/travis/helpers.sh new file mode 100755 index 0000000..d5091c5 --- /dev/null +++ b/ci/travis/helpers.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# +# helpers.sh +# +# Helper functions for Travis build scripts. +# + +# force strict error checking +set -o errexit +set -o pipefail + +# enable extended globbing syntax +shopt -s extglob + +CYAN='\033[0;36m' +MAGENTA='\033[1;35m' +NC='\033[0m' # no color + +# log command before running and add a blank line +run () { + echo -e "${MAGENTA}>>>${NC} $*" + eval "$*" + local retval=$? + echo + return $retval +} + +# print args as a cyan header +header () { + echo + echo -e "${CYAN}$*${NC}" + echo +} + +modified_cask_files () { + if [[ -z "${MODIFIED_CASK_FILES+defined}" ]]; then + MODIFIED_CASK_FILES="$(git diff --name-only --diff-filter=AM "${TRAVIS_COMMIT_RANGE}" -- Casks/*.rb)" + export MODIFIED_CASK_FILES + fi + echo "${MODIFIED_CASK_FILES}" +} + +modified_files_outside_casks () { + if [[ -z "${MODIFIED_FILES_OUTSIDE_CASKS+defined}" ]]; then + MODIFIED_FILES_OUTSIDE_CASKS="$(git diff --name-only "${TRAVIS_COMMIT_RANGE}" -- !(Casks))" + export MODIFIED_FILES_OUTSIDE_CASKS + fi + echo "${MODIFIED_FILES_OUTSIDE_CASKS}" +} + +any_casks_modified () { + [[ -n "$(modified_cask_files)" ]] +} + +must_run_tests () { + [[ -n "$(modified_files_outside_casks)" ]] +} diff --git a/ci/travis/install.sh b/ci/travis/install.sh new file mode 100755 index 0000000..07404e5 --- /dev/null +++ b/ci/travis/install.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash +# +# install.sh +# +# This file is meant to be sourced during the `install` phase of the Travis +# build. Do not attempt to source or run it locally. +# +# shellcheck disable=SC1090 +. "${TRAVIS_BUILD_DIR}/ci/travis/helpers.sh" + +header 'Running install.sh...' + +# install bundler and project dependencies in $GEM_HOME +run gem install --no-ri --no-rdoc bundler +run which bundle +run bundle --version +run bundle install --path="${GEM_HOME%/*/*}" diff --git a/ci/travis/script.sh b/ci/travis/script.sh new file mode 100755 index 0000000..f6c10a8 --- /dev/null +++ b/ci/travis/script.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# +# script.sh +# +# This file is meant to be sourced during the `script` phase of the Travis +# build. Do not attempt to source or run it locally. +# +# shellcheck disable=SC1090 +. "${TRAVIS_BUILD_DIR}/ci/travis/helpers.sh" + +header 'Running script.sh...' + +if any_casks_modified; then + modified_casks=($(modified_cask_files)) + run brew cask style "${modified_casks[@]}" +fi + +if must_run_tests; then + run bundle exec rubocop + run bundle exec rake test +fi diff --git a/test/Casks/compliance_test.rb b/test/Casks/compliance_test.rb new file mode 100755 index 0000000..3512249 --- /dev/null +++ b/test/Casks/compliance_test.rb @@ -0,0 +1,14 @@ +require "test_helper" + +describe "Casks" do + Hbc.all.each do |cask| + describe cask.to_s do + it "passes audit" do + audit = Hbc::Audit.new(cask) + audit.run! + audit.errors.must_equal [], "[#{cask}] Cask audit must be error free" + audit.warnings.must_equal [], "[#{cask}] Cask audit must be warning free" + end + end + end +end diff --git a/test/layout_test.rb b/test/layout_test.rb new file mode 100755 index 0000000..c1f92b5 --- /dev/null +++ b/test/layout_test.rb @@ -0,0 +1,79 @@ +require "test_helper" + +describe "Repo layout" do + project_root = Pathname.new(File.expand_path("#{File.dirname(__FILE__)}/../")) + + # TODO: a more clever way to do this would be to dispense with + # the imperfect IGNORE lists and read the actual repo + # contents by reading the output of "git ls-files" + + # dot dirs are always a project of Dir.entries + # other files are items that the developer hopefully has gitignored + IGNORE_FILES = %w[ + . + .. + .DS_Store + .bundle + ].freeze + + # the developer has hopefully gitignored these + IGNORE_REGEXPS = [ + %r{~$}, # emacs + ].freeze + + TOPLEVEL_DIRS = %w[ + .git + .github + Casks + ci + Formula + developer + spec + test + ].freeze + + TOPLEVEL_FILES = %w[ + .gitignore + .gitattributes + .rspec + .rubocop.yml + .travis.yml + CONTRIBUTING.md + Gemfile + Gemfile.lock + LICENSE + README.md + Rakefile + ].freeze + + describe "toplevel dir" do + it "finds some files at the top level" do + entries = Dir.entries(project_root) + entries.length.must_be :>, 0 + end + + it "only finds expected files at the top level" do + entries = Dir.entries(project_root) - IGNORE_FILES - TOPLEVEL_DIRS - TOPLEVEL_FILES + IGNORE_REGEXPS.each do |regexp| + entries.reject! { |elt| elt.match(regexp) } + end + entries.must_equal [] + end + end + + describe "Casks dir" do + it "finds some files in the Casks dir" do + entries = Dir.entries(project_root.join("Casks")) + entries.length.must_be :>, 0 + end + + it "only finds .rb files in the Casks dir" do + entries = Dir.entries(project_root.join("Casks")) - IGNORE_FILES + IGNORE_REGEXPS.each do |regexp| + entries.reject! { |elt| elt.match(regexp) } + end + entries.reject! { |elt| elt.match(%r{\.rb$}) } + entries.must_equal [] + end + end +end diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100755 index 0000000..173c4ae --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,35 @@ +require "bundler" +require "bundler/setup" + +# just in case +raise "brew-cask: Ruby 2.0 or greater is required." if RUBY_VERSION.to_i < 2 + +homebrew_path = Pathname(`brew --prefix`.chomp) +homebrew_path = Pathname("/usr/local") unless homebrew_path.exist? + +# add homebrew-cask lib to load path +brew_cask_path = homebrew_path.join("Library", "Taps", "caskroom", "homebrew-cask") +lib_path = brew_cask_path.join("lib") +$LOAD_PATH.push(lib_path) + +# require homebrew testing env +# todo: removeme, this is transitional +require "vendor/homebrew-fork/testing_env" + +# must be called after testing_env so at_exit hooks are in proper order +require "minitest/autorun" +# todo, re-enable minitest-colorize, broken under current test environment for unknown reasons +# require 'minitest-colorize' + +# our baby +require "hbc" + +# pretend like we installed the cask tap +project_root = Pathname.new(File.expand_path("#{File.dirname(__FILE__)}/../")) +taps_dest = Hbc.homebrew_prefix.join(*%w[Library Taps caskroom]) + +# create directories +FileUtils.mkdir_p taps_dest +FileUtils.mkdir_p Hbc.homebrew_prefix.join("bin") + +FileUtils.ln_s project_root, taps_dest.join("homebrew-cask")