-
-
Notifications
You must be signed in to change notification settings - Fork 103
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
Added a feature shards build
#136
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
require "./command" | ||
|
||
module Shards | ||
module Commands | ||
class Build < Command | ||
def run | ||
# Return if 'crystal' command is not installed | ||
return unless has_crystal_command? | ||
|
||
@sub ||= "default" | ||
|
||
if @sub == "all" | ||
manager.spec.targets.each do |target| | ||
build target | ||
end | ||
else | ||
target = manager.spec.targets.find{ |t| t.name == @sub } | ||
raise Error.new("Target \'#{@sub}\' is not found") if target.nil? | ||
build target | ||
end | ||
end | ||
|
||
def build(target) | ||
Shards.logger.info "Building: #{target.name}" | ||
|
||
error = MemoryIO.new | ||
status = Process.run("/bin/sh", input: MemoryIO.new(target.cmd), output: nil, error: error) | ||
raise Error.new("#{error.to_s}") unless status.success? | ||
end | ||
|
||
def has_crystal_command? | ||
raise Error.new("\'crystal\' is not installed") unless system("which crystal > /dev/null 2>&1") | ||
true | ||
end | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,13 +5,14 @@ require "../spec" | |
module Shards | ||
abstract class Command | ||
getter path : String | ||
getter sub : String | Nil | ||
getter spec_path : String | ||
getter lockfile_path : String | ||
|
||
@spec : Spec? | ||
@locks : Array(Dependency)? | ||
|
||
def initialize(path) | ||
def initialize(path, @sub = nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is |
||
if File.directory?(path) | ||
@path = path | ||
@spec_path = File.join(path, SPEC_FILENAME) | ||
|
@@ -24,8 +25,8 @@ module Shards | |
|
||
abstract def run | ||
|
||
def self.run(path) | ||
new(path).run | ||
def self.run(path, sub = nil) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unused change? It should be rolledback probably. |
||
new(path, sub).run | ||
end | ||
|
||
def spec | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,6 +3,7 @@ require "yaml" | |
require "./config" | ||
require "./dependency" | ||
require "./errors" | ||
require "./target" | ||
|
||
module Shards | ||
class Spec | ||
|
@@ -94,6 +95,21 @@ module Shards | |
read_mapping(pull) { dependency[pull.read_scalar] = pull.read_scalar } | ||
development_dependencies << dependency | ||
end | ||
when "targets" | ||
read_mapping(pull) do | ||
target = Target.new(pull.read_scalar) | ||
read_mapping(pull) do | ||
case pull.read_scalar | ||
when "main" | ||
target.main = pull.read_scalar | ||
when "options" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's avoid
|
||
read_sequence(pull) do | ||
target.options.push(pull.read_scalar) | ||
end | ||
end | ||
end | ||
targets << target | ||
end | ||
when "libraries" | ||
read_mapping(pull) do | ||
libraries << Library.new(pull) | ||
|
@@ -140,6 +156,10 @@ module Shards | |
@development_dependencies ||= [] of Dependency | ||
end | ||
|
||
def targets | ||
@targets ||= [] of Target | ||
end | ||
|
||
def libraries | ||
@libraries ||= [] of Library | ||
end | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module Shards | ||
class Target | ||
getter name : String | ||
property main : String | ||
property options : Array(String) | ||
|
||
def initialize(@name) | ||
super() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not needed: there are no superclass. |
||
@main = "" | ||
@options = [] of String | ||
end | ||
|
||
def cmd | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about |
||
"crystal build #{@main} #{@options.join(" ")}" | ||
end | ||
end | ||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
require "../integration_helper" | ||
|
||
class BuildCommandTest < Minitest::Test | ||
|
||
def test_succeeds_for_default | ||
metadata = { | ||
targets: { default: { main: "mock.cr" } } | ||
} | ||
|
||
with_shard(metadata) do | ||
Dir.cd(application_path) do | ||
File.open "mock.cr", "w" | ||
run "shards build" | ||
assert File.exists?(File.join(application_path, "mock")) | ||
end | ||
end | ||
end | ||
|
||
def test_succeeds_for_default_with_options | ||
metadata = { | ||
targets: { default: { main: "mock.cr", options: ["--release"] } } | ||
} | ||
|
||
with_shard(metadata) do | ||
Dir.cd(application_path) do | ||
File.open "mock.cr", "w" | ||
run "shards build" | ||
assert File.exists?(File.join(application_path, "mock")) | ||
end | ||
end | ||
end | ||
|
||
def test_succeeds_for_specified_target | ||
metadata = { | ||
targets: { mock: { main: "mock.cr" } } | ||
} | ||
|
||
with_shard(metadata) do | ||
Dir.cd(application_path) do | ||
File.open "mock.cr", "w" | ||
run "shards build mock" | ||
assert File.exists?(File.join(application_path, "mock")) | ||
end | ||
end | ||
end | ||
|
||
def test_succeeds_for_all_targets | ||
metadata = { targets: { | ||
mock1: { main: "mock1.cr" }, | ||
mock2: { main: "mock2.cr" } | ||
} } | ||
|
||
with_shard(metadata) do | ||
Dir.cd(application_path) do | ||
File.open "mock1.cr", "w" | ||
File.open "mock2.cr", "w" | ||
run "shards build all" | ||
assert File.exists?(File.join(application_path, "mock1")) | ||
assert File.exists?(File.join(application_path, "mock2")) | ||
end | ||
end | ||
end | ||
|
||
def test_fails_when_target_is_missing | ||
metadata = { targets: { mock: { main: "mock.cr" } } } | ||
|
||
with_shard(metadata) do | ||
Dir.cd(application_path) do | ||
File.open "mock.cr", "w" | ||
ex = assert_raises(FailedCommand) { run "shards build mock_fake" } | ||
assert_match "\e[31mTarget\e[0m 'mock_fake' is not found\n", ex.stdout | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please pass |
||
end | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
unused?