Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow CRYSTAL env var to determine compiler #415

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion spec/support/factories.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions src/commands/build.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
13 changes: 10 additions & 3 deletions src/config.cr
Original file line number Diff line number Diff line change
Expand Up @@ -64,21 +64,28 @@ 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
end)
end

def self.crystal_version(@@crystal_version : String)
def self.crystal_version=(@@crystal_version : String)
end

private def self.without_prerelease(version)
Expand Down
40 changes: 39 additions & 1 deletion src/script.cr
Original file line number Diff line number Diff line change
Expand Up @@ -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 { "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)

{"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}#{Process::PATH_DELIMITER}#{suffix}" : prefix
end
end
end