Main.hx 21 KB

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