diff --git a/Makefile b/Makefile index 0d0b989a..23c7f5a2 100644 --- a/Makefile +++ b/Makefile @@ -36,9 +36,9 @@ uninstall: phony test: test_unit test_integration test_unit: phony - $(CRYSTAL) spec ./spec/unit/*_spec.cr + $(CRYSTAL) spec ./spec/unit/ test_integration: bin/shards phony - $(CRYSTAL) spec ./spec/integration/*_spec.cr + $(CRYSTAL) spec ./spec/integration/ phony: diff --git a/man/shards.1 b/man/shards.1 index 68ae844f..b6181e2c 100644 --- a/man/shards.1 +++ b/man/shards.1 @@ -39,6 +39,28 @@ dependencies are satisfied, dependencies aren't satisfied. .RE .PP +\fBinfo []\fR +.RS 4 +Displays information about a shard. +.SS +.RS 4 +Commands: +.PP +.TP 3 +\fB--name\fR +Print the name of the shard. +.TP 3 +\fB--version\fR +Print the version in `spec.yml`. +.TP 3 +\fB-h, --help\fR +Print usage synopsis. +.RE +.PP +.RS 4 +If no command is given, a summary including name and version is printed. +.RE +.PP \fBinit\fR .RS 4 Initializes a default \fIshard.yml\fR in the current folder. diff --git a/spec/integration/info_spec.cr b/spec/integration/info_spec.cr new file mode 100644 index 00000000..2eadaccb --- /dev/null +++ b/spec/integration/info_spec.cr @@ -0,0 +1,34 @@ +require "./spec_helper" + +describe "shards info" do + it "reports name" do + Dir.cd(application_path) do + with_shard({name: "foo"}) do + output = run "shards info --name" + output.should eq "foo\n" + end + end + end + + it "reports version" do + Dir.cd(application_path) do + with_shard({version: "1.2.3"}) do + output = run "shards info --version" + output.should eq "1.2.3\n" + end + end + end + + it "reports info" do + Dir.cd(application_path) do + with_shard({name: "foo", version: "1.2.3"}) do + output = run "shards info" + output.should eq <<-OUT + name: foo + version: 1.2.3 + + OUT + end + end + end +end diff --git a/spec/support/cli.cr b/spec/support/cli.cr index 600b6211..79004dff 100644 --- a/spec/support/cli.cr +++ b/spec/support/cli.cr @@ -1,3 +1,5 @@ +require "./factories" + Spec.before_each do path = application_path diff --git a/spec/support/factories.cr b/spec/support/factories.cr index 7d08293d..52ec959b 100644 --- a/spec/support/factories.cr +++ b/spec/support/factories.cr @@ -3,7 +3,7 @@ class FailedCommand < Exception getter stderr : String def initialize(message, @stdout, @stderr) - super message + super "#{message}: #{stderr}" end end diff --git a/spec/unit/commands/info_spec.cr b/spec/unit/commands/info_spec.cr new file mode 100644 index 00000000..2d952ab0 --- /dev/null +++ b/spec/unit/commands/info_spec.cr @@ -0,0 +1,24 @@ +require "../../../src/commands/info" +require "../spec_helper" +require "../../support/cli" + +private def capture(command, *args) + String.build do |io| + command.run(args.to_a, stdout: io) + end.chomp +end + +describe Shards::Commands::Info do + it "reports name" do + with_shard({name: "foo", version: "1.2.3"}) do + info = Shards::Commands::Info.new(application_path) + + capture(info, "--name").should eq "foo" + capture(info, "--version").should eq "1.2.3" + capture(info, "").should eq <<-OUT + name: foo + version: 1.2.3 + OUT + end + end +end diff --git a/src/cli.cr b/src/cli.cr index 3e778788..3b8274ac 100644 --- a/src/cli.cr +++ b/src/cli.cr @@ -2,13 +2,14 @@ require "option_parser" require "./commands/*" module Shards - def self.display_help_and_exit(opts) + def self.display_help(opts) puts <<-HELP shards [...] [] Commands: build [] [] - Build the specified in `bin` path. check - Verify all dependencies are installed. + info [...] - Show information about a shard. Pass `--help` for details. init - Initialize a `shard.yml` file. install - Install dependencies, creating or using the `shard.lock` file. list [--tree] - List installed dependencies. @@ -17,11 +18,12 @@ module Shards prune - Remove unused dependencies from `lib` folder. update [] - Update dependencies and `shard.lock`. version [] - Print the current version of the shard. + --version - Print the `shards` version. + -h, --help - Print usage synopsis. Options: HELP puts opts - exit end def self.run @@ -29,19 +31,19 @@ module Shards path = Dir.current opts.on("--no-color", "Disable colored output.") { self.colors = false } - opts.on("--version", "Print the `shards` version.") { puts self.version_string; exit } opts.on("--production", "Run in release mode. No development dependencies and strict sync between shard.yml and shard.lock.") { self.production = true } opts.on("--local", "Don't update remote repositories, use the local cache only.") { self.local = true } opts.on("-v", "--verbose", "Increase the log verbosity, printing all debug statements.") { self.set_debug_log_level } opts.on("-q", "--quiet", "Decrease the log verbosity, printing only warnings and errors.") { self.set_warning_log_level } - opts.on("-h", "--help", "Print usage synopsis.") { self.display_help_and_exit(opts) } opts.unknown_args do |args, options| - case args[0]? || DEFAULT_COMMAND + case args.shift? || DEFAULT_COMMAND when "build" - build(path, args[1..-1]) + build(path, args) when "check" Commands::Check.run(path) + when "info" + Commands::Info.run(path, args) when "init" Commands::Init.run(path) when "install" @@ -51,7 +53,7 @@ module Shards when "lock" Commands::Lock.run( path, - args[1..-1].reject(&.starts_with?("--")), + args.reject(&.starts_with?("--")), print: args.includes?("--print"), update: args.includes?("--update") ) @@ -62,12 +64,17 @@ module Shards when "update" Commands::Update.run( path, - args[1..-1].reject(&.starts_with?("--")) + args.reject(&.starts_with?("--")) ) when "version" - Commands::Version.run(args[1]? || path) + Commands::Info.run(args.shift? || path, ["--version"]) + when "--version" + puts self.version_string + when "-h", "--help" + display_help(opts) else - display_help_and_exit(opts) + display_help(opts) + exit 1 end exit diff --git a/src/commands/info.cr b/src/commands/info.cr new file mode 100644 index 00000000..2f4bf290 --- /dev/null +++ b/src/commands/info.cr @@ -0,0 +1,56 @@ +require "./command" + +module Shards + module Commands + class Info < Command + def initialize(path) + super lookup_path(path) + end + + def display_help + puts <<-HELP + shards info [] + + Displays information about a shard. + + Commands: + --name - Print the name of the shard. + --version - Print the version in `spec.yml`. + -h, --help - Print usage synopsis. + + If no command is given, a summary including name and version is printed. + HELP + end + + def run(args, *, stdout = STDOUT) + case args.shift? + when "--name" + stdout.puts spec.name + when "--version" + stdout.puts spec.version + when "--help", "-h" + display_help + else + stdout.puts " name: #{spec.name}" + stdout.puts "version: #{spec.version}" + end + end + + # look up for `SPEC_FILENAME` in *path* or up + private def lookup_path(path) + previous = nil + current = File.expand_path(path) + + until !File.directory?(current) || current == previous + shard_file = File.join(current, SPEC_FILENAME) + break if File.exists?(shard_file) + + previous = current + current = File.dirname(current) + end + + current + end + end + end +end diff --git a/src/commands/version.cr b/src/commands/version.cr deleted file mode 100644 index 804580b0..00000000 --- a/src/commands/version.cr +++ /dev/null @@ -1,32 +0,0 @@ -require "./command" - -module Shards - module Commands - class Version < Command - def self.run(path) - path = lookup_path(path) - new(path).run - end - - def run - puts spec.version - end - - # look up for `SPEC_FILENAME` in *path* or up - private def self.lookup_path(path) - previous = nil - current = File.expand_path(path) - - until !File.directory?(current) || current == previous - shard_file = File.join(current, SPEC_FILENAME) - break if File.exists?(shard_file) - - previous = current - current = File.dirname(current) - end - - current - end - end - end -end