Amber: [CLI] Won't compile if path contains spaces.

Created on 10 Jan 2018  Â·  10Comments  Â·  Source: amberframework/amber

Description

If the full path to the current project directory contains any spaces, then amber can't build the project. Originally reported by @elorest

Steps to Reproduce

Spaces in parent path(s)
mkdir "stupid path"
cd "stupid path"
amber new test3 -d sqlite
cd test3
shards
amber w
Spaces in project path itself
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

Versions

$ 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

Additional Information

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.

cli crystal-issue on-hold

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

All 10 comments

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.

Was this page helpful?
0 / 5 - 0 ratings