#!/usr/bin/jjs -scripting

var File = Java.type("java.io.File");

$EXEC("pwd");

var path = $OUT.trim() + "/Nakefile";

var nakefile = new File(path);

if (!nakefile.exists()) {
  print('Nakefile does not exist');
  exit();
}

var tasks = {};

var task = function(name, description, action) {
  tasks[name] = {
    name: name,
    description: description,
    action: action
  };
};

var printTasks = function() {
  print('Tasks:');
  for (var task in tasks) {
    print(" - ${task}");
  }
};

// evaluate Nakefile
load(nakefile.getAbsolutePath());

if (arguments.length == 0) {
  printTasks();
  exit(0);
}

var taskName = arguments[0];
var context = tasks[taskName];
if (!context) {
  print("unknown task: ${taskName}");
  exit(1);
}

context.action.call(this);

@@ -28,43 +28,161 @@
 var 
-File = Java.type(%22java.io.File%22);%0A%0A
+global = this;%0A%0A(function() %7B%0A  var File = Java.type(%22java.io.File%22);%0A%0A  var fatalError = function (message) %7B%0A    print(message);%0A    exit(1);%0A  %7D;%0A%0A%0A  
 $EXE
@@ -192,20 +192,25 @@
 pwd%22);%0A%0A
-var 
+  global.
 path = $
@@ -223,25 +223,13 @@
 im()
- + %22/Nakefile%22
 ;%0A%0A
+  
 var 
@@ -252,16 +252,39 @@
 ile(
-path
+global.path + %22/Nakefile%22
 );%0A%0A
+  
 if (
@@ -311,55 +311,67 @@
 %7B%0A  
-print('Nakefile does not exist');%0A  exit();%0A
+  fatalError(%22Nakefile not found: $%7Bglobal.path%7D%22);%0A  
 %7D%0A%0A
+  
 var 
@@ -379,24 +379,26 @@
 asks = %7B%7D;%0A%0A
+  
 var task = f
@@ -434,16 +434,18 @@
 tion) %7B%0A
+  
   tasks%5B
@@ -458,16 +458,18 @@
 = %7B%0A    
+  
 name: na
@@ -476,16 +476,18 @@
 me,%0A    
+ 
+ 
 descript
@@ -508,16 +508,18 @@
 on,%0A    
+  
 action: 
@@ -529,17 +529,46 @@
 ion%0A
+  
   %7D;%0A
+  
 %7D;%0A%0A
+  global.task = task;%0A%0A  
 var 
@@ -593,24 +593,26 @@
 ion() %7B%0A
+  
   print(
 'Tasks:'
@@ -607,19 +607,56 @@
 int(
-'
+%22
 Tasks
-:'
+ defined in $%7Bglobal.path%7D/Nakefile:%22
 );%0A
+  
   fo
@@ -666,16 +666,20 @@
 var task
+Name
  in task
@@ -691,37 +691,164 @@
     
-print(%22 - $%7Btask%7D
+  var task = tasks%5BtaskName%5D;%0A      print(%22 - $%7Btask.name%7D %5B$%7Btask.description%7D%5D
 %22);%0A  
+ 
+ 
 %7D%0A
+    print(%22%5Cnuse 'nake -- taskName' to execute a task%22);%0A  
 %7D;%0A%0A
+%0A
+  
 // e
@@ -864,16 +864,18 @@
 akefile%0A
+  
 load(nak
@@ -901,20 +901,30 @@
 th());%0A%0A
+%0A
+  
 if (
+global.
 argument
@@ -936,24 +936,26 @@
 gth == 0) %7B%0A
+  
   printTasks
@@ -958,16 +958,18 @@
 asks();%0A
+  
   exit(0
@@ -971,19 +971,23 @@
 xit(0);%0A
+  
 %7D%0A%0A
+  
 var task
@@ -993,16 +993,23 @@
 kName = 
+global.
 argument
@@ -1018,19 +1018,25 @@
 0%5D;%0A
+  
 var c
-ontext
+urrentTask
  = t
@@ -1055,99 +1055,258 @@
 e%5D;%0A
+  
 if (!c
-ontext) %7B%0A  print(%22unknown task: $%7BtaskName%7D%22);%0A  exit(1
+urrentTask) %7B%0A    fatalError(%22no such task: $%7BtaskName%7D%5Cnuse 'nake' to list all available tasks%22
 );%0A
+  
 %7D%0A%0A
-context.action.call(this
+  try %7B%0A    currentTask.action.call(global);%0A  %7D%0A  catch (e) %7B%0A    fatalError(%22failed to execute task $%7BcurrentTask.name%7D: $%7Be%7D%22);%0A  %7D%0A%0A%7D)(
 );%0A

introduce local scope for nake internal stuff