From 2fa4684d9d7f1cdba6827b882e10cc7eaf50e577 Mon Sep 17 00:00:00 2001 From: Jochen Pfeiffer Date: Thu, 4 Jan 2018 15:28:38 +0100 Subject: [PATCH] Handle tasks with rake (#88) * add Rakefile with same tasks as run.sh * improve rakefile * use rake in ci configuration * fix rakefile * fix rakefile * fix circle config * remove run.sh, print debug info before test, fix rakefile * parse destination with env variable --- .circleci/config.yml | 8 +- .../project.pbxproj | 4 +- Gemfile | 2 + Gemfile.lock | 3 + Rakefile | 310 ++++++++++++++++++ scripts/run.sh | 199 ----------- 6 files changed, 321 insertions(+), 205 deletions(-) create mode 100644 Rakefile delete mode 100755 scripts/run.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ca50248..85e910eb 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -53,7 +53,7 @@ aliases: - &run-tests name: Build and run tests - command: ./scripts/run.sh tests "$DESTINATION" + command: bundle exec rake test_destination - &update-codecov name: Update Codecov @@ -125,7 +125,7 @@ jobs: - run: name: Lint Podspec - command: bundle exec pod lib lint + command: bundle exec rake lint_podspec build-documentation: @@ -144,7 +144,7 @@ jobs: - run: name: Build Documentation - command: ./scripts/run.sh documentation + command: bundle exec rake build_documentation swiftlint: @@ -182,7 +182,7 @@ jobs: - run: name: Push Podspec to trunk - command: bundle exec pod trunk push + command: bundle exec rake push_podspec workflows: diff --git a/Example/JJFloatingActionButton.xcodeproj/project.pbxproj b/Example/JJFloatingActionButton.xcodeproj/project.pbxproj index 8c02e454..ace19b14 100644 --- a/Example/JJFloatingActionButton.xcodeproj/project.pbxproj +++ b/Example/JJFloatingActionButton.xcodeproj/project.pbxproj @@ -44,7 +44,6 @@ 195269421FD7E6200053C785 /* UIColorExtensionsSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIColorExtensionsSpec.swift; sourceTree = ""; }; 195269441FD7E63B0053C785 /* JJActionItemSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JJActionItemSpec.swift; sourceTree = ""; }; 195637221FDA9EFB0003B8FF /* config.yml */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = text; lineEnding = 0; name = config.yml; path = ../../.circleci/config.yml; sourceTree = ""; tabWidth = 2; usesTabs = 0; }; - 19746F721FEABAB200C42037 /* run.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = run.sh; path = ../../scripts/run.sh; sourceTree = ""; }; 198B65FD1FBAE904009A17F2 /* JJFloatingActionButton_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JJFloatingActionButton_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 198B66001FBAE904009A17F2 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 198B66021FBAE904009A17F2 /* FirstViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirstViewController.swift; sourceTree = ""; }; @@ -66,6 +65,7 @@ 199592AB1FD73F070058BEFC /* JJFloatingActionButton.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = JJFloatingActionButton.xib; sourceTree = ""; }; 19B10AC21FF7BDDD00D70C32 /* .jazzy.yaml */ = {isa = PBXFileReference; lastKnownFileType = text; name = .jazzy.yaml; path = ../../.jazzy.yaml; sourceTree = ""; }; 19B10AD71FFCEF0800D70C32 /* JJFloationgActionButtonDelegateMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = JJFloationgActionButtonDelegateMock.swift; path = ReferenceImages/JJFloationgActionButtonDelegateMock.swift; sourceTree = ""; }; + 19B10ADB1FFE692100D70C32 /* Rakefile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; fileEncoding = 4; indentWidth = 2; name = Rakefile; path = ../../Rakefile; sourceTree = ""; tabWidth = 2; }; 19DF53B81FF59AE5006E292F /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Package.swift; path = ../../Package.swift; sourceTree = ""; }; 19E247E41FD7E6B5009A7BA1 /* JJActionItem.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = JJActionItem.xib; sourceTree = ""; }; 19E247E91FD854B1009A7BA1 /* .github_changelog_generator */ = {isa = PBXFileReference; lastKnownFileType = text; name = .github_changelog_generator; path = ../../.github_changelog_generator; sourceTree = ""; }; @@ -163,7 +163,7 @@ 198B66231FBAEDD6009A17F2 /* LICENSE */, 19DF53B81FF59AE5006E292F /* Package.swift */, 198B66241FBAEDD6009A17F2 /* README.md */, - 19746F721FEABAB200C42037 /* run.sh */, + 19B10ADB1FFE692100D70C32 /* Rakefile */, ); name = Metadata; path = JJFloatingActionButton; diff --git a/Gemfile b/Gemfile index 5330cd38..76e3cebe 100644 --- a/Gemfile +++ b/Gemfile @@ -6,5 +6,7 @@ source 'https://rubygems.org' do gem 'synx' gem 'github_changelog_generator' gem 'jazzy', '>= 0.9.0' + gem 'rake' + gem 'fileutils' end diff --git a/Gemfile.lock b/Gemfile.lock index bfc2568a..b0691e48 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -54,6 +54,7 @@ GEM faraday-http-cache (2.0.0) faraday (~> 0.8) ffi (1.9.18) + fileutils (1.0.2) fourflusher (2.0.1) fuzzy_match (2.0.4) gh_inspector (1.0.3) @@ -131,8 +132,10 @@ DEPENDENCIES cocoapods! cocoapods-clean! cocoapods-deintegrate! + fileutils! github_changelog_generator! jazzy (>= 0.9.0)! + rake! synx! xcpretty! diff --git a/Rakefile b/Rakefile new file mode 100644 index 00000000..0fe0d081 --- /dev/null +++ b/Rakefile @@ -0,0 +1,310 @@ +# +# Copyright (c) 2017-Present Jochen Pfeiffer +# +# 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. +# + +#-- Bootstrap ----------------------------------------------------------------# + +desc 'Initialize your working copy' +task :bootstrap do + unless system('which bundle') + error_message "Please install the bundler gem manually:\n" \ + ' $ [sudo] gem install bundler' + exit 1 + end + + install_gems + install_cocoapods +end + + +begin + require 'fileutils' + + task default: :test + + + #-- Tests ------------------------------------------------------------------# + + desc 'Run tests' + task :test do + xcodebuild_test "platform=iOS Simulator,name=iPhone X" + end + + desc 'Run tests for DESTINATION env' + task :test_destination do + Rake::Task[:print_debug_info].invoke + xcodebuild_test ENV['DESTINATION'] + end + + desc 'Print debug info' + task :print_debug_info do + title 'Debug info' + sh 'xcodebuild -version' + sh 'xcodebuild -showsdks' + sh 'instruments -s devices' + end + + desc 'Lint swift' + task :lint_swift do + unless system('which swiftlint') + error_message "Please install swiftlint manually:\n" \ + ' $ brew install swiftlint' + exit 1 + end + + title 'Linting swift' + sh "swiftlint" + end + + desc 'Lint podspec' + task :lint_podspec do + title 'Linting podspec' + sh "bundle exec pod lib lint" + end + + + #-- Format -----------------------------------------------------------------# + + desc 'Format code' + task :format do + unless system('which swiftformat') + error_message "Please install swiftformat manually:\n" \ + ' $ brew install swiftformat' + exit 1 + end + + title 'Formating code' + sh "swiftformat Example/Tests Example/JJFloatingActionButton Sources" + end + + desc 'Format and lint code' + task :format_and_lint do + Rake::Task[:format].invoke + Rake::Task[:lint_swift].invoke + end + + + #-- Dependencies -----------------------------------------------------------# + + desc 'Install dependencies' + task :install_dependencies do + install_gems + install_cocoapods + end + + desc 'Update dependencies' + task :update_dependencies do + update_gems + update_cocoapods + end + + + #-- Documentation ----------------------------------------------------------# + + desc 'Build documentation' + task :build_documentation do + generate_documentation + end + + + #-- Changelog --------------------------------------------------------------# + + desc 'Generate changelog' + task :generate_changelog do + generate_changelog "" + end + + + #-- Record Video -----------------------------------------------------------# + + desc 'Record video booted simulator and convert to gif' + task :record_gif do + unless system('which ffmpeg') + error_message "Please install ffmpeg manually:\n" \ + ' $ brew install ffmpeg' + exit 1 + end + + title 'Recording video' + + mov_path='./Images/JJFloatingActionButton.mov' + + trap('SIGINT') { puts } + %x{xcrun simctl io booted recordVideo #{mov_path}} + + title 'Convert to gif' + + gif_path='./Images/JJFloatingActionButton.gif' + palette_path='./Images/palette.png' + filters='fps=30,setpts=1*PTS,scale=250:-1:flags=lanczos' + + sh "ffmpeg -v warning -i #{mov_path} -vf '#{filters},palettegen' -y #{palette_path}" + if File.exist? palette_path + sh "ffmpeg -v warning -i #{mov_path} -i #{palette_path} -lavfi '#{filters} [x]; [x][1:v] paletteuse' -y #{gif_path}" + File.delete palette_path + end + end + + + #-- Release ----------------------------------------------------------------# + + desc 'Release version' + task :release_version, :version do |task, args| + ensure_clean_git_status + update_version_in_podspec args.version + update_version_in_example_project args.version + generate_changelog args.version + install_cocoapods + generate_documentation + create_release_branch_and_commit args.version + open_pull_request args.version + end + + desc 'Push podspec' + task :push_podspec do + title "Pushing podspec" + sh 'bundle exec pod trunk push' + end + +rescue LoadError, NameError => e + error_message 'Some Rake tasks haven been disabled because the environment' \ + ' couldn’t be loaded. Be sure to run `rake bootstrap` first.' + $stderr.puts e.message + $stderr.puts e.backtrace + $stderr.puts +end + + +#-- Helpers ------------------------------------------------------------------# + +private + +def title(title) + cyan_title = "\033[0;36m#{title}\033[0m" + puts + puts '-' * 80 + puts cyan_title + puts '-' * 80 + puts +end + +def error_message(message) + red_message = "\033[0;31m[!] #{message}\e[0m" + $stderr.puts + $stderr.puts red_message + $stderr.puts +end + +def check_parameter(parameter) + if parameter.nil? || parameter.empty? + error_message "parameter can't be empty." + exit 1 + end +end + +def install_gems + title 'Installing gems' + sh 'bundle install' +end + +def install_cocoapods + title 'Installing cocoapods' + sh 'bundle exec pod install --project-directory=Example' +end + +def update_gems + title 'Updating gems' + sh 'bundle update' +end + +def update_cocoapods + title 'Updating cocoapods' + sh 'bundle exec pod update --project-directory=Example' +end + +def xcodebuild_test(destination) + title 'Running tests' + check_parameter(destination) + sh "xcodebuild clean build test" \ + " -workspace Example/JJFloatingActionButton.xcworkspace" \ + " -scheme JJFloatingActionButton_Example" \ + " -sdk iphonesimulator" \ + " -destination \"#{destination}\"" \ + " -enableCodeCoverage YES" \ + " CODE_SIGNING_REQUIRED=NO" \ + " CODE_SIGN_IDENTITY=" \ + " PROVISIONING_PROFILE=" +end + +def ensure_clean_git_status + title "Ensuring clean git status" + unless `git diff --shortstat 2> /dev/null | tail -n1` == '' + error_message "Uncommited changes. Commit first." + exit 1 + end +end + +def update_version_in_example_project(version) + title "Updating version in example project" + check_parameter(version) + sh "/usr/libexec/PlistBuddy -c \"Set :CFBundleShortVersionString #{version}\" ./Example/JJFloatingActionButton/Info.plist" +end + +def generate_changelog(version) + title "Generating changelog" + unless version.nil? || version.empty? + sh "github_changelog_generator --future-release #{version}" + else + sh "github_changelog_generator" + end +end + +def generate_documentation + title 'Generating documentation' + sh 'bundle exec jazzy' +end + +def update_version_in_podspec(version) + title "Updating version in podspec" + check_parameter(version) + file_name = 'JJFloatingActionButton.podspec' + contents = File.read(file_name) + new_contents = contents.gsub(/(spec\.version\s*=\s*)'.*'/, "\\1'#{version}'") + puts new_contents + File.open(file_name, "w") {|file| file.puts new_contents } +end + +def create_release_branch_and_commit(version) + title "Creating release branch and commit" + check_parameter(version) + release_branch = "release/#{version}" + sh "git checkout -b #{release_branch}" + sh "git add --all" + sh "git commit -v -m 'Release #{version}'" + sh "git push --set-upstream origin #{release_branch}" +end + +def open_pull_request(version) + title "Opening pull request" + check_parameter(version) + sh "open 'https://github.com/jjochen/JJFloatingActionButton/compare/release%2F#{version}?expand=1'" +end + diff --git a/scripts/run.sh b/scripts/run.sh deleted file mode 100755 index f049ed56..00000000 --- a/scripts/run.sh +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env bash - -# -# Copyright (c) 2017-Present Jochen Pfeiffer -# -# 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. -# - - -set -e - -function fancy_echo -{ - echo "" - echo $1 -} - -function usage -{ -cat << EOF -usage: - $0 tests [destination] Run tests for given destination - $0 release [version] Release new version - $0 documentation Build documentation - $0 video Record video - $0 help Print this help -EOF -} - -function run_action -{ - action=$1; shift - case ${action} in - tests) - run_tests $* - ;; - release) - release_version $* - ;; - documentation) - build_documentation - ;; - video) - record_video - ;; - *) - usage - exit - ;; - esac -} - -function run_tests -{ - destination=$* - if [[ -z ${destination} ]] - then - fancy_echo "ERROR: Destination has to be specified" - usage - exit 1 - fi - - fancy_echo "Run Tests (${destination})" - - xcodebuild -version - xcodebuild -showsdks - instruments -s devices - - xcodebuild clean build test \ - -workspace Example/JJFloatingActionButton.xcworkspace \ - -scheme JJFloatingActionButton_Example \ - -sdk iphonesimulator \ - -destination "${destination}" \ - -enableCodeCoverage YES \ - CODE_SIGNING_REQUIRED=NO \ - CODE_SIGN_IDENTITY= \ - PROVISIONING_PROFILE= -} - -function release_version -{ - version=$* - if [[ -z ${version} ]] - then - fancy_echo "ERROR: Version number has to be specified" - usage - exit 1 - fi - - fancy_echo "Release Version (${version})" - - ensure_git_status_clean - update_podspec - update_change_log - install_example_pods - update_example_version - build_documentation - commit_to_release_branch - create_pull_request -} - -function build_documentation -{ - fancy_echo "Build Documentation" - bundle exec jazzy -} - -function update_change_log -{ - fancy_echo "Update Change Log" - github_changelog_generator --future-release ${version} -} - -function ensure_git_status_clean -{ - fancy_echo "Ensure git status clean" - if test -n "$(git status --porcelain)" - then - echo "Uncommited changes. Commit first." - git status - exit 1 - else - echo "Clean" - fi -} - -function commit_to_release_branch -{ - fancy_echo "Commit to release branch" - release_branch="release/${version}" - git checkout -b ${release_branch} - git add --all - git commit -v -m "Release ${version}" - git push --set-upstream origin ${release_branch} -} - -function create_pull_request -{ - fancy_echo "Create Pull Request" - open "https://github.com/jjochen/JJFloatingActionButton/compare/release%2F${version}?expand=1" -} - -function update_podspec -{ - fancy_echo "Update Pod Spec" - sed -i "" -e "s/\(spec\.version.*\)'.*'/\1'${version}'/" JJFloatingActionButton.podspec -} - -function install_example_pods -{ - fancy_echo "Install cocoapods in Example" - bundle exec pod install --project-directory=Example -} - -function update_example_version -{ - fancy_echo "Update Version in Example" - /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString ${version}" Example/JJFloatingActionButton/Info.plist -} - -function record_video -{ - fancy_echo "Record video" - - mov_path="./Images/JJFloatingActionButton.mov" - gif_path="./Images/JJFloatingActionButton.gif" - - xcrun simctl io booted recordVideo $mov_path - - fancy_echo "Create gif" - - palette="./Images/palette.png" - filters="fps=30,setpts=1*PTS,scale=250:-1:flags=lanczos" - - ffmpeg -v warning -i $mov_path -vf "$filters,palettegen" -y $palette - if [[ -f $palette ]]; then - ffmpeg -v warning -i $mov_path -i $palette -lavfi "$filters [x]; [x][1:v] paletteuse" -y $gif_path - rm $palette - fi -} - - -run_action $*