1 module glued.application.scanlisteners.bundles; 2 3 import std.algorithm; 4 import std.path; 5 import std.array; 6 7 import glued.logging; 8 9 //todo listener should public import scannable 10 import glued.codescan.scannable; 11 import glued.codescan.listener; 12 13 import glued.adhesives.bundles; 14 import glued.adhesives.config; 15 16 import dejector; 17 18 ///from top-level paths towards lower-level ones; if depth is the same, alphabetical order 19 auto assetComparator(Asset a, Asset b){ 20 auto aDepth = a.path.depth; 21 auto bDepth = b.path.depth; 22 if (aDepth == bDepth) 23 { 24 auto aName = a.path.baseName; 25 auto bName = b.path.baseName; 26 return cmp(aName, bName) < 0; 27 } 28 else 29 { 30 return aDepth < bDepth; 31 } 32 } 33 34 class BundlesListener: ScanListener!Dejector 35 { 36 mixin CreateLogger; 37 private Logger log; 38 private Dejector injector; 39 private BundleRegistrar registrar; 40 private Config config; 41 42 void init(Dejector injector) 43 { 44 this.injector = injector; 45 log = Logger(injector.get!LogSink); 46 registrar = new BundleRegistrar; 47 config = new Config(injector.get!LogSink); 48 injector.bind!(BundleRegistrar)(new InstanceProvider(registrar)); 49 injector.bind!(Config)(new InstanceProvider(config)); 50 registrar.register(new BuildTimeBundle); 51 } 52 53 void onScannable(alias scannable)() if (isScannable!scannable) 54 { 55 //todo track what scannable does asset come from 56 } 57 58 void onType(T)() 59 { 60 } 61 62 void onBundleModule(string modName)() 63 { 64 log.info.emit("Tracking glue-d bundle for module "~modName); 65 registrar.register!(modName)(); 66 } 67 68 void onScannerFreeze() 69 { 70 auto configAssets = registrar 71 .ls() 72 .filter!(a => 73 a.path.baseName == "logging.conf" || 74 a.path.baseName == "application.conf" 75 ); 76 77 //1. scheme=glued 78 //sort from top-level packages towards lower ones 79 auto gluedAssets = configAssets 80 .filter!(a => a.scheme == "glued") 81 .array //required so that result of prev step is random access range 82 .sort!(assetComparator); 83 foreach (a; gluedAssets) 84 config.feed(a); 85 86 //2. scheme=build 87 //order defined in bundles adhesive 88 foreach(n; buildTimeAssetNames) 89 { 90 auto a = registrar.find("build", n); 91 if (!a.empty) 92 { 93 config.feed(a.front()); 94 } 95 } 96 97 //3. others 98 //ditto when it comes to sorting 99 auto otherAssets = configAssets 100 .filter!(a => a.scheme != "glued" && a.scheme != "build") 101 .array //required so that result of prev step is random access range 102 .sort!(assetComparator); 103 foreach (a; otherAssets) 104 config.feed(a); 105 106 //TODO 4. files specified with CLI, in the order of specifying 107 } 108 }