diff --git a/.circleci/config.yml b/.circleci/config.yml index 31f8a1ec..01367200 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -26,10 +26,18 @@ jobs: # fallback to using the latest cache if no exact match is found - v1-dependencies- + - run: + name: Configure Bundler + command: | + echo 'export BUNDLER_VERSION=$(cat Gemfile.lock | tail -1 | tr -d " ")' >> $BASH_ENV + source $BASH_ENV + gem install bundler + bundle config set path '.bundle' + - run: name: install dependencies command: | - bundle install --jobs=4 --retry=3 --path .bundle + bundle install --jobs=4 --retry=3 - save_cache: paths: @@ -44,6 +52,8 @@ jobs: - run: name: run tests command: | + echo $BUNDLER_VERSION + bundle --version bundle exec rake # collect reports diff --git a/Gemfile.lock b/Gemfile.lock index d63e27ae..c8a61e43 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,7 +26,7 @@ GEM byebug (10.0.2) coderay (1.1.2) colored (1.2) - commander (4.4.7) + commander (4.5.0) highline (~> 2.0.0) concurrent-ruby (1.0.5) coveralls (0.8.21) @@ -100,7 +100,7 @@ GEM ruby-progressbar (~> 1.7) unicode-display_width (~> 1.0, >= 1.0.1) ruby-progressbar (1.9.0) - rubyzip (2.0.0) + rubyzip (2.2.0) sawyer (0.8.1) addressable (>= 2.3.5, < 2.6) faraday (~> 0.8, < 1.0) @@ -125,7 +125,7 @@ PLATFORMS x86-mingw32 DEPENDENCIES - bundler (~> 1.13) + bundler (~> 2.0) coveralls github_changelog_generator pry-byebug @@ -136,4 +136,4 @@ DEPENDENCIES u3d! BUNDLED WITH - 1.17.2 + 2.1.4 diff --git a/lib/u3d/commands_generator.rb b/lib/u3d/commands_generator.rb index 524d8217..38dd1a1c 100644 --- a/lib/u3d/commands_generator.rb +++ b/lib/u3d/commands_generator.rb @@ -36,8 +36,11 @@ class CommandsGenerator UNICODE_FILE = File.expand_path('../../assets/utf8.txt', __FILE__) def self.start + U3dCore::UpdateChecker.start_looking_for_update('u3d') check_locale new.run + ensure + U3dCore::UpdateChecker.show_update_status('u3d', U3d::VERSION) end def self.check_locale diff --git a/lib/u3d_core.rb b/lib/u3d_core.rb index 5f276d9e..f52fc96f 100644 --- a/lib/u3d_core.rb +++ b/lib/u3d_core.rb @@ -27,5 +27,8 @@ require 'u3d_core/ui/ui' require 'u3d_core/command_executor' require 'u3d_core/command_runner' +require 'u3d_core/env' +require 'u3d_core/update_checker/changelog' +require 'u3d_core/update_checker/update_checker' require 'colored' require 'commander' diff --git a/lib/u3d_core/env.rb b/lib/u3d_core/env.rb new file mode 100644 index 00000000..66a07a56 --- /dev/null +++ b/lib/u3d_core/env.rb @@ -0,0 +1,32 @@ +## --- BEGIN LICENSE BLOCK --- +# Original work Copyright (c) 2015-present the fastlane authors +# Modified work Copyright 2019-present WeWantToKnow AS +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +## --- END LICENSE BLOCK --- + +module U3dCore + class Env + def self.truthy?(env) + return false unless ENV[env] + return false if %w[no false off 0].include?(ENV[env].to_s) + return true + end + end +end diff --git a/lib/u3d_core/update_checker/changelog.rb b/lib/u3d_core/update_checker/changelog.rb new file mode 100644 index 00000000..856b0db8 --- /dev/null +++ b/lib/u3d_core/update_checker/changelog.rb @@ -0,0 +1,63 @@ +## --- BEGIN LICENSE BLOCK --- +# Original work Copyright (c) 2015-present the fastlane authors +# Modified work Copyright 2019-present WeWantToKnow AS +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +## --- END LICENSE BLOCK --- + +require_relative '../../u3d/utils' + +module U3dCore + class Changelog + class << self + def show_changes(gem_name, current_version, update_gem_command: "bundle update") + did_show_changelog = false + + releases(gem_name).each_with_index do |release, index| + next unless Gem::Version.new(to_version(release['tag_name'])) > Gem::Version.new(current_version) + puts("") + puts(release['name'].green) + puts(release['body']) + did_show_changelog = true + + next unless index == 2 + puts("") + puts("To see all new releases, open https://github.com/DragonBox/#{gem_name}/releases".green) + break + end + + puts("") + puts("Please update using `#{update_gem_command}`".green) if did_show_changelog + rescue StandardError => e + # Something went wrong, we don't care so much about this + UI.error("Unable to show_changes: #{e}") + end + + def to_version(tag_name) + tag_name = tag_name[1..-1] if tag_name[0] == 'v' + tag_name + end + + def releases(gem_name) + url = "https://api.github.com/repos/DragonBox/#{gem_name}/releases" + JSON.parse(U3d::Utils.page_content(url)) + end + end + end +end diff --git a/lib/u3d_core/update_checker/update_checker.rb b/lib/u3d_core/update_checker/update_checker.rb new file mode 100644 index 00000000..0fb32fb4 --- /dev/null +++ b/lib/u3d_core/update_checker/update_checker.rb @@ -0,0 +1,130 @@ +## --- BEGIN LICENSE BLOCK --- +# Original work Copyright (c) 2015-present the fastlane authors +# Modified work Copyright 2019-present WeWantToKnow AS +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. +## --- END LICENSE BLOCK --- + +require_relative 'changelog' +require_relative '../ui/ui' +require_relative '../../u3d/utils' + +module U3dCore + # Verifies the user runs the latest version of this gem + class UpdateChecker + def self.start_looking_for_update(gem_name) + return if Helper.test? + return if U3dCore::Env.truthy?("U3D_SKIP_UPDATE_CHECK") + + @start_time = Time.now + + Thread.new do + begin + server_results[gem_name] = fetch_latest(gem_name) + # rubocop:disable Lint/HandleExceptions + rescue StandardError + # rubocop:enable Lint/HandleExceptions + # we don't want to show a stack trace if something goes wrong + end + end + end + + def self.server_results + @results ||= {} + end + + class << self + attr_reader :start_time + end + + def self.update_available?(gem_name, current_version) + latest = server_results[gem_name] + return (latest && (Gem::Version.new(latest) > Gem::Version.new(current_version))) + end + + # wait a abit for results when commands run real quick + def self.wait_for_results + sleep([0, 0.4 - (Time.now - @start_time)].max) if @start_time + end + + def self.show_update_status(gem_name, current_version) + wait_for_results unless update_available?(gem_name, current_version) + show_update_message(gem_name, current_version) if update_available?(gem_name, current_version) + end + + # Show a message to the user to update to a new version of u3d + # Use this method, as this will detect the current Ruby environment and show an + # appropriate message to the user + def self.show_update_message(gem_name, current_version) + available = server_results[gem_name] + puts("") + puts('#######################################################################') + if available + puts("# #{gem_name} #{available} is available. You are on #{current_version}.") + else + puts("# An update for #{gem_name} is available. You are on #{current_version}.") + end + puts("# You should use the latest version.") + puts("# Please update using `#{update_command(gem_name: gem_name)}`.") + + # this could be fetched from the gem + puts("# To see what's new, open https://github.com/DragonBox/#{gem_name}/releases.") if U3dCore::Env.truthy?("U3D_HIDE_CHANGELOG") + + if !Helper.bundler? && Random.rand(5) == 1 + # We want to show this message from time to time, if the user doesn't use bundler + puts('#######################################################################') + puts("# Run `sudo gem cleanup` from time to time to speed up u3d") + end + puts('#######################################################################') + Changelog.show_changes(gem_name, current_version, update_gem_command: UpdateChecker.update_command(gem_name)) unless U3dCore::Env.truthy?("U3D_HIDE_CHANGELOG") + + ensure_rubygems_source + end + + # The command that the user should use to update the gem + def self.update_command(gem_name) + if Helper.bundler? + "bundle update #{gem_name.downcase}" + else + "sudo gem install #{gem_name.downcase}" + end + end + + # Check if RubyGems is set as a gem source + # on some machines that might not be the case + # and then users can't find the update when + # running the specified command + def self.ensure_rubygems_source + return if `gem sources`.include?("https://rubygems.org") + puts("") + UI.error("RubyGems is not listed as your Gem source") + UI.error("You can run `gem sources` to see all your sources") + UI.error("Please run the following command to fix this:") + UI.command("gem sources --add https://rubygems.org") + end + + def self.fetch_latest(gem_name) + JSON.parse(U3d::Utils.page_content(generate_fetch_url(gem_name)))["version"] + end + + def self.generate_fetch_url(gem_name) + "https://rubygems.org/api/v1/gems/#{gem_name}.json" + end + end +end diff --git a/u3d.gemspec b/u3d.gemspec index eb5d7021..1c7ca54d 100644 --- a/u3d.gemspec +++ b/u3d.gemspec @@ -32,7 +32,7 @@ Gem::Specification.new do |spec| spec.add_dependency 'rubyzip', '>= 1.0.0' # Installation of .zip files spec.add_dependency 'security', '= 0.1.3' # macOS Keychain manager, a dead project, no updates expected # Development only - spec.add_development_dependency "bundler", "~> 1.13" + spec.add_development_dependency "bundler", "~> 2.0" spec.add_development_dependency "coveralls" spec.add_development_dependency "github_changelog_generator" spec.add_development_dependency "pry-byebug"