1

I'm trying to build a GUI application for Mac OS X [El Capitan 10.11.1] using Swift [swift --version prints: Apple Swift version 1.2 (swiftlang-602.0.53.1 clang-602.0.53)], which is able to use my shell and ruby scripts.

The problem I'm having is that when I run a script (either .sh or .rb) using NSTask and NSBundle.mainBundle().pathForResource, the called script doesn't see required scripts from the same directory. It works when I'm using a hardcoded 'external' directory, but that's not an options since the scripts have to be a part of the final build.

I have also tried using relative paths such as './Contents/Resources/...' which didn't work.

(Relevant code below. I hope it's enough. Also, as additional information, I'm not a seasoned programmer and I'm rather new (roughly three months) to Mac, Bash & Ruby and very new (as in started this week) to Xcode 6.4, Swift & Cococa and have never used Objective-C, so apologies for poor style and/or very basic errors)

Swift Code:

class ShellTask {

var filePath: String
var arguments: [String]
init(filePath: String, arguments: [String]) {
    self.filePath = filePath
    self.arguments = arguments
}

func run() {
    let task = NSTask()

    task.launchPath = filePath
    task.arguments = arguments as [String]
    task.launch()
    task.waitUntilExit()
    }
}

class ViewController: NSViewController {    

let shellTask = ShellTask(filePath: "", arguments: [""])

@IBAction func buttonDebug(sender: AnyObject) {
    let mainBundle = NSBundle.mainBundle()
    let resourceDataPath = mainBundle.pathForResource("test", ofType: ".sh")
    shellTask.setFilePath(resourceDataPath!)
    shellTask.run()
}

Shell/Ruby Code I'm currently using for testing (actual scripts are too much to post right now):

test.sh (entry-point):

#!/usr/bin/env bash
WORKDIR=$(dirname $0)
cd "$WORKDIR"
echo "from: test.sh"

ruby test1.rb

exit

test1.rb:

#!/usr/bin/env ruby
require './test2'

def test1()
    puts "from: test1.rb"
end
test1()
test2()

test2.rb:

#!/usr/bin/env ruby

def test2()
    puts "from: test2.rb"
end

Output when running test.sh from terminal:

<user>$ bash test.sh
from: test.sh
from: test1.rb
from: test2.rb

Output when running from Cocoa app:

ruby: No such file or directory -- test1.rb (LoadError)

I've been trying several things for the past two days and read multiple threads, but can't find a solution. But it works without problems when using hardcoded paths, such as '/User/user/Documents/Testfiles/test.sh'.

Also, it's ok if the Xcode terminal doesn't print anything from the test files, it just has to find them. For the actual program, the ruby scripts just have to use functions from modules in different files, which are needed in several scripts, so copy-pasting them in each of the called script would be very annoying later on, when changes have to be made. But surely, there has to be a way to get this here running :/

Thanks in advance

edit1: Using a relative path with NSFileManager.defaultManager().currentDirectoryPath and then adding the path to the resource folder ('/Contents/Resources/test.sh') gives error 'launch path not accessible'.

Elias
  • 11
  • 2
  • Have a look at [this answer](http://stackoverflow.com/a/34910691/2227743), I believe it's the same issue. – Eric Aya Feb 18 '16 at 15:13
  • @Eric D. Turned out as not helpful :( But thanks anyways. The thing is, it seems like the .app-package just can't be used like a 'regular' directory, hence working your way through it via shell scripts doesn't work. Seems like, for my program, the only way is to create a dynamic path to where the .app lies, by building a path to a resource, then cutting off a couple of directories, and from there calling scripts outside the app-package. Not a very pretty solution, but the only one I can find right now. – Elias Feb 19 '16 at 10:56
  • My point was not about using scripts, sorry if I was not clear, it's about using `currentDirectoryPath` like in "version 2" in the linked answer. :) – Eric Aya Feb 19 '16 at 10:59
  • @EricD. Ah ok. Well anyways, it seemed like a solution to my problem at first, but it didn't end up solving it. The thing is, once you call a script that's inside of the app-package, which is very easy, the script itself is basically blind. Usually, you can easily call (or require) new scripts from within a script by having something like 'ruby ./script.rb' but apparently not when they're inside a package. Setting a new, temporary working directory doesn't solve it either. Now I'm having my app + the scripts side by side, which works, but obviously, once you separate them, everything's broken. – Elias Feb 19 '16 at 11:22

0 Answers0