forked from ibolmo/packager
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPackager.php
More file actions
141 lines (114 loc) · 3.6 KB
/
Packager.php
File metadata and controls
141 lines (114 loc) · 3.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
# todo(ibolmo): packages with the same name cause an endless loop
require_once __DIR__ . '/Package.php';
class Packager {
static $instance;
protected $sources = array();
protected $generators = array();
protected $keys = array();
public function __construct($package_paths = '')
{
$this->configure();
if ($package_paths) foreach ((array) $package_paths as $package) $this->add_package($package);
}
static function get_instance()
{
if (!self::$instance) self::$instance = new Packager();
return self::$instance;
}
static function strip_blocks($code, $blocks)
{
foreach ((array) $blocks as $block){
$code = preg_replace_callback("%(/[/*])\s*<$block>(.*?)</$block>(?:\s*\*/)?%s", function($matches){
return (strpos($matches[2], ($matches[1] == "//") ? "\n" : "*/") === false) ? $matches[2] : "";
}, $code);
}
return $code;
}
public function add_component(Source $source, $component)
{
$index = $this->get_source_index($source);
if ($index < 0) $index = $this->add_source($source);
foreach ($this->generators as $name => $callback){
$key = call_user_func($callback, $source, $component);
$this->set_key($key, $index, $name);
}
return $index;
}
public function add_generator($name, $callback)
{
$this->generators[$name] = $callback;
}
public function add_package($package)
{
if (!is_a($package, 'Package')) $package = new Package($package);
$this->packages[] = $package;
}
public function add_source(Source $source)
{
$index = array_push($this->sources, $source) - 1;
return $this->keys[$source->get_name()] = $index;
}
public function build(Source $source)
{
$build = array_map(function($source){
return $source->get_code();
}, $this->get_required_for_source($source));
$build[] = $source->get_code();
return implode('', $build);
}
public function configure()
{
$this->add_generator('component name', function(Source $source, $component){
return $component;
});
$this->add_generator('package and source name', function(Source $source, $component){
return sprintf('%s/%s', $source->get_package_name(), $source->get_name());
});
$this->add_generator('package and component name', function(Source $source, $component){
return sprintf('%s/%s', $source->get_package_name(), $component);
});
}
public function get_source_by_name($name)
{
return isset($this->keys[$name]) ? $this->sources[$this->keys[$name]] : null;
}
public function get_source_index($source)
{
$key = $source->get_name();
return isset($this->keys[$key]) ? $this->keys[$key] : -1;
}
public function get_sources()
{
return $this->sources;
}
public function get_required_for_source(Source $source, &$required = null)
{
$return = false;
if (!$required){
$return = true;
$required = array();
}
foreach ($source->get_requires() as $require){
if (!($require instanceof Source)) $require = $this->sources[$this->keys[$require]];
if ($require->has_requires()) $this->get_required_for_source($require, $required);
}
foreach ($source->get_requires() as $require){
if (!($require instanceof Source)){
if (!isset($this->keys[$require])) throw new Exception("Could not find '$require'.");
$require = $this->sources[$this->keys[$require]];
}
if (!in_array($require, $required)) $required[] = $require;
}
if ($return) return $required;
}
protected function set_key($key, $index, $generator_name)
{
if (isset($this->keys[$key])) $this->warn("Generator '$generator_name' set component key '$key'.");
$this->keys[$key] = $index;
}
protected function warn($message)
{
# todo(ibolmo): log mixin
}
}