-
Notifications
You must be signed in to change notification settings - Fork 184
Add Exec2, the "better version of Exec"
#5103
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -186,3 +186,5 @@ DeclareOperation( "Process", | |
| ## <#/GAPDoc> | ||
| ## | ||
| DeclareGlobalFunction( "Exec" ); | ||
|
|
||
| DeclareGlobalName( "Exec2" ); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -261,3 +261,77 @@ InstallGlobalFunction( Exec, function( arg ) | |
| Process( dir, shell, InputTextUser(), OutputTextUser(), [ cs, cmd ] ); | ||
|
|
||
| end ); | ||
|
|
||
| # TODO: document this, come up with a better name, write some tests... | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still a big TODO 🙂 I don't currently have a better name suggestion but I'll have a think. |
||
| BindGlobal( "Exec2", function( arg ) | ||
| local args, result, a, input, output, dir, cmd; | ||
|
|
||
| args := []; | ||
| result := rec(); | ||
|
|
||
| # parse the inputs | ||
| for a in arg do | ||
| if IsDirectory(a) then | ||
| if IsBound(dir) then | ||
| Error("must specify at most one working directory"); | ||
| fi; | ||
| dir := a; | ||
| elif IsInputStream(a) then | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right now input and output stream can come at any position and in any order. Perhaps I should make this code stricter, and require that they come in a specific place (canonical places: 1. as the first two arguments; 2. after the command name; 3. as the last two arguments)
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. While it would be a bigger change, I wonder if the input should be a record, with keys like
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I like that idea. It could then also be made backwards compatible: if there is a single argument which is a record, then use the new code; otherwise call the old code.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What I don't like about it is that for simple uses, it is much more verbose. Compare: e.g.: old code: Exec( Concatenation("start ", winfilename ) );this PR: Exec2( "start", winfilename );with a record (record entries subject to change, of course): Exec(rec(cmd:= "start", args := [ winfilename ] );A compromise would be to only use a Exec2( "start", winfilename, rec( input := BLAH, output := BLEH ) );but then of course I can't use this to differentiate old and new callers.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So here's a possible way to go:
Does that sound reasonable @ChrisJefferson ?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It sounds reasonable to me at least @fingolfin. |
||
| if IsBound(input) then | ||
| Error("must specify at most one input stream"); | ||
| fi; | ||
| input := a; | ||
| elif IsOutputStream(a) then | ||
| if IsBound(output) then | ||
| Error("must specify at most one output stream"); | ||
| fi; | ||
| output := a; | ||
| elif IsString(a) then | ||
| ConvertToStringRep(a); | ||
| if not IsBound(cmd) then | ||
| cmd := a; | ||
| else | ||
| Add(args, a); | ||
| fi; | ||
| else | ||
| Error("unsupported argument type"); | ||
| fi; | ||
| od; | ||
|
|
||
| if not IsBound(cmd) then | ||
| Error("must specify a command to execute"); | ||
| fi; | ||
|
|
||
| # determine full executable path if it is not already a path | ||
| if not '/' in cmd then | ||
| a := Filename( DirectoriesSystemPrograms(), cmd ); | ||
| if a = fail and ARCH_IS_WINDOWS() then | ||
| a := Filename( DirectoriesSystemPrograms(), Concatenation( cmd, ".exe" ) ); | ||
| fi; | ||
| if a = fail then | ||
| Error("could not locate executable for '", cmd, "'"); | ||
|
fingolfin marked this conversation as resolved.
|
||
| fi; | ||
| cmd := a; | ||
| fi; | ||
|
|
||
| # set default working directory if necessary | ||
| if not IsBound(dir) then | ||
| dir := DirectoryCurrent(); | ||
| fi; | ||
|
|
||
| # if no input stream was specified, pass no input to the command | ||
| if not IsBound(input) then | ||
| input := InputTextNone(); | ||
| fi; | ||
|
|
||
| # if no output stream was specified, put output into the returned record | ||
| if not IsBound(output) then | ||
| result.output := ""; | ||
| output := OutputTextString(result.output, false); | ||
| fi; | ||
|
|
||
| # execute the command | ||
| result.status := Process( dir, cmd, input, output, args ); | ||
|
|
||
| return result; | ||
| end ); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you're using the variable
urlas the-wargument, but the replaced code was using the variablefile. Is this a mistake or a deliberate change?