Closed Bug 366607 Opened 18 years ago Closed 18 years ago

MozBuild::Util::RunShellCommand needs some work

Categories

(Release Engineering :: General, defect)

x86
All
defect
Not set
normal

Tracking

(Not tracked)

RESOLVED FIXED

People

(Reporter: preed, Assigned: preed)

Details

Attachments

(1 file, 2 obsolete files)

MozBuild::Util::RunShellCommand has a couple of deficiencies that it would be nice to have: * The way shell arguments are handled is... bad. If any of the arguments have escaped characters (spaces in file names, mostly), then you have to deal with this in the caller by quoting your arguments. What we really need is the ability to pass an array of arguments, and each element can have spaces/escaped charaters that will correctly make it into the program's ARGC. * We sorta do a hand wavy thing handling stdout/stderr. Right now, the callers will often do "2>&1" in the command. This should be a passed in option, and should be handled correctly. * As a part of that, we should handle these output streams separately, so we can do useful things with them and keep them separate. * It should be possible to "background" a command, and check on it periodically outside of RunShellCommand. * Some of the return semantics don't make sense; we'd return a PID of a dead process, which isn't useful. We'd return a -1 if we timed out, which arguably isn't correct (the comment says callers expect it, but callers should check timedOut if they want to know if it timedOut. * We always append to the given logfile; that should be an option.
Attached patch Address some of these issues (obsolete) — Splinter Review
Assignee: build → preed
Status: NEW → ASSIGNED
Attachment #251112 - Flags: review?(rhelmer)
Attachment #251112 - Flags: review?(benjamin)
Attached patch Address these issues, v2 (obsolete) — Splinter Review
IO::Handle->getline() can return undef if there's nothing to read (in the case of stderr); so, don't append that to output, logfiles, and the screen if there's nothing to output. Also, a couple of variable name typo fixes (perl -c now works ;-)
Attachment #251112 - Attachment is obsolete: true
Attachment #251115 - Flags: review?(rhelmer)
Attachment #251112 - Flags: review?(rhelmer)
Attachment #251112 - Flags: review?(benjamin)
Attachment #251115 - Flags: review?(benjamin)
Comment on attachment 251115 [details] [diff] [review] Address these issues, v2 >Index: Util.pm >+ my @commandParts = split(/\s+/, $shellCommand); Boy, does that feel wrong. oh well
Attachment #251115 - Flags: review?(benjamin) → review+
Attached patch v3Splinter Review
Like v3, except... performant. The problem with v2 is that because the streams are in non-blocking mode, on long running commands, all the getline() calls will cause perl to spin, waiting for input; there's no sleep() or anything else to slow this down, so we hammer the CPU. This is bad. This version fixes that by using the IO::Select module to do this more intelligently. Also did a few optimizations around the case where we throw stderr away. This version also includes some comments plus some *gasp* documentation up top about the features.
Attachment #251115 - Attachment is obsolete: true
Attachment #251253 - Flags: review?(rhelmer)
Attachment #251115 - Flags: review?(rhelmer)
Comment on attachment 251253 [details] [diff] [review] v3 Benjamin: Sorry to make you look again, but the performance of v2 was awful; general concept, of course, is the same, but v3 is actually usable in a tinderbox scenario.
Attachment #251253 - Flags: review?(benjamin)
Comment on attachment 251253 [details] [diff] [review] v3 >+ # This is a compatibility check for the old calling convention; if we >+ # find spaces in the command, turn it into the proper command [ args]-type >+ # call. This will break callers that "escape" their args by quoting them, >+ # i.e. foo "bar baz" buh, expecting the args to foo to be "bar baz" and >+ # "buh". They will turn out to be "\"bar", "baz\" and "buh". These callers >+ # just need to be fixed. >+ if ($shellCommand =~ /\s/) { >+ $shellCommand =~ s/^\s+//; >+ $shellCommand =~ s/\s+$//; >+ >+ my @commandParts = split(/\s+/, $shellCommand); >+ >+ $shellCommand = shift(@commandParts); >+ if (defined($commandArgs)) { >+ push(@{$commandArgs}, @commandParts); >+ } else { >+ $commandArgs = \@commandParts; >+ } >+ } I wouldn't bother with this; just make callers use the new calling convention (passing an array instead of a string). Having callers be subtly broken will be much more annoying to track down than just fixing them to use arrays. How many apps use this class? Just bootstrap right now right? Looks good besides that.
Attachment #251253 - Flags: review?(rhelmer) → review+
(In reply to comment #6) > I wouldn't bother with this; just make callers use the new calling convention > (passing an array instead of a string). Having callers be subtly broken will be > much more annoying to track down than just fixing them to use arrays. How many > apps use this class? Just bootstrap right now right? Ok; that makes it easier for me. :-) How about something like this, to help out old callers: if ($shellCommand =~ /\s/) { $shellCommand =~ s/^\s+//; $shellCommand =~ s/\s+$//; if ($shellCommand =~ /\s/) { die 'ASSERT: RunShellCommand(): old calling convention detected'; } }
Attachment #251253 - Flags: review?(benjamin) → review+
Checking in Util.pm; /cvsroot/mozilla/tools/release/MozBuild/Util.pm,v <-- Util.pm new revision: 1.7; previous revision: 1.6 done
Status: ASSIGNED → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Product: mozilla.org → Release Engineering
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: