1

To run xcpretty command in xcodebuild, i use the below code:

import Foundation

class Command{

func command(args: String...) -> Int32 {
    let task = NSTask()
    task.launchPath = "/usr/bin/env"
    task.arguments = args
    task.currentDirectoryPath = "/Users/Desktop/XCode/Test/"
    task.launch()
    task.waitUntilExit()
    return task.terminationStatus
}


let xcodebuildCommand = Command()
xcodebuildCommand.command("xcodebuild","test","-project","proj.xcodeproj","-scheme","projScheme","-destination","platform=iOS Simulator,name=iPad Air","  | /usr/local/bin/xcpretty --report html --output /Desktop/test_output/report.html")

the error is

xcodebuild: error: Unknown build action ' | /usr/local/bin/xcpretty --report html --output /Desktop/test_output/report.html'.

the below command run properly from terminal:

xcodebuild test -project proj.xcodeproj.xcodeproj -scheme projScheme -destination 'platform=iOS Simulator,name=iPad Air' | xcpretty --repor html --output /pathToReportfolder/report.html

1 Answers1

0

NSTask is not a shell, it will not interpret your shell script for you.

You'll need to manually set up an NSPipe to connect the standard output of your xcodebuild NSTask to an xcpretty NSTask.

import Foundation

func runCommand(workingDirectory: String? = nil,
                           stdin: NSPipe? = nil,
                          stdout: NSPipe? = nil,
                          stderr: NSPipe? = nil,
                            args: String...) -> Int32 {
    let task = NSTask()

    task.launchPath = "/usr/bin/env"
    task.arguments = args

    if let workingDirectory = workingDirectory {
        task.currentDirectoryPath = workingDirectory
    }

    if let stdin  = stdin  { task.standardInput  = stdin  }
    if let stdout = stdout { task.standardOutput = stdout }
    if let stderr = stderr { task.standardError  = stderr }

    task.launch()
    task.waitUntilExit()
    return (task.terminationStatus)
}

let pipe = NSPipe()

//omit "workingDirectory:" in Swift 2
runCommand(workingDirectory: "/Users/Desktop/XCode/Test/",
                     stdout: pipe,
                       args: "xcodebuild","test",
                       "-project","proj.xcodeproj",
                       "-scheme","projScheme",
                       "-destination","platform=iOS Simulator,name=iPad Air")

//omit "workingDirectory:" in Swift 2
runCommand(workingDirectory: "/Users/Desktop/XCode/Test/",
                      stdin: pipe,
                       args: "/usr/local/bin/xcpretty",
                       "--report html",
                       "--output",
                       "/Desktop/test_output/report.html")
Alexander
  • 59,041
  • 12
  • 98
  • 151
  • can u please give me link or an example how i can do this? –  Jun 27 '16 at 14:37
  • Yep, give me a second – Alexander Jun 27 '16 at 14:56
  • There's a first (rought) go at it. I would avoid calling the function `command`, as that's a noun, not a verb. Functions are actions, not things, so their names should be verbs or verb phrases, like "runCommand". Also, I would put it in a struct, not a class. – Alexander Jun 27 '16 at 15:17
  • Where? Compiles fine in swift 3 – Alexander Jun 27 '16 at 15:32
  • Oh, yeah, the behavior is different in Swift 2. The first keyword name is skipped in Swift 2, but required in Swift 3 – Alexander Jun 27 '16 at 15:32
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/115748/discussion-between-helper-and-amomchilov). –  Jun 27 '16 at 15:33
  • for swift 2.2, remove workingDirectory keyword when function is called. –  Jun 27 '16 at 15:52