2
0

Main.hx 24 KB

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