diff --git a/ext/shopify-extensions/shopify_extensions.rb b/ext/shopify-extensions/shopify_extensions.rb index 0ba4383a0b..55f84105af 100644 --- a/ext/shopify-extensions/shopify_extensions.rb +++ b/ext/shopify-extensions/shopify_extensions.rb @@ -4,9 +4,7 @@ require "zlib" require "rubygems" require "rubygems/package" - -require_relative "../../vendor/deps/cli-kit/lib/cli/kit" -require_relative "../../vendor/deps/cli-ui/lib/cli/ui" +require "open3" module ShopifyExtensions class InstallationError < RuntimeError @@ -32,18 +30,17 @@ def self.call(platform: Platform.new, **args) new.call(platform: platform, **args) end - def call(platform:, version:, source:, target:) - source = platform.format_path(source) + def call(platform:, version:, target:) target = platform.format_path(target) releases .find { |release| release.version == version } .tap { |release| raise InstallationError.release_not_found unless release } - .download(platform: platform, source: source, target: target) + .download(platform: platform, target: target) raise InstallationError.not_executable unless File.executable?(target) - installed_server_version, _ = CLI::Kit::System.capture2(target, "version") + installed_server_version, _ = Open3.capture2(target, "version") raise InstallationError.incorrect_version unless installed_server_version.strip == version.strip end @@ -72,11 +69,11 @@ def self.to_proc end end - def download(platform:, source:, target:) + def download(platform:, target:) assets .filter(&:binary?) .find { |asset| asset.os == platform.os && asset.cpu == platform.cpu } - .download(source: source, target: target) + .download(target: target) end end @@ -90,17 +87,17 @@ def self.to_proc end end - def download(source:, target:) + def download(target:) Dir.chdir(File.dirname(target)) do File.open(File.basename(target), "w") do |target_file| - unpack(source, from: decompress(URI.parse(url).open), to: target_file) + decompress(URI.parse(url).open, target_file) end File.chmod(0755, target) end end def binary? - !!/(tar\.gz)|(zip)$/.match(name) + !!/\.gz$/.match(name) end def checksum? @@ -115,33 +112,20 @@ def cpu name_without_extension.split("-")[-1] end - def version - name_without_extension.split("-")[-3] - end - private - def decompress(archive) - decoder = Zlib::GzipReader.new(archive) - unzipped = StringIO.new(decoder.read) - decoder.close - unzipped - end - - def unpack(name, from:, to:) - Gem::Package::TarReader.new(from) do |tar| - tar.each do |entry| - next unless File.basename(entry.full_name) == name - to.write(entry.read) - end - end + def decompress(source, target) + zlib = Zlib::GzipReader.new(source) + target << zlib.read + ensure + zlib.close end def name_without_extension if binary? - File.basename(name, ".tar.gz") + File.basename(File.basename(name, ".gz"), ".exe") elsif checksum? - File.basename(name, "_checksum.txt") + File.basename(File.basename(name, ".md5"), ".exe") else raise NotImplementedError, "Unknown file type" end @@ -155,7 +139,7 @@ def initialize(ruby_config = RbConfig::CONFIG) def format_path(path) case os when "windows" - path + ".exe" + File.extname(path) != ".exe" ? path + ".exe" : path else path end diff --git a/test/ext/shopify-extensions/shopify_extensions_test.rb b/test/ext/shopify-extensions/shopify_extensions_test.rb index ef0a619a8e..3937089531 100644 --- a/test/ext/shopify-extensions/shopify_extensions_test.rb +++ b/test/ext/shopify-extensions/shopify_extensions_test.rb @@ -3,7 +3,7 @@ module ShopifyExtensions class ShopfyExtensionsTest < Minitest::Test - def test_installation_of_existing_version + def test_installation_of_existing_version_for_mac_os stub_releases_request stub_executable_download @@ -15,7 +15,6 @@ def test_installation_of_existing_version "host_cpu" => "x86_64", }), version: "v0.1.0", - source: "shopify-extensions", target: target ) @@ -24,6 +23,25 @@ def test_installation_of_existing_version assert_match(/v0.1.0/, %x(#{target})) end + def test_installation_of_existing_version_for_windows + stub_releases_request + stub_executable_download + + target = File.join(dir = Dir.mktmpdir, "shopify-extensions.exe") + + Install.call( + platform: Platform.new({ + "host_os" => "mingw32", + "host_cpu" => "x64", + }), + version: "v0.1.0", + target: target + ) + + assert File.file?(target) + assert File.executable?(target) + end + def test_installation_of_non_existing_version stub_releases_request stub_executable_download @@ -37,7 +55,6 @@ def test_installation_of_non_existing_version "host_cpu" => "x86_64", }), version: "v0.0.0", - source: "shopify-extensions", target: target ) end @@ -80,143 +97,231 @@ def ruby_config(os:, cpu:) end class AssetTest < MiniTest::Test - def test_initialization + def test_initialization_for_mac_os asset = Asset.new( - name: "shopify-extensions-v0.1.0-darwin-amd64.tar.gz", - url: "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-v0.1.0-darwin-amd64.tar.gz" + name: "shopify-extensions-v0.1.0-darwin-amd64.gz", + url: "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-darwin-amd64.gz" ) - assert_equal "v0.1.0", asset.version assert_equal "darwin", asset.os assert_equal "amd64", asset.cpu end + + def test_initialization_for_windows + asset = Asset.new( + name: "shopify-extensions-v0.1.0-windows-amd64.exe.gz", + url: "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-windows-amd64.exe.gz" + ) + + assert_equal "windows", asset.os + assert_equal "amd64", asset.cpu + end end def stub_releases_request stub_request(:get, "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases") .to_return(status: 200, body: <<~JSON) - [ - { - "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/49152028", - "assets_url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/49152028/assets", - "upload_url": "https://uploads.github.com/repos/Shopify/shopify-cli-extensions/releases/49152028/assets{?name,label}", - "html_url": "https://github.com/Shopify/shopify-cli-extensions/releases/tag/v0.1.0", - "id": 49152028, - "author": { - "login": "t6d", - "id": 77060, - "node_id": "MDQ6VXNlcjc3MDYw", - "avatar_url": "https://avatars.githubusercontent.com/u/77060?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/t6d", - "html_url": "https://github.com/t6d", - "followers_url": "https://api.github.com/users/t6d/followers", - "following_url": "https://api.github.com/users/t6d/following{/other_user}", - "gists_url": "https://api.github.com/users/t6d/gists{/gist_id}", - "starred_url": "https://api.github.com/users/t6d/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/t6d/subscriptions", - "organizations_url": "https://api.github.com/users/t6d/orgs", - "repos_url": "https://api.github.com/users/t6d/repos", - "events_url": "https://api.github.com/users/t6d/events{/privacy}", - "received_events_url": "https://api.github.com/users/t6d/received_events", - "type": "User", - "site_admin": false + [ + { + "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/49531769", + "assets_url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/49531769/assets", + "upload_url": "https://uploads.github.com/repos/Shopify/shopify-cli-extensions/releases/49531769/assets{?name,label}", + "html_url": "https://github.com/Shopify/shopify-cli-extensions/releases/tag/v0.1.0", + "id": 49531769, + "author": { + "login": "t6d", + "id": 77060, + "node_id": "MDQ6VXNlcjc3MDYw", + "avatar_url": "https://avatars.githubusercontent.com/u/77060?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/t6d", + "html_url": "https://github.com/t6d", + "followers_url": "https://api.github.com/users/t6d/followers", + "following_url": "https://api.github.com/users/t6d/following{/other_user}", + "gists_url": "https://api.github.com/users/t6d/gists{/gist_id}", + "starred_url": "https://api.github.com/users/t6d/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/t6d/subscriptions", + "organizations_url": "https://api.github.com/users/t6d/orgs", + "repos_url": "https://api.github.com/users/t6d/repos", + "events_url": "https://api.github.com/users/t6d/events{/privacy}", + "received_events_url": "https://api.github.com/users/t6d/received_events", + "type": "User", + "site_admin": false + }, + "node_id": "RE_kwDOF4czm84C88t5", + "tag_name": "v0.1.0", + "target_commitish": "main", + "name": "v0.1.0", + "draft": false, + "prerelease": true, + "created_at": "2021-09-14T13:43:17Z", + "published_at": "2021-09-14T14:04:11Z", + "assets": [ + { + "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/assets/44743653", + "id": 44743653, + "node_id": "RA_kwDOF4czm84Cqrvl", + "name": "shopify-extensions-darwin-amd64.gz", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/gzip", + "state": "uploaded", + "size": 5073690, + "download_count": 0, + "created_at": "2021-09-14T14:04:52Z", + "updated_at": "2021-09-14T14:04:53Z", + "browser_download_url": "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-darwin-amd64.gz" }, - "node_id": "MDc6UmVsZWFzZTQ5MTUyMDI4", - "tag_name": "v0.1.0", - "target_commitish": "main", - "name": "v0.1.0", - "draft": false, - "prerelease": true, - "created_at": "2021-09-07T19:18:18Z", - "published_at": "2021-09-07T19:28:55Z", - "assets": [ - { - "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/assets/44246360", - "id": 44246360, - "node_id": "MDEyOlJlbGVhc2VBc3NldDQ0MjQ2MzYw", - "name": "shopify-extensions-v0.1.0-darwin-amd64.tar.gz", - "label": "", - "uploader": { - "login": "github-actions[bot]", - "id": 41898282, - "node_id": "MDM6Qm90NDE4OTgyODI=", - "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/github-actions%5Bbot%5D", - "html_url": "https://github.com/apps/github-actions", - "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", - "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", - "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", - "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", - "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", - "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", - "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", - "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", - "type": "Bot", - "site_admin": false - }, - "content_type": "application/gzip", - "state": "uploaded", - "size": 5072802, - "download_count": 1, - "created_at": "2021-09-07T19:29:43Z", - "updated_at": "2021-09-07T19:29:44Z", - "browser_download_url": "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-v0.1.0-darwin-amd64.tar.gz" + { + "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/assets/44743655", + "id": 44743655, + "node_id": "RA_kwDOF4czm84Cqrvn", + "name": "shopify-extensions-darwin-amd64.md5", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false }, - { - "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/assets/44246361", - "id": 44246361, - "node_id": "MDEyOlJlbGVhc2VBc3NldDQ0MjQ2MzYx", - "name": "shopify-extensions-v0.1.0-darwin-amd64.tar.gz.md5", - "label": "", - "uploader": { - "login": "github-actions[bot]", - "id": 41898282, - "node_id": "MDM6Qm90NDE4OTgyODI=", - "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/github-actions%5Bbot%5D", - "html_url": "https://github.com/apps/github-actions", - "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", - "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", - "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", - "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", - "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", - "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", - "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", - "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", - "type": "Bot", - "site_admin": false - }, - "content_type": "text/plain", - "state": "uploaded", - "size": 33, - "download_count": 0, - "created_at": "2021-09-07T19:29:44Z", - "updated_at": "2021-09-07T19:29:45Z", - "browser_download_url": "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-v0.1.0-darwin-amd64.tar.gz.md5" - } - ], - "tarball_url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/tarball/v0.1.0", - "zipball_url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/zipball/v0.1.0", - "body": "Pre-release of `shopify-extensions` for testing the integration with the Shopify CLI." - } - ] + "content_type": "application/octet-stream", + "state": "uploaded", + "size": 53, + "download_count": 0, + "created_at": "2021-09-14T14:04:53Z", + "updated_at": "2021-09-14T14:04:53Z", + "browser_download_url": "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-darwin-amd64.md5" + }, + { + "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/assets/44743627", + "id": 44743627, + "node_id": "RA_kwDOF4czm84CqrvL", + "name": "shopify-extensions-windows-amd64.exe.gz", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/gzip", + "state": "uploaded", + "size": 5121839, + "download_count": 0, + "created_at": "2021-09-14T14:04:46Z", + "updated_at": "2021-09-14T14:04:47Z", + "browser_download_url": "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-windows-amd64.exe.gz" + }, + { + "url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/releases/assets/44743629", + "id": 44743629, + "node_id": "RA_kwDOF4czm84CqrvN", + "name": "shopify-extensions-windows-amd64.exe.md5", + "label": "", + "uploader": { + "login": "github-actions[bot]", + "id": 41898282, + "node_id": "MDM6Qm90NDE4OTgyODI=", + "avatar_url": "https://avatars.githubusercontent.com/in/15368?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/github-actions%5Bbot%5D", + "html_url": "https://github.com/apps/github-actions", + "followers_url": "https://api.github.com/users/github-actions%5Bbot%5D/followers", + "following_url": "https://api.github.com/users/github-actions%5Bbot%5D/following{/other_user}", + "gists_url": "https://api.github.com/users/github-actions%5Bbot%5D/gists{/gist_id}", + "starred_url": "https://api.github.com/users/github-actions%5Bbot%5D/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/github-actions%5Bbot%5D/subscriptions", + "organizations_url": "https://api.github.com/users/github-actions%5Bbot%5D/orgs", + "repos_url": "https://api.github.com/users/github-actions%5Bbot%5D/repos", + "events_url": "https://api.github.com/users/github-actions%5Bbot%5D/events{/privacy}", + "received_events_url": "https://api.github.com/users/github-actions%5Bbot%5D/received_events", + "type": "Bot", + "site_admin": false + }, + "content_type": "application/octet-stream", + "state": "uploaded", + "size": 57, + "download_count": 0, + "created_at": "2021-09-14T14:04:47Z", + "updated_at": "2021-09-14T14:04:47Z", + "browser_download_url": "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-windows-amd64.exe.md5" + } + ], + "tarball_url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/tarball/v0.1.0", + "zipball_url": "https://api.github.com/repos/Shopify/shopify-cli-extensions/zipball/v0.1.0", + "body": "Initial release for integration testing purposes only." + } + ] JSON end def stub_executable_download dummy_archive = load_dummy_archive - stub_request(:get, "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-v0.1.0-darwin-amd64.tar.gz") + stub_request(:get, "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-windows-amd64.exe.gz") + .to_return( + status: 200, + headers: { + "Content-Type" => "application/octet-stream", + "Content-Disposition" => "attachment; filename=shopify-extensions-windows-amd64.exe.gz", + "Content-Length" => dummy_archive.size, + }, + body: dummy_archive + ) + + stub_request(:get, "https://github.com/Shopify/shopify-cli-extensions/releases/download/v0.1.0/shopify-extensions-darwin-amd64.gz") .to_return( status: 200, headers: { "Content-Type" => "application/octet-stream", - "Content-Disposition" => "attachment; filename=shopify-extensions_0.1.0_darwin_amd64.tar.gz", + "Content-Disposition" => "attachment; filename=shopify-extensions-darwin-amd64.gz", "Content-Length" => dummy_archive.size, }, body: dummy_archive @@ -224,7 +329,7 @@ def stub_executable_download end def load_dummy_archive - path = File.expand_path("../../../fixtures/shopify-extensions.tar.gz", __FILE__) + path = File.expand_path("../../../fixtures/shopify-extensions.gz", __FILE__) raise "Dummy archive not found: #{path}" unless File.file?(path) File.read(path) end diff --git a/test/fixtures/shopify-extensions.gz b/test/fixtures/shopify-extensions.gz new file mode 100755 index 0000000000..b61cd670b9 Binary files /dev/null and b/test/fixtures/shopify-extensions.gz differ diff --git a/test/fixtures/shopify-extensions.tar.gz b/test/fixtures/shopify-extensions.tar.gz deleted file mode 100644 index ea0c00cc15..0000000000 Binary files a/test/fixtures/shopify-extensions.tar.gz and /dev/null differ