Main.hx 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731
  1. package tools.haxelib;
  2. enum Answer {
  3. Yes;
  4. No;
  5. Always;
  6. }
  7. class SiteProxy extends haxe.remoting.Proxy<tools.haxelib.SiteApi> {
  8. }
  9. class Progress extends haxe.io.Output {
  10. var o : haxe.io.Output;
  11. var cur : Int;
  12. var max : Int;
  13. var start : Float;
  14. public function new(o) {
  15. this.o = o;
  16. cur = 0;
  17. start = haxe.Timer.stamp();
  18. }
  19. function bytes(n) {
  20. cur += n;
  21. if( max == null )
  22. neko.Lib.print(cur+" bytes\r");
  23. else
  24. neko.Lib.print(cur+"/"+max+" ("+Std.int((cur*100.0)/max)+"%)\r");
  25. }
  26. public override function writeByte(c) {
  27. o.writeByte(c);
  28. bytes(1);
  29. }
  30. public override function writeBytes(s,p,l) {
  31. var r = o.writeBytes(s,p,l);
  32. bytes(r);
  33. return r;
  34. }
  35. public override function close() {
  36. super.close();
  37. o.close();
  38. var time = haxe.Timer.stamp() - start;
  39. var speed = (cur / time) / 1024;
  40. time = Std.int(time * 10) / 10;
  41. speed = Std.int(speed * 10) / 10;
  42. neko.Lib.print("Download complete : "+cur+" bytes in "+time+"s ("+speed+"KB/s)\n");
  43. }
  44. public override function prepare(m) {
  45. max = m;
  46. }
  47. }
  48. class ProgressIn extends haxe.io.Input {
  49. var i : haxe.io.Input;
  50. var pos : Int;
  51. var tot : Int;
  52. public function new( i, tot ) {
  53. this.i = i;
  54. this.pos = 0;
  55. this.tot = tot;
  56. }
  57. public override function readByte() {
  58. var c = i.readByte();
  59. doRead(1);
  60. return c;
  61. }
  62. public override function readBytes(buf,pos,len) {
  63. var k = i.readBytes(buf,pos,len);
  64. doRead(k);
  65. return k;
  66. }
  67. function doRead( nbytes : Int ) {
  68. pos += nbytes;
  69. neko.Lib.print( Std.int((pos * 100.0) / tot) + "%\r" );
  70. }
  71. }
  72. class Main {
  73. static var VERSION = 103;
  74. static var REPNAME = "lib";
  75. static var SERVER = {
  76. host : "lib.haxe.org",
  77. port : 80,
  78. dir : "",
  79. url : "index.n"
  80. };
  81. var argcur : Int;
  82. var args : Array<String>;
  83. var commands : List<{ name : String, doc : String, f : Void -> Void, net : Bool }>;
  84. var siteUrl : String;
  85. var site : SiteProxy;
  86. function new() {
  87. args = neko.Sys.args();
  88. commands = new List();
  89. addCommand("install",install,"install a given project");
  90. addCommand("list",list,"list all installed projects",false);
  91. addCommand("upgrade",upgrade,"upgrade all installed projects");
  92. addCommand("remove",remove,"remove a given project/version",false);
  93. addCommand("set",set,"set the current version for a project",false);
  94. addCommand("search",search,"list projects matching a word");
  95. addCommand("info",info,"list informations on a given project");
  96. addCommand("user",user,"list informations on a given user");
  97. addCommand("register",register,"register a new user");
  98. addCommand("submit",submit,"submit or update a project package");
  99. addCommand("setup",setup,"set the haxelib repository path",false);
  100. addCommand("config",config,"print the repository path",false);
  101. addCommand("path",path,"give paths to libraries",false);
  102. addCommand("run",run,"run the specified project with parameters",false);
  103. addCommand("test",test,"install the specified package localy",false);
  104. addCommand("dev",dev,"set the development directory for a given project",false);
  105. siteUrl = "http://"+SERVER.host+":"+SERVER.port+"/"+SERVER.dir;
  106. site = new SiteProxy(haxe.remoting.HttpConnection.urlConnect(siteUrl+SERVER.url).api);
  107. }
  108. function param( name, ?passwd ) {
  109. if( args.length > argcur )
  110. return args[argcur++];
  111. neko.Lib.print(name+" : ");
  112. if( passwd ) {
  113. var s = new StringBuf();
  114. var c;
  115. while( (c = neko.io.File.getChar(false)) != 13 )
  116. s.addChar(c);
  117. print("");
  118. return s.toString();
  119. }
  120. return neko.io.File.stdin().readLine();
  121. }
  122. function ask( question ) {
  123. while( true ) {
  124. neko.Lib.print(question+" [y/n/a] ? ");
  125. switch( neko.io.File.stdin().readLine() ) {
  126. case "n": return No;
  127. case "y": return Yes;
  128. case "a": return Always;
  129. }
  130. }
  131. return null;
  132. }
  133. function paramOpt() {
  134. if( args.length > argcur )
  135. return args[argcur++];
  136. return null;
  137. }
  138. function addCommand( name, f, doc, ?net ) {
  139. commands.add({ name : name, doc : doc, f : f, net : net });
  140. }
  141. function usage() {
  142. var vmin = Std.string(VERSION % 100);
  143. var ver = Std.int(VERSION/100) + "." + if( vmin.length == 1 ) "0"+vmin else vmin;
  144. print("Haxe Library Manager "+ver+" - (c)2006 Motion-Twin");
  145. print(" Usage : haxelib [command] [options]");
  146. print(" Commands :");
  147. for( c in commands )
  148. print(" "+c.name+" : "+c.doc);
  149. neko.Sys.exit(1);
  150. }
  151. function process() {
  152. var debug = false;
  153. argcur = 0;
  154. if( args[argcur] == "-debug" ) {
  155. argcur++;
  156. debug = true;
  157. }
  158. var cmd = args[argcur++];
  159. if( cmd == null )
  160. usage();
  161. for( c in commands )
  162. if( c.name == cmd ) {
  163. try {
  164. if( c.net ) haxe.Http.PROXY = neko.net.ProxyDetect.detect();
  165. c.f();
  166. } catch( e : Dynamic ) {
  167. if( e == "std@host_resolve" ) {
  168. print("Host "+SERVER.host+" was not found");
  169. print("Please ensure that your internet connection is on");
  170. print("If you don't have an internet connection or if you are behing a proxy");
  171. print("please download manually the file from http://lib.haxe.org/files");
  172. print("and run 'haxelib test <file>' to install the Library.");
  173. neko.Sys.exit(1);
  174. }
  175. if( debug )
  176. neko.Lib.rethrow(e);
  177. print(Std.string(e));
  178. neko.Sys.exit(1);
  179. }
  180. return;
  181. }
  182. print("Unknown command "+cmd);
  183. usage();
  184. }
  185. // ---- COMMANDS --------------------
  186. function search() {
  187. var word = param("Search word");
  188. var l = site.search(word);
  189. for( s in l )
  190. print(s.name);
  191. print(l.length+" projects found");
  192. }
  193. function info() {
  194. var prj = param("Project name");
  195. var inf = site.infos(prj);
  196. print("Name: "+inf.name);
  197. print("Desc: "+inf.desc);
  198. print("Website: "+inf.website);
  199. print("License: "+inf.license);
  200. print("Owner: "+inf.owner);
  201. print("Version: "+inf.curversion);
  202. print("Releases: ");
  203. if( inf.versions.length == 0 )
  204. print(" (no version released yet)");
  205. for( v in inf.versions )
  206. print(" "+v.date+" "+v.name+" : "+v.comments);
  207. }
  208. function user() {
  209. var uname = param("User name");
  210. var inf = site.user(uname);
  211. print("Id: "+inf.name);
  212. print("Name: "+inf.fullname);
  213. print("Mail: "+inf.email);
  214. print("Projects: ");
  215. if( inf.projects.length == 0 )
  216. print(" (no projects)");
  217. for( p in inf.projects )
  218. print(" "+p);
  219. }
  220. function register() {
  221. doRegister(param("User"));
  222. print("Registration successful");
  223. }
  224. function doRegister(name) {
  225. var email = param("Email");
  226. var fullname = param("Fullname");
  227. var pass = param("Password",true);
  228. var pass2 = param("Confirm",true);
  229. if( pass != pass2 )
  230. throw "Password does not match";
  231. pass = haxe.Md5.encode(pass);
  232. site.register(name,pass,email,fullname);
  233. return pass;
  234. }
  235. function submit() {
  236. var file = param("Package");
  237. var data = neko.io.File.getBytes(file);
  238. var zip = neko.zip.Reader.readZip(new haxe.io.BytesInput(data));
  239. var infos = Datas.readInfos(zip);
  240. var user = infos.developers.first();
  241. var password;
  242. if( site.isNewUser(user) ) {
  243. print("This is your first submission as '"+user+"'");
  244. print("Please enter the following informations for registration");
  245. password = doRegister(user);
  246. } else {
  247. if( infos.developers.length > 1 )
  248. user = param("User");
  249. password = haxe.Md5.encode(param("Password",true));
  250. if( !site.checkPassword(user,password) )
  251. throw "Invalid password for "+user;
  252. }
  253. site.checkDeveloper(infos.project,user);
  254. // check dependencies validity
  255. for( d in infos.dependencies ) {
  256. var infos = site.infos(d.project);
  257. if( d.version == "" )
  258. continue;
  259. var found = false;
  260. for( v in infos.versions )
  261. if( v.name == d.version ) {
  262. found = true;
  263. break;
  264. }
  265. if( !found )
  266. throw "Project "+d.project+" does not have version "+d.version;
  267. }
  268. // query a submit id that will identify the file
  269. var id = site.getSubmitId();
  270. // directly send the file data over Http
  271. var h = new haxe.Http("http://"+SERVER.host+":"+SERVER.port+"/"+SERVER.url);
  272. h.onError = function(e) { throw e; };
  273. h.onData = print;
  274. h.fileTransfert("file",id,new ProgressIn(new haxe.io.BytesInput(data),data.length),data.length);
  275. print("Sending data.... ");
  276. h.request(true);
  277. // ask the server to register the sent file
  278. var msg = site.processSubmit(id,user,password);
  279. print(msg);
  280. }
  281. function install() {
  282. var prj = param("Project name");
  283. var inf = site.infos(prj);
  284. if( inf.curversion == null )
  285. throw "This project has not yet released a version";
  286. var reqversion = paramOpt();
  287. var version = if( reqversion != null ) reqversion else inf.curversion;
  288. var found = false;
  289. for( v in inf.versions )
  290. if( v.name == version ) {
  291. found = true;
  292. break;
  293. }
  294. if( !found )
  295. throw "No such version "+version;
  296. doInstall(inf.name,version,version == inf.curversion);
  297. }
  298. function doInstall( project, version, setcurrent ) {
  299. var rep = getRepository();
  300. // check if exists already
  301. if( neko.FileSystem.exists(rep+Datas.safe(project)+"/"+Datas.safe(version)) ) {
  302. print("You already have "+project+" version "+version+" installed");
  303. setCurrent(project,version,true);
  304. return;
  305. }
  306. // download to temporary file
  307. var filename = Datas.fileName(project,version);
  308. var filepath = rep+filename;
  309. var out = neko.io.File.write(filepath,true);
  310. var progress = new Progress(out);
  311. var h = new haxe.Http(siteUrl+Datas.REPOSITORY+"/"+filename);
  312. h.onError = function(e) {
  313. progress.close();
  314. neko.FileSystem.deleteFile(filepath);
  315. throw e;
  316. };
  317. print("Downloading "+filename+"...");
  318. h.customRequest(false,progress);
  319. doInstallFile(filepath,setcurrent);
  320. }
  321. function doInstallFile(filepath,setcurrent,?nodelete) {
  322. // read zip content
  323. var f = neko.io.File.read(filepath,true);
  324. var zip = neko.zip.Reader.readZip(f);
  325. f.close();
  326. var infos = Datas.readInfos(zip);
  327. // create directories
  328. var pdir = getRepository() + Datas.safe(infos.project);
  329. safeDir(pdir);
  330. pdir += "/";
  331. var target = pdir + Datas.safe(infos.version);
  332. safeDir(target);
  333. target += "/";
  334. // locate haxelib.xml base path
  335. var basepath = null;
  336. for( f in zip ) {
  337. if( StringTools.endsWith(f.fileName,Datas.XML) ) {
  338. basepath = f.fileName.substr(0,f.fileName.length - Datas.XML.length);
  339. break;
  340. }
  341. }
  342. if( basepath == null )
  343. throw "No "+Datas.XML+" found";
  344. // unzip content
  345. for( zipfile in zip ) {
  346. var n = zipfile.fileName;
  347. if( StringTools.startsWith(n,basepath) ) {
  348. // remove basepath
  349. n = n.substr(basepath.length,n.length-basepath.length);
  350. if( n.charAt(0) == "/" || n.charAt(0) == "\\" || n.split("..").length > 1 )
  351. throw "Invalid filename : "+n;
  352. var dirs = ~/[\/\\]/g.split(n);
  353. var path = "";
  354. var file = dirs.pop();
  355. for( d in dirs ) {
  356. path += d;
  357. safeDir(target+path);
  358. path += "/";
  359. }
  360. if( file == "" ) {
  361. if( path != "" ) print(" Created "+path);
  362. continue; // was just a directory
  363. }
  364. path += file;
  365. print(" Install "+path);
  366. var data = neko.zip.Reader.unzip(zipfile);
  367. var f = neko.io.File.write(target+path,true);
  368. f.write(data);
  369. f.close();
  370. }
  371. }
  372. // set current version
  373. if( setcurrent || !neko.FileSystem.exists(pdir+".current") ) {
  374. var f = neko.io.File.write(pdir+".current",true);
  375. f.writeString(infos.version);
  376. f.close();
  377. print(" Current version is now "+infos.version);
  378. }
  379. // end
  380. if( !nodelete )
  381. neko.FileSystem.deleteFile(filepath);
  382. print("Done");
  383. // process dependencies
  384. for( d in infos.dependencies ) {
  385. print("Installing dependency "+d.project+" "+d.version);
  386. if( d.version == "" )
  387. d.version = site.infos(d.project).curversion;
  388. doInstall(d.project,d.version,false);
  389. }
  390. }
  391. function safeDir( dir ) {
  392. if( neko.FileSystem.exists(dir) ) {
  393. if( !neko.FileSystem.isDirectory(dir) )
  394. throw ("A file is preventing "+dir+" to be created");
  395. return false;
  396. }
  397. try {
  398. neko.FileSystem.createDirectory(dir);
  399. } catch( e : Dynamic ) {
  400. throw "You don't have enough user rights to create the directory "+dir;
  401. }
  402. return true;
  403. }
  404. function getRepository( ?setup : Bool ) {
  405. var sys = neko.Sys.systemName();
  406. if( sys == "Windows" ) {
  407. var haxepath = neko.Sys.getEnv("HAXEPATH");
  408. if( haxepath == null )
  409. throw "HAXEPATH environment variable not defined, please run haxesetup.exe first";
  410. var last = haxepath.charAt(haxepath.length - 1);
  411. if( last != "/" && last != "\\" )
  412. haxepath += "/";
  413. var rep = haxepath+REPNAME;
  414. try {
  415. safeDir(rep);
  416. } catch( e : Dynamic ) {
  417. throw "The directory defined by HAXEPATH does not exist, please run haxesetup.exe again";
  418. }
  419. return rep+"\\";
  420. }
  421. var config = neko.Sys.getEnv("HOME")+"/.haxelib";
  422. var rep = try
  423. neko.io.File.getContent(config)
  424. catch( e : Dynamic ) try
  425. neko.io.File.getContent("/etc/.haxelib")
  426. catch( e : Dynamic )
  427. if( setup )
  428. "/usr/lib/haxe/"+REPNAME;
  429. else
  430. throw "This is the first time you are runing haxelib. Please run haxelib setup first";
  431. if( setup ) {
  432. print("Please enter haxelib repository path with write access");
  433. print("Hit enter for default ("+rep+")");
  434. var line = param("Path");
  435. if( line != "" )
  436. rep = line;
  437. if( !neko.FileSystem.exists(rep) ) {
  438. try {
  439. neko.FileSystem.createDirectory(rep);
  440. } catch( e : Dynamic ) {
  441. print("Failed to create directory '"+rep+"' ("+Std.string(e)+"), maybe you need appropriate user rights");
  442. neko.Sys.exit(1);
  443. }
  444. }
  445. var f = neko.io.File.write(config,true);
  446. f.writeString(rep);
  447. f.close();
  448. } else if( !neko.FileSystem.exists(rep) )
  449. throw "haxelib Repository "+rep+" does not exists. Please run haxelib setup again";
  450. return rep+"/";
  451. }
  452. function setup() {
  453. var path = getRepository(true);
  454. print("haxelib repository is now "+path);
  455. }
  456. function config() {
  457. print(getRepository());
  458. }
  459. function list() {
  460. var rep = getRepository();
  461. for( p in neko.FileSystem.readDirectory(rep) ) {
  462. if( p.charAt(0) == "." )
  463. continue;
  464. var versions = new Array();
  465. var current = neko.io.File.getContent(rep+p+"/.current");
  466. var dev = try neko.io.File.getContent(rep+p+"/.dev") catch( e : Dynamic ) null;
  467. for( v in neko.FileSystem.readDirectory(rep+p) ) {
  468. if( v.charAt(0) == "." )
  469. continue;
  470. v = Datas.unsafe(v);
  471. if( dev == null && v == current )
  472. v = "["+v+"]";
  473. versions.push(v);
  474. }
  475. if( dev != null )
  476. versions.push("[dev:"+dev+"]");
  477. print(Datas.unsafe(p) + ": "+versions.join(" "));
  478. }
  479. }
  480. function upgrade() {
  481. var rep = getRepository();
  482. var prompt = true;
  483. var update = false;
  484. for( p in neko.FileSystem.readDirectory(rep) ) {
  485. if( p.charAt(0) == "." )
  486. continue;
  487. var p = Datas.unsafe(p);
  488. print("Checking "+p);
  489. var inf = site.infos(p);
  490. if( !neko.FileSystem.exists(rep+Datas.safe(p)+"/"+Datas.safe(inf.curversion)) ) {
  491. if( prompt )
  492. switch ask("Upgrade "+p+" to "+inf.curversion) {
  493. case Yes:
  494. case Always: prompt = false;
  495. case No: continue;
  496. }
  497. doInstall(p,inf.curversion,true);
  498. update = true;
  499. } else
  500. setCurrent(p,inf.curversion,true);
  501. }
  502. if( update )
  503. print("Done");
  504. else
  505. print("All projects are up-to-date");
  506. }
  507. function deleteRec(dir) {
  508. for( p in neko.FileSystem.readDirectory(dir) ) {
  509. var path = dir+"/"+p;
  510. if( neko.FileSystem.isDirectory(path) )
  511. deleteRec(path);
  512. else
  513. neko.FileSystem.deleteFile(path);
  514. }
  515. neko.FileSystem.deleteDirectory(dir);
  516. }
  517. function remove() {
  518. var prj = param("Project");
  519. var version = paramOpt();
  520. var rep = getRepository();
  521. var pdir = rep + Datas.safe(prj);
  522. if( version == null ) {
  523. if( !neko.FileSystem.exists(pdir) )
  524. throw "Project "+prj+" is not installed";
  525. deleteRec(pdir);
  526. print("Project "+prj+" removed");
  527. return;
  528. }
  529. var vdir = pdir + "/" + Datas.safe(version);
  530. if( !neko.FileSystem.exists(vdir) )
  531. throw "Project "+prj+" does not have version "+version+" installed";
  532. var cur = neko.io.File.getContent(pdir+"/.current");
  533. if( cur == version )
  534. throw "Can't remove current version of project "+prj;
  535. deleteRec(vdir);
  536. print("Project "+prj+" version "+version+" removed");
  537. }
  538. function set() {
  539. var prj = param("Project");
  540. var version = param("Version");
  541. setCurrent(prj,version,false);
  542. }
  543. function setCurrent( prj : String, version : String, doAsk : Bool ) {
  544. var pdir = getRepository() + Datas.safe(prj);
  545. var vdir = pdir + "/" + Datas.safe(version);
  546. if( !neko.FileSystem.exists(vdir) )
  547. throw "Project "+prj+" version "+version+" is not installed";
  548. var current = pdir+"/.current";
  549. if( neko.io.File.getContent(current) == version )
  550. return;
  551. if( doAsk && ask("Set "+prj+" to version "+version) == No )
  552. return;
  553. var f = neko.io.File.write(current,true);
  554. f.writeString(version);
  555. f.close();
  556. print("Project "+prj+" current version is now "+version);
  557. }
  558. function checkRec( prj : String, version : String, l : List<{ project : String, version : String }> ) {
  559. var pdir = getRepository() + Datas.safe(prj);
  560. if( !neko.FileSystem.exists(pdir) )
  561. throw "Project "+prj+" is not installed";
  562. var version = if( version != null ) version else neko.io.File.getContent(pdir+"/.current");
  563. var vdir = pdir + "/" + Datas.safe(version);
  564. if( !neko.FileSystem.exists(vdir) )
  565. throw "Project "+prj+" version "+version+" is not installed";
  566. for( p in l )
  567. if( p.project == prj ) {
  568. if( p.version == version )
  569. return;
  570. throw "Project "+prj+" has two version included "+version+" and "+p.version;
  571. }
  572. l.add({ project : prj, version : version });
  573. var xml = neko.io.File.getContent(vdir+"/haxelib.xml");
  574. var inf = Datas.readData(xml);
  575. for( d in inf.dependencies )
  576. checkRec(d.project,if( d.version == "" ) null else d.version,l);
  577. }
  578. function path() {
  579. var list = new List();
  580. while( argcur < args.length ) {
  581. var a = args[argcur++].split(":");
  582. checkRec(a[0],a[1],list);
  583. }
  584. var rep = getRepository();
  585. for( d in list ) {
  586. var pdir = Datas.safe(d.project)+"/"+Datas.safe(d.version)+"/";
  587. var dir = rep + pdir;
  588. try {
  589. dir = neko.io.File.getContent(rep+Datas.safe(d.project)+"/.dev");
  590. if( dir.length == 0 || (dir.charAt(dir.length-1) != '/' && dir.charAt(dir.length-1) != '\\') )
  591. dir += "/";
  592. pdir = dir;
  593. } catch( e : Dynamic ) {
  594. }
  595. var ndir = dir + "ndll";
  596. if( neko.FileSystem.exists(ndir) ) {
  597. var sysdir = ndir+"/"+neko.Sys.systemName();
  598. if( !neko.FileSystem.exists(sysdir) )
  599. throw "Project "+d.project+" version "+d.version+" does not have a neko dll for your system";
  600. neko.Lib.println("-L "+pdir+"ndll/");
  601. }
  602. neko.Lib.println(dir);
  603. }
  604. }
  605. function dev() {
  606. var rep = getRepository();
  607. var project = param("Project");
  608. var dir = paramOpt();
  609. var devfile = rep + Datas.safe(project)+"/.dev";
  610. if( dir == null ) {
  611. if( neko.FileSystem.exists(devfile) )
  612. neko.FileSystem.deleteFile(devfile);
  613. print("Development directory disabled");
  614. } else {
  615. var f = neko.io.File.write(devfile,false);
  616. f.writeString(dir);
  617. f.close();
  618. print("Development directory set to "+dir);
  619. }
  620. }
  621. function run() {
  622. var rep = getRepository();
  623. var project = param("Project");
  624. var pdir = rep + Datas.safe(project);
  625. if( !neko.FileSystem.exists(pdir) )
  626. throw "Project "+project+" is not installed";
  627. pdir += "/";
  628. var version = neko.io.File.getContent(pdir+".current");
  629. var vdir = pdir + Datas.safe(version);
  630. var rdir = vdir + "/run.n";
  631. if( !neko.FileSystem.exists(rdir) )
  632. throw "Project "+project+" version "+version+" does not have a run script";
  633. args.push(neko.Sys.getCwd());
  634. neko.Sys.setCwd(vdir);
  635. var cmd = "neko run.n";
  636. for( i in argcur...args.length )
  637. cmd += " "+escapeArg(args[i]);
  638. neko.Sys.exit(neko.Sys.command(cmd));
  639. }
  640. function escapeArg( a : String ) {
  641. if( a.indexOf(" ") == -1 )
  642. return a;
  643. return '"'+a+'"';
  644. }
  645. function test() {
  646. var file = param("Package");
  647. doInstallFile(file,true,true);
  648. }
  649. // ----------------------------------
  650. static function print(str) {
  651. neko.Lib.print(str+"\n");
  652. }
  653. static function main() {
  654. new Main().process();
  655. }
  656. }