From 4411c8ca4d6cc3e5ba20a6d974f35a87c1ace9c8 Mon Sep 17 00:00:00 2001 From: Tamer Bader Date: Wed, 5 Jun 2024 18:17:21 -0700 Subject: [PATCH 1/5] Initial commit with template rendering --- .ruby-version | 1 + Gemfile | 5 + Gemfile.lock | 20 ++++ MockReaderUI.podspec | 18 ++-- Package.swift | 2 +- README.md | 6 +- Scripts/git/pre-commit-hook | 15 +++ Scripts/git/pre-commit-validator.rb | 88 +++++++++++++++++ .../sdk_constants.rb | 2 +- Scripts/sdk_utilities.rb | 95 +++++++++++++++++++ Scripts/templates/MockReaderUI.podspec.erb | 18 ++++ Scripts/templates/Package.swift.erb | 22 +++++ Scripts/templates/README.md.erb | 65 +++++++++++++ .../SquareMobilePaymentsSDK.podspec.erb | 18 ++++ Scripts/update-sdk-version.rb | 30 ++++++ SquareMobilePaymentsSDK.podspec | 18 ++-- 16 files changed, 398 insertions(+), 25 deletions(-) create mode 100644 .ruby-version create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Scripts/git/pre-commit-hook create mode 100644 Scripts/git/pre-commit-validator.rb rename podspec_constants.rb => Scripts/sdk_constants.rb (99%) create mode 100644 Scripts/sdk_utilities.rb create mode 100644 Scripts/templates/MockReaderUI.podspec.erb create mode 100644 Scripts/templates/Package.swift.erb create mode 100644 Scripts/templates/README.md.erb create mode 100644 Scripts/templates/SquareMobilePaymentsSDK.podspec.erb create mode 100644 Scripts/update-sdk-version.rb diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 0000000..acf9bf0 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +3.2.2 \ No newline at end of file diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..ff364f1 --- /dev/null +++ b/Gemfile @@ -0,0 +1,5 @@ +source 'https://rubygems.org' + +gem 'erb' +gem 'fileutils' +gem 'open3' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 0000000..f8a42ed --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,20 @@ +GEM + remote: https://rubygems.org/ + specs: + cgi (0.4.1) + erb (4.0.4) + cgi (>= 0.3.3) + fileutils (1.7.2) + open3 (0.2.1) + +PLATFORMS + arm64-darwin-21 + arm64-darwin-22 + +DEPENDENCIES + erb + fileutils + open3 + +BUNDLED WITH + 2.3.21 diff --git a/MockReaderUI.podspec b/MockReaderUI.podspec index 87dc73f..dd93d55 100644 --- a/MockReaderUI.podspec +++ b/MockReaderUI.podspec @@ -1,20 +1,18 @@ -require './podspec_constants' - Pod::Spec.new do |s| s.name = 'MockReaderUI' - s.version = SquareMobilePaymentsSDK::VERSION - s.license = SquareMobilePaymentsSDK::LICENSE - s.homepage = SquareMobilePaymentsSDK::HOMEPAGE_URL - s.authors = SquareMobilePaymentsSDK::AUTHORS + s.version = '2.0.0-beta1' + s.license = {:type=>"Square Developer License", :text=>"Copyright (c) 2020-present, Square, Inc. All rights reserved.\n\nYour use of this software is subject to the Square Developer Terms of\nService (https://squareup.com/legal/developers). This copyright notice shall\nbe included in all copies or substantial portions of the software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"} + s.homepage = 'https://github.com/square/mobile-payments-sdk-ios' + s.authors = 'Square' s.summary = 'Enables developers to build use mock readers for testing the MobilePaymentsSDK' - s.ios.deployment_target = SquareMobilePaymentsSDK::IOS_DEPLOYMENT_TARGET + s.ios.deployment_target = '15.0' - s.source ={ :git => "https://github.com/square/mobile-payments-sdk-ios.git" , :tag => SquareMobilePaymentsSDK::VERSION } + s.source ={ :git => "https://github.com/square/mobile-payments-sdk-ios.git" , :tag => "2.0.0-beta1" } s.vendored_frameworks = 'MockReaderUI.xcframework' s.prepare_command = <<-CMD - unzip XCFrameworks/MockReaderUI_#{SquareMobilePaymentsSDK::COMMIT_SHA}.zip + unzip XCFrameworks/MockReaderUI_6432c60c8568.zip CMD -end \ No newline at end of file +end diff --git a/Package.swift b/Package.swift index 07b3aa7..4d9cd6b 100644 --- a/Package.swift +++ b/Package.swift @@ -19,4 +19,4 @@ let package = Package( path: "XCFrameworks/MockReaderUI_6432c60c8568.zip" ), ] -) \ No newline at end of file +) diff --git a/README.md b/README.md index f307a4d..f3762a2 100644 --- a/README.md +++ b/README.md @@ -29,11 +29,11 @@ Install with [CocoaPods](http://cocoapods.org/) by adding the following to your ``` use_frameworks! -pod "SquareMobilePaymentsSDK", "~> 2.0.0.beta1" +pod "SquareMobilePaymentsSDK", "~> 2.0.0-beta1" # Optionally include MockReaderUI if you wish to simulate a physical reader when one is not present. # This feature is only available when provided a sandbox application ID. -pod "MockReaderUI", "~> 2.0.0.beta1", configurations: ['Debug'] +pod "MockReaderUI", "~> 2.0.0-beta1", configurations: ['Debug'] ``` _Note that MockReaderUI framework **requires** the `SquareMobilePaymentsSDK` framework to also be present in your `Podfile`._ @@ -49,7 +49,7 @@ fi Make sure this build phase is after any `[CP] Embed Pods Frameworks` or `Embed Frameworks` Build Phase. -> [!WARNING] +> [!WARNING] > Please note that the `MockReaderUI` product should only be used in debug configurations and is not to be included in the release version of your application. ### 3. Start integrating the SDK diff --git a/Scripts/git/pre-commit-hook b/Scripts/git/pre-commit-hook new file mode 100644 index 0000000..d97b5b5 --- /dev/null +++ b/Scripts/git/pre-commit-hook @@ -0,0 +1,15 @@ +#!/bin/bash + +# Run the Ruby validation script +ruby Scripts/git/pre-commit-validator.rb + +# Capture the exit status of the Ruby script +status=$? + +# If the validation script fails (non-zero exit status), abort the commit +if [ $status -ne 0 ]; then + exit 1 +fi + +# Otherwise, allow the commit to proceed +exit 0 \ No newline at end of file diff --git a/Scripts/git/pre-commit-validator.rb b/Scripts/git/pre-commit-validator.rb new file mode 100644 index 0000000..372c8f1 --- /dev/null +++ b/Scripts/git/pre-commit-validator.rb @@ -0,0 +1,88 @@ +require_relative '../sdk_utilities' +require_relative '../sdk_constants' +require 'fileutils' + +class FileComparator + def self.compare(file1_path, file2_path) + unless File.exist?(file1_path) && File.exist?(file2_path) + return false + end + + file1 = File.open(file1_path) + file2 = File.open(file2_path) + + file1.each_line.zip(file2.each_line) do |line1, line2| + if line1 != line2 + file1.close + file2.close + return false + end + end + + file1.close + file2.close + + true + end +end + +def create_temp_dir + FileUtils.mkdir_p('tmp') +end + +def delete_temp_dir + FileUtils.rm_rf('tmp') +end + +def pass_validation + puts "✅ Pre-Commit Validation Passed!" + exit 0 +end + +def fail_validation + puts "❎ Pre-Commit Validation Failed. Aborting Commit" + exit 1 +end + +create_temp_dir + +template_builder = TemplateBuilder.new( + SquareMobilePaymentsSDK::VERSION, + SquareMobilePaymentsSDK::COMMIT_SHA, + SquareMobilePaymentsSDK::LICENSE, + SquareMobilePaymentsSDK::HOMEPAGE_URL, + SquareMobilePaymentsSDK::AUTHORS, + SquareMobilePaymentsSDK::IOS_DEPLOYMENT_TARGET +) + +# Generate Temporary README +template_builder.build_and_write('./Scripts/templates/README.md.erb', 'README.md', './tmp/') + +# Generate Temporary SquareMobilePaymentsSDK Podsepc +template_builder.build_and_write('./Scripts/templates/SquareMobilePaymentsSDK.podspec.erb', 'SquareMobilePaymentsSDK.podspec', './tmp/') + +# Generate Temporary MockReaderUI Podspec +template_builder.build_and_write('./Scripts/templates/MockReaderUI.podspec.erb', 'MockReaderUI.podspec', './tmp/') + +# Generate Temporary Package.swift +template_builder.build_and_write('./Scripts/templates/Package.swift.erb', 'Package.swift', './tmp/') + +# Validates no changes in the diff between generated files and the files being checked in +if FileComparator.compare('./README.md', './tmp/README.md') && + FileComparator.compare('./SquareMobilePaymentsSDK.podspec', './tmp/SquareMobilePaymentsSDK.podspec') && + FileComparator.compare('./MockReaderUI.podspec', './tmp/MockReaderUI.podspec') && + FileComparator.compare('./Package.swift', './tmp/Package.swift') + # All files are identical! + delete_temp_dir +else + puts "Please ensure you are modifying the erb template and not the actual file" + delete_temp_dir + fail_validation +end + +# Validate Podspec and Package.swift +if Validator.validate_podspecs && Validator.validate_spm_package + pass_validation +else + fail_validation +end diff --git a/podspec_constants.rb b/Scripts/sdk_constants.rb similarity index 99% rename from podspec_constants.rb rename to Scripts/sdk_constants.rb index ef11c79..9bdea81 100644 --- a/podspec_constants.rb +++ b/Scripts/sdk_constants.rb @@ -23,4 +23,4 @@ module SquareMobilePaymentsSDK HOMEPAGE_URL = 'https://github.com/square/mobile-payments-sdk-ios' AUTHORS = 'Square' IOS_DEPLOYMENT_TARGET = '15.0' -end \ No newline at end of file +end diff --git a/Scripts/sdk_utilities.rb b/Scripts/sdk_utilities.rb new file mode 100644 index 0000000..7e83025 --- /dev/null +++ b/Scripts/sdk_utilities.rb @@ -0,0 +1,95 @@ +require 'erb' +require 'open3' + +class TemplateBuilder + def initialize(version, commit_sha, license, homepage_url, authors, ios_deployment_target) + @version = version + @commit_sha = commit_sha + @license = license + @homepage_url = homepage_url + @authors = authors + @ios_deployment_target = ios_deployment_target + end + + def build_and_write(template_path, file_name, output_dir) + template = File.read(template_path) + renderer = ERB.new(template) + result = renderer.result(get_binding) + File.open("#{output_dir}#{file_name}", 'w+') do |file| + file.write(result) + end + end + + private + + def get_binding + binding + end +end + +class CommandExecutor + def self.execute(command) + stdout, stderr, _status = Open3.capture3(command) + [stdout, stderr] + end +end + +class Validator + def self.validate_podspecs + puts "Validating Podspecs..." + command = "pod spec lint" + stdout, _stderr = CommandExecutor.execute(command) + stdout.scan(/^(\w+)/).flatten + if stdout.include?("All the specs passed validation.") + puts "✅ All podspecs have passed validation" + return true + else + puts "❎ Podspecs could not be validated" + puts stdout + return false + end + end + + def self.validate_spm_package + puts "Validating SPM Package..." + command = "swift package describe" + _stdout, stderr = CommandExecutor.execute(command) + stderr.scan(/^(\w+)/).flatten + # It is a known issue that SPM parser errors on binaryTargets. If it is the only error, then proceed as pass + if stderr.nil? || stderr.empty? || stderr.include?("error: unknown binary artifact file extension 'zip'") + puts "✅ SPM Package has passed validation" + return true + else + puts "❎ SPM Package could not be validated" + puts stderr + return false + end + end +end + +class HookInstaller + def self.install_pre_commit_hook + pre_commit_hook_path = './Scripts/git/pre-commit-hook' + destination_path = '.git/hooks/pre-commit' + + # Read the contents of the source file + begin + hook_content = File.read(pre_commit_hook_path) + rescue Errno::ENOENT => e + puts "❎ Error reading source file: #{e.message}" + return + end + + # Write the contents to the destination file + begin + File.open(destination_path, 'w') do |file| + file.write(hook_content) + end + # Make the hook script executable + File.chmod(0755, destination_path) + puts "✅ Pre-commit hook has been installed successfully." + rescue Errno::ENOENT, Errno::EACCES => e + puts "❎ Error writing to destination file: #{e.message}" + end + end +end diff --git a/Scripts/templates/MockReaderUI.podspec.erb b/Scripts/templates/MockReaderUI.podspec.erb new file mode 100644 index 0000000..fb389c1 --- /dev/null +++ b/Scripts/templates/MockReaderUI.podspec.erb @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + s.name = 'MockReaderUI' + s.version = '<%= @version %>' + s.license = <%= @license %> + s.homepage = '<%= @homepage_url %>' + s.authors = '<%= @authors %>' + s.summary = 'Enables developers to build use mock readers for testing the MobilePaymentsSDK' + + s.ios.deployment_target = '<%= @ios_deployment_target %>' + + s.source ={ :git => "https://github.com/square/mobile-payments-sdk-ios.git" , :tag => "<%= @version %>" } + + s.vendored_frameworks = 'MockReaderUI.xcframework' + s.prepare_command = <<-CMD + unzip XCFrameworks/MockReaderUI_<%= @commit_sha %>.zip + CMD + +end diff --git a/Scripts/templates/Package.swift.erb b/Scripts/templates/Package.swift.erb new file mode 100644 index 0000000..35ee0e4 --- /dev/null +++ b/Scripts/templates/Package.swift.erb @@ -0,0 +1,22 @@ +// swift-tools-version:5.3 + +import PackageDescription + +let package = Package( + name: "SquareMobilePaymentsSDK", + products: [ + .library(name: "SquareMobilePaymentsSDK", targets: ["SquareMobilePaymentsSDK"]), + .library(name: "MockReaderUI", targets: ["MockReaderUI"]), + ], + dependencies: [], + targets: [ + .binaryTarget( + name: "SquareMobilePaymentsSDK", + path: "XCFrameworks/SquareMobilePaymentsSDK_<%= @commit_sha %>.zip" + ), + .binaryTarget( + name: "MockReaderUI", + path: "XCFrameworks/MockReaderUI_<%= @commit_sha %>.zip" + ), + ] +) diff --git a/Scripts/templates/README.md.erb b/Scripts/templates/README.md.erb new file mode 100644 index 0000000..0e50096 --- /dev/null +++ b/Scripts/templates/README.md.erb @@ -0,0 +1,65 @@ +[![CocoaPods](https://img.shields.io/cocoapods/v/SquareMobilePaymentsSDK)](https://github.com/CocoaPods/CocoaPods) +[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-4BC51D.svg?style=flat)](https://github.com/apple/swift-package-manager) + +# Square Mobile Payments SDK + +Build remarkable in-person experiences using Square's Mobile Payments SDK product, now in beta. Use the Mobile Payments SDK to accept in-person payments using Square hardware. The Mobile Payments SDK has the advantage of being an API-driven framework that allows for full customization and uses the latest [v2/payments](https://developer.squareup.com/explorer/square/payments-api/list-payments) API. + +Learn what you can do with the Mobile Payments SDK [here](https://developer.squareup.com/docs/mobile-payments-sdk). + +## Installation + +### 1. Add frameworks using SPM or CocoaPods + +#### Option A. Swift Package Manager + +Install with [Swift Package Manager](https://www.swift.org/documentation/package-manager/) by following these steps: + +1. Select `File > Add Package Dependencies...`. +2. Enter the repository URL: `https://github.com/square/mobile-payments-sdk-ios`. +3. Select the `Exact Version` dependency rule and specify the version as `<%= @version %>`. +4. Ensure the `SquareMobilePaymentsSDK` product is added to your target. + +Optionally, you can also add the `MockReaderUI` product to your target to simulate a physical reader when one is not present in a sandbox environment. + +#### Option B. CocoaPods + +Install with [CocoaPods](http://cocoapods.org/) by adding the following to your `Podfile`: + +``` +use_frameworks! + +pod "SquareMobilePaymentsSDK", "~> <%= @version %>" + +# Optionally include MockReaderUI if you wish to simulate a physical reader when one is not present. +# This feature is only available when provided a sandbox application ID. +pod "MockReaderUI", "~> <%= @version %>", configurations: ['Debug'] +``` +_Note that MockReaderUI framework **requires** the `SquareMobilePaymentsSDK` framework to also be present in your `Podfile`._ + +### 2. Add build phase to setup the framework + +On your application targets’ `Build Phases` settings tab, click the + icon and choose `New Run Script Phase`. Create a Run Script in which you specify your shell (ex: /bin/sh), and add the following contents to the script area below the shell: +``` +SETUP_SCRIPT=${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}"/SquareMobilePaymentsSDK.framework/setup" +if [ -f "$SETUP_SCRIPT" ]; then + "$SETUP_SCRIPT" +fi +``` + +Make sure this build phase is after any `[CP] Embed Pods Frameworks` or `Embed Frameworks` Build Phase. + +> [!WARNING] +> Please note that the `MockReaderUI` product should only be used in debug configurations and is not to be included in the release version of your application. + +### 3. Start integrating the SDK + +Follow the [Build on iOS guide](https://developer.squareup.com/docs/mobile-payments-sdk/ios#3-initialize-the-mobile-payments-sdk) to learn how to integrate the Mobile Payments SDK in your app. + +## Documentation +* [Mobile Payments SDK Overview](https://developer.squareup.com/docs/mobile-payments-sdk) +* iOS Tech Reference + * [Mobile Payments SDK Framework](https://developer.squareup.com/docs/sdk/mobile-payments/ios) + +If you need more assistance, contact [Developer and App Marketplace Support](https://squareup.com/help/us/en/contact?panel=BF53A9C8EF68) or ask for help in the [Developer Forums](https://developer.squareup.com/forums/). + diff --git a/Scripts/templates/SquareMobilePaymentsSDK.podspec.erb b/Scripts/templates/SquareMobilePaymentsSDK.podspec.erb new file mode 100644 index 0000000..a516a9a --- /dev/null +++ b/Scripts/templates/SquareMobilePaymentsSDK.podspec.erb @@ -0,0 +1,18 @@ +Pod::Spec.new do |s| + s.name = 'SquareMobilePaymentsSDK' + s.version = '<%= @version %>' + s.license = <%= @license %> + s.homepage = '<%= @homepage_url %>' + s.authors = '<%= @authors %>' + s.summary = 'Enables developers to build secure in-person payment solutions' + + s.ios.deployment_target = '<%= @ios_deployment_target %>' + + s.source ={ :git => "https://github.com/square/mobile-payments-sdk-ios.git", :tag => "<%= @version %>" } + + s.vendored_frameworks = 'SquareMobilePaymentsSDK.xcframework' + s.prepare_command = <<-CMD + unzip XCFrameworks/SquareMobilePaymentsSDK_<%= @commit_sha %>.zip + CMD + +end diff --git a/Scripts/update-sdk-version.rb b/Scripts/update-sdk-version.rb new file mode 100644 index 0000000..71285d9 --- /dev/null +++ b/Scripts/update-sdk-version.rb @@ -0,0 +1,30 @@ +require_relative 'sdk_utilities' +require_relative 'sdk_constants' + +# Install Pre-Commit Hook +HookInstaller.install_pre_commit_hook + +template_builder = TemplateBuilder.new( + SquareMobilePaymentsSDK::VERSION, + SquareMobilePaymentsSDK::COMMIT_SHA, + SquareMobilePaymentsSDK::LICENSE, + SquareMobilePaymentsSDK::HOMEPAGE_URL, + SquareMobilePaymentsSDK::AUTHORS, + SquareMobilePaymentsSDK::IOS_DEPLOYMENT_TARGET +) + +# Generate README +template_builder.build_and_write('./Scripts/templates/README.md.erb', 'README.md', './') +puts "✅ Updated README" + +# Generate SquareMobilePaymentsSDK Podsepc +template_builder.build_and_write('./Scripts/templates/SquareMobilePaymentsSDK.podspec.erb', 'SquareMobilePaymentsSDK.podspec', './') +puts "✅ Updated SquareMobilePaymentsSDK.podspec" + +# Generate MockReaderUI Podspec +template_builder.build_and_write('./Scripts/templates/MockReaderUI.podspec.erb', 'MockReaderUI.podspec', './') +puts "✅ Updated MockReaderUI.podspec" + +# Generate Package.swift +template_builder.build_and_write('./Scripts/templates/Package.swift.erb', 'Package.swift', './') +puts "✅ Updated Package.swift" diff --git a/SquareMobilePaymentsSDK.podspec b/SquareMobilePaymentsSDK.podspec index 934e6a7..f240241 100644 --- a/SquareMobilePaymentsSDK.podspec +++ b/SquareMobilePaymentsSDK.podspec @@ -1,20 +1,18 @@ -require './podspec_constants' - Pod::Spec.new do |s| s.name = 'SquareMobilePaymentsSDK' - s.version = SquareMobilePaymentsSDK::VERSION - s.license = SquareMobilePaymentsSDK::LICENSE - s.homepage = SquareMobilePaymentsSDK::HOMEPAGE_URL - s.authors = SquareMobilePaymentsSDK::AUTHORS + s.version = '2.0.0-beta1' + s.license = {:type=>"Square Developer License", :text=>"Copyright (c) 2020-present, Square, Inc. All rights reserved.\n\nYour use of this software is subject to the Square Developer Terms of\nService (https://squareup.com/legal/developers). This copyright notice shall\nbe included in all copies or substantial portions of the software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"} + s.homepage = 'https://github.com/square/mobile-payments-sdk-ios' + s.authors = 'Square' s.summary = 'Enables developers to build secure in-person payment solutions' - s.ios.deployment_target = SquareMobilePaymentsSDK::IOS_DEPLOYMENT_TARGET + s.ios.deployment_target = '15.0' - s.source ={ :git => "https://github.com/square/mobile-payments-sdk-ios.git", :tag => SquareMobilePaymentsSDK::VERSION } + s.source ={ :git => "https://github.com/square/mobile-payments-sdk-ios.git", :tag => "2.0.0-beta1" } s.vendored_frameworks = 'SquareMobilePaymentsSDK.xcframework' s.prepare_command = <<-CMD - unzip XCFrameworks/SquareMobilePaymentsSDK_#{SquareMobilePaymentsSDK::COMMIT_SHA}.zip + unzip XCFrameworks/SquareMobilePaymentsSDK_6432c60c8568.zip CMD -end \ No newline at end of file +end From 433c7fb6c638ba3cac9dfa6e5fadb56c1d27bcba Mon Sep 17 00:00:00 2001 From: Tamer Bader Date: Tue, 2 Jul 2024 10:50:15 -0700 Subject: [PATCH 2/5] Removing pre-commit validation and opting instead for using a github action --- .github/workflows/validate-pull-request.yml | 27 ++++++ Gemfile.lock | 5 +- Scripts/git/pre-commit-hook | 15 ---- Scripts/git/pre-commit-validator.rb | 88 -------------------- Scripts/git/pull-request-validator.rb | 10 +++ Scripts/sdk_utilities.rb | 58 ++----------- Scripts/sdk_validator.rb | 91 +++++++++++++++++++++ Scripts/update-sdk-version.rb | 3 - 8 files changed, 138 insertions(+), 159 deletions(-) create mode 100644 .github/workflows/validate-pull-request.yml delete mode 100644 Scripts/git/pre-commit-hook delete mode 100644 Scripts/git/pre-commit-validator.rb create mode 100644 Scripts/git/pull-request-validator.rb create mode 100644 Scripts/sdk_validator.rb diff --git a/.github/workflows/validate-pull-request.yml b/.github/workflows/validate-pull-request.yml new file mode 100644 index 0000000..f4cd9f7 --- /dev/null +++ b/.github/workflows/validate-pull-request.yml @@ -0,0 +1,27 @@ +name: MPSDK Pull Request Validator + +on: + pull_request: + branches: + - main + +jobs: + validate: + runs-on: macos-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Setup Ruby + uses: ruby/setup-ruby@v1 + with: + bundler-cache: true # runs 'bundle install' and caches installed gems automatically + + - name: Run Pull Request Validator + run: | + # Make sure the script is executable + chmod +x Scripts/git/pull-request-validator.rb + + # Run the validation script + ruby Scripts/git/pull-request-validator.rb diff --git a/Gemfile.lock b/Gemfile.lock index f8a42ed..27524c2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -8,8 +8,9 @@ GEM open3 (0.2.1) PLATFORMS - arm64-darwin-21 arm64-darwin-22 + arm64-darwin-23 + ruby DEPENDENCIES erb @@ -17,4 +18,4 @@ DEPENDENCIES open3 BUNDLED WITH - 2.3.21 + 2.5.5 diff --git a/Scripts/git/pre-commit-hook b/Scripts/git/pre-commit-hook deleted file mode 100644 index d97b5b5..0000000 --- a/Scripts/git/pre-commit-hook +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# Run the Ruby validation script -ruby Scripts/git/pre-commit-validator.rb - -# Capture the exit status of the Ruby script -status=$? - -# If the validation script fails (non-zero exit status), abort the commit -if [ $status -ne 0 ]; then - exit 1 -fi - -# Otherwise, allow the commit to proceed -exit 0 \ No newline at end of file diff --git a/Scripts/git/pre-commit-validator.rb b/Scripts/git/pre-commit-validator.rb deleted file mode 100644 index 372c8f1..0000000 --- a/Scripts/git/pre-commit-validator.rb +++ /dev/null @@ -1,88 +0,0 @@ -require_relative '../sdk_utilities' -require_relative '../sdk_constants' -require 'fileutils' - -class FileComparator - def self.compare(file1_path, file2_path) - unless File.exist?(file1_path) && File.exist?(file2_path) - return false - end - - file1 = File.open(file1_path) - file2 = File.open(file2_path) - - file1.each_line.zip(file2.each_line) do |line1, line2| - if line1 != line2 - file1.close - file2.close - return false - end - end - - file1.close - file2.close - - true - end -end - -def create_temp_dir - FileUtils.mkdir_p('tmp') -end - -def delete_temp_dir - FileUtils.rm_rf('tmp') -end - -def pass_validation - puts "✅ Pre-Commit Validation Passed!" - exit 0 -end - -def fail_validation - puts "❎ Pre-Commit Validation Failed. Aborting Commit" - exit 1 -end - -create_temp_dir - -template_builder = TemplateBuilder.new( - SquareMobilePaymentsSDK::VERSION, - SquareMobilePaymentsSDK::COMMIT_SHA, - SquareMobilePaymentsSDK::LICENSE, - SquareMobilePaymentsSDK::HOMEPAGE_URL, - SquareMobilePaymentsSDK::AUTHORS, - SquareMobilePaymentsSDK::IOS_DEPLOYMENT_TARGET -) - -# Generate Temporary README -template_builder.build_and_write('./Scripts/templates/README.md.erb', 'README.md', './tmp/') - -# Generate Temporary SquareMobilePaymentsSDK Podsepc -template_builder.build_and_write('./Scripts/templates/SquareMobilePaymentsSDK.podspec.erb', 'SquareMobilePaymentsSDK.podspec', './tmp/') - -# Generate Temporary MockReaderUI Podspec -template_builder.build_and_write('./Scripts/templates/MockReaderUI.podspec.erb', 'MockReaderUI.podspec', './tmp/') - -# Generate Temporary Package.swift -template_builder.build_and_write('./Scripts/templates/Package.swift.erb', 'Package.swift', './tmp/') - -# Validates no changes in the diff between generated files and the files being checked in -if FileComparator.compare('./README.md', './tmp/README.md') && - FileComparator.compare('./SquareMobilePaymentsSDK.podspec', './tmp/SquareMobilePaymentsSDK.podspec') && - FileComparator.compare('./MockReaderUI.podspec', './tmp/MockReaderUI.podspec') && - FileComparator.compare('./Package.swift', './tmp/Package.swift') - # All files are identical! - delete_temp_dir -else - puts "Please ensure you are modifying the erb template and not the actual file" - delete_temp_dir - fail_validation -end - -# Validate Podspec and Package.swift -if Validator.validate_podspecs && Validator.validate_spm_package - pass_validation -else - fail_validation -end diff --git a/Scripts/git/pull-request-validator.rb b/Scripts/git/pull-request-validator.rb new file mode 100644 index 0000000..63b26cb --- /dev/null +++ b/Scripts/git/pull-request-validator.rb @@ -0,0 +1,10 @@ +require_relative '../sdk_validator' + +# Validate Podspecs, SPM, and Templated Files +unless Validator.validate_podspecs && Validator.validate_spm_package && Validator.validate_template_files + puts "❎ Pull Request Validation Failed." + exit 1 +else + puts "✅ Pull Request Validation Passed!" + exit 0 +end diff --git a/Scripts/sdk_utilities.rb b/Scripts/sdk_utilities.rb index 7e83025..5b082b6 100644 --- a/Scripts/sdk_utilities.rb +++ b/Scripts/sdk_utilities.rb @@ -1,4 +1,5 @@ require 'erb' +require 'fileutils' require 'open3' class TemplateBuilder @@ -34,62 +35,17 @@ def self.execute(command) end end -class Validator - def self.validate_podspecs - puts "Validating Podspecs..." - command = "pod spec lint" - stdout, _stderr = CommandExecutor.execute(command) - stdout.scan(/^(\w+)/).flatten - if stdout.include?("All the specs passed validation.") - puts "✅ All podspecs have passed validation" - return true - else - puts "❎ Podspecs could not be validated" - puts stdout +class FileComparator + def self.compare(file1_path, file2_path) + unless File.exist?(file1_path) && File.exist?(file2_path) + puts "File at #{file1_path} or at #{file2_path} does not exist." return false end - end - def self.validate_spm_package - puts "Validating SPM Package..." - command = "swift package describe" - _stdout, stderr = CommandExecutor.execute(command) - stderr.scan(/^(\w+)/).flatten - # It is a known issue that SPM parser errors on binaryTargets. If it is the only error, then proceed as pass - if stderr.nil? || stderr.empty? || stderr.include?("error: unknown binary artifact file extension 'zip'") - puts "✅ SPM Package has passed validation" - return true - else - puts "❎ SPM Package could not be validated" - puts stderr + unless FileUtils.identical?(file1_path, file2_path) return false end - end -end - -class HookInstaller - def self.install_pre_commit_hook - pre_commit_hook_path = './Scripts/git/pre-commit-hook' - destination_path = '.git/hooks/pre-commit' - # Read the contents of the source file - begin - hook_content = File.read(pre_commit_hook_path) - rescue Errno::ENOENT => e - puts "❎ Error reading source file: #{e.message}" - return - end - - # Write the contents to the destination file - begin - File.open(destination_path, 'w') do |file| - file.write(hook_content) - end - # Make the hook script executable - File.chmod(0755, destination_path) - puts "✅ Pre-commit hook has been installed successfully." - rescue Errno::ENOENT, Errno::EACCES => e - puts "❎ Error writing to destination file: #{e.message}" - end + return true end end diff --git a/Scripts/sdk_validator.rb b/Scripts/sdk_validator.rb new file mode 100644 index 0000000..b929f09 --- /dev/null +++ b/Scripts/sdk_validator.rb @@ -0,0 +1,91 @@ +require_relative 'sdk_utilities' +require_relative 'sdk_constants' +require 'fileutils' + +class Validator + def self.validate_podspecs + puts "Validating Podspecs..." + + # Runs pod spec lint validation + command = "pod spec lint" + stdout, stderr = CommandExecutor.execute(command) + stdout.scan(/^(\w+)/).flatten + + # Validates output + unless stdout.include?("All the specs passed validation.") + puts "❎ Podspecs could not be validated" + puts stderr + return false + end + + puts "✅ All podspecs have passed validation" + return true + end + + def self.validate_spm_package + puts "Validating SPM Package..." + + # Resolves all packages in Package.swift + command = "swift package resolve" + _stdout, stderr = CommandExecutor.execute(command) + stderr.scan(/^(\w+)/).flatten + + # Validates output of resolve does not have errors. + unless stderr.nil? || stderr.empty? + puts "❎ SPM Package could not be validated" + puts stderr + return false + end + + packages_to_validate = [ + 'SquareMobilePaymentsSDK', + 'MockReaderUI' + ] + + # Validates SPM was able to resolve and extract the xcframeworks + for package in packages_to_validate do + unless File.directory?("./.build/artifacts/mobile-payments-sdk-ios/#{package}/#{package}.xcframework") + puts "❎ SPM was unable to resolve #{package}" + return false + end + end + + puts "✅ SPM package has passed validation" + return true + end + + def self.validate_template_files + # Creates a temporary directory to write to in the CI + FileUtils.mkdir_p('tmp') + + # Creates Template Builder + template_builder = TemplateBuilder.new( + SquareMobilePaymentsSDK::VERSION, + SquareMobilePaymentsSDK::COMMIT_SHA, + SquareMobilePaymentsSDK::LICENSE, + SquareMobilePaymentsSDK::HOMEPAGE_URL, + SquareMobilePaymentsSDK::AUTHORS, + SquareMobilePaymentsSDK::IOS_DEPLOYMENT_TARGET + ) + + files_to_test = [ + 'README.md', + 'SquareMobilePaymentsSDK.podspec', + 'MockReaderUI.podspec', + 'Package.swift' + ] + + # Validates the files found in the root of the repo match the output of the templated form of the file + for file in files_to_test do + template_builder.build_and_write("./Scripts/templates/#{file}.erb", file, './tmp/') + unless FileComparator.compare("./#{file}", "./tmp/#{file}") + puts "Output of #{file}.erb rendering does not match #{file_name}." + puts "Please ensure you are modifying the erb template and not the output file" + return false + end + end + + puts "✅ Template files have passed validation" + return true + end +end diff --git a/Scripts/update-sdk-version.rb b/Scripts/update-sdk-version.rb index 71285d9..587dd3c 100644 --- a/Scripts/update-sdk-version.rb +++ b/Scripts/update-sdk-version.rb @@ -1,9 +1,6 @@ require_relative 'sdk_utilities' require_relative 'sdk_constants' -# Install Pre-Commit Hook -HookInstaller.install_pre_commit_hook - template_builder = TemplateBuilder.new( SquareMobilePaymentsSDK::VERSION, SquareMobilePaymentsSDK::COMMIT_SHA, From 14f6d077bf3fb09a171a8329149201fb63cbfe48 Mon Sep 17 00:00:00 2001 From: Tamer Bader Date: Tue, 2 Jul 2024 11:17:36 -0700 Subject: [PATCH 3/5] Removing binding method and ensuring validation output files get cleaned --- Scripts/git/pull-request-validator.rb | 4 ++-- Scripts/sdk_utilities.rb | 8 +------- Scripts/sdk_validator.rb | 10 ++++++++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Scripts/git/pull-request-validator.rb b/Scripts/git/pull-request-validator.rb index 63b26cb..a1b317a 100644 --- a/Scripts/git/pull-request-validator.rb +++ b/Scripts/git/pull-request-validator.rb @@ -2,9 +2,9 @@ # Validate Podspecs, SPM, and Templated Files unless Validator.validate_podspecs && Validator.validate_spm_package && Validator.validate_template_files - puts "❎ Pull Request Validation Failed." + puts "❎ Pull Request Validation Failed" exit 1 else - puts "✅ Pull Request Validation Passed!" + puts "✅ Pull Request Validation Passed" exit 0 end diff --git a/Scripts/sdk_utilities.rb b/Scripts/sdk_utilities.rb index 5b082b6..23e4141 100644 --- a/Scripts/sdk_utilities.rb +++ b/Scripts/sdk_utilities.rb @@ -15,17 +15,11 @@ def initialize(version, commit_sha, license, homepage_url, authors, ios_deployme def build_and_write(template_path, file_name, output_dir) template = File.read(template_path) renderer = ERB.new(template) - result = renderer.result(get_binding) + result = renderer.result(binding) File.open("#{output_dir}#{file_name}", 'w+') do |file| file.write(result) end end - - private - - def get_binding - binding - end end class CommandExecutor diff --git a/Scripts/sdk_validator.rb b/Scripts/sdk_validator.rb index b929f09..c73c2d5 100644 --- a/Scripts/sdk_validator.rb +++ b/Scripts/sdk_validator.rb @@ -14,7 +14,7 @@ def self.validate_podspecs # Validates output unless stdout.include?("All the specs passed validation.") puts "❎ Podspecs could not be validated" - puts stderr + puts stdout return false end @@ -46,10 +46,13 @@ def self.validate_spm_package for package in packages_to_validate do unless File.directory?("./.build/artifacts/mobile-payments-sdk-ios/#{package}/#{package}.xcframework") puts "❎ SPM was unable to resolve #{package}" + FileUtils.rm_rf('.build') return false end end + FileUtils.rm_rf('.build') + puts "✅ SPM package has passed validation" return true end @@ -79,12 +82,15 @@ def self.validate_template_files for file in files_to_test do template_builder.build_and_write("./Scripts/templates/#{file}.erb", file, './tmp/') unless FileComparator.compare("./#{file}", "./tmp/#{file}") - puts "Output of #{file}.erb rendering does not match #{file_name}." + puts "Output of #{file}.erb rendering does not match #{file}." puts "Please ensure you are modifying the erb template and not the output file" + FileUtils.rm_rf('tmp') return false end end + FileUtils.rm_rf('tmp') + puts "✅ Template files have passed validation" return true end From 57117b4e046765c9dd09c1ff8c2c7b8fab1f0162 Mon Sep 17 00:00:00 2001 From: Tamer Bader Date: Tue, 2 Jul 2024 15:30:59 -0700 Subject: [PATCH 4/5] Updating green X icons to red X icons --- Scripts/git/pull-request-validator.rb | 2 +- Scripts/sdk_validator.rb | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Scripts/git/pull-request-validator.rb b/Scripts/git/pull-request-validator.rb index a1b317a..abe6b8e 100644 --- a/Scripts/git/pull-request-validator.rb +++ b/Scripts/git/pull-request-validator.rb @@ -2,7 +2,7 @@ # Validate Podspecs, SPM, and Templated Files unless Validator.validate_podspecs && Validator.validate_spm_package && Validator.validate_template_files - puts "❎ Pull Request Validation Failed" + puts "❌ Pull Request Validation Failed" exit 1 else puts "✅ Pull Request Validation Passed" diff --git a/Scripts/sdk_validator.rb b/Scripts/sdk_validator.rb index c73c2d5..c120c72 100644 --- a/Scripts/sdk_validator.rb +++ b/Scripts/sdk_validator.rb @@ -13,7 +13,7 @@ def self.validate_podspecs # Validates output unless stdout.include?("All the specs passed validation.") - puts "❎ Podspecs could not be validated" + puts "❌ Podspecs could not be validated" puts stdout return false end @@ -32,7 +32,7 @@ def self.validate_spm_package # Validates output of resolve does not have errors. unless stderr.nil? || stderr.empty? - puts "❎ SPM Package could not be validated" + puts "❌ SPM Package could not be validated" puts stderr return false end @@ -45,7 +45,7 @@ def self.validate_spm_package # Validates SPM was able to resolve and extract the xcframeworks for package in packages_to_validate do unless File.directory?("./.build/artifacts/mobile-payments-sdk-ios/#{package}/#{package}.xcframework") - puts "❎ SPM was unable to resolve #{package}" + puts "❌ SPM was unable to resolve #{package}" FileUtils.rm_rf('.build') return false end From 909ba79bf21bd0a31728bb94c8285c68d962678a Mon Sep 17 00:00:00 2001 From: Tamer Bader Date: Wed, 3 Jul 2024 09:18:30 -0700 Subject: [PATCH 5/5] Allowing github action to validate on push to main --- .github/workflows/validate-pull-request.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/validate-pull-request.yml b/.github/workflows/validate-pull-request.yml index f4cd9f7..a49a23b 100644 --- a/.github/workflows/validate-pull-request.yml +++ b/.github/workflows/validate-pull-request.yml @@ -4,6 +4,9 @@ on: pull_request: branches: - main + push: + branches: + - main jobs: validate: