Main.hx 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728
  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 neko.io.Output {
  10. var o : neko.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 writeChar(c) {
  27. o.writeChar(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 neko.io.Input {
  49. var i : neko.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 readChar() {
  58. var c = i.readChar();
  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 }>;
  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");
  91. addCommand("upgrade",upgrade,"upgrade all installed projects");
  92. addCommand("remove",remove,"remove a given project/version");
  93. addCommand("set",set,"set the current version for a project");
  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");
  100. addCommand("config",config,"print the repository path");
  101. addCommand("path",path,"give paths to libraries");
  102. addCommand("run",run,"run the specified project with parameters");
  103. addCommand("test",test,"install the specified package localy");
  104. addCommand("dev",dev,"set the development directory for a given project");
  105. siteUrl = "http://"+SERVER.host+":"+SERVER.port+"/"+SERVER.dir;
  106. site = new SiteProxy(haxe.remoting.Connection.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 ) {
  139. commands.add({ name : name, doc : doc, f : f });
  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. c.f();
  165. } catch( e : Dynamic ) {
  166. if( e == "std@host_resolve" ) {
  167. print("Host "+SERVER.host+" was not found");
  168. print("Please ensure that your internet connection is on");
  169. print("If you don't have an internet connection or if you are behing a proxy");
  170. print("please download manually the file from http://lib.haxe.org/files");
  171. print("and run 'haxelib test <file>' to install the Library.");
  172. neko.Sys.exit(1);
  173. }
  174. if( debug )
  175. neko.Lib.rethrow(e);
  176. print(Std.string(e));
  177. neko.Sys.exit(1);
  178. }
  179. return;
  180. }
  181. print("Unknown command "+cmd);
  182. usage();
  183. }
  184. // ---- COMMANDS --------------------
  185. function search() {
  186. var word = param("Search word");
  187. var l = site.search(word);
  188. for( s in l )
  189. print(s.name);
  190. print(l.length+" projects found");
  191. }
  192. function info() {
  193. var prj = param("Project name");
  194. var inf = site.infos(prj);
  195. print("Name: "+inf.name);
  196. print("Desc: "+inf.desc);
  197. print("Website: "+inf.website);
  198. print("License: "+inf.license);
  199. print("Owner: "+inf.owner);
  200. print("Version: "+inf.curversion);
  201. print("Releases: ");
  202. if( inf.versions.length == 0 )
  203. print(" (no version released yet)");
  204. for( v in inf.versions )
  205. print(" "+v.date+" "+v.name+" : "+v.comments);
  206. }
  207. function user() {
  208. var uname = param("User name");
  209. var inf = site.user(uname);
  210. print("Id: "+inf.name);
  211. print("Name: "+inf.fullname);
  212. print("Mail: "+inf.email);
  213. print("Projects: ");
  214. if( inf.projects.length == 0 )
  215. print(" (no projects)");
  216. for( p in inf.projects )
  217. print(" "+p);
  218. }
  219. function register() {
  220. doRegister(param("User"));
  221. print("Registration successful");
  222. }
  223. function doRegister(name) {
  224. var email = param("Email");
  225. var fullname = param("Fullname");
  226. var pass = param("Password",true);
  227. var pass2 = param("Confirm",true);
  228. if( pass != pass2 )
  229. throw "Password does not match";
  230. pass = haxe.Md5.encode(pass);
  231. site.register(name,pass,email,fullname);
  232. return pass;
  233. }
  234. function submit() {
  235. var file = param("Package");
  236. var data = neko.io.File.getContent(file);
  237. var zip = neko.zip.Reader.readZip(new neko.io.StringInput(data));
  238. var infos = Datas.readInfos(zip);
  239. var user = infos.developers.first();
  240. var password;
  241. if( site.isNewUser(user) ) {
  242. print("This is your first submission as '"+user+"'");
  243. print("Please enter the following informations for registration");
  244. password = doRegister(user);
  245. } else {
  246. if( infos.developers.length > 1 )
  247. user = param("User");
  248. password = haxe.Md5.encode(param("Password",true));
  249. if( !site.checkPassword(user,password) )
  250. throw "Invalid password for "+user;
  251. }
  252. site.checkDeveloper(infos.project,user);
  253. // check dependencies validity
  254. for( d in infos.dependencies ) {
  255. var infos = site.infos(d.project);
  256. if( d.version == "" )
  257. continue;
  258. var found = false;
  259. for( v in infos.versions )
  260. if( v.name == d.version ) {
  261. found = true;
  262. break;
  263. }
  264. if( !found )
  265. throw "Project "+d.project+" does not have version "+d.version;
  266. }
  267. // query a submit id that will identify the file
  268. var id = site.getSubmitId();
  269. // directly send the file data over Http
  270. var h = new haxe.Http("http://"+SERVER.host+":"+SERVER.port+"/"+SERVER.url);
  271. h.onError = function(e) { throw e; };
  272. h.onData = print;
  273. h.fileTransfert("file",id,new ProgressIn(new neko.io.StringInput(data),data.length),data.length);
  274. print("Sending data.... ");
  275. h.request(true);
  276. // ask the server to register the sent file
  277. var msg = site.processSubmit(id,user,password);
  278. print(msg);
  279. }
  280. function install() {
  281. var prj = param("Project name");
  282. var inf = site.infos(prj);
  283. if( inf.curversion == null )
  284. throw "This project has not yet released a version";
  285. var reqversion = paramOpt();
  286. var version = if( reqversion != null ) reqversion else inf.curversion;
  287. var found = false;
  288. for( v in inf.versions )
  289. if( v.name == version ) {
  290. found = true;
  291. break;
  292. }
  293. if( !found )
  294. throw "No such version "+version;
  295. doInstall(inf.name,version,version == inf.curversion);
  296. }
  297. function doInstall( project, version, setcurrent ) {
  298. var rep = getRepository();
  299. // check if exists already
  300. if( neko.FileSystem.exists(rep+Datas.safe(project)+"/"+Datas.safe(version)) ) {
  301. print("You already have "+project+" version "+version+" installed");
  302. setCurrent(project,version,true);
  303. return;
  304. }
  305. // download to temporary file
  306. var filename = Datas.fileName(project,version);
  307. var filepath = rep+filename;
  308. var out = neko.io.File.write(filepath,true);
  309. var progress = new Progress(out);
  310. var h = new haxe.Http(siteUrl+Datas.REPOSITORY+"/"+filename);
  311. h.onError = function(e) {
  312. progress.close();
  313. neko.FileSystem.deleteFile(filepath);
  314. throw e;
  315. };
  316. print("Downloading "+filename+"...");
  317. h.customRequest(false,progress);
  318. doInstallFile(filepath,setcurrent);
  319. }
  320. function doInstallFile(filepath,setcurrent,?nodelete) {
  321. // read zip content
  322. var f = neko.io.File.read(filepath,true);
  323. var zip = neko.zip.Reader.readZip(f);
  324. f.close();
  325. var infos = Datas.readInfos(zip);
  326. // create directories
  327. var pdir = getRepository() + Datas.safe(infos.project);
  328. safeDir(pdir);
  329. pdir += "/";
  330. var target = pdir + Datas.safe(infos.version);
  331. safeDir(target);
  332. target += "/";
  333. // locate haxelib.xml base path
  334. var basepath = null;
  335. for( f in zip ) {
  336. if( StringTools.endsWith(f.fileName,Datas.XML) ) {
  337. basepath = f.fileName.substr(0,f.fileName.length - Datas.XML.length);
  338. break;
  339. }
  340. }
  341. if( basepath == null )
  342. throw "No "+Datas.XML+" found";
  343. // unzip content
  344. for( zipfile in zip ) {
  345. var n = zipfile.fileName;
  346. if( StringTools.startsWith(n,basepath) ) {
  347. // remove basepath
  348. n = n.substr(basepath.length,n.length-basepath.length);
  349. if( n.charAt(0) == "/" || n.charAt(0) == "\\" || n.split("..").length > 1 )
  350. throw "Invalid filename : "+n;
  351. var dirs = ~/[\/\\]/g.split(n);
  352. var path = "";
  353. var file = dirs.pop();
  354. for( d in dirs ) {
  355. path += d;
  356. safeDir(target+path);
  357. path += "/";
  358. }
  359. if( file == "" ) {
  360. if( path != "" ) print(" Created "+path);
  361. continue; // was just a directory
  362. }
  363. path += file;
  364. print(" Install "+path);
  365. var data = neko.zip.Reader.unzip(zipfile);
  366. var f = neko.io.File.write(target+path,true);
  367. f.write(data);
  368. f.close();
  369. }
  370. }
  371. // set current version
  372. if( setcurrent || !neko.FileSystem.exists(pdir+".current") ) {
  373. var f = neko.io.File.write(pdir+".current",true);
  374. f.write(infos.version);
  375. f.close();
  376. print(" Current version is now "+infos.version);
  377. }
  378. // end
  379. if( !nodelete )
  380. neko.FileSystem.deleteFile(filepath);
  381. print("Done");
  382. // process dependencies
  383. for( d in infos.dependencies ) {
  384. print("Installing dependency "+d.project+" "+d.version);
  385. if( d.version == "" )
  386. d.version = site.infos(d.project).curversion;
  387. doInstall(d.project,d.version,false);
  388. }
  389. }
  390. function safeDir( dir ) {
  391. if( neko.FileSystem.exists(dir) ) {
  392. if( !neko.FileSystem.isDirectory(dir) )
  393. throw ("A file is preventing "+dir+" to be created");
  394. return false;
  395. }
  396. try {
  397. neko.FileSystem.createDirectory(dir);
  398. } catch( e : Dynamic ) {
  399. throw "You don't have enough user rights to create the directory "+dir;
  400. }
  401. return true;
  402. }
  403. function getRepository( ?setup : Bool ) {
  404. var sys = neko.Sys.systemName();
  405. if( sys == "Windows" ) {
  406. var haxepath = neko.Sys.getEnv("HAXEPATH");
  407. if( haxepath == null )
  408. throw "HAXEPATH environment variable not defined, please run haxesetup.exe first";
  409. var rep = haxepath+REPNAME;
  410. try {
  411. safeDir(rep);
  412. } catch( e : Dynamic ) {
  413. throw "The directory defined by HAXEPATH does not exist, please run haxesetup.exe again";
  414. }
  415. return rep+"\\";
  416. }
  417. var config = neko.Sys.getEnv("HOME")+"/.haxelib";
  418. var rep = try
  419. neko.io.File.getContent(config)
  420. catch( e : Dynamic ) try
  421. neko.io.File.getContent("/etc/.haxelib")
  422. catch( e : Dynamic )
  423. if( setup )
  424. "/usr/lib/haxe/"+REPNAME;
  425. else
  426. throw "This is the first time you are runing haxelib. Please run haxelib setup first";
  427. if( setup ) {
  428. print("Please enter haxelib repository path with write access");
  429. print("Hit enter for default ("+rep+")");
  430. var line = param("Path");
  431. if( line != "" )
  432. rep = line;
  433. if( !neko.FileSystem.exists(rep) ) {
  434. try {
  435. neko.FileSystem.createDirectory(rep);
  436. } catch( e : Dynamic ) {
  437. print("Failed to create directory '"+rep+"' ("+Std.string(e)+"), maybe you need appropriate user rights");
  438. neko.Sys.exit(1);
  439. }
  440. }
  441. var f = neko.io.File.write(config,true);
  442. f.write(rep);
  443. f.close();
  444. } else if( !neko.FileSystem.exists(rep) )
  445. throw "haxelib Repository "+rep+" does not exists. Please run haxelib setup again";
  446. return rep+"/";
  447. }
  448. function setup() {
  449. var path = getRepository(true);
  450. print("haxelib repository is now "+path);
  451. }
  452. function config() {
  453. print(getRepository());
  454. }
  455. function list() {
  456. var rep = getRepository();
  457. for( p in neko.FileSystem.readDirectory(rep) ) {
  458. if( p.charAt(0) == "." )
  459. continue;
  460. var versions = new Array();
  461. var current = neko.io.File.getContent(rep+p+"/.current");
  462. var dev = try neko.io.File.getContent(rep+p+"/.dev") catch( e : Dynamic ) null;
  463. for( v in neko.FileSystem.readDirectory(rep+p) ) {
  464. if( v.charAt(0) == "." )
  465. continue;
  466. v = Datas.unsafe(v);
  467. if( dev == null && v == current )
  468. v = "["+v+"]";
  469. versions.push(v);
  470. }
  471. if( dev != null )
  472. versions.push("[dev:"+dev+"]");
  473. print(Datas.unsafe(p) + ": "+versions.join(" "));
  474. }
  475. }
  476. function upgrade() {
  477. var rep = getRepository();
  478. var prompt = true;
  479. var update = false;
  480. for( p in neko.FileSystem.readDirectory(rep) ) {
  481. if( p.charAt(0) == "." )
  482. continue;
  483. var p = Datas.unsafe(p);
  484. print("Checking "+p);
  485. var inf = site.infos(p);
  486. if( !neko.FileSystem.exists(rep+Datas.safe(p)+"/"+Datas.safe(inf.curversion)) ) {
  487. if( prompt )
  488. switch ask("Upgrade "+p+" to "+inf.curversion) {
  489. case Yes:
  490. case Always: prompt = false;
  491. case No: continue;
  492. }
  493. doInstall(p,inf.curversion,true);
  494. update = true;
  495. } else
  496. setCurrent(p,inf.curversion,true);
  497. }
  498. if( update )
  499. print("Done");
  500. else
  501. print("All projects are up-to-date");
  502. }
  503. function deleteRec(dir) {
  504. for( p in neko.FileSystem.readDirectory(dir) ) {
  505. var path = dir+"/"+p;
  506. if( neko.FileSystem.isDirectory(path) )
  507. deleteRec(path);
  508. else
  509. neko.FileSystem.deleteFile(path);
  510. }
  511. neko.FileSystem.deleteDirectory(dir);
  512. }
  513. function remove() {
  514. var prj = param("Project");
  515. var version = paramOpt();
  516. var rep = getRepository();
  517. var pdir = rep + Datas.safe(prj);
  518. if( version == null ) {
  519. if( !neko.FileSystem.exists(pdir) )
  520. throw "Project "+prj+" is not installed";
  521. deleteRec(pdir);
  522. print("Project "+prj+" removed");
  523. return;
  524. }
  525. var vdir = pdir + "/" + Datas.safe(version);
  526. if( !neko.FileSystem.exists(vdir) )
  527. throw "Project "+prj+" does not have version "+version+" installed";
  528. var cur = neko.io.File.getContent(pdir+"/.current");
  529. if( cur == version )
  530. throw "Can't remove current version of project "+prj;
  531. deleteRec(vdir);
  532. print("Project "+prj+" version "+version+" removed");
  533. }
  534. function set() {
  535. var prj = param("Project");
  536. var version = param("Version");
  537. setCurrent(prj,version,false);
  538. }
  539. function setCurrent( prj : String, version : String, doAsk : Bool ) {
  540. var pdir = getRepository() + Datas.safe(prj);
  541. var vdir = pdir + "/" + Datas.safe(version);
  542. if( !neko.FileSystem.exists(vdir) )
  543. throw "Project "+prj+" version "+version+" is not installed";
  544. var current = pdir+"/.current";
  545. if( neko.io.File.getContent(current) == version )
  546. return;
  547. if( doAsk && ask("Set "+prj+" to version "+version) == No )
  548. return;
  549. var f = neko.io.File.write(current,true);
  550. f.write(version);
  551. f.close();
  552. print("Project "+prj+" current version is now "+version);
  553. }
  554. function checkRec( prj : String, version : String, l : List<{ project : String, version : String }> ) {
  555. var pdir = getRepository() + Datas.safe(prj);
  556. if( !neko.FileSystem.exists(pdir) )
  557. throw "Project "+prj+" is not installed";
  558. var version = if( version != null ) version else neko.io.File.getContent(pdir+"/.current");
  559. var vdir = pdir + "/" + Datas.safe(version);
  560. if( !neko.FileSystem.exists(vdir) )
  561. throw "Project "+prj+" version "+version+" is not installed";
  562. for( p in l )
  563. if( p.project == prj ) {
  564. if( p.version == version )
  565. return;
  566. throw "Project "+prj+" has two version included "+version+" and "+p.version;
  567. }
  568. l.add({ project : prj, version : version });
  569. var xml = neko.io.File.getContent(vdir+"/haxelib.xml");
  570. var inf = Datas.readData(xml);
  571. for( d in inf.dependencies )
  572. checkRec(d.project,if( d.version == "" ) null else d.version,l);
  573. }
  574. function path() {
  575. var list = new List();
  576. while( argcur < args.length ) {
  577. var a = args[argcur++].split(":");
  578. checkRec(a[0],a[1],list);
  579. }
  580. var rep = getRepository();
  581. for( d in list ) {
  582. var pdir = Datas.safe(d.project)+"/"+Datas.safe(d.version)+"/";
  583. var dir = rep + pdir;
  584. try {
  585. dir = neko.io.File.getContent(rep+Datas.safe(d.project)+"/.dev");
  586. if( dir.length == 0 || (dir.charAt(dir.length-1) != '/' && dir.charAt(dir.length-1) != '\\') )
  587. dir += "/";
  588. pdir = dir;
  589. } catch( e : Dynamic ) {
  590. }
  591. var ndir = dir + "ndll";
  592. if( neko.FileSystem.exists(ndir) ) {
  593. var sysdir = ndir+"/"+neko.Sys.systemName();
  594. if( !neko.FileSystem.exists(sysdir) )
  595. throw "Project "+d.project+" version "+d.version+" does not have a neko dll for your system";
  596. neko.Lib.println("-L "+pdir+"ndll/");
  597. }
  598. neko.Lib.println(dir);
  599. }
  600. }
  601. function dev() {
  602. var rep = getRepository();
  603. var project = param("Project");
  604. var dir = paramOpt();
  605. var devfile = rep + Datas.safe(project)+"/.dev";
  606. if( dir == null ) {
  607. if( neko.FileSystem.exists(devfile) )
  608. neko.FileSystem.deleteFile(devfile);
  609. print("Development directory disabled");
  610. } else {
  611. var f = neko.io.File.write(devfile,false);
  612. f.write(dir);
  613. f.close();
  614. print("Development directory set to "+dir);
  615. }
  616. }
  617. function run() {
  618. var rep = getRepository();
  619. var project = param("Project");
  620. var pdir = rep + Datas.safe(project);
  621. if( !neko.FileSystem.exists(pdir) )
  622. throw "Project "+project+" is not installed";
  623. pdir += "/";
  624. var version = neko.io.File.getContent(pdir+".current");
  625. var vdir = pdir + Datas.safe(version);
  626. var rdir = vdir + "/run.n";
  627. if( !neko.FileSystem.exists(rdir) )
  628. throw "Project "+project+" version "+version+" does not have a run script";
  629. args.push(neko.Sys.getCwd());
  630. neko.Sys.setCwd(vdir);
  631. var cmd = "neko run.n";
  632. for( i in argcur...args.length )
  633. cmd += " "+escapeArg(args[i]);
  634. neko.Sys.exit(neko.Sys.command(cmd));
  635. }
  636. function escapeArg( a : String ) {
  637. if( a.indexOf(" ") == -1 )
  638. return a;
  639. return '"'+a+'"';
  640. }
  641. function test() {
  642. var file = param("Package");
  643. doInstallFile(file,true,true);
  644. }
  645. // ----------------------------------
  646. static function print(str) {
  647. neko.Lib.print(str+"\n");
  648. }
  649. static function main() {
  650. haxe.Http.PROXY = neko.net.ProxyDetect.detect();
  651. new Main().process();
  652. }
  653. }