88using System . Runtime . InteropServices ;
99using System . Text . RegularExpressions ;
1010using System . Collections . Generic ;
11+ using System . Text ;
1112
1213namespace VueCliMiddleware
1314{
@@ -19,23 +20,48 @@ internal class ScriptRunner
1920 {
2021 public EventedStreamReader StdOut { get ; }
2122 public EventedStreamReader StdErr { get ; }
23+ public Process RunnerProcess { get ; }
2224
2325 public ScriptRunnerType Runner { get ; }
2426
25- private string GetExeName ( ) => Runner == ScriptRunnerType . Npm ? "npm" : "yarn" ;
26- private string GetArgPrefix ( ) => Runner == ScriptRunnerType . Npm ? "run " : "" ;
27- private string GetArgSuffix ( ) => Runner == ScriptRunnerType . Npm ? "-- " : "" ;
27+ private string GetExeName ( )
28+ {
29+ switch ( Runner )
30+ {
31+ case ScriptRunnerType . Npm :
32+ return "npm" ;
33+ case ScriptRunnerType . Yarn :
34+ return "yarn" ;
35+ case ScriptRunnerType . Npx :
36+ return "npx" ;
37+ default :
38+ return "npm" ;
39+ }
40+ }
41+
42+ private static string BuildCommand ( ScriptRunnerType runner , string scriptName , string arguments )
43+ {
44+ var command = new StringBuilder ( ) ;
45+
46+ if ( runner == ScriptRunnerType . Npm ) { command . Append ( "run " ) ; }
47+
48+ command . Append ( scriptName ) ;
49+ command . Append ( ' ' ) ;
50+
51+ if ( runner == ScriptRunnerType . Npm ) { command . Append ( "-- " ) ; }
52+
53+ if ( ! string . IsNullOrWhiteSpace ( arguments ) ) { command . Append ( arguments ) ; }
54+ return command . ToString ( ) ;
55+ }
2856
2957 private static Regex AnsiColorRegex = new Regex ( "\x001b \\ [[0-9;]*m" , RegexOptions . None , TimeSpan . FromSeconds ( 1 ) ) ;
3058
31- public Process RunnerProcess => _runnerProcess ;
3259
33- private Process _runnerProcess ;
3460
3561 public void Kill ( )
3662 {
37- try { _runnerProcess ? . Kill ( ) ; } catch { }
38- try { _runnerProcess ? . WaitForExit ( ) ; } catch { }
63+ try { RunnerProcess ? . Kill ( ) ; } catch { }
64+ try { RunnerProcess ? . WaitForExit ( ) ; } catch { }
3965 }
4066
4167 public ScriptRunner ( string workingDirectory , string scriptName , string arguments , IDictionary < string , string > envVars , ScriptRunnerType runner )
@@ -52,18 +78,19 @@ public ScriptRunner(string workingDirectory, string scriptName, string arguments
5278
5379 Runner = runner ;
5480
55- var npmExe = GetExeName ( ) ;
56- var completeArguments = $ "{ GetArgPrefix ( ) } { scriptName } { GetArgSuffix ( ) } { arguments ?? string . Empty } ";
81+ var exeName = GetExeName ( ) ;
82+ var completeArguments = BuildCommand ( runner , scriptName , arguments ) ;
83+
5784 if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) )
5885 {
5986 // On Windows, the NPM executable is a .cmd file, so it can't be executed
6087 // directly (except with UseShellExecute=true, but that's no good, because
6188 // it prevents capturing stdio). So we need to invoke it via "cmd /c".
62- completeArguments = $ "/c { npmExe } { completeArguments } ";
63- npmExe = "cmd" ;
89+ completeArguments = $ "/c { exeName } { completeArguments } ";
90+ exeName = "cmd" ;
6491 }
6592
66- var processStartInfo = new ProcessStartInfo ( npmExe )
93+ var processStartInfo = new ProcessStartInfo ( exeName )
6794 {
6895 Arguments = completeArguments ,
6996 UseShellExecute = false ,
@@ -81,9 +108,10 @@ public ScriptRunner(string workingDirectory, string scriptName, string arguments
81108 }
82109 }
83110
84- _runnerProcess = LaunchNodeProcess ( processStartInfo ) ;
85- StdOut = new EventedStreamReader ( _runnerProcess . StandardOutput ) ;
86- StdErr = new EventedStreamReader ( _runnerProcess . StandardError ) ;
111+ RunnerProcess = LaunchNodeProcess ( processStartInfo ) ;
112+
113+ StdOut = new EventedStreamReader ( RunnerProcess . StandardOutput ) ;
114+ StdErr = new EventedStreamReader ( RunnerProcess . StandardError ) ;
87115 }
88116
89117 public void AttachToLogger ( ILogger logger )
0 commit comments