@@ -90,232 +90,6 @@ import Algorithms
9090}
9191
9292
93- public extension ShellOutCommand {
94- static func bash( arguments: [ Argument ] ) -> Self {
95- let arguments = arguments. first == " -c " ? Array ( arguments. dropFirst ( ) ) : arguments
96- return . init( command: " bash " , arguments: [ " -c " , arguments. map ( \. description) . joined ( separator: " " ) ] )
97- }
98- }
99-
100- /// Git commands
101- public extension ShellOutCommand {
102- /// Initialize a git repository
103- static func gitInit( ) -> ShellOutCommand {
104- . init( command: " git " , arguments: [ " init " ] )
105- }
106-
107- /// Clone a git repository at a given URL
108- static func gitClone( url: URL , to path: String ? = nil , allowingPrompt: Bool = true , quiet: Bool = true ) -> ShellOutCommand {
109- var command = git ( allowingPrompt: allowingPrompt)
110- . appending ( arguments: [ " clone " , url. absoluteString] )
111-
112- path. map { command. append ( argument: $0) }
113-
114- if quiet {
115- command. append ( argument: " --quiet " )
116- }
117-
118- return command
119- }
120-
121- /// Create a git commit with a given message (also adds all untracked file to the index)
122- static func gitCommit( message: String , allowingPrompt: Bool = true , quiet: Bool = true ) -> ShellOutCommand {
123- var command = git ( allowingPrompt: allowingPrompt)
124- . appending ( arguments: [ " commit " , " -a " , " -m " , " \( message. quoted) " ] )
125-
126- if quiet {
127- command. append ( argument: " --quiet " )
128- }
129-
130- return command
131- }
132-
133- /// Perform a git push
134- static func gitPush( remote: String ? = nil , branch: String ? = nil , allowingPrompt: Bool = true , quiet: Bool = true ) -> ShellOutCommand {
135- var command = git ( allowingPrompt: allowingPrompt)
136- . appending ( arguments: [ " push " ] )
137- remote. map { command. append ( argument: $0) }
138- branch. map { command. append ( argument: $0) }
139-
140- if quiet {
141- command. append ( argument: " --quiet " )
142- }
143-
144- return command
145- }
146-
147- /// Perform a git pull
148- static func gitPull( remote: String ? = nil , branch: String ? = nil , allowingPrompt: Bool = true , quiet: Bool = true ) -> ShellOutCommand {
149- var command = git ( allowingPrompt: allowingPrompt)
150- . appending ( arguments: [ " pull " ] )
151- remote. map { command. append ( argument: $0) }
152- branch. map { command. append ( argument: $0) }
153-
154- if quiet {
155- command. append ( argument: " --quiet " )
156- }
157-
158- return command
159- }
160-
161- /// Run a git submodule update
162- static func gitSubmoduleUpdate( initializeIfNeeded: Bool = true , recursive: Bool = true , allowingPrompt: Bool = true , quiet: Bool = true ) -> ShellOutCommand {
163- var command = git ( allowingPrompt: allowingPrompt)
164- . appending ( arguments: [ " submodule update " ] )
165-
166- if initializeIfNeeded {
167- command. append ( argument: " --init " )
168- }
169-
170- if recursive {
171- command. append ( argument: " --recursive " )
172- }
173-
174- if quiet {
175- command. append ( argument: " --quiet " )
176- }
177-
178- return command
179- }
180-
181- /// Checkout a given git branch
182- static func gitCheckout( branch: String , quiet: Bool = true ) -> ShellOutCommand {
183- var command = ShellOutCommand ( command: " git " ,
184- arguments: [ " checkout " , branch] )
185-
186- if quiet {
187- command. append ( argument: " --quiet " )
188- }
189-
190- return command
191- }
192-
193- private static func git( allowingPrompt: Bool ) -> Self {
194- allowingPrompt
195- ? . init( command: " git " )
196- : . init( command: " env " ,
197- arguments: [ " GIT_TERMINAL_PROMPT=0 " , " git " ] )
198-
199- }
200- }
201-
202- /// File system commands
203- public extension ShellOutCommand {
204- /// Create a folder with a given name
205- static func createFolder( named name: String ) -> ShellOutCommand {
206- . init( command: " mkdir " , arguments: [ name] )
207- }
208-
209- /// Create a file with a given name and contents (will overwrite any existing file with the same name)
210- static func createFile( named name: String , contents: String ) -> ShellOutCommand {
211- . bash( arguments: [ " -c " , #"echo \#( contents. quoted) > \#( name. quoted) "# . verbatim] )
212- }
213-
214- /// Move a file from one path to another
215- static func moveFile( from originPath: String , to targetPath: String ) -> ShellOutCommand {
216- . init( command: " mv " , arguments: [ originPath, targetPath] )
217- }
218-
219- /// Copy a file from one path to another
220- static func copyFile( from originPath: String , to targetPath: String ) -> ShellOutCommand {
221- . init( command: " cp " , arguments: [ originPath, targetPath] )
222- }
223-
224- /// Remove a file
225- static func removeFile( from path: String , arguments: [ String ] = [ " -f " ] ) -> ShellOutCommand {
226- . init( command: " rm " , arguments: arguments + [ path] )
227- }
228-
229- /// Open a file using its designated application
230- static func openFile( at path: String ) -> ShellOutCommand {
231- . init( command: " open " , arguments: [ path] )
232- }
233-
234- /// Read a file as a string
235- static func readFile( at path: String ) -> ShellOutCommand {
236- . init( command: " cat " , arguments: [ path] )
237- }
238-
239- /// Create a symlink at a given path, to a given target
240- static func createSymlink( to targetPath: String , at linkPath: String ) -> ShellOutCommand {
241- . init( command: " ln " , arguments: [ " -s " , targetPath, linkPath] )
242- }
243-
244- /// Expand a symlink at a given path, returning its target path
245- static func expandSymlink( at path: String ) -> ShellOutCommand {
246- . init( command: " readlink " , arguments: [ path] )
247- }
248- }
249-
250- /// Swift Package Manager commands
251- public extension ShellOutCommand {
252- /// Enum defining available package types when using the Swift Package Manager
253- enum SwiftPackageType : String {
254- case library
255- case executable
256- }
257-
258- /// Enum defining available build configurations when using the Swift Package Manager
259- enum SwiftBuildConfiguration : String {
260- case debug
261- case release
262- }
263-
264- /// Create a Swift package with a given type (see SwiftPackageType for options)
265- static func createSwiftPackage( withType type: SwiftPackageType = . library) -> ShellOutCommand {
266- . init( command: " swift " ,
267- arguments: [ " package " , " init " , " --type " , " \( type) " ] )
268- }
269-
270- /// Update all Swift package dependencies
271- static func updateSwiftPackages( ) -> ShellOutCommand {
272- . init( command: " swift " , arguments: [ " package " , " update " ] )
273- }
274-
275- /// Build a Swift package using a given configuration (see SwiftBuildConfiguration for options)
276- static func buildSwiftPackage( withConfiguration configuration: SwiftBuildConfiguration = . debug) -> ShellOutCommand {
277- . init( command: " swift " ,
278- arguments: [ " build -c \( configuration) " ] )
279- }
280-
281- /// Test a Swift package using a given configuration (see SwiftBuildConfiguration for options)
282- static func testSwiftPackage( withConfiguration configuration: SwiftBuildConfiguration = . debug) -> ShellOutCommand {
283- . init( command: " swift " ,
284- arguments: [ " test " , " -c " , " \( configuration) " ] )
285- }
286- }
287-
288- /// Error type thrown by the `shellOut()` function, in case the given command failed
289- public struct ShellOutError : Swift . Error {
290- /// The termination status of the command that was run
291- public let terminationStatus : Int32
292- /// The error message as a UTF8 string, as returned through `STDERR`
293- public var message : String { return errorData. shellOutput ( ) }
294- /// The raw error buffer data, as returned through `STDERR`
295- public let errorData : Data
296- /// The raw output buffer data, as retuned through `STDOUT`
297- public let outputData : Data
298- /// The output of the command as a UTF8 string, as returned through `STDOUT`
299- public var output : String { return outputData. shellOutput ( ) }
300- }
301-
302- extension ShellOutError : CustomStringConvertible {
303- public var description : String {
304- return """
305- ShellOut encountered an error
306- Status code: \( terminationStatus)
307- Message: " \( message) "
308- Output: " \( output) "
309- """
310- }
311- }
312-
313- extension ShellOutError : LocalizedError {
314- public var errorDescription : String ? {
315- return description
316- }
317- }
318-
31993// MARK: - Private
32094
32195private extension TSCBasic . Process {
@@ -365,15 +139,3 @@ private extension TSCBasic.Process {
365139 }
366140}
367141
368- private extension Data {
369- func shellOutput( ) -> String {
370- let output = String ( decoding: self , as: UTF8 . self)
371-
372- guard !output. hasSuffix ( " \n " ) else {
373- return String ( output. dropLast ( ) )
374- }
375-
376- return output
377-
378- }
379- }
0 commit comments