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

Rake removes trailing whitespaces from parameters when task is being executed from command line. #216

Open
trushkevich opened this issue Aug 10, 2017 · 9 comments

Comments

@trushkevich
Copy link

trushkevich commented Aug 10, 2017

Having a simple rake task:

  task :ws, [:str] => :environment do |t, args|
    puts args.str.inspect
  end

I get following results when run this task in command line:

  $ rake ws[' ']
  nil
  
  $ rake ws['    ']
  nil
  
  $ rake ws['    1']
  "    1"
  
  $ rake ws['    1    ']
  "    1"
  
  $ rake 'ws[ ]'
  nil
  
  $ rake 'ws[    ]'
  nil
  
  $ rake 'ws[    1]'
  "    1"
  
  $ rake 'ws[    1    ]'
  "    1"

While when the task is being invoked in rails console everything works as expected:

  2.3.3 :258 > Rake::Task['ws'].invoke(' ')
  " "
  2.3.3 :259 > Rake::Task['ws'].reenable
  2.3.3 :260 > Rake::Task['ws'].invoke('    ')
  "    "
  2.3.3 :261 > Rake::Task['ws'].reenable
  2.3.3 :262 > Rake::Task['ws'].invoke('    1')
  "    1"
  2.3.3 :263 > Rake::Task['ws'].reenable
  2.3.3 :264 > Rake::Task['ws'].invoke('    1    ')
  "    1    "

Again, it is definitely not the OS who is responsible for that trimming, since it shouldn't trim anything between quote marks. And besides it can be easily tested this way:

  task :ws, [:str] => :environment do |t, args|
    puts args.str.inspect
    puts ARGV[1].inspect
  end

then in command line:

  $ rake 'ws[  1  ]' '  2  '
  "  1"
  "  2  "

Rake version 12.0.0

some investigation on the issue https://stackoverflow.com/questions/45622716/rake-removes-trailing-whitespaces-from-parameters-how-to-prevent#answer-45623592

@dstull
Copy link

dstull commented Oct 6, 2017

+1
I hit this same issue after upgrading from rake 10.4.2 to rake 12.1.0

empty string arguments are interpreted to nil...but I was relying on them being a string.

i.e. rake sometask[''] now evaluates that empty string to nil

@grzuy
Copy link
Contributor

grzuy commented Feb 23, 2018

Nice catch @trushkevich

I can reproduce the same you experience.

After troubleshooting a bit, it seems like rake should actually remove leading whitespaces, it's what it currently does for every other argument except the first one.

$ bundle exec rake "ws[  1  ,  2  ,  3  ]"
"  1"
"2"
"3"

@trushkevich
Copy link
Author

trushkevich commented Feb 23, 2018

Personally I would expect it not to trim anything at all. May be in some cases it somehow makes sense (but wouldn't it be better to just pass a raw value and let user decide what he wants to do?), like in your example, but e.g. in both following cases

$ rake ws[' '] 
$ rake 'ws[ ]'

it is pretty clear that the intention is to pass a whitespace as an argument (it could be for example specifying a separator character for some data output - just a quick idea from the top of my mind) - but currently it is impossible. And of course the behavior should be consistent with what we see in the console in any case.

@grzuy
Copy link
Contributor

grzuy commented Feb 23, 2018

wouldn't it be better to just pass a raw value and let user decide what he wants to do?

Maybe. Not sure.

The thing is that current rake behavior is: trim everything except leading whitespaces for first argument only. So it's currently inconsistent.

I'd rather, at least for now, achieve consistency by just fixing that trimming corner-case than by removing trimming of all leading and trailing spaces in all arguments. The later seems a lot more likely to break existing users rake tasks than the former.

it is pretty clear that the intention is to pass a whitespace as an argument

I think it depends on the case.
In the following example i guess user expects rake to actually trim leading whitespaces from 2nd and 3rd arguments.

$ rake "ws[one, two, three]"

@trushkevich
Copy link
Author

trushkevich commented Feb 23, 2018

it is pretty clear that the intention is to pass a whitespace as an argument

I think it depends on the case.

I've been referring to those 2 examples I provided, and even provided a possible use-case of passing a whitespace to a rake task (separator), so I think there is no ambiguity and the intention in those 2 cases is pretty clear.

Sorry, but to my mind your commit does not solve the issue I described.

BTW @grzuy in fact you discovered an interesting point. See:

single argument

task :ws, [:str] => :environment do |t, args|
  args.each {|a| puts a.inspect }
end

command line:

$ rake ws[' 1 ,  2  ,  3']
[:str, " 1"]

console:

2.5.0 :002 > Rake::Task['ws'].invoke(' 1 ,  2  ,  3')
[:str, " 1 ,  2  ,  3"]

multiple arguments

task :ws, [:s1, :s2, :s3] => :environment do |t, args|
  args.each {|a| puts a.inspect }
end

command line:

$ rake ws[' 1 ,  2  ,  3']
[:s1, " 1"]
[:s2, "2"]
[:s3, "3"]

console:

2.5.0 :002 > Rake::Task['ws'].invoke(' 1 ,  2  ,  3')
[:s1, " 1 ,  2  ,  3"]
2.5.0 :003 > Rake::Task['ws'].invoke(' 1 ', ' 2 ', ' 3 ')
[:s1, " 1 "]
[:s2, " 2 "]
[:s3, " 3 "]

The simplest solution for command line would be probably just to split by , without any regexes at all (however I'm not sure about corner cases). Also the behavior in console seems to be logical, but at the same time it's pretty confusing when compared to what we get in console with nearly the same input.

@grzuy
Copy link
Contributor

grzuy commented Feb 23, 2018

Sorry, but to my mind your commit does not solve the issue I described

You're right. They can be treated as separate issues.
I think i'll report a separate issue for the argument trimming inconsistency.

UPDATE: New issue reported #260

@trushkevich
Copy link
Author

makes sense, at least multiple arguments in command line will work consistently with each other :) though not in a way I would expect and not consistently with rails console

@grzuy
Copy link
Contributor

grzuy commented Feb 23, 2018

Keep in mind part of the parsing is done by ruby with how it makes ARGV available to the ruby script

For example, forget about rake and see the following bare ruby example

$ cat argv_inspector.rb 
puts ARGV.inspect
$ ruby argv_inspector.rb task[' 1 , 2 , 3 ']
["task[ 1 , 2 , 3 ]"]
$ ruby argv_inspector.rb "task[ 1 , 2 , 3 ]"
["task[ 1 , 2 , 3 ]"]

So given that rake uses ARGV to receive task name and arguments, it cannot distinguish between those two situations, i think... :-)

@trushkevich
Copy link
Author

Yeah, sure I understand it. The 2 cases you provided are identical from the OS point of view since they are basically:

  • case1 - 3 strings concatenated: task[, 1 , 2 , 3 (wrapped with quotes) and ]
  • case2 - 1 string task[ 1 , 2 , 3 ]
    so in the end the expression from case 1 is evaluated into exactly the same string as in the case 2.

But things can be a bit more complex too. One can write for example

$ ruby argv_inspector.rb "task[' 1 , 2 , 3 ']"

and get in ARGV:

["task[' 1 , 2 , 3 ']"]

And a question arises whether this case should be treated as if multiple arguments are provided or as if it is a single argument (since there are explicit quotes). Currently rake treats it as there are multiple arguments:

  • task with multiple arguments
$ rake "ws[' 1 ,  2  ,  3']"
[:s1, "' 1"]
[:s2, "2"]
[:s3, "3'"]
  • task with a single argument
$ rake "ws[' 1 ,  2  ,  3']"
[:s1, "' 1"]

And even a more intersting case is where the number of quotes is not even:

$ ruby argv_inspector.rb "task[' 1 , '2 , 3 ']"
["task[' 1 , '2 , 3 ']"]

I have no idea how this should be interpreted :) (and it's just a simple case with 1,2,3 but there can be a complex sentence - e.g. there could be a task to send an email that accepts email body as an argument).

But still it would be great if a simple case with a single argument would be processed correctly without cutting off any characters - just like in the console.

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

No branches or pull requests

3 participants