If the full path to the current project directory contains any spaces, then amber can't build the project. Originally reported by @elorest
mkdir "stupid path"
cd "stupid path"
amber new test3 -d sqlite
cd test3
shards
amber w
amber new test3 -d sqlite
mv test3 "test three"
cd "test three"
shards
amber w
Expected behavior: amber w succeeds
Actual behavior:
09:00:10 Watcher | Building project Test3...
Error in src/test3.cr:1: while requiring "../config/*": can't specify arguments in both, command and args without including "${@}" into your command
require "../config/*"
^
09:00:12 Watcher | Starting Test3...
execvp: No such file or directory (Errno)
from Process::exec_internal<String, Array(Pointer(UInt8)), Nil, Bool, (IO::FileDescriptor | Process::Redirect), (IO::FileDescriptor | Process::Redirect), (IO::FileDescriptor | Process::Redirect), Nil>:Nil
from Process#initialize:output:error<String, Process::Redirect, Process::Redirect>:Nil
from Process::new:output:error<String, Process::Redirect, Process::Redirect>:Process
from Sentry::ProcessRunner#create_watch_process:Process
from Sentry::ProcessRunner#create_all_processes:(IO+ | Nil)
from Sentry::ProcessRunner#start_all_processes:(IO+ | Nil)
from Sentry::ProcessRunner#start_app:(IO+ | Nil)
from Sentry::ProcessRunner#scan_files:(IO+ | Nil)
from Sentry::ProcessRunner#run:NoReturn
from Amber::CLI::MainCommand::Watch@Sentry::SentryCommand#run:NoReturn
from Amber::CLI::MainCommand::Watch#run:NoReturn
from Cli::CommandClass+@Cli::CommandClass#amber_cli_main_command_watch__run<Cli::CommandBase+, Array(String)>:Cli::Exit
from ~procProc(Cli::CommandBase, Array(String), Nil)@src/amber/cli/commands/watch.cr:8
from Cli::CommandClass+@Cli::CommandClass#run<Amber::CLI::MainCommand, Array(String)>:Nil
from Cli::CommandClass::Alias#run<Amber::CLI::MainCommand, Array(String)>:Nil
from Amber::CLI::MainCommand@Cli::Supercommand#run:Nil
from Cli::CommandClass+@Cli::CommandClass#amber_cli_main_command__run<Nil, Array(String)>:(Cli::Exit | Nil)
from Cli::CommandClass+@Cli::CommandClass#amber_cli_main_command__run<Array(String)>:(Cli::Exit | Nil)
from Amber::CLI::MainCommand::run<Array(String)>:(Cli::Exit | Nil)
from __crystal_main
from _crystal_main<Int32, Pointer(Pointer(UInt8))>:Nil
from Crystal::main_user_code<Int32, Pointer(Pointer(UInt8))>:Nil
from Crystal::main<Int32, Pointer(Pointer(UInt8))>:Int32
from main
Reproduces how often: Always
$ amber --version
Amber CLI (amberframework.org) - v0.6.1
$ crystal --version
Crystal 0.24.1 (2017-12-26)
LLVM: 5.0.1
Default target: x86_64-apple-macosx
Even just crystal build src/test3.cr fails.
I was able to narrow it down line 25 in config/routes.cr:
24 routes :web do
25 get "/", HomeController, :index
26 end
When the get "/" ... line is commented out then the project builds properly.
Upon further diving, I've found that if you add require "./application.cr" to the top of config/routes.cr then issue crystal build config/routes.cr you get:
$ crystal build config/routes.cr
can't specify arguments in both, command and args without including "${@}" into your command
Process::prepare_argv<String, Array(String), Bool>:Tuple(String, Array(Pointer(UInt8)))
Crystal::Program#macro_run<String, Array(String)>:Crystal::Program::MacroRunResult
Crystal::MacroInterpreter#interpret_top_level_call?<Crystal::Call>:(Crystal::ASTNode+ | Nil)
Crystal::MacroInterpreter#interpret_top_level_call<Crystal::Call>:Crystal::ASTNode+
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MacroInterpreter>:Nil
Crystal::MacroInterpreter#visit<Crystal::MacroExpression>:Bool
Crystal::Program#expand_macro<Crystal::MacroExpression, Crystal::Type+, (Crystal::Type+ | Nil), (Hash(String, Crystal::ASTNode | Crystal::Type)+ | Nil), (Crystal::Def+ | Nil)>:String
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_inline_macro<Crystal::MacroExpression, Nil>:Crystal::ASTNode+
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Block>:(Bool | Nil)
Crystal::MainVisitor#visit<Crystal::Yield>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Block>:(Bool | Nil)
Crystal::MainVisitor#visit<Crystal::Yield>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::Call#instantiate<Crystal::Matches, Crystal::Type+, Nil>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in_type<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil), Nil, String, Bool, Bool>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil)>:Array(Crystal::Def+)
Crystal::Call#recalculate:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::Call#instantiate<Crystal::Matches, Crystal::Type+, Nil>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in_type<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil), Nil, String, Bool, Bool>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil)>:Array(Crystal::Def+)
Crystal::Call#recalculate:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Assign>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::Call#instantiate<Crystal::Matches, Crystal::Type+, Nil>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in_type<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil), Nil, String, Bool, Bool>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil)>:Array(Crystal::Def+)
Crystal::Call#recalculate:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::If>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Assign>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Block>:(Bool | Nil)
Crystal::MainVisitor#visit<Crystal::Yield>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::Call#instantiate<Crystal::Matches, Crystal::Type+, Nil>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in_type<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil), Nil, String, Bool, Bool>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil)>:Array(Crystal::Def+)
Crystal::Call#recalculate:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor@Crystal::SemanticVisitor#expand_macro<Crystal::Call, Bool, Bool>:Bool
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::MainVisitor#visit<Crystal::Block>:(Bool | Nil)
Crystal::MainVisitor#visit<Crystal::Yield>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::Call#instantiate<Crystal::Matches, Crystal::Type+, Nil>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in_type<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil), Nil, String, Bool, Bool>:Array(Crystal::Def+)
Crystal::Call#lookup_matches_in<Crystal::Type+, Array(Crystal::Type+), (Array(Crystal::NamedArgumentType) | Nil)>:Array(Crystal::Def+)
Crystal::Call#recalculate:Nil
Crystal::MainVisitor#visit<Crystal::Call>:Bool
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::ASTNode+@Crystal::ASTNode#accept<Crystal::MainVisitor>:Nil
Crystal::Program#visit_main<Crystal::ASTNode+, Crystal::MainVisitor, Bool, Bool>:Crystal::ASTNode+
Crystal::Program#semantic<Crystal::ASTNode+, Bool>:Crystal::ASTNode+
Crystal::Compiler#compile<Array(Crystal::Compiler::Source), String>:Crystal::Compiler::Result
Crystal::Command#run:(Bool | Crystal::Compiler::Result | IO::FileDescriptor | Nil)
main
Error: you've found a bug in the Crystal compiler. Please open an issue, including source code that will allow us to reproduce the bug: https://github.com/crystal-lang/crystal/issues
We had a similar issue on Lucky: https://github.com/luckyframework/lucky_cli/issues/147
It is actually a problem in Crystal that has likely been fixed by https://github.com/crystal-lang/crystal/pull/5543
So hopefully the next Crystal release will fix this :D
@paulcsmith ow!
Thanks @Paulcsmith
@amberframework/contributors Is this issue already fixed?
Current behavior:
$ mkdir 'test yolo'
$ cd 'test yolo'
$ amber new test -d sqlite
09:04:21 Database | (ERROR) Path and project name can't contain a space.
09:04:21 Database | (ERROR) Replace spaces with underscores or dashes.
09:04:21 Database | (ERROR) /Users/robert/Documents/repositories/amberframework/test yolo/test should be /Users/robert/Documents/repositories/amberframework/test_yolo/test
I guess the error message is more helpful than just breaking, but Amber shouldn't have an opinion on how people name the folders on their machines.
I don't think it's fixed yet. I believe there's a fix in the next version of crystal for this as it's not actually something uniq to amber.
Any status on this?
@eliasjpr still an issue on amber, although crystal looks good :sweat_smile:
➜ ~ mkdir "foo bar"
➜ ~ cd foo\ bar
➜ foo bar amber new baz -d sqlite
03:58:31 Class | (ERROR) Path and project name can't contain a space.
03:58:31 Class | (INFO) Replace spaces with underscores or dashes.
03:58:31 Class | (INFO) /home/main/foo bar/baz should be /home/main/foo_bar/baz
➜ foo bar crystal init app baz
create baz/.gitignore
create baz/.editorconfig
create baz/LICENSE
create baz/README.md
create baz/.travis.yml
create baz/shard.yml
create baz/src/baz.cr
create baz/src/baz/version.cr
create baz/spec/spec_helper.cr
create baz/spec/baz_spec.cr
Initialized empty Git repository in /home/main/foo bar/baz/.git/
➜ foo bar cd baz
➜ baz git:(master) ✗ shards build
Dependencies are satisfied
Building: baz
We are providing an error message to let the user know this isn't allowed. If we feel we need to support spaces, we can reopen this.
Most helpful comment
We had a similar issue on Lucky: https://github.com/luckyframework/lucky_cli/issues/147
It is actually a problem in Crystal that has likely been fixed by https://github.com/crystal-lang/crystal/pull/5543
So hopefully the next Crystal release will fix this :D