Skip to content

Commit

Permalink
Merge pull request #399 from Shopify/fix-ruby-path-for-homebrew
Browse files Browse the repository at this point in the history
Fix Ruby path for Homebrew installations
  • Loading branch information
gonzaloriestra committed Aug 31, 2022
2 parents ef2cc39 + 08c42c4 commit 27b0eb6
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 27 deletions.
5 changes: 5 additions & 0 deletions .changeset/curly-lemons-check.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@shopify/cli-kit': patch
---

Use the Ruby bin directory from environment variable when provided (to fix homebrew issues)
8 changes: 4 additions & 4 deletions packages/cli-kit/src/node/ruby.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ describe('execCLI', () => {
})

it('throws an exception when RubyGems version requirement is not met', async () => {
const rubyVersion = '2.4.0'
const rubyVersion = '2.7.5'
const rubyGemsVersion = '2.3.0'
vi.mocked(file.exists).mockResolvedValue(true)
vi.mocked(system.captureOutput).mockResolvedValueOnce(rubyVersion)
Expand All @@ -39,7 +39,7 @@ describe('execCLI', () => {
})

it('throws an exception when Bundler is not installed', async () => {
const rubyVersion = '2.4.0'
const rubyVersion = '2.7.5'
const rubyGemsVersion = '2.6.0'
vi.mocked(file.exists).mockResolvedValue(true)
vi.mocked(system.captureOutput).mockResolvedValueOnce(rubyVersion)
Expand All @@ -50,7 +50,7 @@ describe('execCLI', () => {
})

it('throws an exception when Bundler version requirement is not met', async () => {
const rubyVersion = '2.4.0'
const rubyVersion = '2.7.5'
const rubyGemsVersion = '2.5.0'
const bundlerVersion = '2.2.0'
vi.mocked(file.exists).mockResolvedValue(true)
Expand All @@ -64,7 +64,7 @@ describe('execCLI', () => {
})

it('throws an exception when creating CLI working directory', async () => {
const rubyVersion = '2.4.0'
const rubyVersion = '2.7.5'
const rubyGemsVersion = '2.5.0'
const bundlerVersion = '2.4.0'
vi.mocked(file.exists).mockResolvedValue(true)
Expand Down
54 changes: 35 additions & 19 deletions packages/cli-kit/src/node/ruby.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {Writable} from 'node:stream'
const RubyCLIVersion = '2.23.0'
const ThemeCheckVersion = '1.10.3'
const MinBundlerVersion = '2.3.8'
const MinRubyVersion = '2.3.0'
const MinRubyVersion = '2.7.5'
const MinRubyGemVersion = '2.5.0'

interface ExecCLI2Options {
Expand Down Expand Up @@ -46,7 +46,7 @@ export async function execCLI2(args: string[], {adminSession, storefrontToken, d
}

try {
await system.exec('bundle', ['exec', 'shopify'].concat(args), {
await system.exec(bundleBinary(), ['exec', 'shopify'].concat(args), {
stdio: 'inherit',
cwd: directory ?? process.cwd(),
env,
Expand Down Expand Up @@ -100,7 +100,7 @@ export async function execThemeCheckCLI({
}
},
})
await system.exec('bundle', ['exec', 'theme-check'].concat([directory, ...(args || [])]), {
await system.exec(bundleBinary(), ['exec', 'theme-check'].concat([directory, ...(args || [])]), {
stdout,
stderr: customStderr,
cwd: themeCheckDirectory(),
Expand Down Expand Up @@ -178,13 +178,13 @@ async function validateRubyEnv() {
async function validateRuby() {
let version
try {
const stdout = await system.captureOutput('ruby', ['-v'])
const stdout = await system.captureOutput(rubyBinary(), ['-v'])
version = coerce(stdout)
} catch {
throw new Abort(
'Ruby environment not found',
`Make sure you have Ruby installed on your system: ${
content`${token.link('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value
`Make sure you have Ruby installed on your system. ${
content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value
}`,
)
}
Expand All @@ -193,23 +193,23 @@ async function validateRuby() {
if (isValid === -1 || isValid === undefined) {
throw new Abort(
`Ruby version ${content`${token.yellow(version.raw)}`.value} is not supported`,
`Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system: ${
content`${token.link('', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value
`Make sure you have at least Ruby ${content`${token.yellow(MinRubyVersion)}`.value} installed on your system. ${
content`${token.link('Documentation.', 'https://www.ruby-lang.org/en/documentation/installation/')}`.value
}`,
)
}
}

async function validateRubyGems() {
const stdout = await system.captureOutput('gem', ['-v'])
const stdout = await system.captureOutput(`${rubyBinDir()}gem`, ['-v'])
const version = coerce(stdout)

const isValid = version?.compare(MinRubyGemVersion)
if (isValid === -1 || isValid === undefined) {
throw new Abort(
`RubyGems version ${content`${token.yellow(version.raw)}`.value} is not supported`,
`To update to the latest version of RubyGems, run ${
content`${token.genericShellCommand('gem update --system')}`.value
content`${token.genericShellCommand(`${rubyBinDir()}gem update --system`)}`.value
}`,
)
}
Expand All @@ -218,13 +218,13 @@ async function validateRubyGems() {
async function validateBundler() {
let version
try {
const stdout = await system.captureOutput('bundler', ['-v'])
const stdout = await system.captureOutput(bundleBinary(), ['-v'])
version = coerce(stdout)
} catch {
throw new Abort(
'Bundler not found',
`To install the latest version of Bundler, run ${
content`${token.genericShellCommand('gem install bundler')}`.value
content`${token.genericShellCommand(`${rubyBinDir()}gem install bundler`)}`.value
}`,
)
}
Expand All @@ -234,7 +234,7 @@ async function validateBundler() {
throw new Abort(
`Bundler version ${content`${token.yellow(version.raw)}`.value} is not supported`,
`To update to the latest version of Bundler, run ${
content`${token.genericShellCommand('gem install bundler')}`.value
content`${token.genericShellCommand(`${rubyBinDir()}gem install bundler`)}`.value
}`,
)
}
Expand All @@ -259,17 +259,21 @@ async function createThemeCheckGemfile() {
}

async function bundleInstallLocalShopifyCLI() {
await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})
await system.exec(bundleBinary(), ['install'], {cwd: shopifyCLIDirectory()})
}

async function bundleInstallShopifyCLI() {
await system.exec('bundle', ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {cwd: shopifyCLIDirectory()})
await system.exec('bundle', ['install'], {cwd: shopifyCLIDirectory()})
await system.exec(bundleBinary(), ['config', 'set', '--local', 'path', shopifyCLIDirectory()], {
cwd: shopifyCLIDirectory(),
})
await system.exec(bundleBinary(), ['install'], {cwd: shopifyCLIDirectory()})
}

async function bundleInstallThemeCheck() {
await system.exec('bundle', ['config', 'set', '--local', 'path', themeCheckDirectory()], {cwd: themeCheckDirectory()})
await system.exec('bundle', ['install'], {cwd: themeCheckDirectory()})
await system.exec(bundleBinary(), ['config', 'set', '--local', 'path', themeCheckDirectory()], {
cwd: themeCheckDirectory(),
})
await system.exec(bundleBinary(), ['install'], {cwd: themeCheckDirectory()})
}

function shopifyCLIDirectory() {
Expand All @@ -286,7 +290,19 @@ function themeCheckDirectory() {
export async function version(): Promise<string | undefined> {
const parseOutput = (version: string) => version.match(/ruby (\d+\.\d+\.\d+)/)?.[1]
return system
.captureOutput('ruby', ['-v'])
.captureOutput(rubyBinary(), ['-v'])
.then(parseOutput)
.catch(() => undefined)
}

function rubyBinDir(): string {
return process.env.SHOPIFY_RUBY_BINDIR || ''
}

function rubyBinary(): string {
return `${rubyBinDir()}ruby`
}

function bundleBinary(): string {
return `${rubyBinDir()}bundle`
}
16 changes: 12 additions & 4 deletions packaging/src/shopify-cli@3.rb.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

require "formula"
require "language/node"
require "fileutils"

class ShopifyCliAT3 < Formula
desc "A CLI tool to build for the Shopify platform"
Expand Down Expand Up @@ -35,11 +36,18 @@ class ShopifyCliAT3 < Formula

system "npm", "install", *Language::Node.std_npm_install_args(libexec)

executable_path = "#{libexec}/bin/shopify"
executable_3_path = "#{libexec}/bin/shopify3"
File.symlink executable_path, executable_3_path
executable_path = "#{libexec}/bin/shopify3"
executable_content = <<~SCRIPT
#!/usr/bin/env node

bin.install_symlink executable_3_path
process.env.SHOPIFY_RUBY_BINDIR = Formula["ruby"].opt_bin

import("./shopify");
SCRIPT
File.write executable_path, executable_content
FileUtils.chmod("+x", executable_path)

bin.install_symlink executable_path

resource("cli-theme-commands").stage {
system "npm", "install", *Language::Node.std_npm_install_args(libexec)
Expand Down

0 comments on commit 27b0eb6

Please sign in to comment.