From 18254bc5d8b9f0710a743d2bf2ac5a61584fa3ab Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 23 Jun 2020 14:42:20 -0300 Subject: [PATCH 1/7] Fix method to be setter Although it is not used. But that's the pattern followed in config.cr for now. --- src/config.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config.cr b/src/config.cr index 32460f4a..42f65112 100644 --- a/src/config.cr +++ b/src/config.cr @@ -78,7 +78,7 @@ module Shards end) end - def self.crystal_version(@@crystal_version : String) + def self.crystal_version=(@@crystal_version : String) end private def self.without_prerelease(version) From 5a8daa377428243088a1c10fd01a6440b8876974 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 23 Jun 2020 14:41:44 -0300 Subject: [PATCH 2/7] Lookup crystal location from CRYSTAL env var Avoid requiring crystal to be available in path. This can allow wrapper scripts on shards and have a cleaner override of the CRYSTAL_VERSION to use to resolve dependencies. --- spec/support/factories.cr | 2 +- src/commands/build.cr | 5 +++-- src/config.cr | 11 +++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/spec/support/factories.cr b/spec/support/factories.cr index 3f5daefa..133d1c44 100644 --- a/spec/support/factories.cr +++ b/spec/support/factories.cr @@ -121,7 +121,7 @@ end def run(command, *, env = nil) cmd_env = { - "CRYSTAL_PATH" => "#{Shards::INSTALL_DIR}:#{`crystal env CRYSTAL_PATH`.chomp}", + "CRYSTAL_PATH" => "#{Shards::INSTALL_DIR}:#{`#{Shards.crystal_bin} env CRYSTAL_PATH`.chomp}", } cmd_env.merge!(env) if env output, error = IO::Memory.new, IO::Memory.new diff --git a/src/commands/build.cr b/src/commands/build.cr index 30e90b3c..ef79d503 100644 --- a/src/commands/build.cr +++ b/src/commands/build.cr @@ -31,10 +31,11 @@ module Shards target.main, ] options.each { |option| args << option } - Log.debug { "crystal #{args.join(' ')}" } + Log.debug { "#{Shards.crystal_bin} #{args.join(' ')}" } error = IO::Memory.new - status = Process.run("crystal", args: args, output: Process::Redirect::Inherit, error: error) + + status = Process.run(Shards.crystal_bin, args: args, output: Process::Redirect::Inherit, error: error) raise Error.new("Error target #{target.name} failed to compile:\n#{error}") unless status.success? end end diff --git a/src/config.cr b/src/config.cr index 42f65112..5a83396a 100644 --- a/src/config.cr +++ b/src/config.cr @@ -64,14 +64,21 @@ module Shards def self.bin_path=(@@bin_path : String) end + def self.crystal_bin + @@crystal_bin ||= ENV.fetch("CRYSTAL", "crystal") + end + + def self.crystal_bin=(@@crystal_bin : String) + end + def self.crystal_version @@crystal_version ||= without_prerelease(ENV["CRYSTAL_VERSION"]? || begin output = IO::Memory.new error = IO::Memory.new status = begin - Process.run("crystal", {"env", "CRYSTAL_VERSION"}, output: output, error: error) + Process.run(crystal_bin, {"env", "CRYSTAL_VERSION"}, output: output, error: error) rescue e - raise Error.new("Could not execute 'crystal': #{e.message}") + raise Error.new("Could not execute '#{crystal_bin}': #{e.message}") end raise Error.new("Error executing crystal:\n#{error}") unless status.success? output.to_s.strip From b8e31cb89b8498e3f279cb7fb463dcd033151ba8 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 23 Jun 2020 15:26:18 -0300 Subject: [PATCH 3/7] Honor CRYSTAL env var in specs --- spec/integration/spec_helper.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/spec_helper.cr b/spec/integration/spec_helper.cr index 0c4749de..7d94e680 100644 --- a/spec/integration/spec_helper.cr +++ b/spec/integration/spec_helper.cr @@ -90,7 +90,7 @@ private def setup_repositories create_git_release "transitive", "0.2.0", { dependencies: {version: {git: git_path(:version)}}, scripts: { - postinstall: "crystal build src/version.cr", + postinstall: %(${CRYSTAL:-"crystal"} build src/version.cr), }, } From 8f968f6bd84dfc7ae9340eefde2de3ec5e02e255 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Wed, 24 Jun 2020 17:55:35 -0300 Subject: [PATCH 4/7] Create a temp directory with symlinks to shards and crystal --- src/script.cr | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/src/script.cr b/src/script.cr index c270aa5e..e13eac1b 100644 --- a/src/script.cr +++ b/src/script.cr @@ -6,9 +6,47 @@ module Shards def self.run(path, command, script_name, dependency_name) Dir.cd(path) do output = IO::Memory.new - status = Process.run("/bin/sh", input: IO::Memory.new(command), output: output, error: output) + status = Process.run("/bin/sh", env: Script.environment, input: IO::Memory.new(command), output: output, error: output) raise Error.new("Failed #{script_name} of #{dependency_name} on #{command}:\n#{output.to_s.rstrip}") unless status.success? end end + + @@environment : Process::Env = nil + + def self.environment : Process::Env + @@environment ||= + begin + bin_path = File.tempname(".shards-env") + Dir.mkdir(bin_path) + at_exit do + Dir.new(bin_path).each_child do |e| + File.delete(File.join(bin_path, e)) + end + Dir.delete bin_path + end + env_path = prepend_path(bin_path, ENV["PATH"]?) + Log.debug { "Creating shards script environment created at #{bin_path}. PATH=#{env_path}" } + + add_executable bin_path, "shards", Process.executable_path + add_executable bin_path, "crystal", Process.find_executable(Shards.crystal_bin) + + {"PATH" => env_path} + rescue e + Log.error(exception: e) { "Unable to create shards script environment" } + + {} of String => String + end + end + + private def self.add_executable(bin_path : String, name : String, original_path : String?) + if original_path + Log.debug { "Adding #{name}=#{original_path} to shards script environment" } + File.symlink(original_path, File.join(bin_path, name)) + end + end + + private def self.prepend_path(prefix : String, suffix : String?) + suffix ? "#{prefix}:#{suffix}" : prefix + end end end From 14a220c47dc3f5e986cc6ed4b4496ccd7b208e33 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Tue, 23 Jun 2020 15:26:18 -0300 Subject: [PATCH 5/7] Revert "Honor CRYSTAL env var in specs" This reverts commit b8e31cb89b8498e3f279cb7fb463dcd033151ba8. --- spec/integration/spec_helper.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/integration/spec_helper.cr b/spec/integration/spec_helper.cr index 7d94e680..0c4749de 100644 --- a/spec/integration/spec_helper.cr +++ b/spec/integration/spec_helper.cr @@ -90,7 +90,7 @@ private def setup_repositories create_git_release "transitive", "0.2.0", { dependencies: {version: {git: git_path(:version)}}, scripts: { - postinstall: %(${CRYSTAL:-"crystal"} build src/version.cr), + postinstall: "crystal build src/version.cr", }, } From 26990d7f01b5137956720177c2e4a0520b34b5ae Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Wed, 24 Jun 2020 20:12:42 -0300 Subject: [PATCH 6/7] Update src/script.cr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonne Haß --- src/script.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script.cr b/src/script.cr index e13eac1b..59fdad1d 100644 --- a/src/script.cr +++ b/src/script.cr @@ -25,7 +25,7 @@ module Shards Dir.delete bin_path end env_path = prepend_path(bin_path, ENV["PATH"]?) - Log.debug { "Creating shards script environment created at #{bin_path}. PATH=#{env_path}" } + Log.debug { "shards script environment created at #{bin_path}. Updated PATH=#{env_path}" } add_executable bin_path, "shards", Process.executable_path add_executable bin_path, "crystal", Process.find_executable(Shards.crystal_bin) From cfc818da1d9ee81592a63cc95d5e00353cbc94e3 Mon Sep 17 00:00:00 2001 From: "Brian J. Cardiff" Date: Wed, 24 Jun 2020 20:12:49 -0300 Subject: [PATCH 7/7] Update src/script.cr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jonne Haß --- src/script.cr | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/script.cr b/src/script.cr index 59fdad1d..356530f0 100644 --- a/src/script.cr +++ b/src/script.cr @@ -46,7 +46,7 @@ module Shards end private def self.prepend_path(prefix : String, suffix : String?) - suffix ? "#{prefix}:#{suffix}" : prefix + suffix ? "#{prefix}#{Process::PATH_DELIMITER}#{suffix}" : prefix end end end