diff --git a/spec/compiler/crystal/tools/init_spec.cr b/spec/compiler/crystal/tools/init_spec.cr index fa70296481f1..40e32651f077 100644 --- a/spec/compiler/crystal/tools/init_spec.cr +++ b/spec/compiler/crystal/tools/init_spec.cr @@ -6,17 +6,14 @@ require "spec" require "yaml" PROJECT_ROOT_DIR = "#{__DIR__}/../../../.." -BIN_CRYSTAL = File.expand_path("#{PROJECT_ROOT_DIR}/bin/crystal") private def exec_init(project_name, project_dir = nil, type = "lib") - args = ["init", type, project_name] + args = [type, project_name] args << project_dir if project_dir - process = Process.new(BIN_CRYSTAL, args, shell: true, error: Process::Redirect::Pipe) - stderr = process.error.gets_to_end - status = process.wait - $? = status - stderr + config = Crystal::Init.parse_args(args) + config.silent = true + Crystal::Init::InitProject.new(config).run end # Creates a temporary directory, cd to it and run the block inside it. @@ -193,11 +190,16 @@ end within_temporary_directory do existing_dir = "existing-dir" Dir.mkdir(existing_dir) - exec_init(existing_dir).should contain("file or directory #{existing_dir} already exists") + + expect_raises(Crystal::Init::Error, "File or directory #{existing_dir} already exists") do + exec_init(existing_dir) + end existing_file = "existing-file" File.touch(existing_file) - exec_init(existing_file).should contain("file or directory #{existing_file} already exists") + expect_raises(Crystal::Init::Error, "File or directory #{existing_file} already exists") do + exec_init(existing_file) + end end end @@ -208,9 +210,11 @@ end Dir.mkdir(project_name) - exec_init(project_name, project_dir).should_not contain("file or directory #{project_name} already exists") + exec_init(project_name, project_dir) - exec_init(project_name, project_dir).should contain("file or directory #{project_dir} already exists") + expect_raises(Crystal::Init::Error, "File or directory #{project_dir} already exists") do + exec_init(project_name, project_dir) + end end end end diff --git a/src/compiler/crystal/command.cr b/src/compiler/crystal/command.cr index c46cf0174347..f08cce6c8454 100644 --- a/src/compiler/crystal/command.cr +++ b/src/compiler/crystal/command.cr @@ -157,7 +157,12 @@ class Crystal::Command end private def init - Init.run(options) + begin + Init.run(options) + rescue ex : Init::Error + STDERR.puts ex + exit 1 + end end private def build diff --git a/src/compiler/crystal/tools/init.cr b/src/compiler/crystal/tools/init.cr index 151325324fa1..0238f77160dd 100644 --- a/src/compiler/crystal/tools/init.cr +++ b/src/compiler/crystal/tools/init.cr @@ -7,7 +7,18 @@ module Crystal module Init WHICH_GIT_COMMAND = "which git >/dev/null" + class Error < ::Exception + def self.new(message, opts : OptionParser) + new("#{message}\n#{opts}\n") + end + end + def self.run(args) + config = parse_args(args) + InitProject.new(config).run + end + + def self.parse_args(args) config = Config.new OptionParser.parse(args) do |opts| @@ -40,7 +51,7 @@ module Crystal config.author = fetch_author config.email = fetch_email config.github_name = fetch_github_name - InitProject.new(config).run + config end def self.fetch_author @@ -74,8 +85,7 @@ module Crystal def self.fetch_directory(args, project_name) directory = args.empty? ? project_name : args.shift if Dir.exists?(directory) || File.exists?(directory) - STDERR.puts "file or directory #{directory} already exists" - exit 1 + raise Error.new "File or directory #{directory} already exists" end directory end @@ -83,18 +93,14 @@ module Crystal def self.fetch_skeleton_type(opts, args) skeleton_type = fetch_required_parameter(opts, args, "TYPE") unless {"lib", "app"}.includes?(skeleton_type) - STDERR.puts "invalid TYPE value: #{skeleton_type}" - STDERR.puts opts - exit 1 + raise Error.new "Invalid TYPE value: #{skeleton_type}", opts end skeleton_type end def self.fetch_required_parameter(opts, args, name) if args.empty? - STDERR.puts "#{name} is missing" - STDERR.puts opts - exit 1 + raise Error.new "Argument #{name} is missing", opts end args.shift end