Skip to content
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

Running commands on Windows is broken #387

Closed
maxmeyer opened this issue May 7, 2016 · 13 comments · Fixed by #422
Closed

Running commands on Windows is broken #387

maxmeyer opened this issue May 7, 2016 · 13 comments · Fixed by #422
Milestone

Comments

@maxmeyer
Copy link
Member

maxmeyer commented May 7, 2016

Summary

Running commands on windows seems to be broken. Have look at this build. Anyone using Ruby on Windows is welcome to help us fixing this.

Expected Behavior

Commands should be run on Windows.

Current Behavior

Running commands fails on AppVeyor CI.

Possible Solution

Fix code to run commands.

Steps to Reproduce (for bugs)

See CI Build

Context

Your Environment

  • Version used: latest
  • Operating System and version: AppVeyor CI
@maxmeyer maxmeyer added this to the 1.0.0 milestone May 7, 2016
@hferentschik
Copy link

For what I can tell, the problem lies in Aruba:Processes:SpawnProcess. In the start method we have:

@process = ChildProcess.build(*[command_string.to_a, arguments].flatten)

command_string is of type Aruba:Platforms:WindowsCommandString. Prior to calling to_a on this command string, it looks for example like this (which is correct):

C:\Windows\System32\cmd.exe /c "C:\Ruby200-x64\bin\bundle.bat"

After to_a it is:

["C:WindowsSystem32cmd.exe", "/c", "C:Ruby200-x64binbundle.bat"]

Notice that the path separator '' is gone. I think the problem is that WindowsCommandString uses Ruby's Shellwords.split to process the command line. AFAIU Shellwords should/can only be used for bash. It won't work on Windows. In particular it seems to tread '' as an escape character.

This leads then in the end to the error of "The system cannot find the file specified".

@hferentschik
Copy link

I tried to temporarily modify WindowsCommandString.to_a to do something like __getobj__.to_s.split(' ') (probably to simplistic) and the command now actually executes. Unfortunately, a new exception is then thrown in Aruba:Processes:SpawnProcess.read. The problem is File.read command_string.to_s. I am not so familiar with the code base, but my guess is that Aruba tries to save the output of a command to a file. This fails here, since WindowsCommandString actually modifies the command to add cmd.exe, something like C:\Windows\System32\cmd.exe /c "C:\Ruby200-x64\bin\bundle.bat". Calling to_s on this and passing it to File.read will of course fail. Not sure whether there are more problems still. Hope it helps.

@hferentschik
Copy link

Another minor detail. Here:

raise LaunchError, "It tried to start #{commandline}. " + e.message

the variable 'commandline' is used which is not defined, creating a misleading error. It should be command_string instead.

@ghost
Copy link

ghost commented May 12, 2016

Great! Thanks for the hint. Can you help me and send a PR fixing it?

@hferentschik
Copy link

This might be helpful

Not sure whether it is worth introducing a new dependency, but if all that's needed is the split functionality it could be taken from there!?

@ghost
Copy link

ghost commented May 12, 2016

I am not so familiar with the code base, but my guess is that Aruba tries to save the output oof a command to a file.

No problem, I can guide you.

AFAIU Shellwords should/can only be used for bash

Ah. Ok.

Not sure whether it is worth introducing a new dependency, but if all that's needed is the split functionality it could be taken from there!?

I would prefer to take over the bits we need. The gem is MIT-licensed so we don't have a problem here.

#387 (comment)

That was fixed for the Unix/Linux part already with #357. So we forgot this bit.

Calling to_s on this and passing it to File.read

Mmmh... Sure. That's a problem. Do you have a good idea how to implement it in a nice way? I would like to see Windows and Unix CommandString to be implemented quite similar. Maybe just add a #raw method to CommandString?

he problem is File.read command_string.to_s. I am not so familiar with the code base, but my guess is that Aruba tries to save the output of a command to a file.

Yes, it reads the script and output its for debugging purposes when the correct announcer is given. I think it was announce-command-content.

Not sure whether there are more problems still.

Maybe. The windows support is still quite "brittle".

@hferentschik
Copy link

Great! Thanks for the hint. Can you help me and send a PR fixing it?

I cannot promise anything, but maybe I can give a quick try...

@ghost
Copy link

ghost commented May 18, 2016

Yay. That would be great.

@jpc2
Copy link

jpc2 commented Oct 21, 2016

Rather than starting something new...and a bit long...

I'm a relative newbie with Ruby. I'm an Old FORTRAN Programmer (and other things OFP can stand for). I use FRUIT to build tests for FORTRAN and it is Ruby based so I've gotten a bit into Ruby. I'd really like to use cucumber and aruba on Windows but.... Here is what I've found so far.

First problem: Trying to setup a simple CLI program with GLI and the book 'Build Awesome Command-Line Applications in Ruby 2', I try to run the basic infrastructure setup by GLI with cucumber and I get:


`
C:\Work\Awesome_Cmd_Line_Apps\TODO_pgm\todo>cucumber
@Annotate
Feature: My bootstrapped app kinda works
In order to get going on coding my awesome app
I want to have aruba and cucumber setup
So I don't have to do it myself

Scenario: App just runs # features/todo.feature:7
When I get help for "todo" # features/step_definitions/todo_steps.rb:1
Command "todo" not found in PATH-variable "C:/Work/Awesome_Cmd_Line_Apps/TODO_pgm/todo/bin:C:/Work/Awesome_Cmd_Line_Apps/TODO_pgm/todo/exe:U1;C:\Rubies\Ruby22\b
in;U2;C:\Program Files\MATLAB\MATLAB Runtime\v85\runtime\win64;C:\ProgramData............
(Aruba::LaunchError)
./features/step_definitions/todo_steps.rb:3:in /^I get help for "([^"]*)"$/' features/todo.feature:8:inWhen I get help for "todo"'
Then the exit status should be 0 # aruba-0.14.2/lib/aruba/cucumber/command.rb:278

Failing Scenarios:
cucumber features/todo.feature:7 # Scenario: App just runs

1 scenario (1 failed)
2 steps (1 failed, 1 skipped)
0m0.449s
`
After staring at the PATH for a bit I noticed that the separators are wrong. This "/todo/bin:C:/Work/Awesome" should be "/todo/bin;C:/Work/Awesome". Windows uses ';' to separate things in the PATH and other lists of directories - others use ':'. It appears that the 'standard' way of handling this is File::PATH_SEPARAROR. This can also be seen in the ApVayor build mentioned at the beginning at line 870. Mucking around in the aruba code I found three files, aruba/rspec.rb, cucumber/command.rb and cucumber/hooks.rb with lines like this:

prepend_environment_variable 'PATH', aruba.config.command_search_paths.join(':') + ':'

I changed them to look like this:
prepend_environment_variable( 'PATH', aruba.config.command_search_paths.join(File::PATH_SEPARATOR) + File::PATH_SEPARATOR)

There are probably others for things like LIB and such.
Now when I run cucumber I get:


`
C:\Work\Awesome_Cmd_Line_Apps\TODO_pgm\todo>cucumber
@Annotate
Feature: My bootstrapped app kinda works
In order to get going on coding my awesome app
I want to have aruba and cucumber setup
So I don't have to do it myself

Scenario: App just runs # features/todo.feature:7
When I get help for "todo" # features/step_definitions/todo_steps.rb:1
undefined local variable or method cmd' for #<Aruba::Processes::SpawnProcess:0x2f7e610> (NameError) ./features/step_definitions/todo_steps.rb:3:in/^I get help for "([^"]*)"$/'
features/todo.feature:8:in `When I get help for "todo"'
Then the exit status should be 0 # aruba-0.14.2/lib/aruba/cucumber/command.rb:278

Failing Scenarios:
cucumber features/todo.feature:7 # Scenario: App just runs

1 scenario (1 failed)
2 steps (1 failed, 1 skipped)
0m0.145s

C:\Work\Awesome_Cmd_Line_Apps\TODO_pgm\todo>

`

Second problem:
So I set up a new directory and initialize aruba. (Ruby -- 2.2.5, aruba - 0.14.2)
I copy in the console.feature file from the features/getting_started directory in the installed Gem. It appears to be the simplest that actually tries to run something that is not generated. Doesn't run!

I run cucumber and get


`Feature: Aruba Console

Background: # features/console.feature:3
Given a mocked home directory # aruba-0.14.2/lib/aruba/cucumber/environment.rb:1

Scenario: Start console # features/console.feature:6
Given I run aruba console interactively # aruba-0.14.2/lib/aruba/cucumber/command.rb:50
undefined local variable or method cmd' for #<Aruba::Processes::SpawnProcess:0x28f04b8> (NameError) features/console.feature:7:inGiven I run aruba console interactively'
When I close the stdin stream # aruba-0.14.2/lib/aruba/cucumber/command.rb:64
Then the output should contain: # aruba-0.14.2/lib/aruba/cucumber/command.rb:206
"""
aruba:001:0>
"""

`

I've chased it a bit but haven't found why 'cmd' is undefined.

I'd be happy if the basic run commands worked. There are things that might never work but it should be possible to make some of it work.

@thomthom
Copy link

thomthom commented Jan 4, 2017

Is there a previous version of aruba that worked on Windows?

@thomthom
Copy link

thomthom commented Jan 4, 2017

Like @jpc2 I am running into:

undefined local variable or method `cmd' for #<Aruba::Processes::SpawnProcess:0x3df8750> (NameError)

Though, I'm not sure if that is the same issue the original poster was referring to?

Looking at the source I don't understand why it would ever claim cmd is undefined, it should be provided by the block.

@thomthom
Copy link

thomthom commented Jan 4, 2017

This pull request fixed the issue for me: #422

@SteveDonie
Copy link

SteveDonie commented Jan 4, 2017 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants