Compare commits
3796 Commits
v0.8.16
...
efischer/d
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
30e563bd23 | ||
|
|
5450f9b917 | ||
|
|
72a3d35d0c | ||
|
|
a21d3d353b | ||
|
|
2850ca60be | ||
|
|
4095eb2196 | ||
|
|
f7ee8d001a | ||
|
|
57033a62fa | ||
|
|
31cab4bae2 | ||
|
|
66ea42f8d7 | ||
|
|
f5c9a8c2ee | ||
|
|
5333a799ea | ||
|
|
90070c317d | ||
|
|
a3f1ae8c4f | ||
|
|
a9a29d207d | ||
|
|
e119c32a9c | ||
|
|
82808f944a | ||
|
|
83897af710 | ||
|
|
d39322e278 | ||
|
|
974749aaf6 | ||
|
|
6acfcd82b1 | ||
|
|
079d063c6d | ||
|
|
db7c3d2de6 | ||
|
|
2053db4d17 | ||
|
|
7ebb17e459 | ||
|
|
e73a1a4ec3 | ||
|
|
77c24d4127 | ||
|
|
80754a4062 | ||
|
|
8170bcfcdd | ||
|
|
07e0da24c5 | ||
|
|
22d2786940 | ||
|
|
e9bc3a9e32 | ||
|
|
848299ba38 | ||
|
|
2ddaabed25 | ||
|
|
062ff13da6 | ||
|
|
93cb2db531 | ||
|
|
a7e568b1d1 | ||
|
|
19bbe5e421 | ||
|
|
86fe78f5f1 | ||
|
|
85be3aefa7 | ||
|
|
24c0ece841 | ||
|
|
2b6833cb80 | ||
|
|
73620fe868 | ||
|
|
e6bac6f208 | ||
|
|
63859bf113 | ||
|
|
5cfa74801f | ||
|
|
5970b7a00a | ||
|
|
41750ce70d | ||
|
|
d154f151aa | ||
|
|
6d2d5806b5 | ||
|
|
8a481e7e13 | ||
|
|
86d39255ec | ||
|
|
2efd7a5e0b | ||
|
|
dae219d5c3 | ||
|
|
459b6eae11 | ||
|
|
3194f2001b | ||
|
|
05f5ba4bf9 | ||
|
|
73cae8d9c4 | ||
|
|
52ae0ea055 | ||
|
|
de12a34415 | ||
|
|
243d516bf0 | ||
|
|
6500ac80e4 | ||
|
|
a2692e4ef5 | ||
|
|
bdc825fc3c | ||
|
|
64d3f87e60 | ||
|
|
7eb386e55e | ||
|
|
5da9116c06 | ||
|
|
aca8576de4 | ||
|
|
e81f3daa28 | ||
|
|
7b49166f9b | ||
|
|
a44beee172 | ||
|
|
65abd279cd | ||
|
|
87d15212eb | ||
|
|
4b354cbe26 | ||
|
|
226d4f04f3 | ||
|
|
5661afa315 | ||
|
|
0c8462723b | ||
|
|
fbe76c41fd | ||
|
|
78685addbb | ||
|
|
55b1182a4c | ||
|
|
d5903e4612 | ||
|
|
f0f2c6c486 | ||
|
|
a177b9be8a | ||
|
|
df623dad15 | ||
|
|
835b8f246e | ||
|
|
d7873b5319 | ||
|
|
c1af0d3806 | ||
|
|
d4e3699510 | ||
|
|
466da3afcc | ||
|
|
90e5ccd98c | ||
|
|
13f636ec68 | ||
|
|
c8dd1bb40b | ||
|
|
3445a781eb | ||
|
|
6641f42417 | ||
|
|
296212d78d | ||
|
|
f4ec99ecb4 | ||
|
|
b99e945e6d | ||
|
|
7f57405eac | ||
|
|
e8afbfbce7 | ||
|
|
5dcc0f7802 | ||
|
|
9509c10064 | ||
|
|
f182590aae | ||
|
|
54ef9443d3 | ||
|
|
74dd7a36b5 | ||
|
|
749a4e78c7 | ||
|
|
3df208efc0 | ||
|
|
69931996bf | ||
|
|
f9cb21e886 | ||
|
|
0074ecd6fa | ||
|
|
8b94937609 | ||
|
|
bd8aab00e4 | ||
|
|
ae20e53cfb | ||
|
|
37faa41b6f | ||
|
|
1e673bfa42 | ||
|
|
27793d97dc | ||
|
|
9ec1c0e18e | ||
|
|
042666eb7e | ||
|
|
826732efec | ||
|
|
eb13cbe9bd | ||
|
|
0d17d90b29 | ||
|
|
3edfa390f7 | ||
|
|
bc64990bc6 | ||
|
|
483e4116c0 | ||
|
|
e1c2ea5123 | ||
|
|
c815aed207 | ||
|
|
d4377c1293 | ||
|
|
633e540a17 | ||
|
|
ec7f58bf96 | ||
|
|
1be63348b5 | ||
|
|
568305ddff | ||
|
|
cd6c370303 | ||
|
|
f147d64527 | ||
|
|
04cee45ac9 | ||
|
|
2b0444b6f4 | ||
|
|
b6fad65f52 | ||
|
|
1363b05e93 | ||
|
|
5cc76f7d84 | ||
|
|
59ce0c7514 | ||
|
|
ddf1879bed | ||
|
|
90dd26397c | ||
|
|
7135299a66 | ||
|
|
ac15d5d619 | ||
|
|
eac9a5905f | ||
|
|
80742b2647 | ||
|
|
8a0824df09 | ||
|
|
a388871083 | ||
|
|
2b83ea30e7 | ||
|
|
f56de63972 | ||
|
|
0b8a3ad8ad | ||
|
|
aa6a6df640 | ||
|
|
e905ce16c9 | ||
|
|
11e595089d | ||
|
|
87d0a7c315 | ||
|
|
09c9786fab | ||
|
|
1edfc82123 | ||
|
|
e6a122417a | ||
|
|
f59653ac2c | ||
|
|
84e331c586 | ||
|
|
db59f87e32 | ||
|
|
240f1fd223 | ||
|
|
867121ca68 | ||
|
|
bf1072c902 | ||
|
|
8061deb883 | ||
|
|
e7f4fd404d | ||
|
|
aa860bf4df | ||
|
|
158deae625 | ||
|
|
cfde03e694 | ||
|
|
4bca1c5440 | ||
|
|
d380d16427 | ||
|
|
2be065418b | ||
|
|
a095fd517f | ||
|
|
fb9f6fe9b5 | ||
|
|
9d4a36a62f | ||
|
|
0c75c13cc0 | ||
|
|
38dcd6bce9 | ||
|
|
102ac7bcf1 | ||
|
|
5362864cc9 | ||
|
|
15d9fb1879 | ||
|
|
2042e9a6d8 | ||
|
|
1339714eec | ||
|
|
5d690c9270 | ||
|
|
e5743db9b9 | ||
|
|
d195576fba | ||
|
|
5e5024342f | ||
|
|
4de45c2684 | ||
|
|
ce6ac93abe | ||
|
|
1f5a21decf | ||
|
|
ab049eca41 | ||
|
|
37fc258313 | ||
|
|
faa0a0e4c3 | ||
|
|
cf2f902b82 | ||
|
|
bf028990e7 | ||
|
|
025609c63f | ||
|
|
7aaad89ba9 | ||
|
|
2b94d7cf8e | ||
|
|
5d48c108a3 | ||
|
|
3ea1325620 | ||
|
|
dd30066feb | ||
|
|
e65a8b6a9a | ||
|
|
8121ac2c27 | ||
|
|
93f5a750cb | ||
|
|
281f6f18e1 | ||
|
|
db87a9d3ce | ||
|
|
d7329d7bc2 | ||
|
|
e9edfec0ec | ||
|
|
2ad21e7070 | ||
|
|
09d96bef9f | ||
|
|
9ebbde0e01 | ||
|
|
1de5817b58 | ||
|
|
f699d7c08e | ||
|
|
152fa33a55 | ||
|
|
3cf2fd40a8 | ||
|
|
653905e3a2 | ||
|
|
f800708ef3 | ||
|
|
6a62a6b693 | ||
|
|
a07a0ef54b | ||
|
|
3c81bb44ba | ||
|
|
e0db1f0268 | ||
|
|
9e16902397 | ||
|
|
63592096c5 | ||
|
|
4983ebcf7c | ||
|
|
d3f115933e | ||
|
|
18d155e713 | ||
|
|
a6afaeb974 | ||
|
|
769408130a | ||
|
|
90f68d2c66 | ||
|
|
8e20a14945 | ||
|
|
f403f256ca | ||
|
|
20221ee3aa | ||
|
|
594a6710ed | ||
|
|
d6dedee6ff | ||
|
|
0c02ee86a7 | ||
|
|
e12d7aadda | ||
|
|
fd11db92e1 | ||
|
|
ba0577dc96 | ||
|
|
ef1369c365 | ||
|
|
e17862c421 | ||
|
|
d5bb2955b1 | ||
|
|
d4274b32f2 | ||
|
|
6ab78eb88e | ||
|
|
d7665a63e3 | ||
|
|
369b2ef01f | ||
|
|
1ac1cc3d2c | ||
|
|
3c6f6fc811 | ||
|
|
bacfa91cfd | ||
|
|
cabcdf0ec9 | ||
|
|
fcc8b1d3e4 | ||
|
|
61b3ecb6d2 | ||
|
|
af8741c23c | ||
|
|
a591e183bc | ||
|
|
584e5506f2 | ||
|
|
2bd1a51193 | ||
|
|
1578a95982 | ||
|
|
7affaca321 | ||
|
|
b7fa2c4e21 | ||
|
|
2e1dbd0697 | ||
|
|
e69423a154 | ||
|
|
e68b7d8c63 | ||
|
|
638f779841 | ||
|
|
be1158f7a3 | ||
|
|
f0609699ba | ||
|
|
43371c31a2 | ||
|
|
dce105d16f | ||
|
|
4acf6d76bf | ||
|
|
a7bfaa3797 | ||
|
|
88bb67e279 | ||
|
|
46e9d85283 | ||
|
|
7c46a4c0e4 | ||
|
|
3e6ebd577f | ||
|
|
353726f08f | ||
|
|
7ae163d436 | ||
|
|
b9195b415a | ||
|
|
2f1c000f62 | ||
|
|
d7d12aa2dc | ||
|
|
48997cffa1 | ||
|
|
4ff4eab476 | ||
|
|
f90692cf81 | ||
|
|
13d9eed85b | ||
|
|
941acef009 | ||
|
|
b5a117c923 | ||
|
|
1534a115bd | ||
|
|
a03a35565e | ||
|
|
326b9838ed | ||
|
|
fa70a837d4 | ||
|
|
91004158c6 | ||
|
|
2929fb0a4d | ||
|
|
3f26bbc8b3 | ||
|
|
a3322fab0a | ||
|
|
21158195fb | ||
|
|
74a181febc | ||
|
|
9490bd2154 | ||
|
|
4c8672ed1f | ||
|
|
c77425bb22 | ||
|
|
a6605d842b | ||
|
|
f2f5f6c279 | ||
|
|
c994565c62 | ||
|
|
1b9becc541 | ||
|
|
08ff7b65af | ||
|
|
4d72e0fb9d | ||
|
|
a5a4525bed | ||
|
|
949621eb7f | ||
|
|
857a03c127 | ||
|
|
114da813a3 | ||
|
|
bf467c5df3 | ||
|
|
6c3623422f | ||
|
|
63121a0c49 | ||
|
|
12d1263980 | ||
|
|
6f332c7e4c | ||
|
|
bfcec69630 | ||
|
|
4373a2b629 | ||
|
|
a57d94af03 | ||
|
|
a1703bf70d | ||
|
|
dea7bbb4a0 | ||
|
|
565bd5f51e | ||
|
|
bef7e2645a | ||
|
|
f6a4a6b00f | ||
|
|
0c0b37800d | ||
|
|
4ecf481337 | ||
|
|
6f7e12d49b | ||
|
|
0aa513ad70 | ||
|
|
450c750214 | ||
|
|
a4e59c2758 | ||
|
|
9433e84776 | ||
|
|
17f0eb5148 | ||
|
|
ba11f19efc | ||
|
|
bb5dd49206 | ||
|
|
679ceabf36 | ||
|
|
31042e8ed1 | ||
|
|
2705f2c0e3 | ||
|
|
c678a9e3da | ||
|
|
0cf1f917d5 | ||
|
|
bc2e0cc87c | ||
|
|
0425f5d523 | ||
|
|
0ce98d4d65 | ||
|
|
7f43a7d134 | ||
|
|
661708b7fa | ||
|
|
ae167c09fc | ||
|
|
14d861a41c | ||
|
|
e864d27641 | ||
|
|
b892cebe8a | ||
|
|
49e47966a8 | ||
|
|
e861e35acf | ||
|
|
1847aa035d | ||
|
|
630ff6871d | ||
|
|
94238eebfa | ||
|
|
5b79f0d04a | ||
|
|
dc9fcea989 | ||
|
|
15514792d5 | ||
|
|
851bc506e4 | ||
|
|
932300256c | ||
|
|
6361f5c2d4 | ||
|
|
2d51ea5da4 | ||
|
|
fed7ba1dab | ||
|
|
19578d954f | ||
|
|
ab885a5397 | ||
|
|
4014a29d2b | ||
|
|
b4cd2a85df | ||
|
|
f5aed63b0b | ||
|
|
5cac0a528c | ||
|
|
bdb64c2e39 | ||
|
|
0903ae0599 | ||
|
|
1e3a5d4e26 | ||
|
|
6db99a4fe7 | ||
|
|
5b1a882fc2 | ||
|
|
a2578c21e4 | ||
|
|
8d0758fc4c | ||
|
|
880cbb2217 | ||
|
|
3b4820f290 | ||
|
|
9e05fdf4a1 | ||
|
|
7e53f4328f | ||
|
|
e470478dc1 | ||
|
|
7d303afd64 | ||
|
|
1552ed943a | ||
|
|
31b7580b76 | ||
|
|
cc3fc2ba4c | ||
|
|
0ce54c99af | ||
|
|
aaa5c9e8a4 | ||
|
|
cca240c8f9 | ||
|
|
ec09dfe5d1 | ||
|
|
fbbb82259a | ||
|
|
ea11aab71f | ||
|
|
2042c94a6c | ||
|
|
64be8a80b2 | ||
|
|
7185fe2876 | ||
|
|
0724eba935 | ||
|
|
441bb83682 | ||
|
|
2cffc90284 | ||
|
|
68cedd2599 | ||
|
|
d00fd06095 | ||
|
|
3d571ad934 | ||
|
|
8815f0a0b5 | ||
|
|
bfd03db12a | ||
|
|
f14eb07dc1 | ||
|
|
a9cc6a7d08 | ||
|
|
be2f2e42db | ||
|
|
05e5276aec | ||
|
|
dbf799bbf9 | ||
|
|
f39e570f36 | ||
|
|
58a6039c0a | ||
|
|
0662b953f0 | ||
|
|
1b04b8be01 | ||
|
|
500218df80 | ||
|
|
173a16b38a | ||
|
|
68ba5377c1 | ||
|
|
253507c0c3 | ||
|
|
7684652ce3 | ||
|
|
b12dc34ba7 | ||
|
|
9c31ee8a75 | ||
|
|
ae5ba2b110 | ||
|
|
13499f1655 | ||
|
|
49e9f365d8 | ||
|
|
0fa8a491d3 | ||
|
|
41cd861861 | ||
|
|
2913aa8d09 | ||
|
|
1bd2def41e | ||
|
|
386f0e577a | ||
|
|
7207ce2a18 | ||
|
|
20e52e5052 | ||
|
|
e9944150a5 | ||
|
|
fc1804974c | ||
|
|
12167e8f37 | ||
|
|
8dc26bbcd9 | ||
|
|
ee7acc6b13 | ||
|
|
f4422dc165 | ||
|
|
dc7e0899a0 | ||
|
|
5bb2d3baa0 | ||
|
|
5e97eb5ec4 | ||
|
|
6c80b15220 | ||
|
|
aad5a4c4b3 | ||
|
|
5eebb2defa | ||
|
|
b6ce0e6f0e | ||
|
|
943896e237 | ||
|
|
8ee4df8101 | ||
|
|
572f1cd427 | ||
|
|
e04662f84f | ||
|
|
5caaa2cd75 | ||
|
|
3759f62cba | ||
|
|
07f2dd5498 | ||
|
|
eab56b71be | ||
|
|
3040381f03 | ||
|
|
f855cf6bab | ||
|
|
b1e6c58ff2 | ||
|
|
4e6fdd12e2 | ||
|
|
458deaae5e | ||
|
|
9c7b98dcc8 | ||
|
|
e4525e57bb | ||
|
|
dba384108b | ||
|
|
e4ced765f1 | ||
|
|
a2d4dcc636 | ||
|
|
969e785d94 | ||
|
|
5b7ec8de95 | ||
|
|
e19872e77f | ||
|
|
eb865b0df2 | ||
|
|
c6a05f4a7d | ||
|
|
3126ed5f21 | ||
|
|
d684b17c06 | ||
|
|
5cfaa557d3 | ||
|
|
23006d1195 | ||
|
|
81cd458c26 | ||
|
|
27986c9edf | ||
|
|
b7bf88c761 | ||
|
|
29278090eb | ||
|
|
b1e5ec0573 | ||
|
|
4f09e8c975 | ||
|
|
a8855f48aa | ||
|
|
4181fd79cd | ||
|
|
b51be2bb1b | ||
|
|
773bca159a | ||
|
|
ec9959b152 | ||
|
|
1be486c90a | ||
|
|
7220bc1766 | ||
|
|
395c616a48 | ||
|
|
ebbcebac62 | ||
|
|
fa92f58167 | ||
|
|
ac2e0962ce | ||
|
|
fb2d2303d6 | ||
|
|
f5b4664c7c | ||
|
|
00d7fd8e21 | ||
|
|
adffba5081 | ||
|
|
e083c91d5e | ||
|
|
ed737cb2a2 | ||
|
|
488550c2e6 | ||
|
|
8523f75e6c | ||
|
|
4707362ccd | ||
|
|
dd5b1ac098 | ||
|
|
bcbe9c02da | ||
|
|
1544f98ee0 | ||
|
|
f0d5317913 | ||
|
|
2ae7429b18 | ||
|
|
4efe022165 | ||
|
|
796308ed85 | ||
|
|
4c105895ab | ||
|
|
9523e50732 | ||
|
|
52f0249c61 | ||
|
|
a27cb639d8 | ||
|
|
cf8f14780f | ||
|
|
098af17971 | ||
|
|
5745ede31d | ||
|
|
0b1d03abe6 | ||
|
|
00280936da | ||
|
|
480fe9cb9a | ||
|
|
bd91dd9d6d | ||
|
|
732c24f603 | ||
|
|
4e1f86881a | ||
|
|
07d4c6cf0b | ||
|
|
ead1b93f75 | ||
|
|
0be4c7dfbd | ||
|
|
5e5e36a659 | ||
|
|
16f67b5bb1 | ||
|
|
b8444aa518 | ||
|
|
a09bebcaea | ||
|
|
a9541997ae | ||
|
|
bd02892f7b | ||
|
|
ea9fa81ba5 | ||
|
|
670157b364 | ||
|
|
e5ae48a9da | ||
|
|
47514d07b1 | ||
|
|
f2e8f27c15 | ||
|
|
fc79b104f0 | ||
|
|
97143768c8 | ||
|
|
d3b97227a1 | ||
|
|
da2b695f93 | ||
|
|
10c285a774 | ||
|
|
0654ee6a10 | ||
|
|
8cf03c209f | ||
|
|
c588ce9648 | ||
|
|
3fac2dcc41 | ||
|
|
0080ffcf9f | ||
|
|
ce902bf27a | ||
|
|
2cde6aaabd | ||
|
|
578ddea418 | ||
|
|
cf0f5756f5 | ||
|
|
9e1d26e973 | ||
|
|
e389afedaa | ||
|
|
b9c79824a2 | ||
|
|
0777d3a5ba | ||
|
|
2344ffd0c7 | ||
|
|
0c75174ec3 | ||
|
|
e973adf84b | ||
|
|
f9137f606f | ||
|
|
8856a226c7 | ||
|
|
d8acd41ba1 | ||
|
|
8efbec3c0b | ||
|
|
4c7c9f4ff5 | ||
|
|
cd4f429f72 | ||
|
|
24c14ff7a8 | ||
|
|
eda1176ba7 | ||
|
|
c9f4e8ce5a | ||
|
|
6983c1d30d | ||
|
|
412618d531 | ||
|
|
7db4170062 | ||
|
|
f4fb9a0771 | ||
|
|
79e066d53c | ||
|
|
106147716a | ||
|
|
0d18f7249c | ||
|
|
26d1ddc176 | ||
|
|
4c506b36c5 | ||
|
|
4434f482c0 | ||
|
|
3def8ef60e | ||
|
|
20584ab084 | ||
|
|
7c28338d60 | ||
|
|
17a63c9646 | ||
|
|
01a361d637 | ||
|
|
7f20678969 | ||
|
|
69e36c9821 | ||
|
|
c503b43e38 | ||
|
|
83330d2b59 | ||
|
|
6501cba5a7 | ||
|
|
26480f14f9 | ||
|
|
6b0fb476ab | ||
|
|
dd7bd4f320 | ||
|
|
1315753e70 | ||
|
|
1c9cf668a1 | ||
|
|
8034536054 | ||
|
|
afa4cdc2d8 | ||
|
|
25e765baae | ||
|
|
a64a2e72cf | ||
|
|
c4b4ce7d85 | ||
|
|
4ad29b6c9b | ||
|
|
7e16a4edd7 | ||
|
|
acfeb5d043 | ||
|
|
71684cb071 | ||
|
|
4dec06e4f4 | ||
|
|
94df1b801a | ||
|
|
7555c3d949 | ||
|
|
013cfafe57 | ||
|
|
218fc602fa | ||
|
|
25a9181a1b | ||
|
|
02340062b4 | ||
|
|
4a276807b1 | ||
|
|
51834773b4 | ||
|
|
46ee4a3a53 | ||
|
|
607813d5ce | ||
|
|
67fade5b1e | ||
|
|
a9ed2296a1 | ||
|
|
fa0bbb57ea | ||
|
|
49cd6f6269 | ||
|
|
653f25d676 | ||
|
|
089189afaf | ||
|
|
0a89342508 | ||
|
|
06f57a31c1 | ||
|
|
19df1ea79d | ||
|
|
2b4d2b8748 | ||
|
|
a46138dea9 | ||
|
|
ea425a101a | ||
|
|
583232ea52 | ||
|
|
89c9bec81e | ||
|
|
262ab40188 | ||
|
|
199a8af7cc | ||
|
|
e9f42c1a94 | ||
|
|
a96eb7096d | ||
|
|
cc027148eb | ||
|
|
2b3ba850b3 | ||
|
|
b3789a4693 | ||
|
|
4030f8d7c3 | ||
|
|
cddaba8add | ||
|
|
192369dd2b | ||
|
|
73f10c9363 | ||
|
|
cdc2ebee90 | ||
|
|
2e4966c854 | ||
|
|
c898b9db04 | ||
|
|
117743863e | ||
|
|
28ce08b9e2 | ||
|
|
0e8bf79fa4 | ||
|
|
dc671ad037 | ||
|
|
1bd3a702c9 | ||
|
|
561748a063 | ||
|
|
9ea4f80f15 | ||
|
|
0752eccfa5 | ||
|
|
6175ce7559 | ||
|
|
987fb137f9 | ||
|
|
514c61b8fe | ||
|
|
992250ddea | ||
|
|
d61190c3ff | ||
|
|
96e9dbca08 | ||
|
|
5a1ed51dcd | ||
|
|
63101e9914 | ||
|
|
8c1cc44522 | ||
|
|
36f818b9fb | ||
|
|
c0be585b67 | ||
|
|
656b2d562f | ||
|
|
f761130343 | ||
|
|
f1d85ac2e9 | ||
|
|
1585c014d7 | ||
|
|
37ce4108ce | ||
|
|
e822257565 | ||
|
|
a4a2f179c7 | ||
|
|
4663288b49 | ||
|
|
64b1bafd41 | ||
|
|
5f1b6f000d | ||
|
|
b29b7595dd | ||
|
|
1f3cb2b93c | ||
|
|
077848fc0b | ||
|
|
f3e9588457 | ||
|
|
487ec2aff1 | ||
|
|
b8e2799700 | ||
|
|
5d152edcaf | ||
|
|
faa3d43d9c | ||
|
|
a0584c78a8 | ||
|
|
d71a12438b | ||
|
|
39aef5fc00 | ||
|
|
a82385cdae | ||
|
|
0ca1a481a3 | ||
|
|
ac1701ae29 | ||
|
|
77965ce5bf | ||
|
|
6fd45520da | ||
|
|
45c675fe7f | ||
|
|
bae97d17d0 | ||
|
|
bdf82246f7 | ||
|
|
1ae43b3405 | ||
|
|
6d2ec9baf7 | ||
|
|
b4682c8ca3 | ||
|
|
e275b567eb | ||
|
|
64d91943ec | ||
|
|
3e718920d1 | ||
|
|
3051c3d71d | ||
|
|
e052aaf44d | ||
|
|
668b4f1b2c | ||
|
|
5ffc50732b | ||
|
|
fcfe2618d5 | ||
|
|
d24c11f2b1 | ||
|
|
3864da6300 | ||
|
|
d09b0c95ec | ||
|
|
0e2afedb7f | ||
|
|
de9cce3e80 | ||
|
|
52ca215e29 | ||
|
|
b8bd02c5b2 | ||
|
|
a73d91a2e5 | ||
|
|
27aa265abd | ||
|
|
b7d9b58cc5 | ||
|
|
955d02049c | ||
|
|
069de3f008 | ||
|
|
04b3d8d86f | ||
|
|
502d15fd3b | ||
|
|
5e323b052a | ||
|
|
81daaddfe9 | ||
|
|
38e722f75d | ||
|
|
15790d7018 | ||
|
|
551d9eb328 | ||
|
|
1b08296392 | ||
|
|
8de84b5d8a | ||
|
|
78ac11ff88 | ||
|
|
283d621b6e | ||
|
|
86b1b28906 | ||
|
|
efdcd199c1 | ||
|
|
db1516d582 | ||
|
|
d99fbbb68f | ||
|
|
11960e53ef | ||
|
|
5f861e075c | ||
|
|
255d05a9c1 | ||
|
|
6d36ec3d76 | ||
|
|
7f6541ef02 | ||
|
|
664bdd359f | ||
|
|
306e601d4e | ||
|
|
fbaff33f3f | ||
|
|
a729c332c8 | ||
|
|
1682257b35 | ||
|
|
691e628726 | ||
|
|
85947d0985 | ||
|
|
0d3a52ae29 | ||
|
|
1b553f2b21 | ||
|
|
f14cd67446 | ||
|
|
84afaf385f | ||
|
|
1cc6e42682 | ||
|
|
38550bbc1b | ||
|
|
7551e4c14f | ||
|
|
b29d5e6032 | ||
|
|
b0f4052bd8 | ||
|
|
e482994a15 | ||
|
|
c086ccdab6 | ||
|
|
33d0660abc | ||
|
|
3338fcf014 | ||
|
|
c8137194f0 | ||
|
|
f04258eb29 | ||
|
|
1fa67e458c | ||
|
|
642be5fa3d | ||
|
|
2759f14f23 | ||
|
|
1b9e8a0e65 | ||
|
|
bb8a8ecda3 | ||
|
|
49e8e4b590 | ||
|
|
1a1bf31032 | ||
|
|
1b53452618 | ||
|
|
d339f2af29 | ||
|
|
4c1b53660d | ||
|
|
a2be05f24b | ||
|
|
719b6bfffd | ||
|
|
8c1274bbbb | ||
|
|
fb6d850637 | ||
|
|
b9148b1751 | ||
|
|
403a55afb2 | ||
|
|
663b30b3e8 | ||
|
|
6bb31a9a4c | ||
|
|
91da3d8e64 | ||
|
|
c6e89d9283 | ||
|
|
14cef6eab8 | ||
|
|
c096bb332a | ||
|
|
081918d71a | ||
|
|
58487accdd | ||
|
|
3df0f1902d | ||
|
|
4e27d91351 | ||
|
|
57eaea2e8c | ||
|
|
61fe89bda0 | ||
|
|
3d755a148b | ||
|
|
03fdb2058a | ||
|
|
379f23be02 | ||
|
|
9b926a480f | ||
|
|
780a57367d | ||
|
|
32e086f44a | ||
|
|
c8fc56686c | ||
|
|
63e45c586c | ||
|
|
a47b3ba01b | ||
|
|
f5f7abd71f | ||
|
|
2b9d02d594 | ||
|
|
4c063c6055 | ||
|
|
976b2b4d25 | ||
|
|
1f64f08cb3 | ||
|
|
cb9c4ac866 | ||
|
|
79b3ef0362 | ||
|
|
55c4a676ad | ||
|
|
d687e332ad | ||
|
|
690937f953 | ||
|
|
6bac1598f6 | ||
|
|
f2a692c515 | ||
|
|
d166c04db5 | ||
|
|
1de675e976 | ||
|
|
d5abcc5c88 | ||
|
|
519b760222 | ||
|
|
53bbbfbe21 | ||
|
|
9fb8030370 | ||
|
|
85982017b6 | ||
|
|
861f174f66 | ||
|
|
3e8391458c | ||
|
|
890df7153a | ||
|
|
2143c38ab8 | ||
|
|
6d988dde8d | ||
|
|
3100c5948a | ||
|
|
729f23b432 | ||
|
|
0de4ba738b | ||
|
|
31e9ded768 | ||
|
|
d10fceaacc | ||
|
|
0e171127b9 | ||
|
|
f0f7b23c8a | ||
|
|
fe4ef286f2 | ||
|
|
56adb5d9a5 | ||
|
|
16a4c49f98 | ||
|
|
d784d561fc | ||
|
|
e837be1af9 | ||
|
|
137db14b75 | ||
|
|
d3b0cb56b7 | ||
|
|
6793a54748 | ||
|
|
ba1ada5424 | ||
|
|
a770151359 | ||
|
|
6327877a6f | ||
|
|
50ac98bc04 | ||
|
|
ba87937fff | ||
|
|
1b7eedbb7d | ||
|
|
0e422dec8c | ||
|
|
bc2fa76588 | ||
|
|
30d083c6b7 | ||
|
|
a7b8cb6901 | ||
|
|
6f4b0e9bda | ||
|
|
cfd380d514 | ||
|
|
cd943ebe94 | ||
|
|
37728afada | ||
|
|
5f720f9b7c | ||
|
|
e3e94f0ac9 | ||
|
|
89bf5f4045 | ||
|
|
7ec191ce0b | ||
|
|
6f69c01915 | ||
|
|
2fcaa011ce | ||
|
|
06de8c56af | ||
|
|
eb388306fd | ||
|
|
c996632113 | ||
|
|
bc1320d83a | ||
|
|
7df89896f4 | ||
|
|
b71d430af6 | ||
|
|
0fd58fb585 | ||
|
|
32c801bbf6 | ||
|
|
ad48ad7586 | ||
|
|
5cdd37959a | ||
|
|
6810965457 | ||
|
|
18612eca59 | ||
|
|
48888b0f8e | ||
|
|
c4c167c1ca | ||
|
|
51b0f53b33 | ||
|
|
06e38d2ca2 | ||
|
|
793c9f5546 | ||
|
|
0384794912 | ||
|
|
26325fe812 | ||
|
|
9bb918915f | ||
|
|
7fb45e4bfd | ||
|
|
d7c2f683d9 | ||
|
|
b80a03e6b6 | ||
|
|
9026fb8e8a | ||
|
|
3ea9d1e665 | ||
|
|
bf4eeb48b9 | ||
|
|
76458f5bfc | ||
|
|
798dabc8f2 | ||
|
|
0faa6dd753 | ||
|
|
0185226042 | ||
|
|
99c3ed56fa | ||
|
|
305d5698df | ||
|
|
a15aee5d8e | ||
|
|
d899059075 | ||
|
|
b4c36164b5 | ||
|
|
3bc4a38b78 | ||
|
|
13fcb3c083 | ||
|
|
f3f309a22a | ||
|
|
73213ac59d | ||
|
|
a1db306a0c | ||
|
|
19b69ce3a5 | ||
|
|
ece72e5337 | ||
|
|
bad32724ec | ||
|
|
8f28df1d14 | ||
|
|
8b35940857 | ||
|
|
30993357d7 | ||
|
|
f86f6c6274 | ||
|
|
7d85902f37 | ||
|
|
c096aa9557 | ||
|
|
f3accb111e | ||
|
|
7cf1313572 | ||
|
|
18222de7b6 | ||
|
|
9de0503188 | ||
|
|
11863d2de3 | ||
|
|
a2ba60f6a8 | ||
|
|
e5b36583b5 | ||
|
|
acd9014553 | ||
|
|
ea88d9cfe9 | ||
|
|
055f7f4ab6 | ||
|
|
2c6c21a3bf | ||
|
|
71a297f121 | ||
|
|
8921bf4552 | ||
|
|
65e3ac4132 | ||
|
|
27e9bc6d02 | ||
|
|
d566510a40 | ||
|
|
3f4bf04dde | ||
|
|
8f846d507d | ||
|
|
10810482bc | ||
|
|
ffe9e77e36 | ||
|
|
86893e3dc4 | ||
|
|
ff3e56cf9a | ||
|
|
c904a42c5b | ||
|
|
f29b55957a | ||
|
|
b66f5b6231 | ||
|
|
e398c0dc5b | ||
|
|
060fb596f7 | ||
|
|
97feca0888 | ||
|
|
e41d67e031 | ||
|
|
8b5467e65d | ||
|
|
a7ffb2c1a4 | ||
|
|
bbe2db5814 | ||
|
|
66089c89aa | ||
|
|
2efc67da60 | ||
|
|
e0fbf14f99 | ||
|
|
8f3954c1bd | ||
|
|
4041f45b6c | ||
|
|
58cff1290d | ||
|
|
0521b9bb32 | ||
|
|
f18e1a9371 | ||
|
|
3f90fee614 | ||
|
|
77cd474a2d | ||
|
|
70a25c4587 | ||
|
|
cbd5a0a6e3 | ||
|
|
db81a74d66 | ||
|
|
a3431c5a73 | ||
|
|
d515877d91 | ||
|
|
4c4f3e9747 | ||
|
|
76d950b103 | ||
|
|
5aa3131385 | ||
|
|
b86e3047f3 | ||
|
|
45482187b4 | ||
|
|
f6aa864bc4 | ||
|
|
ac728d3e60 | ||
|
|
6180e6c047 | ||
|
|
6fb7b0fcf7 | ||
|
|
88888f5ba0 | ||
|
|
1303b5a6a9 | ||
|
|
fe30113502 | ||
|
|
0377f3580b | ||
|
|
f74d4b0660 | ||
|
|
9b299cb2bb | ||
|
|
cec283f608 | ||
|
|
aa86488fd9 | ||
|
|
c2d0870924 | ||
|
|
42ff1aaa75 | ||
|
|
31bb47356f | ||
|
|
b3881701c5 | ||
|
|
0fbd2fe224 | ||
|
|
c09111bbef | ||
|
|
59318f4705 | ||
|
|
8047edfb56 | ||
|
|
265b9bcb0f | ||
|
|
be407f531e | ||
|
|
28b2e36230 | ||
|
|
afff40e584 | ||
|
|
c9eb5f8173 | ||
|
|
5dfc2052bd | ||
|
|
98d03c74e1 | ||
|
|
7e1ee463ca | ||
|
|
5a55bb3f8d | ||
|
|
79fae306f6 | ||
|
|
81ac3b62fc | ||
|
|
9500f2718b | ||
|
|
a21e845ce7 | ||
|
|
2220784eda | ||
|
|
1dc62e8a19 | ||
|
|
12b9d6da10 | ||
|
|
8bdb6695c7 | ||
|
|
ce105e9bbe | ||
|
|
84e21703bd | ||
|
|
83b0c16728 | ||
|
|
973caa3a07 | ||
|
|
e43eaad557 | ||
|
|
a0c0728ea8 | ||
|
|
b4da4425ff | ||
|
|
fa471a4ed1 | ||
|
|
d8b9cda632 | ||
|
|
cf4a34c657 | ||
|
|
1cc04cff27 | ||
|
|
71e92774eb | ||
|
|
8fa8fc239f | ||
|
|
e5b08544ff | ||
|
|
2009354719 | ||
|
|
a5086f474e | ||
|
|
92a7c0ddd5 | ||
|
|
64aaf7ba81 | ||
|
|
83d4cdc090 | ||
|
|
a07056d67b | ||
|
|
64c83638ff | ||
|
|
15e6b88a8b | ||
|
|
36275f8e6e | ||
|
|
ccb62b4620 | ||
|
|
f9efb746d7 | ||
|
|
9e0c20c794 | ||
|
|
a17d1efe7c | ||
|
|
670669ef80 | ||
|
|
a33077b77f | ||
|
|
51cf847647 | ||
|
|
8af1c5fc8f | ||
|
|
c703bfb54d | ||
|
|
652a5eb592 | ||
|
|
62b2f2a7c9 | ||
|
|
4569df025e | ||
|
|
9a8d109650 | ||
|
|
d7f48e1ff0 | ||
|
|
0bbbfc2ef7 | ||
|
|
8770f2a0ea | ||
|
|
0743ef4d0b | ||
|
|
a4ac99877a | ||
|
|
536fa73d5f | ||
|
|
448f8c43d4 | ||
|
|
fe5eec5230 | ||
|
|
80d444624b | ||
|
|
24f65c502e | ||
|
|
b2aa78d6ab | ||
|
|
4eeaff175c | ||
|
|
a660c60eb1 | ||
|
|
8970785d33 | ||
|
|
a813f03955 | ||
|
|
4850b9d4d1 | ||
|
|
7da405e630 | ||
|
|
7213b12324 | ||
|
|
0e64c25ffc | ||
|
|
37dc13edaf | ||
|
|
8704a4ed35 | ||
|
|
fe256870b4 | ||
|
|
cb3505769b | ||
|
|
6649f9edc2 | ||
|
|
64acbbfcf0 | ||
|
|
df84fe0b58 | ||
|
|
f351e011d1 | ||
|
|
9ee6cbfb40 | ||
|
|
344280154a | ||
|
|
005827ab23 | ||
|
|
f60ae61652 | ||
|
|
8867adf942 | ||
|
|
c7dfa1699a | ||
|
|
a5aa159d9d | ||
|
|
6b03770602 | ||
|
|
88b73bacdb | ||
|
|
17b868381f | ||
|
|
a1cbb73f8b | ||
|
|
8d9ffcf565 | ||
|
|
88b671f8b1 | ||
|
|
76dfaa71a7 | ||
|
|
40d25d9062 | ||
|
|
f3d6818d5c | ||
|
|
c90cc465f5 | ||
|
|
d4df4375d5 | ||
|
|
1724ff5658 | ||
|
|
3fcd54203c | ||
|
|
2fc9ac4036 | ||
|
|
a7ab064a9e | ||
|
|
ea80c8d3c3 | ||
|
|
daa46105a7 | ||
|
|
44e188f111 | ||
|
|
7b97ea248a | ||
|
|
9cf1257be4 | ||
|
|
deb4f919cf | ||
|
|
9d99042fed | ||
|
|
716f12dd58 | ||
|
|
0e04e65ae0 | ||
|
|
5fe531050c | ||
|
|
e76083205f | ||
|
|
6390acc660 | ||
|
|
6d714e4425 | ||
|
|
3d3a26cd9a | ||
|
|
36decbfa69 | ||
|
|
d0d83cfe1e | ||
|
|
d04dc8440f | ||
|
|
4d40f86bd3 | ||
|
|
5358ffbe5a | ||
|
|
9ceb8fea78 | ||
|
|
a860a3d614 | ||
|
|
c803f7ae98 | ||
|
|
4ede87a8b0 | ||
|
|
9dd1f2747a | ||
|
|
08badb5a35 | ||
|
|
ff3469385b | ||
|
|
bfedeadacb | ||
|
|
a19c8b343e | ||
|
|
b09bee8158 | ||
|
|
b59d4f243b | ||
|
|
05d7378da5 | ||
|
|
ca5180f7a2 | ||
|
|
e6ec372926 | ||
|
|
e226837d33 | ||
|
|
8861c99333 | ||
|
|
5ba5ef6c46 | ||
|
|
94d0f21823 | ||
|
|
4767185082 | ||
|
|
5cd09af066 | ||
|
|
3c234a7d3b | ||
|
|
450b082daf | ||
|
|
427fa7fd0a | ||
|
|
52160bff18 | ||
|
|
d398ebe21f | ||
|
|
b96b32e9ec | ||
|
|
77e8096a6f | ||
|
|
bfb0985c38 | ||
|
|
a7a640bfb8 | ||
|
|
b05a565648 | ||
|
|
5d3965c7a6 | ||
|
|
7727f6fc7e | ||
|
|
4dcb15cf6d | ||
|
|
bdb9af63ed | ||
|
|
8ff7cbb9ce | ||
|
|
1601cf1b14 | ||
|
|
31d2c38687 | ||
|
|
b89bcdff62 | ||
|
|
1b28991e0a | ||
|
|
30c9d976f6 | ||
|
|
5300ffac7f | ||
|
|
a6681f2d7f | ||
|
|
59c9816dbf | ||
|
|
0e9f8bd38d | ||
|
|
953b65abcc | ||
|
|
6c0ea77d1d | ||
|
|
3737169450 | ||
|
|
eb9b00b210 | ||
|
|
0fea167f97 | ||
|
|
992bcac794 | ||
|
|
85502e34f9 | ||
|
|
bc038eb7c3 | ||
|
|
883f601bca | ||
|
|
915115386a | ||
|
|
2a4d440003 | ||
|
|
454acf58af | ||
|
|
e3ca5e6676 | ||
|
|
4952c4c7de | ||
|
|
7ce08c4216 | ||
|
|
65896ff2ed | ||
|
|
4b9707f8ea | ||
|
|
3b71d78f3c | ||
|
|
42a10d5690 | ||
|
|
2d21693b9d | ||
|
|
564483936f | ||
|
|
4a61efe641 | ||
|
|
f4a39457de | ||
|
|
165411f4a5 | ||
|
|
498c098d11 | ||
|
|
e124c86a4f | ||
|
|
bb19dffb26 | ||
|
|
ad0cfa41aa | ||
|
|
738720a000 | ||
|
|
bb57b82794 | ||
|
|
2262bc95f1 | ||
|
|
25b2f7b1d7 | ||
|
|
a2754894ea | ||
|
|
5715799d4e | ||
|
|
4925be0bc4 | ||
|
|
de1ec4be8b | ||
|
|
196737c217 | ||
|
|
835982faed | ||
|
|
864191b6ed | ||
|
|
5b023bb0a1 | ||
|
|
c7b48f6fef | ||
|
|
f751d68177 | ||
|
|
30e8e77fb6 | ||
|
|
bdd874eb7f | ||
|
|
02cadb882b | ||
|
|
669caefccb | ||
|
|
d43cfefa43 | ||
|
|
2d6db06fca | ||
|
|
ffa6fed3a3 | ||
|
|
422d3d4db6 | ||
|
|
09b1daa7b9 | ||
|
|
408aa10210 | ||
|
|
a3f39c2315 | ||
|
|
97e2834816 | ||
|
|
2207ab8f23 | ||
|
|
0e71b5dde8 | ||
|
|
30c204a0a5 | ||
|
|
bc557cc765 | ||
|
|
24d160e93e | ||
|
|
0b5ce9e16a | ||
|
|
8b6035ab82 | ||
|
|
9d04dccb79 | ||
|
|
3d2b25e45c | ||
|
|
27bc49d8c8 | ||
|
|
b843b73bb5 | ||
|
|
552cfac6ed | ||
|
|
1fb4fa02e3 | ||
|
|
fca8034578 | ||
|
|
53dcc39b72 | ||
|
|
3ab8468e73 | ||
|
|
0451c8e55f | ||
|
|
d802144f39 | ||
|
|
5d4a0e4050 | ||
|
|
97bad2c1ac | ||
|
|
58052e6632 | ||
|
|
cb673765c2 | ||
|
|
0df0677d5b | ||
|
|
9db8dc1895 | ||
|
|
817f43f927 | ||
|
|
c03c689cb2 | ||
|
|
564e7f5e5b | ||
|
|
7bdf63a0fa | ||
|
|
29b85fbce0 | ||
|
|
6f96484f83 | ||
|
|
e82fb5b58f | ||
|
|
24ee32d7b0 | ||
|
|
f3f0122f11 | ||
|
|
b14ba31250 | ||
|
|
716991775d | ||
|
|
08a9d80ebc | ||
|
|
f96c979024 | ||
|
|
c4d5bd13c7 | ||
|
|
fd345c8ef0 | ||
|
|
9f4e599232 | ||
|
|
08c8d1d1f7 | ||
|
|
4122ecbc80 | ||
|
|
4f591a6fe3 | ||
|
|
fe79e43459 | ||
|
|
d7e84fe07c | ||
|
|
04061ece4f | ||
|
|
66aaaa1751 | ||
|
|
1eed2ee985 | ||
|
|
c2ac47235f | ||
|
|
e8b4d5fb6f | ||
|
|
c16d7c481c | ||
|
|
22ca72e7b9 | ||
|
|
69585cb6e3 | ||
|
|
33e1dcc476 | ||
|
|
f0a9c45207 | ||
|
|
98a4a9f2cc | ||
|
|
becec8ac7e | ||
|
|
9dad7c2ace | ||
|
|
6dcdb50a3e | ||
|
|
0ae1298d25 | ||
|
|
f49644cdea | ||
|
|
023504ed64 | ||
|
|
dd5a6914f1 | ||
|
|
f6a0cd1bf8 | ||
|
|
285646bbfa | ||
|
|
2f18a34458 | ||
|
|
7b063e3e6c | ||
|
|
a2f90453f4 | ||
|
|
dc4ca26441 | ||
|
|
96f65479e7 | ||
|
|
e95eedb165 | ||
|
|
040c122719 | ||
|
|
9c1da4fa4c | ||
|
|
189e8b3f34 | ||
|
|
88bec814eb | ||
|
|
c0661744cc | ||
|
|
b968603a57 | ||
|
|
3b675d8b70 | ||
|
|
0036483ded | ||
|
|
c30fe932d9 | ||
|
|
8f99334f11 | ||
|
|
76d42b5200 | ||
|
|
0f40174723 | ||
|
|
734fb459a4 | ||
|
|
3a68dd2011 | ||
|
|
74dc7ffe4d | ||
|
|
dd26c0bbcc | ||
|
|
483ec0d762 | ||
|
|
c9ba73d931 | ||
|
|
b5d0a38860 | ||
|
|
1bca69f272 | ||
|
|
064d3584c0 | ||
|
|
0ef6843d85 | ||
|
|
9c95ec0b29 | ||
|
|
561a4fbeea | ||
|
|
84707ed926 | ||
|
|
6fba102d7d | ||
|
|
513aae5ef8 | ||
|
|
1da6bbd146 | ||
|
|
d438ea0880 | ||
|
|
d7612e7aaa | ||
|
|
6c352132d0 | ||
|
|
c78349a3a4 | ||
|
|
ce3146e91a | ||
|
|
0890ac4507 | ||
|
|
3ab56a188e | ||
|
|
00de72272d | ||
|
|
9bd4bc02d6 | ||
|
|
425beb4d97 | ||
|
|
404b7c7c4f | ||
|
|
4c87ef915f | ||
|
|
d087086581 | ||
|
|
c3767d593d | ||
|
|
09eed08b9c | ||
|
|
7303c387e8 | ||
|
|
b485ca8198 | ||
|
|
d94972503a | ||
|
|
0514dd5ebd | ||
|
|
175a042fd3 | ||
|
|
2e77cc635e | ||
|
|
a233ed2de7 | ||
|
|
a51566ec6e | ||
|
|
36450b9bc9 | ||
|
|
19c8a52fe1 | ||
|
|
1bf306bbbd | ||
|
|
126fc10b9d | ||
|
|
63459ab0c7 | ||
|
|
01d5ffcd87 | ||
|
|
16431f7a4c | ||
|
|
b25da51638 | ||
|
|
6926f4d0da | ||
|
|
5417f1cdc6 | ||
|
|
b1e5eafb80 | ||
|
|
deb5011d08 | ||
|
|
b4b7942230 | ||
|
|
9f8ff32bcc | ||
|
|
faa0f2a13c | ||
|
|
80310a3b7c | ||
|
|
c53b1be8b4 | ||
|
|
9f59c128be | ||
|
|
a1f8cc2817 | ||
|
|
29635b7bbd | ||
|
|
434ff28af4 | ||
|
|
d391670755 | ||
|
|
78c46aab35 | ||
|
|
637da63506 | ||
|
|
af7785727b | ||
|
|
bbbffe7423 | ||
|
|
23c7089789 | ||
|
|
fcc30cbf30 | ||
|
|
267666cd97 | ||
|
|
582d01784a | ||
|
|
d592a1655f | ||
|
|
502420ceff | ||
|
|
9d584d0c47 | ||
|
|
15e9d5f96e | ||
|
|
1a187e73ae | ||
|
|
138307dd0c | ||
|
|
6384264aa7 | ||
|
|
fcc4c1b2f2 | ||
|
|
6c95a5d496 | ||
|
|
f16228d811 | ||
|
|
3d9c8f4fd4 | ||
|
|
631cbdbda8 | ||
|
|
7b9b18f03c | ||
|
|
471950434e | ||
|
|
1774c7a7b3 | ||
|
|
80c02ad36a | ||
|
|
af4af94203 | ||
|
|
761c5c8450 | ||
|
|
52c8bedb9c | ||
|
|
a74bc9369b | ||
|
|
0fd9cdb861 | ||
|
|
65ff89a0b0 | ||
|
|
7705603f73 | ||
|
|
62dd040a8f | ||
|
|
8859a09cd2 | ||
|
|
4acdfeae61 | ||
|
|
1bbe6409e1 | ||
|
|
77a34ebdf9 | ||
|
|
9780427940 | ||
|
|
dacedfcc0e | ||
|
|
52c359bc77 | ||
|
|
53df9fbb4f | ||
|
|
0ffa959044 | ||
|
|
0fbf70d95d | ||
|
|
459c647bc9 | ||
|
|
71d9911539 | ||
|
|
b7aa47a178 | ||
|
|
c6524d0311 | ||
|
|
a045154b5e | ||
|
|
21d4f3a356 | ||
|
|
c2ca5f44b4 | ||
|
|
2bfa4d7e4f | ||
|
|
577657b3f7 | ||
|
|
0816e9554d | ||
|
|
915f91a619 | ||
|
|
0c33e8ac48 | ||
|
|
a2197f3a41 | ||
|
|
f50439b990 | ||
|
|
df30182a10 | ||
|
|
0668b6d7ba | ||
|
|
21161a60ff | ||
|
|
fffc2d2765 | ||
|
|
12e36ee0e7 | ||
|
|
b5979b13e3 | ||
|
|
efa506b235 | ||
|
|
c5a35acd67 | ||
|
|
4bf9b168a5 | ||
|
|
b3ede099e2 | ||
|
|
c98afe2205 | ||
|
|
8078845273 | ||
|
|
8ddc1f8977 | ||
|
|
e3cd0a67d0 | ||
|
|
e9b71872a8 | ||
|
|
fce6ecb05c | ||
|
|
f43cab0951 | ||
|
|
4a6ec6377d | ||
|
|
6ee21727de | ||
|
|
8db35ab9a2 | ||
|
|
67999d1b1c | ||
|
|
e763eeacdd | ||
|
|
b8a91db089 | ||
|
|
4c9dd028d2 | ||
|
|
088dce709e | ||
|
|
ab41fd6692 | ||
|
|
5e13bba068 | ||
|
|
d9cc1f85a5 | ||
|
|
03307f91df | ||
|
|
3526d92660 | ||
|
|
d7020434d9 | ||
|
|
e2e72b14b2 | ||
|
|
3ece0e7b76 | ||
|
|
68c681bb78 | ||
|
|
e7ced54369 | ||
|
|
14fe0b8ad2 | ||
|
|
2dc49ee88d | ||
|
|
45bf93405a | ||
|
|
c5a19b57f7 | ||
|
|
2e1810e3a7 | ||
|
|
566fec4015 | ||
|
|
8bec127a1d | ||
|
|
9482ce1fce | ||
|
|
e200a41d3d | ||
|
|
0b5836cfce | ||
|
|
c043275f1b | ||
|
|
9cf5404bb7 | ||
|
|
5879f8207f | ||
|
|
ee7ec4fa66 | ||
|
|
19f4b27fd2 | ||
|
|
8ea5e946a2 | ||
|
|
8bcb812529 | ||
|
|
2a11cb8b76 | ||
|
|
6906911e85 | ||
|
|
b63d11d5b0 | ||
|
|
5cb45c253e | ||
|
|
1b997f10a8 | ||
|
|
8cba8d6d1d | ||
|
|
240c0643f2 | ||
|
|
82ce798f41 | ||
|
|
2fb128fb34 | ||
|
|
0216fa2a00 | ||
|
|
fd5d89b61c | ||
|
|
eaf046c6a4 | ||
|
|
bb4b6c8ee2 | ||
|
|
eba264fcd0 | ||
|
|
78ae5d7723 | ||
|
|
22bb0562fe | ||
|
|
b215b19cae | ||
|
|
361b629034 | ||
|
|
809ded74c9 | ||
|
|
0b7b25487f | ||
|
|
3d3a520a7d | ||
|
|
6d6eb0f2d1 | ||
|
|
fc8d18ebdc | ||
|
|
9030541e4b | ||
|
|
78d25ad337 | ||
|
|
c512b37a4e | ||
|
|
f158375054 | ||
|
|
d7847ff768 | ||
|
|
2aa4387eba | ||
|
|
c1e6b52184 | ||
|
|
05b6c3f8cf | ||
|
|
6e462abb4d | ||
|
|
5d477bc956 | ||
|
|
98faee1d5c | ||
|
|
a49662276d | ||
|
|
4cb91d6f7b | ||
|
|
7d74e209f3 | ||
|
|
3f20014f33 | ||
|
|
3e717842c9 | ||
|
|
836d081bca | ||
|
|
190c437980 | ||
|
|
979b53cab6 | ||
|
|
965e7f471f | ||
|
|
8fec824484 | ||
|
|
c8d8860742 | ||
|
|
c90ecc6847 | ||
|
|
fa44cd5cef | ||
|
|
71e49e289a | ||
|
|
c3f3f26632 | ||
|
|
0b7c673205 | ||
|
|
f5fb771573 | ||
|
|
cd9cdd6410 | ||
|
|
f8f71b1c2c | ||
|
|
ad42579f08 | ||
|
|
c11a665ba1 | ||
|
|
1a563c2b31 | ||
|
|
aca5941a0e | ||
|
|
8f4efeea97 | ||
|
|
9eee71edf7 | ||
|
|
42edb6840e | ||
|
|
a2528a86b4 | ||
|
|
35cf52d182 | ||
|
|
8ce45d2161 | ||
|
|
a1ebdf63f3 | ||
|
|
6c46a5d623 | ||
|
|
2a38ec4c93 | ||
|
|
57e495943f | ||
|
|
b1da3664ec | ||
|
|
87c772b117 | ||
|
|
ccccd7b60d | ||
|
|
f21fcb3b88 | ||
|
|
d2004a186c | ||
|
|
69f6baf28e | ||
|
|
0f427ed334 | ||
|
|
1cc94a0f79 | ||
|
|
cbfba84aa2 | ||
|
|
1568e64f95 | ||
|
|
5e471719a6 | ||
|
|
2fde72075f | ||
|
|
e672e10219 | ||
|
|
a996b8aa7f | ||
|
|
813fefbc71 | ||
|
|
e60f25f209 | ||
|
|
d3ade02c16 | ||
|
|
81cb520b47 | ||
|
|
e9c83db42b | ||
|
|
e3115aa505 | ||
|
|
474048ae8b | ||
|
|
405b04efab | ||
|
|
b063ab42bf | ||
|
|
2e0ee5404d | ||
|
|
c6ac709d70 | ||
|
|
92b7534885 | ||
|
|
23ec6c6bb0 | ||
|
|
a7026da45c | ||
|
|
222c84d9be | ||
|
|
045e5bd458 | ||
|
|
6665a996e6 | ||
|
|
58733eb26a | ||
|
|
b211829fb1 | ||
|
|
4473311bdb | ||
|
|
cbae98670b | ||
|
|
ceab445b9f | ||
|
|
88d2f6b83a | ||
|
|
7e6be184bc | ||
|
|
3948b082ad | ||
|
|
7a2d65967c | ||
|
|
970196d825 | ||
|
|
6e07f46df8 | ||
|
|
73107d6b0f | ||
|
|
0c853ac3ea | ||
|
|
7151fd8836 | ||
|
|
3d7684277a | ||
|
|
497ed9f933 | ||
|
|
ea408cc0d0 | ||
|
|
7145b72482 | ||
|
|
bd63545b0c | ||
|
|
e2f390c5da | ||
|
|
95c7f4fba3 | ||
|
|
72b91758c9 | ||
|
|
f1900f6a7b | ||
|
|
2d1430da13 | ||
|
|
7d5bb088b4 | ||
|
|
d392056457 | ||
|
|
1523ebe9f7 | ||
|
|
22afc6dadd | ||
|
|
7ec28231d9 | ||
|
|
1de110fbba | ||
|
|
7dbf6f97f6 | ||
|
|
1cf2526a79 | ||
|
|
86449790fe | ||
|
|
c82db2116b | ||
|
|
7bf724b1d3 | ||
|
|
9f212e7201 | ||
|
|
06b9433351 | ||
|
|
bc087cfefb | ||
|
|
9f37e4c907 | ||
|
|
addcde4f35 | ||
|
|
2f821b9e9b | ||
|
|
db80c5e97e | ||
|
|
9a39ccea8f | ||
|
|
1bb7bfaf7f | ||
|
|
3fc1344865 | ||
|
|
11b62114bb | ||
|
|
44f089508b | ||
|
|
d45b2c7947 | ||
|
|
6a48385111 | ||
|
|
1203a14563 | ||
|
|
9fb1a9537d | ||
|
|
407920e40a | ||
|
|
18d2b28c49 | ||
|
|
c37ea9aff5 | ||
|
|
f84f04591b | ||
|
|
c6fb6bde40 | ||
|
|
ddcb97f953 | ||
|
|
473a5542be | ||
|
|
30b65d3114 | ||
|
|
e28ca3922f | ||
|
|
d5a760776a | ||
|
|
6a418cfb8d | ||
|
|
f2f1c49c90 | ||
|
|
07fd0ccc9a | ||
|
|
592045cd54 | ||
|
|
3cd3052c56 | ||
|
|
c078deaab1 | ||
|
|
9776dc0433 | ||
|
|
2cdfe14e5a | ||
|
|
13e52962ee | ||
|
|
10b0cb108c | ||
|
|
c3bc4d6195 | ||
|
|
b12fb7ebc8 | ||
|
|
56557f7ff6 | ||
|
|
4ee1bca1d9 | ||
|
|
c6a7af3fa7 | ||
|
|
d00680a883 | ||
|
|
c7f23ca0d6 | ||
|
|
d0acc9827a | ||
|
|
c1010c3422 | ||
|
|
1181ad2bf0 | ||
|
|
053e687e79 | ||
|
|
7ac8ddde96 | ||
|
|
3dd5b2845b | ||
|
|
55f1cafb70 | ||
|
|
90b7b7ba5c | ||
|
|
2243de9e2f | ||
|
|
ef202fbe0c | ||
|
|
45e77e7739 | ||
|
|
076ed08bdd | ||
|
|
1785de0f31 | ||
|
|
27de2a42d9 | ||
|
|
514a8c737a | ||
|
|
32f7b06a36 | ||
|
|
67d64b804f | ||
|
|
bfe009f98d | ||
|
|
796bf5f85c | ||
|
|
7eb463a66e | ||
|
|
f417b1cf90 | ||
|
|
c3317819cb | ||
|
|
88fa9084e2 | ||
|
|
a3d2d0cd22 | ||
|
|
eaa45d8a9a | ||
|
|
f4260da1c2 | ||
|
|
f850e4d2d4 | ||
|
|
51c6867f72 | ||
|
|
40d578be95 | ||
|
|
0583bc9859 | ||
|
|
98f8192bde | ||
|
|
89621faaea | ||
|
|
e74cc0df27 | ||
|
|
afef04bb54 | ||
|
|
60048c6550 | ||
|
|
179d308fe0 | ||
|
|
372a455bea | ||
|
|
aa7444cd3d | ||
|
|
4fecf33416 | ||
|
|
2eb4248f90 | ||
|
|
cde1d18399 | ||
|
|
999dda8f83 | ||
|
|
568800c045 | ||
|
|
7255f6969b | ||
|
|
17fa1b5007 | ||
|
|
61e5ee5d63 | ||
|
|
cfc25d0a92 | ||
|
|
9c3d8dae57 | ||
|
|
6dad59cb92 | ||
|
|
4e2154e58f | ||
|
|
c110865bf2 | ||
|
|
b99c8b641a | ||
|
|
e111add17f | ||
|
|
5ae7276682 | ||
|
|
26c5bc9d97 | ||
|
|
346f102234 | ||
|
|
8c140f4725 | ||
|
|
631e235ef3 | ||
|
|
c33ffbae04 | ||
|
|
83108f815c | ||
|
|
f8c14e1d98 | ||
|
|
a588a1fd84 | ||
|
|
11596ec0f8 | ||
|
|
8fc43046eb | ||
|
|
a2b9a000dc | ||
|
|
c926214640 | ||
|
|
584501a1cc | ||
|
|
3ad71700dd | ||
|
|
176b9febb4 | ||
|
|
17f696d3b3 | ||
|
|
3c10e3b502 | ||
|
|
10d8ed4d98 | ||
|
|
4ba73dac34 | ||
|
|
8cd13d4b35 | ||
|
|
49956faab9 | ||
|
|
3b84345b77 | ||
|
|
1b731e525f | ||
|
|
c35994d5bf | ||
|
|
b75a3e112b | ||
|
|
ae5198e5e7 | ||
|
|
4d466fe879 | ||
|
|
71ca837ada | ||
|
|
8773a0b747 | ||
|
|
8617ceddf3 | ||
|
|
62d806d512 | ||
|
|
ee6a75c9b5 | ||
|
|
e53571d2f0 | ||
|
|
b5ebd12fe2 | ||
|
|
b1ba869b37 | ||
|
|
4846ab70d8 | ||
|
|
ec5bb88820 | ||
|
|
42fab1591d | ||
|
|
12dbd65f4c | ||
|
|
b7c064142e | ||
|
|
92afa52eec | ||
|
|
d1a9328793 | ||
|
|
55d339194d | ||
|
|
1d2916da8c | ||
|
|
7fc69a6b51 | ||
|
|
237c843621 | ||
|
|
ef0fefc506 | ||
|
|
9fb514ff81 | ||
|
|
dfc0efa8ed | ||
|
|
b56bfcea96 | ||
|
|
8ec5e81186 | ||
|
|
8e227f603d | ||
|
|
603467785b | ||
|
|
f70046e6b7 | ||
|
|
99b52e6e71 | ||
|
|
0ff4120692 | ||
|
|
8a45aa4185 | ||
|
|
168f9c46ea | ||
|
|
17b7305086 | ||
|
|
1a585a6c74 | ||
|
|
dd37959899 | ||
|
|
ff9145f8a5 | ||
|
|
42be50d10b | ||
|
|
b81cb554f5 | ||
|
|
2b7b7f6d97 | ||
|
|
4e671c54ee | ||
|
|
797af2e80f | ||
|
|
a7ffffc336 | ||
|
|
ed16bd133a | ||
|
|
22e4ee5604 | ||
|
|
e32416430c | ||
|
|
248248c6b2 | ||
|
|
4e062d86b4 | ||
|
|
d701d2ccf3 | ||
|
|
62d175c984 | ||
|
|
0cbaecca60 | ||
|
|
e7d2fa7084 | ||
|
|
67a01ef2ee | ||
|
|
fa02f94ca4 | ||
|
|
5c4bb69af9 | ||
|
|
a0989ad672 | ||
|
|
ef9347bcfb | ||
|
|
d5d1e89cbd | ||
|
|
867e1333d0 | ||
|
|
7c155f7456 | ||
|
|
e92da6a6ba | ||
|
|
1acb2a1a09 | ||
|
|
5deaaa278c | ||
|
|
44321c5c24 | ||
|
|
bce276d573 | ||
|
|
50b148ca22 | ||
|
|
18a241fe21 | ||
|
|
c69acfa5c8 | ||
|
|
00f44d558a | ||
|
|
dd84a57580 | ||
|
|
63bade7a0c | ||
|
|
375de085e2 | ||
|
|
fb4f361cd0 | ||
|
|
523be30974 | ||
|
|
a25e33d96e | ||
|
|
e03e87b791 | ||
|
|
c005b5fe9c | ||
|
|
93c22dd978 | ||
|
|
69f8d8fa7a | ||
|
|
cf1914fc00 | ||
|
|
a73b7052c9 | ||
|
|
9e456acbab | ||
|
|
01fab24c15 | ||
|
|
d6a232dbe0 | ||
|
|
f8543f7755 | ||
|
|
420a61491d | ||
|
|
2bffd569d7 | ||
|
|
f9aafeee1e | ||
|
|
2cf9ebc62c | ||
|
|
5717cb981e | ||
|
|
1b4c4be151 | ||
|
|
2fe9bfcd82 | ||
|
|
c422ce7c1d | ||
|
|
fcd58a95dd | ||
|
|
c96dd43174 | ||
|
|
a138196a6c | ||
|
|
04392babca | ||
|
|
7acc7c4dae | ||
|
|
abe744c5a0 | ||
|
|
01f2dd03d5 | ||
|
|
73fb2345fc | ||
|
|
27280ea8be | ||
|
|
80678b2188 | ||
|
|
41f365112c | ||
|
|
cb6c6fb374 | ||
|
|
882e2e42cf | ||
|
|
3959ca6270 | ||
|
|
0e2b1359e3 | ||
|
|
a5a5dbc408 | ||
|
|
df7e3f8635 | ||
|
|
6cffac79bd | ||
|
|
3a281b2399 | ||
|
|
01a36ab333 | ||
|
|
5bcd1e7ccd | ||
|
|
20b9f34b5c | ||
|
|
6e56ba9f24 | ||
|
|
3a4aac0213 | ||
|
|
f461b99722 | ||
|
|
618b3f5f2d | ||
|
|
277efc1dfb | ||
|
|
1af88be371 | ||
|
|
0d1a1b7526 | ||
|
|
6ff6c805af | ||
|
|
9eaf735bcd | ||
|
|
dcd6b19348 | ||
|
|
6c409d6b92 | ||
|
|
7d19154e18 | ||
|
|
7b777568ed | ||
|
|
0ad317213c | ||
|
|
07df403203 | ||
|
|
143a4d7f76 | ||
|
|
1714f410f0 | ||
|
|
7dc1524c08 | ||
|
|
e73caad0d7 | ||
|
|
8a7f34665b | ||
|
|
b19d6ab9c5 | ||
|
|
6059da918e | ||
|
|
bbd328d307 | ||
|
|
4437bae16d | ||
|
|
feee268970 | ||
|
|
cac819766e | ||
|
|
25d48f700c | ||
|
|
ddaba07d82 | ||
|
|
d62766a94d | ||
|
|
32779ab1f6 | ||
|
|
c113d390a7 | ||
|
|
fbabfc593d | ||
|
|
99117cbc90 | ||
|
|
918ad28a93 | ||
|
|
380a2b23e6 | ||
|
|
4001663982 | ||
|
|
73b6214a13 | ||
|
|
749508af01 | ||
|
|
3bf75fab3f | ||
|
|
71e9f1ab8d | ||
|
|
21b7734d92 | ||
|
|
7904f75782 | ||
|
|
e4cfe74887 | ||
|
|
e993c17f89 | ||
|
|
d636b4fdde | ||
|
|
3c8e055ed0 | ||
|
|
9b3c7b8afa | ||
|
|
071548a62f | ||
|
|
f221f64509 | ||
|
|
c3c70cf704 | ||
|
|
340ad44aab | ||
|
|
2e05830eb1 | ||
|
|
872f049b30 | ||
|
|
21ad5162c4 | ||
|
|
8ef9d68542 | ||
|
|
e104592e1f | ||
|
|
11771d9a37 | ||
|
|
0ebb192b2f | ||
|
|
ffed252df4 | ||
|
|
670cb423f9 | ||
|
|
5da37c573f | ||
|
|
2968b60ee0 | ||
|
|
ca7d701007 | ||
|
|
a87ae5173f | ||
|
|
c352249e30 | ||
|
|
4ce03b75bc | ||
|
|
7fc0b1ebd2 | ||
|
|
d546d828d3 | ||
|
|
faf4a1e370 | ||
|
|
b09d87970c | ||
|
|
cefcbfea8e | ||
|
|
c010a6f8b0 | ||
|
|
c546b75443 | ||
|
|
9d2ef9f453 | ||
|
|
2b3a8a4a5a | ||
|
|
aaf2830b8b | ||
|
|
281ccb3dad | ||
|
|
48d70d960c | ||
|
|
3a3f9789ce | ||
|
|
77b688f4fa | ||
|
|
c0eb5844e5 | ||
|
|
9bfc83ac5c | ||
|
|
0296f96c7b | ||
|
|
6d73c86209 | ||
|
|
9c071ea40d | ||
|
|
3404a61ebf | ||
|
|
2fd2a5403f | ||
|
|
db23d27eb4 | ||
|
|
cd3086f78d | ||
|
|
0ff059e388 | ||
|
|
aef7065e85 | ||
|
|
9bb99de0a7 | ||
|
|
83d6e04d39 | ||
|
|
9c60f122a6 | ||
|
|
8404f084c8 | ||
|
|
a10ab78e28 | ||
|
|
3a4210e9d7 | ||
|
|
d0ca3952a3 | ||
|
|
badf5b047b | ||
|
|
7bc28cc334 | ||
|
|
6ebed7a2a6 | ||
|
|
220fb068aa | ||
|
|
5084130e71 | ||
|
|
e0b9f79b9b | ||
|
|
a8b856432a | ||
|
|
c7b11360e9 | ||
|
|
266f64d848 | ||
|
|
2d49842cd1 | ||
|
|
bd005b6ba6 | ||
|
|
6755c397c9 | ||
|
|
932ed6b280 | ||
|
|
a43cb60097 | ||
|
|
a6c1cfe037 | ||
|
|
7197f15783 | ||
|
|
d375ddadc4 | ||
|
|
a7e13b1963 | ||
|
|
bb968fc5a2 | ||
|
|
f40b0f52e0 | ||
|
|
401dcb3635 | ||
|
|
131d34f318 | ||
|
|
14f073d410 | ||
|
|
0bf61ad57b | ||
|
|
2809fe95db | ||
|
|
c3f7b035fd | ||
|
|
2f4d8a634d | ||
|
|
79836520d9 | ||
|
|
e0ff3f16cc | ||
|
|
40c279ef95 | ||
|
|
e436f84244 | ||
|
|
c952c0ca16 | ||
|
|
1c483ffe4e | ||
|
|
9f7db44574 | ||
|
|
2126683203 | ||
|
|
adccd18015 | ||
|
|
a88c6da9ac | ||
|
|
624b576b1e | ||
|
|
281835887a | ||
|
|
c6d8208150 | ||
|
|
edf6e9ceac | ||
|
|
71ffe2f1c4 | ||
|
|
e4f7b78e9b | ||
|
|
459aab628d | ||
|
|
cfd5e69b81 | ||
|
|
d4e6b15d98 | ||
|
|
f5a77d3958 | ||
|
|
09d657e98e | ||
|
|
b1b94d2b7f | ||
|
|
9eb314fcaa | ||
|
|
d0c8245a58 | ||
|
|
87b70e2cb4 | ||
|
|
c5f3475f48 | ||
|
|
220c72d67f | ||
|
|
66038ef729 | ||
|
|
a670408617 | ||
|
|
1f93c39c58 | ||
|
|
5d2151ed64 | ||
|
|
63f824b218 | ||
|
|
2441068d54 | ||
|
|
0840ffa3dd | ||
|
|
e2a7b7e50d | ||
|
|
a6f6c2b9c5 | ||
|
|
a6b87ee144 | ||
|
|
837eff1704 | ||
|
|
a0902ad8d8 | ||
|
|
3b0311a1e4 | ||
|
|
123996aad0 | ||
|
|
0bcfd09536 | ||
|
|
6d0b4a28ab | ||
|
|
4f6320a7eb | ||
|
|
7430f9142f | ||
|
|
397e0d1368 | ||
|
|
360994b638 | ||
|
|
44b8947445 | ||
|
|
a88c15e101 | ||
|
|
8d9ab6a061 | ||
|
|
a364ab0d0f | ||
|
|
ef5c973c93 | ||
|
|
35322eccc1 | ||
|
|
892b8f155f | ||
|
|
228130ddc8 | ||
|
|
b4580eb04c | ||
|
|
3ba9cfba01 | ||
|
|
2ad5d2ea2a | ||
|
|
279291221c | ||
|
|
be2862ef4e | ||
|
|
67ec7ee5e9 | ||
|
|
f1a0619821 | ||
|
|
2bc43f7f37 | ||
|
|
4ab362ae17 | ||
|
|
d1a3adfcf0 | ||
|
|
dbb25bfeed | ||
|
|
8da62b310e | ||
|
|
5506e89aa9 | ||
|
|
4bc6ace201 | ||
|
|
213e9746ad | ||
|
|
a65519def0 | ||
|
|
0ceb7c411b | ||
|
|
01657e6991 | ||
|
|
b909da759d | ||
|
|
9519f3d988 | ||
|
|
8ae84cfaba | ||
|
|
78be85c84f | ||
|
|
e7ae983b41 | ||
|
|
f3b353f5f9 | ||
|
|
8948cb100b | ||
|
|
17075736a0 | ||
|
|
42729d9cce | ||
|
|
9153e03e5c | ||
|
|
3b19cc303f | ||
|
|
5c95977dcc | ||
|
|
bc309e42d8 | ||
|
|
a7ceacb991 | ||
|
|
5b1ef64e31 | ||
|
|
f2051f0440 | ||
|
|
dd1c667d8d | ||
|
|
2abdd71b41 | ||
|
|
9e9f5d01ad | ||
|
|
bafc6cebe1 | ||
|
|
5b6eefbf04 | ||
|
|
c017387214 | ||
|
|
81b9148b9e | ||
|
|
98bb151d85 | ||
|
|
a0c42a3fd1 | ||
|
|
c40559433b | ||
|
|
03d907e1e5 | ||
|
|
ce4de6227e | ||
|
|
bee224c567 | ||
|
|
e4de235e75 | ||
|
|
f42b1dfcbd | ||
|
|
c337b52ec8 | ||
|
|
c69b9b7b24 | ||
|
|
a4eff6de3f | ||
|
|
7f469eadff | ||
|
|
3c8881487f | ||
|
|
abee9c83b4 | ||
|
|
4ddba5f7ed | ||
|
|
a06f682e49 | ||
|
|
7e9baf9e25 | ||
|
|
d96ea5ba00 | ||
|
|
ad402ff85b | ||
|
|
653d7c5257 | ||
|
|
e0fdb34104 | ||
|
|
62ae830e49 | ||
|
|
b3a384e1d8 | ||
|
|
a05bea7de5 | ||
|
|
dfc5cf288c | ||
|
|
275943d8df | ||
|
|
e1fdd4341b | ||
|
|
ccc1b23bea | ||
|
|
f80e839ff4 | ||
|
|
63c3feb79e | ||
|
|
7e7461e8fb | ||
|
|
7753d823cb | ||
|
|
f9bcce6a68 | ||
|
|
197f07306b | ||
|
|
40cea0110f | ||
|
|
02879d94ff | ||
|
|
dd61795bb8 | ||
|
|
a14527ec06 | ||
|
|
1141f11955 | ||
|
|
09e77812b6 | ||
|
|
4e87cf9d74 | ||
|
|
207215980b | ||
|
|
dd60cc326c | ||
|
|
5eefca43e7 | ||
|
|
0da545ecac | ||
|
|
d8579a5b80 | ||
|
|
f3dd889d44 | ||
|
|
e00cab75bd | ||
|
|
97cdd79478 | ||
|
|
9c894f5935 | ||
|
|
eb397b5693 | ||
|
|
8b45d6f84f | ||
|
|
3bd550d6a2 | ||
|
|
7eca1284c8 | ||
|
|
ccd155572f | ||
|
|
e0f463c4f9 | ||
|
|
fc73e93b50 | ||
|
|
5695e4c03d | ||
|
|
ec107b290f | ||
|
|
9061800b30 | ||
|
|
82c09e66d2 | ||
|
|
20600b8cac | ||
|
|
e049fc2840 | ||
|
|
66bb71534b | ||
|
|
cde3320582 | ||
|
|
dce590fb21 | ||
|
|
b0b882cbb3 | ||
|
|
439d3b3ddb | ||
|
|
cc42391e0f | ||
|
|
69ebc8173e | ||
|
|
9cff241ad5 | ||
|
|
a82a587b32 | ||
|
|
4a6b5d5247 | ||
|
|
9b130e1d19 | ||
|
|
a1c965d70d | ||
|
|
11ca06b104 | ||
|
|
9c391bbda1 | ||
|
|
965ce633c3 | ||
|
|
f603c82e81 | ||
|
|
497adc3b42 | ||
|
|
06c98320a8 | ||
|
|
57ced37229 | ||
|
|
618a9b2d7b | ||
|
|
c7011d21aa | ||
|
|
9889b1a5fe | ||
|
|
8f675b0ee8 | ||
|
|
358b387283 | ||
|
|
42ec822379 | ||
|
|
8b2e79bcfa | ||
|
|
680563cc4c | ||
|
|
1d2d4b94c5 | ||
|
|
8019748396 | ||
|
|
6699399e51 | ||
|
|
eec50b524b | ||
|
|
5172f09b9f | ||
|
|
26a72619ae | ||
|
|
21e81e92a9 | ||
|
|
828aeefb1d | ||
|
|
7f2db8c267 | ||
|
|
d096b155f4 | ||
|
|
c33a63cabc | ||
|
|
416fcd0810 | ||
|
|
0fc9326a4c | ||
|
|
df995c4ef8 | ||
|
|
8c9f887613 | ||
|
|
3f12a51759 | ||
|
|
e51fe2934e | ||
|
|
fade526ae4 | ||
|
|
7897f10126 | ||
|
|
eb5b0767aa | ||
|
|
2fb599ea86 | ||
|
|
50e4b609c6 | ||
|
|
7e4e2c988a | ||
|
|
88a7a23132 | ||
|
|
2162627f35 | ||
|
|
bc3314a57d | ||
|
|
45b4895888 | ||
|
|
b6a35716ce | ||
|
|
b91a155e8d | ||
|
|
18db930866 | ||
|
|
76006fc346 | ||
|
|
30ba96e58f | ||
|
|
83fea631f1 | ||
|
|
f15249afe5 | ||
|
|
3e39daeb12 | ||
|
|
fd67da607e | ||
|
|
540e57f026 | ||
|
|
fdd7e91ba0 | ||
|
|
bd5abb2922 | ||
|
|
6423eab917 | ||
|
|
142d1f5cbc | ||
|
|
315623d361 | ||
|
|
03c8a91f6a | ||
|
|
0d4d201b70 | ||
|
|
7fb463abb9 | ||
|
|
9985816642 | ||
|
|
fe71ba992d | ||
|
|
13bf7d4ff1 | ||
|
|
38ea75e8ca | ||
|
|
823edd0bb2 | ||
|
|
3be081f476 | ||
|
|
254f65f299 | ||
|
|
8643e21913 | ||
|
|
b1cd8ea241 | ||
|
|
758a9c9096 | ||
|
|
7cf1b7ed51 | ||
|
|
1306cdd998 | ||
|
|
4be8472f61 | ||
|
|
f031bdfbc9 | ||
|
|
e1848c1d28 | ||
|
|
c83d22b5fc | ||
|
|
9b8b17b6f1 | ||
|
|
e4adc675e5 | ||
|
|
f095e619b9 | ||
|
|
dbfa6c925e | ||
|
|
ed0f6f75a7 | ||
|
|
b10a98a3ac | ||
|
|
4e5dfc8b18 | ||
|
|
688eca23ff | ||
|
|
acaa589bdd | ||
|
|
34a8f0c96b | ||
|
|
d93f2b335d | ||
|
|
0fbdb3f65d | ||
|
|
cc582dd4b4 | ||
|
|
091fcc3aa9 | ||
|
|
a4f5084589 | ||
|
|
71c976d212 | ||
|
|
38350ae33d | ||
|
|
01918a6f48 | ||
|
|
c4134ee71e | ||
|
|
5b3c96a9bb | ||
|
|
cb9fba98d8 | ||
|
|
474db2085e | ||
|
|
7c729d4c3c | ||
|
|
0ee993569f | ||
|
|
6c8d51f403 | ||
|
|
24264eb00e | ||
|
|
27f337aa11 | ||
|
|
2d69f386d0 | ||
|
|
4a15477783 | ||
|
|
8823a5ac1c | ||
|
|
cb2e6c9d02 | ||
|
|
4f44431900 | ||
|
|
20a00c4cdf | ||
|
|
1728a0c3e6 | ||
|
|
d05e4581c9 | ||
|
|
fd1784369a | ||
|
|
5f68e14d3b | ||
|
|
1eb7b8cf46 | ||
|
|
e56f5c4d6b | ||
|
|
7618dc504c | ||
|
|
75460d8586 | ||
|
|
1f8d79b69a | ||
|
|
d25026b749 | ||
|
|
3214cd0d56 | ||
|
|
1664d1b503 | ||
|
|
6e847b7d76 | ||
|
|
6e0e6d2654 | ||
|
|
6eb97a30a3 | ||
|
|
e32eb7e990 | ||
|
|
f323f54704 | ||
|
|
1a3bdf03c3 | ||
|
|
eed0ccad73 | ||
|
|
a5a4cce7f1 | ||
|
|
a26992ef55 | ||
|
|
cb97e8dd93 | ||
|
|
3c5a1605d5 | ||
|
|
aca8b5c89d | ||
|
|
23bf70296e | ||
|
|
3f32dd767e | ||
|
|
41a97c8f80 | ||
|
|
b255f02762 | ||
|
|
ee5e507ff6 | ||
|
|
7ec450912d | ||
|
|
039efd55d5 | ||
|
|
8bf8617876 | ||
|
|
4b46e21685 | ||
|
|
b1516f64eb | ||
|
|
439d47b4e4 | ||
|
|
e88df95b42 | ||
|
|
48b35bb495 | ||
|
|
861a235ecb | ||
|
|
799f1f6768 | ||
|
|
624e56db6a | ||
|
|
77b94f6030 | ||
|
|
5d06daeb5e | ||
|
|
b79fce76cb | ||
|
|
6f9a0e73bb | ||
|
|
953fb35f82 | ||
|
|
553fff270a | ||
|
|
8e77f17760 | ||
|
|
c5c92d50eb | ||
|
|
efef229b85 | ||
|
|
7569204a53 | ||
|
|
3a3443dff6 | ||
|
|
3fcaf5b903 | ||
|
|
b926d8a0cd | ||
|
|
fbeffee91e | ||
|
|
aef6d50b08 | ||
|
|
7b283bfaff | ||
|
|
bba66cbe28 | ||
|
|
d493658a58 | ||
|
|
c0f0350634 | ||
|
|
6251c97cd5 | ||
|
|
db61a09cf1 | ||
|
|
95ad2875b6 | ||
|
|
620c120503 | ||
|
|
ed0b5e649d | ||
|
|
d02d72e06d | ||
|
|
f5f7d47be1 | ||
|
|
d632266a40 | ||
|
|
fd067dd8b8 | ||
|
|
ac7323118e | ||
|
|
c50d6ac902 | ||
|
|
16fa40b893 | ||
|
|
e9126baaab | ||
|
|
23f3f1adfe | ||
|
|
741bea032c | ||
|
|
151b04637e | ||
|
|
af7e3cadde | ||
|
|
76672a4e34 | ||
|
|
4e9ba49272 | ||
|
|
6acb830263 | ||
|
|
fb60d01f6a | ||
|
|
80495e50f9 | ||
|
|
1fa38689d8 | ||
|
|
491babd5cd | ||
|
|
1e468c5541 | ||
|
|
ccd90df62f | ||
|
|
67ca2c704b | ||
|
|
5f6f2d5f51 | ||
|
|
ec8cc2b528 | ||
|
|
076cc764a7 | ||
|
|
82ba0c6c07 | ||
|
|
3b24db92b5 | ||
|
|
4cf4bf3a03 | ||
|
|
f9438c75d0 | ||
|
|
f3ea0420f8 | ||
|
|
179ed7cce6 | ||
|
|
1689131043 | ||
|
|
84b7cd593f | ||
|
|
a88c02854a | ||
|
|
1b279cd7ff | ||
|
|
802acb4d16 | ||
|
|
90268876f7 | ||
|
|
9e4c757f50 | ||
|
|
e558809043 | ||
|
|
ac394718ec | ||
|
|
e673127263 | ||
|
|
38c3c84969 | ||
|
|
3da4d6664b | ||
|
|
f0f0663d1b | ||
|
|
9cdd79e33f | ||
|
|
f07d4c9439 | ||
|
|
63f9f4291a | ||
|
|
d46d897ac9 | ||
|
|
fa2a66db67 | ||
|
|
bb04d5cc63 | ||
|
|
905549ea2d | ||
|
|
39a792adda | ||
|
|
ac762e95a6 | ||
|
|
597727f8be | ||
|
|
9c29966674 | ||
|
|
b45ec3f04e | ||
|
|
b2c98feea4 | ||
|
|
68d22253ec | ||
|
|
7eca383b10 | ||
|
|
108ea1522a | ||
|
|
15bbd088e6 | ||
|
|
d8a402ae5b | ||
|
|
23ba0c3396 | ||
|
|
cdd2ea3067 | ||
|
|
c8cc6f4fc1 | ||
|
|
ccced9f290 | ||
|
|
cc3d9f4eb7 | ||
|
|
572cb93bf8 | ||
|
|
c85888eb57 | ||
|
|
bcea1df01c | ||
|
|
f20247ae55 | ||
|
|
0d9a6d3c25 | ||
|
|
f9923452b3 | ||
|
|
f2761270f3 | ||
|
|
f45b8b1083 | ||
|
|
05c761dee9 | ||
|
|
003fd4d834 | ||
|
|
ec42db62a3 | ||
|
|
8b715d9c3f | ||
|
|
5c865b9b70 | ||
|
|
6f26c45143 | ||
|
|
3383486adc | ||
|
|
0426796d9f | ||
|
|
030e8dd1ac | ||
|
|
4c9a52044a | ||
|
|
857f791286 | ||
|
|
9885f1a19e | ||
|
|
003957a689 | ||
|
|
c1a8574d8f | ||
|
|
4236157823 | ||
|
|
a6389eb7de | ||
|
|
90bb855ffa | ||
|
|
7cd478418d | ||
|
|
90f2e40ff9 | ||
|
|
145390c7f3 | ||
|
|
1179217334 | ||
|
|
081bdd0828 | ||
|
|
6ec65cd4ca | ||
|
|
3060f27909 | ||
|
|
bae03404f4 | ||
|
|
1c7f754e5b | ||
|
|
4574f768ef | ||
|
|
f5e8857c5e | ||
|
|
1d70b590fc | ||
|
|
f40c78a064 | ||
|
|
ac88cab68f | ||
|
|
30df1c838d | ||
|
|
4693af0736 | ||
|
|
2bbf42b49d | ||
|
|
670024cf77 | ||
|
|
caf6dc0f05 | ||
|
|
280384fce3 | ||
|
|
30adc4c9b8 | ||
|
|
78ef0618bc | ||
|
|
b9fcae8da6 | ||
|
|
7ae6c62ddb | ||
|
|
835b47c196 | ||
|
|
c4fddcc6e9 | ||
|
|
b637f75164 | ||
|
|
4f14db8af2 | ||
|
|
82b7067fdf | ||
|
|
1fe196f95c | ||
|
|
048c406f49 | ||
|
|
b0572a5462 | ||
|
|
0244d794cd | ||
|
|
b0377da771 | ||
|
|
ad6625456e | ||
|
|
c31f797ab0 | ||
|
|
b701aa10d4 | ||
|
|
267e83d8a7 | ||
|
|
bf1639e044 | ||
|
|
52cdcdde76 | ||
|
|
f56939c16c | ||
|
|
d51c8997ee | ||
|
|
23cbc2b1d9 | ||
|
|
dd0ae255ad | ||
|
|
1f06dd40f7 | ||
|
|
a384ad5b12 | ||
|
|
ca10229565 | ||
|
|
6e82ab1f15 | ||
|
|
8c96ca42d5 | ||
|
|
b93a2ba1cf | ||
|
|
113e942c3c | ||
|
|
e6a3468598 | ||
|
|
45ef496dd5 | ||
|
|
383e73a5f5 | ||
|
|
a4d40177fd | ||
|
|
d06ebf23d4 | ||
|
|
87db69478d | ||
|
|
b43c277dc6 | ||
|
|
ad7d89b165 | ||
|
|
8ac1752743 | ||
|
|
bf4d51ea0b | ||
|
|
8e76cda200 | ||
|
|
ca343889fc | ||
|
|
4887936809 | ||
|
|
24fe8699ea | ||
|
|
f01d1c4385 | ||
|
|
c67b922185 | ||
|
|
5b22873b3d | ||
|
|
9c61843737 | ||
|
|
df84677d16 | ||
|
|
a1be45d0e7 | ||
|
|
0c7d0c0b6c | ||
|
|
a4861a3072 | ||
|
|
e0e545774a | ||
|
|
747855b960 | ||
|
|
31cebb969a | ||
|
|
214deeda54 | ||
|
|
5aadb6df19 | ||
|
|
18ce5ccf8f | ||
|
|
77ec27c730 | ||
|
|
b7750cf61c | ||
|
|
1e7d946d91 | ||
|
|
96e1b2d25c | ||
|
|
bff7107f56 | ||
|
|
4d1703fc06 | ||
|
|
12ddf241a5 | ||
|
|
547933e7e4 | ||
|
|
f2bcc6cc35 | ||
|
|
153841f91a | ||
|
|
a399451e1e | ||
|
|
265ef337a8 | ||
|
|
108277fb5d | ||
|
|
ada675dea2 | ||
|
|
1ee90a6fe7 | ||
|
|
240ada5775 | ||
|
|
e515042a36 | ||
|
|
ae87948a23 | ||
|
|
ad103dcafa | ||
|
|
14d48eba46 | ||
|
|
c59546fae0 | ||
|
|
7d847f4dc4 | ||
|
|
07255da6e9 | ||
|
|
220b6a9fee | ||
|
|
24f0757d82 | ||
|
|
3dd630d0a5 | ||
|
|
0b864aacdc | ||
|
|
ac67f3b53e | ||
|
|
097df180e2 | ||
|
|
a9d7135c19 | ||
|
|
bfce2c7508 | ||
|
|
fc6aa7374a | ||
|
|
8d2538f205 | ||
|
|
f663d37da7 | ||
|
|
f90eaa5f46 | ||
|
|
6449e8b1b9 | ||
|
|
a7b918837e | ||
|
|
dce691e15d | ||
|
|
648d08eb30 | ||
|
|
b043c4a5b8 | ||
|
|
5db9673904 | ||
|
|
0eb6ef2cd0 | ||
|
|
a2af4940aa | ||
|
|
310099d888 | ||
|
|
202fbc6812 | ||
|
|
311d71ec86 | ||
|
|
5af543dc4a | ||
|
|
c5d9ee8924 | ||
|
|
7183db1b7d | ||
|
|
a531a4f5e3 | ||
|
|
63ae407169 | ||
|
|
1b6909dd9b | ||
|
|
f5cc63156c | ||
|
|
e5276856cb | ||
|
|
db92699c02 | ||
|
|
7f4a69319a | ||
|
|
5ef3621556 | ||
|
|
6701977f1a | ||
|
|
353d12d2e6 | ||
|
|
717bcb8624 | ||
|
|
4f9a309de8 | ||
|
|
487b2495a1 | ||
|
|
2b48728741 | ||
|
|
58efe1550d | ||
|
|
16d8c25b23 | ||
|
|
65d4169f00 | ||
|
|
ffb9574312 | ||
|
|
976d0240c4 | ||
|
|
6e7b00a0f6 | ||
|
|
b4298979fe | ||
|
|
676591ffc0 | ||
|
|
975cba295b | ||
|
|
e46bac19fa | ||
|
|
90e90f61c1 | ||
|
|
47c8e1366f | ||
|
|
25f20b1967 | ||
|
|
51f60f3a1e | ||
|
|
6bbadbfaac | ||
|
|
340ecf6e9a | ||
|
|
86e90bba87 | ||
|
|
81e236b2de | ||
|
|
45887dec8e | ||
|
|
f27f2f8e49 | ||
|
|
4d74784209 | ||
|
|
527bb7abfe | ||
|
|
9f6ebd7c6e | ||
|
|
615ea969f8 | ||
|
|
4601c36f57 | ||
|
|
21cd05aad5 | ||
|
|
ca41909ec5 | ||
|
|
4d63544fe9 | ||
|
|
901e4851b9 | ||
|
|
9001b9ed3c | ||
|
|
d649b715ed | ||
|
|
65b2a24f7c | ||
|
|
726b350689 | ||
|
|
a0c6519de9 | ||
|
|
8421dcb762 | ||
|
|
9c565b155a | ||
|
|
94e5297960 | ||
|
|
52081c46d6 | ||
|
|
21d125c914 | ||
|
|
be306d09e9 | ||
|
|
c488f7c4d8 | ||
|
|
8174489787 | ||
|
|
99b76c8c3c | ||
|
|
a9f0b98d4d | ||
|
|
eb1d90a8cf | ||
|
|
15ae92aae9 | ||
|
|
e414c5fdfb | ||
|
|
a339ac0a72 | ||
|
|
21181075b4 | ||
|
|
67f327f805 | ||
|
|
8f3ac9ac8b | ||
|
|
30d9ca2bde | ||
|
|
b591d2b501 | ||
|
|
ccd4a79b39 | ||
|
|
eb96f38298 | ||
|
|
f0149faf88 | ||
|
|
ac55ce989d | ||
|
|
7176e5ef07 | ||
|
|
5989e3f65d | ||
|
|
5e4d3e7b82 | ||
|
|
550df4cdd6 | ||
|
|
9ac2556285 | ||
|
|
b43a5498a1 | ||
|
|
f161609929 | ||
|
|
34be473b7c | ||
|
|
863a5bc4fa | ||
|
|
20845a739f | ||
|
|
8d1c06d141 | ||
|
|
bd7c189c12 | ||
|
|
5c3c6e7f06 | ||
|
|
234681306c | ||
|
|
2de81cfc62 | ||
|
|
9e844d974c | ||
|
|
7779974143 | ||
|
|
339f4bfd23 | ||
|
|
5d5d3c5858 | ||
|
|
6f42dd556d | ||
|
|
976ae91dcc | ||
|
|
5ce97eeda5 | ||
|
|
0d23ff92b0 | ||
|
|
87610a5102 | ||
|
|
93a746043c | ||
|
|
4316f1cd31 | ||
|
|
cfa7c4feb8 | ||
|
|
083b7b46d9 | ||
|
|
3c87d137a3 | ||
|
|
ebc5e26c2d | ||
|
|
a385dae1ae | ||
|
|
1367ccab93 | ||
|
|
22bf4bc080 | ||
|
|
1a7d6ed49a | ||
|
|
725d6d5fce | ||
|
|
a8de45ce28 | ||
|
|
18ddbae60e | ||
|
|
5c8dd6c3c8 | ||
|
|
97c3854c40 | ||
|
|
30c3047482 | ||
|
|
3c1aa9a4ad | ||
|
|
19d10291bf | ||
|
|
28218755a5 | ||
|
|
d8a70166d3 | ||
|
|
c112cf66fe | ||
|
|
00125e4688 | ||
|
|
3558404c03 | ||
|
|
0a6b54a8c4 | ||
|
|
93a92a00ee | ||
|
|
d9e8bf1807 | ||
|
|
54042e399b | ||
|
|
1d484dbe5f | ||
|
|
ab4006ee2c | ||
|
|
524e9b372e | ||
|
|
2c20fc2ebf | ||
|
|
2a79537ba1 | ||
|
|
9a5e0c59b0 | ||
|
|
6cd76d69c3 | ||
|
|
0388093f7a | ||
|
|
fca7ef2f7b | ||
|
|
8cab10214e | ||
|
|
a3039c4c67 | ||
|
|
62b0293963 | ||
|
|
31ab238306 | ||
|
|
19dca4bcc9 | ||
|
|
35a602baaf | ||
|
|
09254014b1 | ||
|
|
3c8bbeafc7 | ||
|
|
9a6221ea40 | ||
|
|
db50f52bbc | ||
|
|
9e4671a4b4 | ||
|
|
96a4d3f432 | ||
|
|
bf162e60f1 | ||
|
|
d8c0edcc81 | ||
|
|
9868333e8e | ||
|
|
a06e29fecb | ||
|
|
43670cbbd0 | ||
|
|
52647b9a5d | ||
|
|
c799301011 | ||
|
|
7732f375d2 | ||
|
|
69064395eb | ||
|
|
9a2c1090a6 | ||
|
|
dc6a33b716 | ||
|
|
5038a38e29 | ||
|
|
2cd9ad8ce6 | ||
|
|
63911d4165 | ||
|
|
8e33cc1ae1 | ||
|
|
ff81aff254 | ||
|
|
f0db7190ff | ||
|
|
d541a4bd29 | ||
|
|
64436e7752 | ||
|
|
77c17e1d92 | ||
|
|
90e1b1f0ea | ||
|
|
247a4bc751 | ||
|
|
70985170e5 | ||
|
|
d7f674ce96 | ||
|
|
8e8c63bd67 | ||
|
|
3e1be63b0f | ||
|
|
b9d09202c9 | ||
|
|
e8704433de | ||
|
|
b272a8881b | ||
|
|
ca3cdb4458 | ||
|
|
157ec210a7 | ||
|
|
e7454132a2 | ||
|
|
77e93e1b79 | ||
|
|
cb8d5ab183 | ||
|
|
fb234205c2 | ||
|
|
d0ae6dd401 | ||
|
|
2650c60374 | ||
|
|
bcf705b85e | ||
|
|
e23c260cb0 | ||
|
|
21a5a34041 | ||
|
|
d7b3ed08ab | ||
|
|
a1bd65550e | ||
|
|
fe8aca630c | ||
|
|
f729cf621a | ||
|
|
25e2be3efd | ||
|
|
f7134990bd | ||
|
|
0358522533 | ||
|
|
4bf57ef56f | ||
|
|
71a25a109a | ||
|
|
4b22c2406c | ||
|
|
15324c276f | ||
|
|
e2a95d4b50 | ||
|
|
e3a0e1881d | ||
|
|
b98c120fb8 | ||
|
|
031c292136 | ||
|
|
5d1a639afd | ||
|
|
e1b3c286ef | ||
|
|
f38851b73d | ||
|
|
b6434d9581 | ||
|
|
72ca311f17 | ||
|
|
c5455ceee5 | ||
|
|
5a3338323c | ||
|
|
8a4b86dac9 | ||
|
|
bc4bf71d8f | ||
|
|
fe358e24e3 | ||
|
|
44c1b06609 | ||
|
|
587d356d6e | ||
|
|
d2fb1522a3 | ||
|
|
ab3698e3a4 | ||
|
|
422e87badb | ||
|
|
2b140b9a34 | ||
|
|
c8d2275c06 | ||
|
|
e67507478a | ||
|
|
b0707a61e7 | ||
|
|
9eb037bc87 | ||
|
|
140510fedf | ||
|
|
b8facc0ea9 | ||
|
|
360abb070a | ||
|
|
3bf6fed7b3 | ||
|
|
2ae6fd9d1e | ||
|
|
d14d50beb6 | ||
|
|
74225544c6 | ||
|
|
cd54793913 | ||
|
|
b574c4ad51 | ||
|
|
5907cc0de5 | ||
|
|
2bea7f8d69 | ||
|
|
9fb5ddbb4c | ||
|
|
dda16bfea6 | ||
|
|
06535f25dc | ||
|
|
d9548c01af | ||
|
|
6b2d25580c | ||
|
|
4f34031534 | ||
|
|
7e65f4da82 | ||
|
|
0e52c30bb8 | ||
|
|
06f3cc33ba | ||
|
|
824546d343 | ||
|
|
5850d8530e | ||
|
|
0cf03518f3 | ||
|
|
603f5e69ee | ||
|
|
e76b722e28 | ||
|
|
07bb6fef01 | ||
|
|
c2bb00ca2f | ||
|
|
6122642b81 | ||
|
|
47035671e8 | ||
|
|
f7f192e12b | ||
|
|
f1d8f30342 | ||
|
|
90750f59c1 | ||
|
|
65b57f0c21 | ||
|
|
23af31cb1c | ||
|
|
c344b30fc4 | ||
|
|
d7bd023afa | ||
|
|
4d239b3038 | ||
|
|
81ccba202c | ||
|
|
c6bb00085f | ||
|
|
7891346a4f | ||
|
|
ee6f69a227 | ||
|
|
5e3b7a4247 | ||
|
|
093b831799 | ||
|
|
6f11a64af5 | ||
|
|
1a52700238 | ||
|
|
1d18f2031c | ||
|
|
d4a771a623 | ||
|
|
fa888a4ba1 | ||
|
|
d4180d35dd | ||
|
|
323bba99f1 | ||
|
|
8ef800f64f | ||
|
|
004c99ab2f | ||
|
|
fb5274145a | ||
|
|
41cd8f8e6d | ||
|
|
539dea6411 | ||
|
|
5502fd1054 | ||
|
|
a48d0a494f | ||
|
|
d3ff8ca00f | ||
|
|
fe50593c66 | ||
|
|
be354e85c9 | ||
|
|
64a9549225 | ||
|
|
71f5d5da36 | ||
|
|
b6731ea47c | ||
|
|
545300e474 | ||
|
|
a653d2f5e2 | ||
|
|
9f99ee61c7 | ||
|
|
10de5a3ec7 | ||
|
|
4a55b97d11 | ||
|
|
2e58bc3113 | ||
|
|
04a8439c39 | ||
|
|
571386cdf4 | ||
|
|
ca3edc3673 | ||
|
|
2f70c842b8 | ||
|
|
6b3f023d98 | ||
|
|
1da672df7d | ||
|
|
10848c2e9a | ||
|
|
25f7dbd3e9 | ||
|
|
c58d8af706 | ||
|
|
03d5ee6738 | ||
|
|
ea9d0c0263 | ||
|
|
950246b331 | ||
|
|
d9b344a247 | ||
|
|
f0a6bfa23c | ||
|
|
dab65e4ba6 | ||
|
|
785c01218f | ||
|
|
88f2a1d43a | ||
|
|
a8132470e4 | ||
|
|
1c2a2dde8e | ||
|
|
c0228d8ff2 | ||
|
|
088b6f0ea9 | ||
|
|
e25150296a | ||
|
|
ce5ecda534 | ||
|
|
840b41c450 | ||
|
|
15713219e5 | ||
|
|
b71b478a36 | ||
|
|
19caac69d8 | ||
|
|
974fc65e0f | ||
|
|
65f65ec4e4 | ||
|
|
72d5cdf9ab | ||
|
|
ab27fdc692 | ||
|
|
965af75d23 | ||
|
|
88c810ed09 | ||
|
|
6c9800bcc3 | ||
|
|
83de658ee4 | ||
|
|
0acc90759c | ||
|
|
e6aa2610bc | ||
|
|
98706d31dc | ||
|
|
00185a39d9 | ||
|
|
f092e69d12 | ||
|
|
ae7c999712 | ||
|
|
f3d62f1d3b | ||
|
|
9be37da077 | ||
|
|
e5267506e0 | ||
|
|
e121faffa1 | ||
|
|
0d42cdaffd | ||
|
|
530f8e5b26 | ||
|
|
fbab88b0e1 | ||
|
|
58f18d5b12 | ||
|
|
d20ca32440 | ||
|
|
fe640d764a | ||
|
|
f48fc0d8b1 | ||
|
|
16f1267c29 | ||
|
|
01c5b53ba1 | ||
|
|
047f1b9de9 | ||
|
|
b7b4faff96 | ||
|
|
67ea7ce0ab | ||
|
|
cee7bfa9f0 | ||
|
|
ad32f64ef6 | ||
|
|
8d6342c53d | ||
|
|
58162ec170 | ||
|
|
d802165e03 | ||
|
|
c1e57e49ae | ||
|
|
4bab6f9fdb | ||
|
|
afcd5420ee | ||
|
|
85e8f8eb6a | ||
|
|
635e053e6d | ||
|
|
77c6038711 | ||
|
|
a473830533 | ||
|
|
99390be127 | ||
|
|
c20f8eb5b3 | ||
|
|
1a145f68a7 | ||
|
|
5364474823 | ||
|
|
97b492756a | ||
|
|
5984bc2ad3 | ||
|
|
358b2ab4ba | ||
|
|
81f1311a60 | ||
|
|
f4b87e2967 | ||
|
|
60656b6255 | ||
|
|
e585a5d8a3 | ||
|
|
981cefe8d3 | ||
|
|
36a428b8fc | ||
|
|
d22cf1aed1 | ||
|
|
8e54babf10 | ||
|
|
e1a0af8745 | ||
|
|
16e9d658d5 | ||
|
|
342f4bc2e0 | ||
|
|
eac795abc3 | ||
|
|
4f60948bff | ||
|
|
c3bf1a7741 | ||
|
|
f6680a0051 | ||
|
|
7fc308ed26 | ||
|
|
7d0256c9fb | ||
|
|
0a993cd9d7 | ||
|
|
3e703cc281 | ||
|
|
aa3897a880 | ||
|
|
aa00999fca | ||
|
|
d869d8e86f | ||
|
|
b567cb57e1 | ||
|
|
05b30bf83e | ||
|
|
1268b41570 | ||
|
|
93fdb06d7d | ||
|
|
f9fbb57d31 | ||
|
|
f55bba7244 | ||
|
|
244ee673d6 | ||
|
|
a56575a6d2 | ||
|
|
7fe5eaf6b7 | ||
|
|
aa1f96c73b | ||
|
|
37f1337a0b | ||
|
|
78b57787fa | ||
|
|
767f286a9f | ||
|
|
ffaa4a8922 | ||
|
|
848728858c | ||
|
|
5e3c883f2c | ||
|
|
528f9cd583 | ||
|
|
8ead7783ab | ||
|
|
2a36ba9680 | ||
|
|
8eb16ba02d | ||
|
|
a6f2cc9cbf | ||
|
|
180c673c78 | ||
|
|
6985d2c914 | ||
|
|
5520ce3c4a | ||
|
|
9b3e0255f4 | ||
|
|
4ac530d289 | ||
|
|
5bdc6e53e5 | ||
|
|
dd0aa90aa1 | ||
|
|
1a3c0063a5 | ||
|
|
a13c461890 | ||
|
|
1f78b9c7af | ||
|
|
da8b08b5fe | ||
|
|
30da85c3d8 | ||
|
|
50727527bc | ||
|
|
36d74d2a97 | ||
|
|
a5588e4bb7 | ||
|
|
8af8c10559 | ||
|
|
d3c96ec2ee | ||
|
|
85220dd77d | ||
|
|
01f2c38ee7 | ||
|
|
25e398645f | ||
|
|
c4f2373ac2 | ||
|
|
2ac5ea42af | ||
|
|
d2b925c709 | ||
|
|
87e8430921 | ||
|
|
d380820f3a | ||
|
|
309425833b | ||
|
|
9bbb9a8f0a | ||
|
|
054c6eefdb | ||
|
|
674dd27649 | ||
|
|
adbe1d4f06 | ||
|
|
6a51b1d570 | ||
|
|
81a389151f | ||
|
|
625570e730 | ||
|
|
23c5a1e6e9 | ||
|
|
9f2dbc9df4 | ||
|
|
992b9c46dd | ||
|
|
aab1a67d05 | ||
|
|
79a1de2f17 | ||
|
|
b18732173a | ||
|
|
d9f1a55c90 | ||
|
|
d5ff7fda6e | ||
|
|
3d7e7c53c5 | ||
|
|
0c9acb0f62 | ||
|
|
2ac2985cf2 | ||
|
|
e628896c2b | ||
|
|
da8fd5b30a | ||
|
|
9615efd940 | ||
|
|
41046499c6 | ||
|
|
04f908a957 | ||
|
|
8da1dd2b45 | ||
|
|
6e5238d037 | ||
|
|
2b2d4bae4e | ||
|
|
2b4dd8b9af | ||
|
|
aa28e4e81f | ||
|
|
6da1a105cb | ||
|
|
6ca1e5c4b0 | ||
|
|
86230b9ac8 | ||
|
|
d3d37ad0ce | ||
|
|
6214148d35 | ||
|
|
a9e9f9afb0 | ||
|
|
1b0d064743 | ||
|
|
d2da41b0bd | ||
|
|
49908386ef | ||
|
|
7ad3e2b56b | ||
|
|
ba63111f45 | ||
|
|
53d4f82ce1 | ||
|
|
83917c4c30 | ||
|
|
6ccd9d6fa4 | ||
|
|
175f20a9dc | ||
|
|
1646bec1a4 | ||
|
|
dd04b6a873 | ||
|
|
a651572cfd | ||
|
|
b4a0004f44 | ||
|
|
51bd91edc0 | ||
|
|
8e56c93fef | ||
|
|
e790146627 | ||
|
|
fd7c1fe584 | ||
|
|
84c7e457e9 | ||
|
|
a65fa54514 | ||
|
|
20cbc1d145 | ||
|
|
7670dc7efc | ||
|
|
24ba60168d | ||
|
|
7f29b870e7 | ||
|
|
61b03b72b0 | ||
|
|
93c9c45580 | ||
|
|
29e0ff61d7 | ||
|
|
cfe54b201d | ||
|
|
c649610473 | ||
|
|
d6768cf921 | ||
|
|
60d8413940 | ||
|
|
48b9023de4 | ||
|
|
751503c434 | ||
|
|
7ba6067a37 | ||
|
|
1edbaa4e62 | ||
|
|
9848ad32fd | ||
|
|
2b801e2086 | ||
|
|
d2c2c46541 | ||
|
|
c18dfa058a | ||
|
|
12632f16b8 | ||
|
|
25934200de | ||
|
|
24ced90913 | ||
|
|
0dcc87bd21 | ||
|
|
20e8b67eb6 | ||
|
|
7e362e0c46 | ||
|
|
751208cedf | ||
|
|
53808f254e | ||
|
|
ff82e41404 | ||
|
|
96e5905bce | ||
|
|
133fda11f2 | ||
|
|
884f317d50 | ||
|
|
b02faf5641 | ||
|
|
21fae634a5 | ||
|
|
56937416a9 | ||
|
|
20b7f8a8e0 | ||
|
|
bf4231dd4b | ||
|
|
31803d10aa | ||
|
|
d95d169ac5 | ||
|
|
f499f71f64 | ||
|
|
356836ccbb | ||
|
|
03537a6be4 | ||
|
|
f5a49280c3 | ||
|
|
dcddb19e5b | ||
|
|
3c64c18bfc | ||
|
|
48ebb25c25 | ||
|
|
7062b216b8 | ||
|
|
99a73cb4fa | ||
|
|
48f19b5fde | ||
|
|
5d89fb8dfa | ||
|
|
4ae98f8b21 | ||
|
|
fcdf08e4d7 | ||
|
|
cc8c783bb2 | ||
|
|
30f5ccb80d | ||
|
|
01f811d546 | ||
|
|
31f674da3c | ||
|
|
926efed31c | ||
|
|
d842365e4c | ||
|
|
8726d2fe2e | ||
|
|
3e3667f254 | ||
|
|
496e485691 | ||
|
|
99a73c5991 | ||
|
|
d7607973fa | ||
|
|
e8e6368cc8 | ||
|
|
1f8ba53ca7 | ||
|
|
ff0d871612 | ||
|
|
39e360f93a | ||
|
|
4e8e298eb3 | ||
|
|
487ac9cd19 | ||
|
|
bef52570ae | ||
|
|
c65fd3a289 | ||
|
|
34401cf0c3 | ||
|
|
be12720eb7 | ||
|
|
9a23e1a9df | ||
|
|
52625de52c | ||
|
|
01f7e768f6 | ||
|
|
f37f872e5f | ||
|
|
51f546fe92 | ||
|
|
309877088d | ||
|
|
a58dd8f6ab | ||
|
|
28d61f0d7f | ||
|
|
5ca5884ad6 | ||
|
|
21dae4577a | ||
|
|
d63cb8b537 | ||
|
|
0d4b77a24b | ||
|
|
2b89d9b1db | ||
|
|
60ec79eac3 | ||
|
|
a540a68561 | ||
|
|
d1d23ec5e6 | ||
|
|
1771063fe2 | ||
|
|
552d8ca5f0 | ||
|
|
6831ee6f0a | ||
|
|
6dc1fc03c1 | ||
|
|
9017ec5865 | ||
|
|
3427174eb0 | ||
|
|
100ada0ed6 | ||
|
|
41fd380d1b | ||
|
|
b1d40efd99 | ||
|
|
3db1c1761e | ||
|
|
5bcec9289e | ||
|
|
157e42de22 | ||
|
|
642ee87fcc | ||
|
|
792b033255 | ||
|
|
0f6884421b | ||
|
|
d85a46380c | ||
|
|
fc43f3c730 | ||
|
|
61f07b0c4d | ||
|
|
bfc72c04fb | ||
|
|
2ba6bb21fb | ||
|
|
fe0fdf60b4 | ||
|
|
c3aaf005e2 | ||
|
|
f9326053b9 | ||
|
|
73ea15db8e | ||
|
|
611537eaed | ||
|
|
d5e9279c1d | ||
|
|
ba22fc8b78 | ||
|
|
a411c497ab | ||
|
|
0a191d6b09 | ||
|
|
dccfcd10f7 | ||
|
|
bb329d8a5c | ||
|
|
d6edaa0970 | ||
|
|
14c9c61275 | ||
|
|
27d52badb1 | ||
|
|
614c4d1876 | ||
|
|
37db5928b7 | ||
|
|
22a4eb6b27 | ||
|
|
1b086c928c | ||
|
|
9edba18489 | ||
|
|
53cb7e828b | ||
|
|
3d3bea618e | ||
|
|
32f96b5c73 | ||
|
|
e403576cf9 | ||
|
|
527154e6df | ||
|
|
429e15c4a6 | ||
|
|
df5dc1c9bb | ||
|
|
a62f590653 | ||
|
|
8dd1f3ffa5 | ||
|
|
7cc4d88726 | ||
|
|
5f9a61616b | ||
|
|
52e3364efa | ||
|
|
b7e926eef6 | ||
|
|
ce8bd20944 | ||
|
|
3e1ba6cc24 | ||
|
|
abd3d3946d | ||
|
|
f3837dd686 | ||
|
|
dfbf1b2205 | ||
|
|
8dc32aeedb | ||
|
|
3198522a7f | ||
|
|
a173324069 | ||
|
|
ffd1d95806 | ||
|
|
f91e1ae83f | ||
|
|
217a2d9ea5 | ||
|
|
4d982f5aca | ||
|
|
c02cbaecd8 | ||
|
|
5d61888657 | ||
|
|
6b6a82c147 | ||
|
|
107c0dd1a8 | ||
|
|
85c02dbe7b | ||
|
|
9cab88071b | ||
|
|
9ac4c730fb | ||
|
|
09b6e8e804 | ||
|
|
5b665226a2 | ||
|
|
82aa366adf | ||
|
|
cc9266e56c | ||
|
|
d5018e77a3 | ||
|
|
2f9ee88408 | ||
|
|
917fb328bb | ||
|
|
0a0cd4b9d3 | ||
|
|
dc3b54a681 | ||
|
|
6e074a196a | ||
|
|
3d39d035c1 | ||
|
|
ed7db8e489 | ||
|
|
26b3d15ea0 | ||
|
|
1bfb16592b | ||
|
|
8df4fd9e94 | ||
|
|
0fc83ba999 | ||
|
|
afbd0e77d0 | ||
|
|
3dd6cbc556 | ||
|
|
6ee2eb21dd | ||
|
|
b5216f6ec8 | ||
|
|
31df2dd9dd | ||
|
|
fee88d289d | ||
|
|
7526a89463 | ||
|
|
281a869ef6 | ||
|
|
6f978af77b | ||
|
|
79a641ccf1 | ||
|
|
c5b7eba457 | ||
|
|
786f4cd2c2 | ||
|
|
25f2b01a3c | ||
|
|
3163d016db | ||
|
|
0daa08416a | ||
|
|
f6eb000381 | ||
|
|
20e67bc5e6 | ||
|
|
31863c68d8 | ||
|
|
e46af913be | ||
|
|
8ebac18f50 | ||
|
|
537451f0b1 | ||
|
|
e009a910cc | ||
|
|
c41b9b7ddc | ||
|
|
b8bb24d4bf | ||
|
|
4d5eb4ce7d | ||
|
|
0356ba34a0 | ||
|
|
c5b9732aed | ||
|
|
e7ab8d476d | ||
|
|
6bc86a6baa | ||
|
|
b0434fa486 | ||
|
|
fcabf0ef0d | ||
|
|
f8e046bb33 | ||
|
|
1a22a507d6 | ||
|
|
36272c8136 | ||
|
|
77bf133cd2 | ||
|
|
aff95ee587 | ||
|
|
29537b9991 | ||
|
|
530e049d4a | ||
|
|
5891847ae4 | ||
|
|
a56c7e5f1a | ||
|
|
0f4efc018d | ||
|
|
5a5990be09 | ||
|
|
50bd4d2e4e | ||
|
|
b98b612204 | ||
|
|
028cca16e6 | ||
|
|
1a132e4fdb | ||
|
|
aa137d8be0 | ||
|
|
4bb6f23ae1 | ||
|
|
39a3cfd4d9 | ||
|
|
4b2168ab8e | ||
|
|
0544b164fc | ||
|
|
4e0d47f1dd | ||
|
|
d7fdb8e015 | ||
|
|
58f2b39bc8 | ||
|
|
89fbe4fdfa | ||
|
|
b85dccca92 | ||
|
|
d3d9b5401b | ||
|
|
a075d581ef | ||
|
|
a173ab1e31 | ||
|
|
114e4d3fe6 | ||
|
|
cd1207329b | ||
|
|
d5c7cd5e50 | ||
|
|
55237b094a | ||
|
|
45ffcdee7b | ||
|
|
b253308eee | ||
|
|
05b791a621 | ||
|
|
cc349e9a32 | ||
|
|
dfcf567de0 | ||
|
|
73ef06018e | ||
|
|
a338e0efd5 | ||
|
|
7383bd393e | ||
|
|
763d850a0e | ||
|
|
89d5127900 | ||
|
|
1fe626ec7c | ||
|
|
c5ed7e2a15 | ||
|
|
fc96f62794 | ||
|
|
d50a18d9eb | ||
|
|
f8ffb005c8 | ||
|
|
60f7756626 | ||
|
|
3ce99cf4e1 | ||
|
|
04f032d6e3 | ||
|
|
e6d232bfef | ||
|
|
18dea24df8 | ||
|
|
0adf93853d | ||
|
|
c526c71f56 | ||
|
|
a0d388875e | ||
|
|
5081ba6802 | ||
|
|
70049185a5 | ||
|
|
a1553dd12b | ||
|
|
e2412e3f21 | ||
|
|
58d497ab7a | ||
|
|
52cce2d710 | ||
|
|
099fa1df34 | ||
|
|
cf3d236b9f | ||
|
|
894fcd90e7 | ||
|
|
1d90d98e40 | ||
|
|
bddab5e489 | ||
|
|
4dd47fbc78 | ||
|
|
98ccad8105 | ||
|
|
de2213a621 | ||
|
|
583b8e3ade | ||
|
|
b5fffc71c9 | ||
|
|
0011903e23 | ||
|
|
9bc27561ec | ||
|
|
76100a6f08 | ||
|
|
38b83362b6 | ||
|
|
c13329c25a | ||
|
|
6798c177c6 | ||
|
|
1447fd0a12 | ||
|
|
8fbd79fa2e | ||
|
|
9d4638ef4c | ||
|
|
8f56f5cfcc | ||
|
|
60fd7e2268 | ||
|
|
cb21a5b309 | ||
|
|
1330c10fc8 | ||
|
|
be92d0b6a4 | ||
|
|
df4e79c06c | ||
|
|
7392e1af59 | ||
|
|
8c06b92225 | ||
|
|
34700d560f | ||
|
|
5e93dd6592 | ||
|
|
4edcc59c3d | ||
|
|
c023b1000e | ||
|
|
150e43f3fd | ||
|
|
b6d368d7a0 | ||
|
|
34e445a480 | ||
|
|
5086a1e825 | ||
|
|
38ce53bc85 | ||
|
|
89c11221ed | ||
|
|
025566b494 | ||
|
|
4f8380959c | ||
|
|
2db5de76fc | ||
|
|
2e51e207f9 | ||
|
|
cbc552e91e | ||
|
|
511ffc3b44 | ||
|
|
e36fd7d29f | ||
|
|
af9fe0a038 | ||
|
|
893e05540c | ||
|
|
b2a85bc12e | ||
|
|
721eb56d0c | ||
|
|
cc49f9b657 | ||
|
|
2491a67ebf | ||
|
|
1003b847b6 | ||
|
|
ad0a1bf70d | ||
|
|
b98c25c1fb | ||
|
|
5eb8e1eec8 | ||
|
|
d40897404b | ||
|
|
485528cffa | ||
|
|
d3ead7061e | ||
|
|
45d981caab | ||
|
|
ca01adb503 | ||
|
|
fceb5a75b0 | ||
|
|
bfd05d3d27 | ||
|
|
72fa3c0492 | ||
|
|
9458f7c7d0 | ||
|
|
a5ba69d68d | ||
|
|
8feaefadcf | ||
|
|
38fdd063d9 | ||
|
|
72c9604bcb | ||
|
|
55662eca69 | ||
|
|
9dc05a57ec | ||
|
|
7c89f9d18c | ||
|
|
8c259859ab | ||
|
|
297cebd833 | ||
|
|
e78b8c16be | ||
|
|
9c30e0210b | ||
|
|
6d7b26d4e0 | ||
|
|
eb2c083159 | ||
|
|
185f40eb8b | ||
|
|
3067705c10 | ||
|
|
8a13d344a8 | ||
|
|
271a839957 | ||
|
|
679b617649 | ||
|
|
95a34628a3 | ||
|
|
7e6fc79eb2 | ||
|
|
5347f460b4 | ||
|
|
cd69681ae5 | ||
|
|
5417a514e9 | ||
|
|
5e75a5c81c | ||
|
|
6f339939c4 | ||
|
|
6fa0bb991a | ||
|
|
5a9394c65f | ||
|
|
cb5bc242db | ||
|
|
2d77173dfa | ||
|
|
42b5b7d2dd | ||
|
|
db1b21b9aa | ||
|
|
7989a7f903 | ||
|
|
f9c8c4d216 | ||
|
|
4ed22ad932 | ||
|
|
666d9e88f5 | ||
|
|
14b30de407 | ||
|
|
27c64f7740 | ||
|
|
42bc552dd7 | ||
|
|
79ed9de4c1 | ||
|
|
0ae05fdf99 | ||
|
|
4a72bd7919 | ||
|
|
076eaba6e3 | ||
|
|
0ced060b87 | ||
|
|
2aa501bf3d | ||
|
|
046b348bd3 | ||
|
|
aa9b14aff4 | ||
|
|
7e6b7795f1 | ||
|
|
d6a2ab08ac | ||
|
|
f106da0d09 | ||
|
|
e0498ce54a | ||
|
|
0fcb368f47 | ||
|
|
9474b8cdac | ||
|
|
886861c9f4 | ||
|
|
08729315c6 | ||
|
|
53fb74b3f0 | ||
|
|
19876161c7 | ||
|
|
618a1c7119 | ||
|
|
1c4ef29962 | ||
|
|
f201bfb998 | ||
|
|
0d993947ee | ||
|
|
b61d554dc8 | ||
|
|
2bc73b4a27 | ||
|
|
3a73ae1683 | ||
|
|
9bf8e8573c | ||
|
|
e3a02ea5c7 | ||
|
|
35532d6b0a | ||
|
|
37260962e5 | ||
|
|
5ac974c9b2 | ||
|
|
339da1da3d | ||
|
|
058e72d29c | ||
|
|
eb2cf1698f | ||
|
|
16f0ece75b | ||
|
|
9a91da9ccd | ||
|
|
e39586c81d | ||
|
|
2d87bb92ed | ||
|
|
db0695e46a | ||
|
|
6e56070386 | ||
|
|
d177184777 | ||
|
|
0a004e0fce | ||
|
|
7ab921ff02 | ||
|
|
382d8478bf | ||
|
|
09597fe8dc | ||
|
|
aec50722fc | ||
|
|
6db2a58008 | ||
|
|
a1c42c2753 | ||
|
|
671faa4b99 | ||
|
|
58adff307f | ||
|
|
5d626ac561 | ||
|
|
11c3a9f60d | ||
|
|
130d2d8de0 | ||
|
|
ed0c80e1cb | ||
|
|
fec6674597 | ||
|
|
dab230845d | ||
|
|
21e9d5c5c3 | ||
|
|
a58ae0c5d0 | ||
|
|
bf8479bec6 | ||
|
|
50d0a2643b | ||
|
|
2c163d175f | ||
|
|
ddbfc40303 | ||
|
|
b88da83a12 | ||
|
|
e8f5a85ffd | ||
|
|
af7b96c14a | ||
|
|
3913c10afb | ||
|
|
8b22a4f4f8 | ||
|
|
6c9b10f73d | ||
|
|
17a58ee0a9 | ||
|
|
3b554c709b | ||
|
|
070e2a3c13 | ||
|
|
9d90cb6962 | ||
|
|
cd2a23384f | ||
|
|
9576860f8c | ||
|
|
6a16040462 | ||
|
|
ead8ac58c6 | ||
|
|
908a93a470 | ||
|
|
cc0ee3dc29 | ||
|
|
d76c923623 | ||
|
|
e812c35689 | ||
|
|
ea872f8098 | ||
|
|
246423b4b4 | ||
|
|
f76b3890ff | ||
|
|
38508c5a3f | ||
|
|
9f496e5efa | ||
|
|
41c01b523f | ||
|
|
cbcc6fc9f5 | ||
|
|
7cb557cba7 | ||
|
|
caf93cc408 | ||
|
|
e6a44bd8ac | ||
|
|
f475ec4ce6 | ||
|
|
24838a62b4 | ||
|
|
2a61ff0794 | ||
|
|
fb9eca4226 | ||
|
|
c082abfb65 | ||
|
|
1f662465c2 | ||
|
|
b6833f08df | ||
|
|
c8f01480d6 | ||
|
|
c388cbe8e4 | ||
|
|
6773a2b3bf | ||
|
|
59dfb1c175 | ||
|
|
345fd3b285 | ||
|
|
ddefab8d56 | ||
|
|
e0e79a2cb3 | ||
|
|
a89abb435f | ||
|
|
9b387e7682 | ||
|
|
51b69ef00b | ||
|
|
c31da9bc8f | ||
|
|
ca3cc5b23e | ||
|
|
3ba2842b53 | ||
|
|
7e2f3cff44 | ||
|
|
ec5560374c | ||
|
|
aab7102b9b | ||
|
|
3a4bdf1856 | ||
|
|
ff0d039a1f | ||
|
|
f4460894be | ||
|
|
3c788147ca | ||
|
|
805fa96951 | ||
|
|
7598612b86 | ||
|
|
44ba16a391 | ||
|
|
67b94acd42 | ||
|
|
fe76e0aea2 | ||
|
|
43f58d9f61 | ||
|
|
f39e40664f | ||
|
|
13e02bb179 | ||
|
|
39f0f000f8 | ||
|
|
6cd976d036 | ||
|
|
49b91235bb | ||
|
|
82ed1bc343 | ||
|
|
e451421db3 | ||
|
|
fec197ccac | ||
|
|
ccdf105759 | ||
|
|
d328f4c3b6 | ||
|
|
29e03ac851 | ||
|
|
4997f0fe57 | ||
|
|
c985ad7644 | ||
|
|
b9bf0b942c | ||
|
|
f2b4341ad6 | ||
|
|
11861fb8d7 | ||
|
|
e3d703b80f | ||
|
|
2ae7839b66 | ||
|
|
0d66362cee | ||
|
|
3ce85b2270 | ||
|
|
9ec4ae83af | ||
|
|
4f21344e87 | ||
|
|
71dcf8833c | ||
|
|
1ce6d8b627 | ||
|
|
d16095c856 | ||
|
|
9f56d9c807 | ||
|
|
6cd22e5786 | ||
|
|
b7249d66b3 | ||
|
|
2c81875019 | ||
|
|
5dd39bfca5 | ||
|
|
58c5373890 | ||
|
|
5d64012868 | ||
|
|
b6d2a12ceb | ||
|
|
06fe879745 | ||
|
|
17de9a37f1 | ||
|
|
d44571257a | ||
|
|
f068d1ba57 | ||
|
|
fac4428766 | ||
|
|
6fcf16b710 | ||
|
|
18f0b24a7f | ||
|
|
e4d2ba30b5 | ||
|
|
650c9d4e36 | ||
|
|
53d70fff01 | ||
|
|
53cde110b1 | ||
|
|
987cd9e78f | ||
|
|
ee68a76a19 | ||
|
|
8d7b7e5d5d | ||
|
|
b5c597b318 | ||
|
|
59f89dd3be | ||
|
|
f4e72f33c8 | ||
|
|
d00314c621 | ||
|
|
c809cc9273 | ||
|
|
f3254ff02d | ||
|
|
e9f7d033ff | ||
|
|
79808da760 | ||
|
|
1501786fd9 | ||
|
|
75d30b08fb | ||
|
|
c6cd8ae243 | ||
|
|
cc6252cdfa | ||
|
|
5563c66675 | ||
|
|
5fda7daf57 | ||
|
|
dd21a01dc4 | ||
|
|
8818f4ac5e | ||
|
|
adbd393c39 | ||
|
|
13eb461ec3 | ||
|
|
521632b3dc | ||
|
|
6d4eed3845 | ||
|
|
82ea7aec51 | ||
|
|
d474eeb424 | ||
|
|
5d6baacc56 | ||
|
|
46cf0a23d9 | ||
|
|
f02af701e5 | ||
|
|
5f826a0ab7 | ||
|
|
ba83dd56a1 | ||
|
|
84823ed828 | ||
|
|
3ade141829 | ||
|
|
30acc6f2f0 | ||
|
|
22ba02b22b | ||
|
|
b5d7cd55ce | ||
|
|
e4e22ed17e | ||
|
|
3691201b4f | ||
|
|
d0e22b2240 | ||
|
|
fb73979345 | ||
|
|
e17ad6a684 | ||
|
|
6dff42be09 | ||
|
|
ccf311c9c6 | ||
|
|
cd23d2eaa2 | ||
|
|
99ca0f3153 | ||
|
|
b06117f77a | ||
|
|
9c8e46dc22 | ||
|
|
ac088bae6a | ||
|
|
c3246ee8ba | ||
|
|
f406fcb843 | ||
|
|
c5c9ada7b0 | ||
|
|
6af49d41fd | ||
|
|
13fd742610 | ||
|
|
babbc5bb45 | ||
|
|
10bc981d0b | ||
|
|
9345e78779 | ||
|
|
ce8df65d7b | ||
|
|
e32c59f805 | ||
|
|
4a2bd1753a | ||
|
|
2c3e7a6f87 | ||
|
|
1c9c5a385d | ||
|
|
360b307f68 | ||
|
|
689dbb8fb6 | ||
|
|
24c609b6df | ||
|
|
fb1874165b | ||
|
|
55f68bb2b0 | ||
|
|
1da56e5290 | ||
|
|
8821715377 | ||
|
|
fe9959d4da | ||
|
|
40b21d7cbe | ||
|
|
bd1cd83d71 | ||
|
|
a2f2e6a4ff | ||
|
|
92f398a897 | ||
|
|
da98b07624 | ||
|
|
e58ee88a63 | ||
|
|
7ea328659f | ||
|
|
c7b8d09c7f | ||
|
|
92ea86dc36 | ||
|
|
ec47ab16ce | ||
|
|
c8f65c1530 | ||
|
|
a2b5b61e7f | ||
|
|
17c2a0d6f3 | ||
|
|
58f848fa29 | ||
|
|
6f75f5bd6a | ||
|
|
f34b04e555 | ||
|
|
d6bf9c9887 | ||
|
|
d017c5080a | ||
|
|
067ecb90b9 | ||
|
|
1792115b4d | ||
|
|
7182671f8f | ||
|
|
7d80983362 | ||
|
|
7ebb4fcedc | ||
|
|
016eef6a16 | ||
|
|
9174c06598 | ||
|
|
27ca697b43 | ||
|
|
1e2f421faa | ||
|
|
00ab6eb616 | ||
|
|
6ad5210216 | ||
|
|
9fee7be695 | ||
|
|
e8235b10c6 | ||
|
|
23971bae92 | ||
|
|
eff5016653 | ||
|
|
a9c737f911 | ||
|
|
f5093094eb | ||
|
|
15ec3cb3cd | ||
|
|
b4e0804b37 | ||
|
|
64c8fd3fa1 | ||
|
|
13421dc4aa | ||
|
|
0591980cbe | ||
|
|
d1f127d8ef | ||
|
|
19123b4c48 | ||
|
|
e097696390 | ||
|
|
9087f26537 | ||
|
|
8828dbf2e8 | ||
|
|
0d308ca30f | ||
|
|
2e90599283 | ||
|
|
9d1f8f6bfd | ||
|
|
6f8a4318c5 | ||
|
|
889485181e | ||
|
|
fda208f6b8 | ||
|
|
2e37523428 | ||
|
|
ddfc276688 | ||
|
|
5acd7cad9a | ||
|
|
e06d351f7a | ||
|
|
7625881cb3 | ||
|
|
6892d7189f | ||
|
|
6f94a2567b | ||
|
|
b3e34be972 | ||
|
|
25c1678004 | ||
|
|
9f27ddc256 | ||
|
|
edfcac32c3 | ||
|
|
afe86e0d68 | ||
|
|
a51d4afe3e | ||
|
|
6ed5dd7427 | ||
|
|
314ecc54fe | ||
|
|
2bc660e83c | ||
|
|
f832719ceb | ||
|
|
96e213c110 | ||
|
|
0c028e24b4 | ||
|
|
55e24548c3 | ||
|
|
912c29471a | ||
|
|
b8aeab0439 | ||
|
|
cfb883646f | ||
|
|
0b5ca25358 | ||
|
|
277df08676 | ||
|
|
607f263fbc | ||
|
|
3cb10f92af | ||
|
|
9955df896b | ||
|
|
a087fd71e4 | ||
|
|
d92ac2a6b2 | ||
|
|
afe3c5b6bb | ||
|
|
0e3d994b05 | ||
|
|
cd581d1d5a | ||
|
|
2d465ffd10 | ||
|
|
f420f9393a | ||
|
|
04bcf43649 | ||
|
|
874326a1ad | ||
|
|
c0d667106a | ||
|
|
e2cb3b97fd | ||
|
|
b98454b8b2 | ||
|
|
c8ad456fd6 | ||
|
|
8839eeb421 | ||
|
|
eab3d4811e | ||
|
|
e64c0f4e4e | ||
|
|
1857b7736f | ||
|
|
bde9c7eee3 | ||
|
|
0a92349f90 | ||
|
|
3f3ceb24c4 | ||
|
|
0fc3b58890 | ||
|
|
0570660d81 | ||
|
|
26b9592780 | ||
|
|
8b9dcfe635 | ||
|
|
5d94864b6c | ||
|
|
50d7b3df2b | ||
|
|
8215c85619 | ||
|
|
c43b5d670b | ||
|
|
b6ad37557f | ||
|
|
d266bf0184 | ||
|
|
5294e2b9b9 | ||
|
|
c5ab3f4e82 | ||
|
|
f29fc5822b | ||
|
|
eb9859ce75 | ||
|
|
53feb12ea0 | ||
|
|
b9746de52e | ||
|
|
03780ea105 | ||
|
|
422a75e4b8 | ||
|
|
5d7a6c0c46 | ||
|
|
1f0246f970 | ||
|
|
9d71093500 | ||
|
|
fd34f4b119 | ||
|
|
454d06c25c | ||
|
|
c174fe6199 | ||
|
|
d461aa3722 | ||
|
|
a23e1579e3 | ||
|
|
ab31f989db | ||
|
|
96ec75f7fe | ||
|
|
5ac5c021b8 | ||
|
|
0cf9e0698c | ||
|
|
dae33a31c0 | ||
|
|
15aee0de1a | ||
|
|
c158012655 | ||
|
|
c4f5a881e6 | ||
|
|
6dffe2ddd1 | ||
|
|
be3e8170de | ||
|
|
d19538af07 | ||
|
|
123778dec2 | ||
|
|
37aa88ba2a | ||
|
|
74b0a9c059 | ||
|
|
83af842a74 | ||
|
|
16c2588635 | ||
|
|
bf6a73fa3e | ||
|
|
ea7b65e2f2 | ||
|
|
92c21d7134 | ||
|
|
0035100186 | ||
|
|
9b40d93fc2 | ||
|
|
ceecd2ce41 | ||
|
|
5676cb0dd1 | ||
|
|
8cbae642cc | ||
|
|
6f8f1bf7af | ||
|
|
c622337802 | ||
|
|
f813d823a1 | ||
|
|
f68e64d738 | ||
|
|
46b91ddf57 | ||
|
|
09151785b3 | ||
|
|
b2f46c703d | ||
|
|
76cb3eb7d2 | ||
|
|
cd1ca36488 | ||
|
|
805122c789 | ||
|
|
095ff1cb4a | ||
|
|
50970b72d8 | ||
|
|
c44db0133f | ||
|
|
cd5fa128c5 | ||
|
|
ef9deeccd1 | ||
|
|
09fff39990 | ||
|
|
13ff1a9bf6 | ||
|
|
b4a26c496c | ||
|
|
43e5465592 | ||
|
|
3c49487424 | ||
|
|
25af6478c5 | ||
|
|
793b842f99 | ||
|
|
535c1fac87 | ||
|
|
3b1898b8e4 | ||
|
|
c105a8d42a | ||
|
|
1f8ce403dc | ||
|
|
0944ba120c | ||
|
|
5d2ee893c4 | ||
|
|
29e833dfef | ||
|
|
2f3b0481de | ||
|
|
9412fc8083 | ||
|
|
8e87b2176a | ||
|
|
d6a5266976 | ||
|
|
5b32101ef2 | ||
|
|
3cfbc0520a | ||
|
|
42c88aa3ca | ||
|
|
1d0975bac6 | ||
|
|
d687962b74 | ||
|
|
53e8e44a8b | ||
|
|
bbc973cc5f | ||
|
|
8c4fe6d249 | ||
|
|
278e70e533 | ||
|
|
13132c6b97 | ||
|
|
1d6524f299 | ||
|
|
5c04b3c480 | ||
|
|
8b14a46201 | ||
|
|
c1be1a362b | ||
|
|
97a20cac58 | ||
|
|
0f5b26c9cd | ||
|
|
314120212d | ||
|
|
5077a2a343 | ||
|
|
ab40d0b1a4 | ||
|
|
c4a6d04131 | ||
|
|
203fd861aa | ||
|
|
37a5c3b09f | ||
|
|
634abdbcea | ||
|
|
89731d4a7d | ||
|
|
2b9dd718ae | ||
|
|
50687e08cb | ||
|
|
ad62b93df9 | ||
|
|
a4cce9eb69 | ||
|
|
c10773503b | ||
|
|
fa53bb835c | ||
|
|
6776c1945d | ||
|
|
b2f54bac95 | ||
|
|
744df77691 | ||
|
|
8364f0404c | ||
|
|
1b75b34eb6 | ||
|
|
3d2df174d1 | ||
|
|
af92250c7e | ||
|
|
30e45df8a5 | ||
|
|
e23dd3e3bb | ||
|
|
8921d52a82 | ||
|
|
51cb785695 | ||
|
|
0de021d427 | ||
|
|
08f37d478f | ||
|
|
41256e7369 | ||
|
|
2f2eab0e15 | ||
|
|
bbfc519ee5 |
34
.coveragerc
Normal file
34
.coveragerc
Normal file
@@ -0,0 +1,34 @@
|
||||
# -*- conf -*-
|
||||
# .coveragerc to control coverage.py
|
||||
[run]
|
||||
branch = True
|
||||
source = lib
|
||||
omit =
|
||||
lib/spack/spack/test/*
|
||||
lib/spack/env/*
|
||||
lib/spack/docs/*
|
||||
lib/spack/external/*
|
||||
|
||||
[report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
exclude_lines =
|
||||
# Have to re-enable the standard pragma
|
||||
pragma: no cover
|
||||
|
||||
# Don't complain about missing debug-only code:
|
||||
def __repr__
|
||||
if self\.debug
|
||||
|
||||
# Don't complain if tests don't hit defensive assertion code:
|
||||
raise AssertionError
|
||||
raise NotImplementedError
|
||||
|
||||
# Don't complain if non-runnable code isn't run:
|
||||
if 0:
|
||||
if False:
|
||||
if __name__ == .__main__.:
|
||||
|
||||
ignore_errors = True
|
||||
|
||||
[html]
|
||||
directory = htmlcov
|
||||
23
.flake8
Normal file
23
.flake8
Normal file
@@ -0,0 +1,23 @@
|
||||
# -*- conf -*-
|
||||
# flake8 settings for Spack.
|
||||
#
|
||||
# Below we describe which flake8 checks Spack ignores and what the
|
||||
# rationale is.
|
||||
#
|
||||
# Let people line things up nicely:
|
||||
# - E221: multiple spaces before operator
|
||||
# - E241: multiple spaces after ‘,’
|
||||
#
|
||||
# Let people use terse Python features:
|
||||
# - E731 : lambda expressions
|
||||
#
|
||||
# Spack allows wildcard imports:
|
||||
# - F403: disable wildcard import
|
||||
#
|
||||
# These are required to get the package.py files to test clean.
|
||||
# - F821: undefined name (needed for cmake, configure, etc.)
|
||||
# - F999: name name be undefined or undefined from star imports.
|
||||
#
|
||||
[flake8]
|
||||
ignore = E129,E221,E241,E272,E731,F403,F821,F999,F405
|
||||
max-line-length = 79
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
@@ -1,9 +1,17 @@
|
||||
/var/spack/stage
|
||||
/var/spack/cache
|
||||
/var/spack/repos/*/index.yaml
|
||||
/var/spack/repos/*/lock
|
||||
*.pyc
|
||||
/opt/
|
||||
/opt
|
||||
*~
|
||||
.DS_Store
|
||||
.idea
|
||||
/etc/spack/licenses
|
||||
/etc/spack/*.yaml
|
||||
/etc/spackconfig
|
||||
/share/spack/dotkit
|
||||
/share/spack/modules
|
||||
/TAGS
|
||||
/htmlcov
|
||||
.coverage
|
||||
|
||||
20
.mailmap
Normal file
20
.mailmap
Normal file
@@ -0,0 +1,20 @@
|
||||
Todd Gamblin <tgamblin@llnl.gov> George Todd Gamblin <gamblin2@llnl.gov>
|
||||
Todd Gamblin <tgamblin@llnl.gov> Todd Gamblin <gamblin2@llnl.gov>
|
||||
Adam Moody <moody20@llnl.gov> Adam T. Moody <moody20@llnl.gov>
|
||||
Alfredo Gimenez <gimenez1@llnl.gov> Alfredo Gimenez <alfredo.gimenez@gmail.com>
|
||||
David Boehme <boehme3@llnl.gov> David Boehme <boehme3@sierra324.llnl.gov>
|
||||
David Boehme <boehme3@llnl.gov> David Boehme <boehme3@sierra648.llnl.gov>
|
||||
Kevin Brandstatter <kjbrandstatter@gmail.com> Kevin Brandstatter <kbrandst@hawk.iit.edu>
|
||||
Luc Jaulmes <luc.jaulmes@bsc.es> Luc Jaulmes <jaulmes1@llnl.gov>
|
||||
Saravan Pantham <saravan.pantham@gmail.com> Saravan Pantham <pantham1@surface86.llnl.gov>
|
||||
Tom Scogland <tscogland@llnl.gov> Tom Scogland <scogland1@llnl.gov>
|
||||
Tom Scogland <tscogland@llnl.gov> Tom Scogland <tom.scogland@gmail.com>
|
||||
Joachim Protze <protze@rz.rwth-aachen.de> jprotze <protze@rz.rwth-aachen.de>
|
||||
Gregory L. Lee <lee218@llnl.gov> Gregory L. Lee <lee218@surface86.llnl.gov>
|
||||
Gregory L. Lee <lee218@llnl.gov> Gregory L. Lee <lee218@cab687.llnl.gov>
|
||||
Gregory L. Lee <lee218@llnl.gov> Gregory L. Lee <lee218@cab690.llnl.gov>
|
||||
Gregory L. Lee <lee218@llnl.gov> Gregory L. Lee <lee218@catalyst159.llnl.gov>
|
||||
Gregory L. Lee <lee218@llnl.gov> Gregory Lee <lee218@llnl.gov>
|
||||
Massimiliano Culpo <massimiliano.culpo@epfl.ch> Massimiliano Culpo <massimiliano.culpo@googlemail.com>
|
||||
Massimiliano Culpo <massimiliano.culpo@epfl.ch> alalazo <massimiliano.culpo@googlemail.com>
|
||||
Mark Miller <miller86@llnl.gov> miller86 <miller86@llnl.gov>
|
||||
46
.travis.yml
Normal file
46
.travis.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
language: python
|
||||
|
||||
python:
|
||||
- "2.6"
|
||||
- "2.7"
|
||||
env:
|
||||
- TEST_TYPE=unit
|
||||
- TEST_TYPE=flake8
|
||||
|
||||
# Exclude flake8 from python 2.6
|
||||
matrix:
|
||||
exclude:
|
||||
- python: "2.6"
|
||||
env: TEST_TYPE=flake8
|
||||
|
||||
# Use new Travis infrastructure (Docker can't sudo yet)
|
||||
sudo: false
|
||||
|
||||
# Install coveralls to obtain code coverage
|
||||
install:
|
||||
- "pip install coveralls"
|
||||
- "pip install flake8"
|
||||
|
||||
before_install:
|
||||
# Need this for the git tests to succeed.
|
||||
- git config --global user.email "spack@example.com"
|
||||
- git config --global user.name "Test User"
|
||||
|
||||
# Need this to be able to compute the list of changed files
|
||||
- git fetch origin develop:develop
|
||||
|
||||
script:
|
||||
# Run unit tests with code coverage plus install libdwarf
|
||||
- 'if [ "$TEST_TYPE" = "unit" ]; then share/spack/qa/run-unit-tests; fi'
|
||||
# Run flake8 code style checks.
|
||||
- 'if [ "$TEST_TYPE" = "flake8" ]; then share/spack/qa/run-flake8; fi'
|
||||
|
||||
after_success:
|
||||
- 'if [ "$TEST_TYPE" = "unit" ] && [ "$TRAVIS_PYTHON_VERSION" = "2.7" ]; then coveralls; fi'
|
||||
|
||||
notifications:
|
||||
email:
|
||||
recipients:
|
||||
- tgamblin@llnl.gov
|
||||
on_success: change
|
||||
on_failure: always
|
||||
66
LICENSE
66
LICENSE
@@ -1,56 +1,62 @@
|
||||
Copyright (c) 2013-2014, Lawrence Livermore National Security, LLC.
|
||||
########################################################################
|
||||
GNU LESSER GENERAL PUBLIC LICENSE (Lesser GPL)
|
||||
Version 2.1, February 1999
|
||||
########################################################################
|
||||
Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
||||
Produced at the Lawrence Livermore National Laboratory.
|
||||
|
||||
This file is part of Spack.
|
||||
Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
LLNL-CODE-647188
|
||||
|
||||
For details, see https://scalability-llnl.github.io/spack
|
||||
For details, see https://github.com/llnl/spack
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License (as published by
|
||||
the Free Software Foundation) version 2.1 dated February 1999.
|
||||
it under the terms of the GNU Lesser General Public License (as
|
||||
published by the Free Software Foundation) version 2.1, February 1999.
|
||||
|
||||
This program is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
||||
conditions of the GNU General Public License for more details.
|
||||
conditions of the GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
OUR NOTICE AND TERMS AND CONDITIONS OF THE GNU GENERAL PUBLIC LICENSE
|
||||
########################################################################
|
||||
LLNL NOTICE AND TERMS AND CONDITIONS OF THE GNU LGPL
|
||||
|
||||
Our Preamble Notice
|
||||
LLNL Preamble Notice
|
||||
|
||||
A. This notice is required to be provided under our contract with the
|
||||
U.S. Department of Energy (DOE). This work was produced at the
|
||||
Lawrence Livermore National Laboratory under Contract
|
||||
No. DE-AC52-07NA27344 with the DOE.
|
||||
A. This notice is required to be provided under LLNL's contract with
|
||||
the U.S. Department of Energy (DOE). This work was produced at the
|
||||
Lawrence Livermore National Laboratory under Contract
|
||||
No. DE-AC52-07NA27344 with the DOE.
|
||||
|
||||
B. Neither the United States Government nor Lawrence Livermore
|
||||
National Security, LLC nor any of their employees, makes any warranty,
|
||||
express or implied, or assumes any liability or responsibility for the
|
||||
accuracy, completeness, or usefulness of any information, apparatus,
|
||||
product, or process disclosed, or represents that its use would not
|
||||
infringe privately-owned rights.
|
||||
National Security, LLC nor any of their employees, makes any
|
||||
warranty, express or implied, or assumes any liability or
|
||||
responsibility for the accuracy, completeness, or usefulness of any
|
||||
information, apparatus, product, or process disclosed, or
|
||||
represents that its use would not infringe privately-owned rights.
|
||||
|
||||
C. Also, reference herein to any specific commercial products,
|
||||
process, or services by trade name, trademark, manufacturer or
|
||||
otherwise does not necessarily constitute or imply its endorsement,
|
||||
recommendation, or favoring by the United States Government or
|
||||
Lawrence Livermore National Security, LLC. The views and opinions of
|
||||
authors expressed herein do not necessarily state or reflect those of
|
||||
the United States Government or Lawrence Livermore National Security,
|
||||
LLC, and shall not be used for advertising or product endorsement
|
||||
purposes.
|
||||
process, or services by trade name, trademark, manufacturer or
|
||||
otherwise does not necessarily constitute or imply its endorsement,
|
||||
recommendation, or favoring by the United States Government or
|
||||
Lawrence Livermore National Security, LLC. The views and opinions
|
||||
of authors expressed herein do not necessarily state or reflect
|
||||
those of the United States Government or Lawrence Livermore
|
||||
National Security, LLC, and shall not be used for advertising or
|
||||
product endorsement purposes.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follows.
|
||||
|
||||
GNU Lesser GPL terms and Conditions for Copying, Distribution, and
|
||||
Modification
|
||||
########################################################################
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License Agreement applies to any software library or other
|
||||
program which contains a notice placed by the copyright holder or
|
||||
|
||||
87
README.md
87
README.md
@@ -1,5 +1,8 @@
|
||||
Spack
|
||||
===========
|
||||

|
||||
============
|
||||
|
||||
[](https://travis-ci.org/LLNL/spack)
|
||||
[](https://coveralls.io/github/LLNL/spack?branch=develop)
|
||||
|
||||
Spack is a package management tool designed to support multiple
|
||||
versions and configurations of software on a wide variety of platforms
|
||||
@@ -13,42 +16,86 @@ can coexist on the same system.
|
||||
Most importantly, Spack is simple. It offers a simple spec syntax so
|
||||
that users can specify versions and configuration options
|
||||
concisely. Spack is also simple for package authors: package files are
|
||||
writtin in pure Python, and specs allow package authors to write a
|
||||
written in pure Python, and specs allow package authors to write a
|
||||
single build script for many different builds of the same package.
|
||||
|
||||
See the
|
||||
[Feature Overview](http://scalability-llnl.github.io/spack/features.html)
|
||||
[Feature Overview](http://software.llnl.gov/spack/features.html)
|
||||
for examples and highlights.
|
||||
|
||||
To install spack and install your first package:
|
||||
|
||||
$ git clone https://github.com/scalability-llnl/spack.git
|
||||
$ git clone https://github.com/llnl/spack.git
|
||||
$ cd spack/bin
|
||||
$ ./spack install libelf
|
||||
|
||||
Documentation
|
||||
----------------
|
||||
|
||||
[Full documentation](http://scalability-llnl.github.io/spack)
|
||||
for Spack is also available.
|
||||
[**Full documentation**](http://software.llnl.gov/spack) for Spack is
|
||||
the first place to look.
|
||||
|
||||
See also:
|
||||
* [Technical paper](http://www.computer.org/csdl/proceedings/sc/2015/3723/00/2807623.pdf) and
|
||||
[slides](https://tgamblin.github.io/files/Gamblin-Spack-SC15-Talk.pdf) on Spack's design and implementation.
|
||||
* [Short presentation](https://tgamblin.github.io/files/Gamblin-Spack-Lightning-Talk-BOF-SC15.pdf) from the *Getting Scientific Software Installed* BOF session at Supercomputing 2015.
|
||||
|
||||
|
||||
Get Involved!
|
||||
------------------------
|
||||
|
||||
Spack is an open source project. Questions, discussion, and
|
||||
contributions are welcome. Contributions can be anything from new
|
||||
packages to bugfixes, or even new core features.
|
||||
|
||||
### Mailing list
|
||||
|
||||
If you are interested in contributing to spack, the first step is to
|
||||
join the mailing list. We're using a Google Group for this, and you
|
||||
can join it here:
|
||||
|
||||
* [Spack Google Group](https://groups.google.com/d/forum/spack)
|
||||
|
||||
### Contributions
|
||||
|
||||
Contributing to Spack is relatively easy. Just send us a
|
||||
[pull request](https://help.github.com/articles/using-pull-requests/).
|
||||
When you send your request, make ``develop`` the destination branch on the
|
||||
[Spack repository](https://github.com/LLNL/spack).
|
||||
|
||||
Before you send a PR, your code should pass the following checks:
|
||||
|
||||
* Your contribution will need to pass the `spack test` command.
|
||||
Run this before submitting your PR.
|
||||
|
||||
* Also run the `share/spack/qa/run-flake8` script to check for PEP8 compliance.
|
||||
To encourage contributions and readability by a broad audience,
|
||||
Spack uses the [PEP8](https://www.python.org/dev/peps/pep-0008/) coding
|
||||
standard with [a few exceptions](https://github.com/LLNL/spack/blob/develop/.flake8).
|
||||
|
||||
We enforce these guidelines with [Travis CI](https://travis-ci.org/LLNL/spack).
|
||||
|
||||
Spack uses a rough approximation of the [Git
|
||||
Flow](http://nvie.com/posts/a-successful-git-branching-model/)
|
||||
branching model. The ``develop`` branch contains the latest
|
||||
contributions, and ``master`` is always tagged and points to the
|
||||
latest stable release.
|
||||
|
||||
|
||||
Authors
|
||||
----------------
|
||||
Spack was written by Todd Gamblin, tgamblin@llnl.gov.
|
||||
Many thanks go to Spack's [contributors](https://github.com/llnl/spack/graphs/contributors).
|
||||
|
||||
Significant contributions were also made by:
|
||||
Spack was originally written by Todd Gamblin, tgamblin@llnl.gov.
|
||||
|
||||
* David Beckingsale
|
||||
* David Boehme
|
||||
* Alfredo Gimenez
|
||||
* Luc Jaulmes
|
||||
* Matt Legendre
|
||||
* Greg Lee
|
||||
* Adam Moody
|
||||
* Saravan Pantham
|
||||
* Joachim Protze
|
||||
* Bob Robey
|
||||
* Justin Too
|
||||
### Citing Spack
|
||||
|
||||
If you are referencing Spack in a publication, please cite the following paper:
|
||||
|
||||
* Todd Gamblin, Matthew P. LeGendre, Michael R. Collette, Gregory L. Lee,
|
||||
Adam Moody, Bronis R. de Supinski, and W. Scott Futral.
|
||||
[**The Spack Package Manager: Bringing Order to HPC Software Chaos**](http://www.computer.org/csdl/proceedings/sc/2015/3723/00/2807623.pdf).
|
||||
In *Supercomputing 2015 (SC’15)*, Austin, Texas, November 15-20 2015. LLNL-CONF-669890.
|
||||
|
||||
Release
|
||||
----------------
|
||||
|
||||
119
bin/sbang
Executable file
119
bin/sbang
Executable file
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
##############################################################################
|
||||
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
||||
# Produced at the Lawrence Livermore National Laboratory.
|
||||
#
|
||||
# This file is part of Spack.
|
||||
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License (as
|
||||
# published by the Free Software Foundation) version 2.1, February 1999.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
||||
# conditions of the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
##############################################################################
|
||||
#
|
||||
# `sbang`: Run scripts with long shebang lines.
|
||||
#
|
||||
# Many operating systems limit the length of shebang lines, making it
|
||||
# hard to use interpreters that are deep in the directory hierarchy.
|
||||
# `sbang` can run such scripts, either as a shebang interpreter, or
|
||||
# directly on the command line.
|
||||
#
|
||||
# Usage
|
||||
# -----------------------------
|
||||
# Suppose you have a script, long-shebang.sh, like this:
|
||||
#
|
||||
# 1 #!/very/long/path/to/some/interpreter
|
||||
# 2
|
||||
# 3 echo "success!"
|
||||
#
|
||||
# Invoking this script will result in an error on some OS's. On
|
||||
# Linux, you get this:
|
||||
#
|
||||
# $ ./long-shebang.sh
|
||||
# -bash: ./long: /very/long/path/to/some/interp: bad interpreter:
|
||||
# No such file or directory
|
||||
#
|
||||
# On Mac OS X, the system simply assumes the interpreter is the shell
|
||||
# and tries to run with it, which is likely not what you want.
|
||||
#
|
||||
#
|
||||
# `sbang` on the command line
|
||||
# -----------------------------
|
||||
# You can use `sbang` in two ways. The first is to use it directly,
|
||||
# from the command line, like this:
|
||||
#
|
||||
# $ sbang ./long-shebang.sh
|
||||
# success!
|
||||
#
|
||||
#
|
||||
# `sbang` as the interpreter
|
||||
# -----------------------------
|
||||
# You can also use `sbang` *as* the interpreter for your script. Put
|
||||
# `#!/bin/bash /path/to/sbang` on line 1, and move the original
|
||||
# shebang to line 2 of the script:
|
||||
#
|
||||
# 1 #!/bin/bash /path/to/sbang
|
||||
# 2 #!/long/path/to/real/interpreter with arguments
|
||||
# 3
|
||||
# 4 echo "success!"
|
||||
#
|
||||
# $ ./long-shebang.sh
|
||||
# success!
|
||||
#
|
||||
# On Linux, you could shorten line 1 to `#!/path/to/sbang`, but other
|
||||
# operating systems like Mac OS X require the interpreter to be a
|
||||
# binary, so it's best to use `sbang` as a `bash` argument.
|
||||
# Obviously, for this to work, `sbang` needs to have a short enough
|
||||
# path that *it* will run without hitting OS limits.
|
||||
#
|
||||
# For Lua, scripts the second line can't start with #!, as # is not
|
||||
# the comment character in lua (even though lua ignores #! on the
|
||||
# *first* line of a script). So, instrument a lua script like this,
|
||||
# using -- instead of # on the second line:
|
||||
#
|
||||
# 1 #!/bin/bash /path/to/sbang
|
||||
# 2 --!/long/path/to/lua with arguments
|
||||
# 3
|
||||
# 4 print "success!"
|
||||
#
|
||||
# How it works
|
||||
# -----------------------------
|
||||
# `sbang` is a very simple bash script. It looks at the first two
|
||||
# lines of a script argument and runs the last line starting with
|
||||
# `#!`, with the script as an argument. It also forwards arguments.
|
||||
#
|
||||
|
||||
# First argument is the script we want to actually run.
|
||||
script="$1"
|
||||
|
||||
# Search the first two lines of script for interpreters.
|
||||
lines=0
|
||||
while read line && ((lines < 2)) ; do
|
||||
if [[ "$line" = '#!'* ]]; then
|
||||
interpreter="${line#\#!}"
|
||||
elif [[ "$line" = '--!'*lua* ]]; then
|
||||
interpreter="${line#--!}"
|
||||
fi
|
||||
lines=$((lines+1))
|
||||
done < "$script"
|
||||
|
||||
# Invoke any interpreter found, or raise an error if none was found.
|
||||
if [ -n "$interpreter" ]; then
|
||||
exec $interpreter "$@"
|
||||
else
|
||||
echo "error: sbang found no interpreter in $script"
|
||||
exit 1
|
||||
fi
|
||||
115
bin/spack
115
bin/spack
@@ -1,32 +1,34 @@
|
||||
#!/usr/bin/env python
|
||||
# flake8: noqa
|
||||
##############################################################################
|
||||
# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
|
||||
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
||||
# Produced at the Lawrence Livermore National Laboratory.
|
||||
#
|
||||
# This file is part of Spack.
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License (as published by
|
||||
# the Free Software Foundation) version 2.1 dated February 1999.
|
||||
# it under the terms of the GNU Lesser General Public License (as
|
||||
# published by the Free Software Foundation) version 2.1, February 1999.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
||||
# conditions of the GNU General Public License for more details.
|
||||
# conditions of the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
##############################################################################
|
||||
import sys
|
||||
if not sys.version_info[:2] >= (2,6):
|
||||
if not sys.version_info[:2] >= (2, 6):
|
||||
v_info = sys.version_info[:3]
|
||||
sys.exit("Spack requires Python 2.6 or higher. This is Python %d.%d.%d." % v_info)
|
||||
sys.exit("Spack requires Python 2.6 or higher. "
|
||||
"This is Python %d.%d.%d." % v_info)
|
||||
|
||||
import os
|
||||
|
||||
@@ -38,6 +40,32 @@ SPACK_PREFIX = os.path.dirname(os.path.dirname(SPACK_FILE))
|
||||
# Allow spack libs to be imported in our scripts
|
||||
SPACK_LIB_PATH = os.path.join(SPACK_PREFIX, "lib", "spack")
|
||||
sys.path.insert(0, SPACK_LIB_PATH)
|
||||
SPACK_EXTERNAL_LIBS = os.path.join(SPACK_LIB_PATH, "external")
|
||||
sys.path.insert(0, SPACK_EXTERNAL_LIBS)
|
||||
|
||||
import warnings
|
||||
# Avoid warnings when nose is installed with the python exe being used to run
|
||||
# spack. Note this must be done after Spack's external libs directory is added
|
||||
# to sys.path.
|
||||
with warnings.catch_warnings():
|
||||
warnings.filterwarnings("ignore", ".*nose was already imported")
|
||||
import nose
|
||||
|
||||
# Quick and dirty check to clean orphaned .pyc files left over from
|
||||
# previous revisions. These files were present in earlier versions of
|
||||
# Spack, were removed, but shadow system modules that Spack still
|
||||
# imports. If we leave them, Spack will fail in mysterious ways.
|
||||
# TODO: more elegant solution for orphaned pyc files.
|
||||
orphaned_pyc_files = [os.path.join(SPACK_EXTERNAL_LIBS, n)
|
||||
for n in ('functools.pyc', 'ordereddict.pyc')]
|
||||
for pyc_file in orphaned_pyc_files:
|
||||
if not os.path.exists(pyc_file):
|
||||
continue
|
||||
try:
|
||||
os.remove(pyc_file)
|
||||
except OSError as e:
|
||||
print ("WARNING: Spack may fail mysteriously. "
|
||||
"Couldn't remove orphaned .pyc file: %s" % pyc_file)
|
||||
|
||||
# If there is no working directory, use the spack prefix.
|
||||
try:
|
||||
@@ -49,25 +77,41 @@ except OSError:
|
||||
# clean up the scope and start using spack package instead.
|
||||
del SPACK_FILE, SPACK_PREFIX, SPACK_LIB_PATH
|
||||
import llnl.util.tty as tty
|
||||
from llnl.util.tty.color import *
|
||||
import spack
|
||||
from spack.error import SpackError
|
||||
from external import argparse
|
||||
import argparse
|
||||
|
||||
# Command parsing
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Spack: the Supercomputing PACKage Manager.')
|
||||
parser.add_argument('-V', '--version', action='version',
|
||||
version="%s" % spack.spack_version)
|
||||
parser.add_argument('-v', '--verbose', action='store_true',
|
||||
help="Print additional output during builds")
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
description="Spack: the Supercomputing PACKage Manager." + colorize("""
|
||||
|
||||
spec expressions:
|
||||
PACKAGE [CONSTRAINTS]
|
||||
|
||||
CONSTRAINTS:
|
||||
@c{@version}
|
||||
@g{%compiler @compiler_version}
|
||||
@B{+variant}
|
||||
@r{-variant} or @r{~variant}
|
||||
@m{=architecture}
|
||||
[^DEPENDENCY [CONSTRAINTS] ...]"""))
|
||||
|
||||
parser.add_argument('-d', '--debug', action='store_true',
|
||||
help="Write out debug logs during compile")
|
||||
parser.add_argument('-D', '--pdb', action='store_true',
|
||||
help="Run spack under the pdb debugger")
|
||||
parser.add_argument('-k', '--insecure', action='store_true',
|
||||
help="Do not check ssl certificates when downloading archives.")
|
||||
help="Do not check ssl certificates when downloading.")
|
||||
parser.add_argument('-m', '--mock', action='store_true',
|
||||
help="Use mock packages instead of real ones.")
|
||||
parser.add_argument('-p', '--profile', action='store_true',
|
||||
help="Profile execution using cProfile.")
|
||||
parser.add_argument('-v', '--verbose', action='store_true',
|
||||
help="Print additional output during builds")
|
||||
parser.add_argument('-V', '--version', action='version',
|
||||
version="%s" % spack.spack_version)
|
||||
|
||||
# each command module implements a parser() function, to which we pass its
|
||||
# subparser for setup.
|
||||
@@ -87,49 +131,54 @@ if len(sys.argv) == 1:
|
||||
# actually parse the args.
|
||||
args = parser.parse_args()
|
||||
|
||||
|
||||
def main():
|
||||
# Set up environment based on args.
|
||||
tty.set_verbose(args.verbose)
|
||||
tty.set_debug(args.debug)
|
||||
spack.debug = args.debug
|
||||
|
||||
if spack.debug:
|
||||
import spack.util.debug as debug
|
||||
debug.register_interrupt_handler()
|
||||
|
||||
from spack.yaml_version_check import check_yaml_versions
|
||||
check_yaml_versions()
|
||||
|
||||
spack.spack_working_dir = working_dir
|
||||
if args.mock:
|
||||
from spack.packages import PackageDB
|
||||
spack.db = PackageDB(spack.mock_packages_path)
|
||||
from spack.repository import RepoPath
|
||||
spack.repo.swap(RepoPath(spack.mock_packages_path))
|
||||
|
||||
# If the user asked for it, don't check ssl certs.
|
||||
if args.insecure:
|
||||
tty.warn("You asked for --insecure, which does not check SSL certificates or checksums.")
|
||||
tty.warn("You asked for --insecure. Will NOT check SSL certificates.")
|
||||
spack.curl.add_default_arg('-k')
|
||||
|
||||
# Try to load the particular command asked for and run it
|
||||
command = spack.cmd.get_command(args.command)
|
||||
try:
|
||||
return_val = command(parser, args)
|
||||
except SpackError, e:
|
||||
if spack.debug:
|
||||
# In debug mode, raise with a full stack trace.
|
||||
raise
|
||||
elif e.long_message:
|
||||
tty.die(e.message, e.long_message)
|
||||
else:
|
||||
tty.die(e.message)
|
||||
|
||||
except SpackError as e:
|
||||
e.die()
|
||||
except KeyboardInterrupt:
|
||||
sys.stderr.write('\n')
|
||||
tty.die("Keyboard interrupt.")
|
||||
|
||||
# Allow commands to return values if they want to exit with some ohter code.
|
||||
# Allow commands to return values if they want to exit with some other code.
|
||||
if return_val is None:
|
||||
sys.exit(0)
|
||||
elif isinstance(return_val, int):
|
||||
sys.exit(return_val)
|
||||
else:
|
||||
tty.die("Bad return value from command %s: %s" % (args.command, return_val))
|
||||
tty.die("Bad return value from command %s: %s"
|
||||
% (args.command, return_val))
|
||||
|
||||
if args.profile:
|
||||
import cProfile
|
||||
cProfile.run('main()', sort='tottime')
|
||||
cProfile.run('main()', sort='time')
|
||||
elif args.pdb:
|
||||
import pdb
|
||||
pdb.run('main()')
|
||||
else:
|
||||
main()
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
#!/bin/sh
|
||||
##############################################################################
|
||||
# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
|
||||
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
||||
# Produced at the Lawrence Livermore National Laboratory.
|
||||
#
|
||||
# This file is part of Spack.
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License (as published by
|
||||
# the Free Software Foundation) version 2.1 dated February 1999.
|
||||
# it under the terms of the GNU Lesser General Public License (as
|
||||
# published by the Free Software Foundation) version 2.1, February 1999.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
||||
# conditions of the GNU General Public License for more details.
|
||||
# conditions of the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
##############################################################################
|
||||
#
|
||||
# spack-python
|
||||
|
||||
40
etc/spack/defaults/modules.yaml
Normal file
40
etc/spack/defaults/modules.yaml
Normal file
@@ -0,0 +1,40 @@
|
||||
# -------------------------------------------------------------------------
|
||||
# This is the default configuration for Spack's module file generation.
|
||||
#
|
||||
# Settings here are versioned with Spack and are intended to provide
|
||||
# sensible defaults out of the box. Spack maintainers should edit this
|
||||
# file to keep it current.
|
||||
#
|
||||
# Users can override these settings by editing the following files.
|
||||
#
|
||||
# Per-spack-instance settings (overrides defaults):
|
||||
# $SPACK_ROOT/etc/spack/modules.yaml
|
||||
#
|
||||
# Per-user settings (overrides default and site settings):
|
||||
# ~/.spack/modules.yaml
|
||||
# -------------------------------------------------------------------------
|
||||
modules:
|
||||
enable:
|
||||
- tcl
|
||||
- dotkit
|
||||
prefix_inspections:
|
||||
bin:
|
||||
- PATH
|
||||
man:
|
||||
- MANPATH
|
||||
share/man:
|
||||
- MANPATH
|
||||
lib:
|
||||
- LIBRARY_PATH
|
||||
- LD_LIBRARY_PATH
|
||||
lib64:
|
||||
- LIBRARY_PATH
|
||||
- LD_LIBRARY_PATH
|
||||
include:
|
||||
- CPATH
|
||||
lib/pkgconfig:
|
||||
- PKG_CONFIG_PATH
|
||||
lib64/pkgconfig:
|
||||
- PKG_CONFIG_PATH
|
||||
'':
|
||||
- CMAKE_PREFIX_PATH
|
||||
21
etc/spack/defaults/packages.yaml
Normal file
21
etc/spack/defaults/packages.yaml
Normal file
@@ -0,0 +1,21 @@
|
||||
# -------------------------------------------------------------------------
|
||||
# This file controls default concretization preferences for Spack.
|
||||
#
|
||||
# Settings here are versioned with Spack and are intended to provide
|
||||
# sensible defaults out of the box. Spack maintainers should edit this
|
||||
# file to keep it current.
|
||||
#
|
||||
# Users can override these settings by editing the following files.
|
||||
#
|
||||
# Per-spack-instance settings (overrides defaults):
|
||||
# $SPACK_ROOT/etc/spack/packages.yaml
|
||||
#
|
||||
# Per-user settings (overrides default and site settings):
|
||||
# ~/.spack/packages.yaml
|
||||
# -------------------------------------------------------------------------
|
||||
packages:
|
||||
all:
|
||||
providers:
|
||||
mpi: [openmpi, mpich]
|
||||
blas: [openblas]
|
||||
lapack: [openblas]
|
||||
14
etc/spack/defaults/repos.yaml
Normal file
14
etc/spack/defaults/repos.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
# -------------------------------------------------------------------------
|
||||
# This is the default spack repository configuration. It includes the
|
||||
# builtin spack package repository.
|
||||
#
|
||||
# Users can override these settings by editing the following files.
|
||||
#
|
||||
# Per-spack-instance settings (overrides defaults):
|
||||
# $SPACK_ROOT/etc/spack/repos.yaml
|
||||
#
|
||||
# Per-user settings (overrides default and site settings):
|
||||
# ~/.spack/repos.yaml
|
||||
# -------------------------------------------------------------------------
|
||||
repos:
|
||||
- $spack/var/spack/repos/builtin
|
||||
@@ -5,7 +5,7 @@
|
||||
"""
|
||||
import os
|
||||
|
||||
VERSION = (0, 1, 5)
|
||||
VERSION = (0, 1, 8)
|
||||
|
||||
__version__ = ".".join(str(v) for v in VERSION)
|
||||
__version_full__ = __version__
|
||||
|
||||
@@ -1,15 +1,23 @@
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="{{ pathto(master_doc) }}">Docs</a> »</li>
|
||||
<li><a href="">{{ title }}</a></li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
{% if display_github %}
|
||||
<a href="https://github.com/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}.rst" class="icon icon-github"> Edit on GitHub</a>
|
||||
{% elif display_bitbucket %}
|
||||
<a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}.rst'" class="icon icon-bitbucket"> Edit on Bitbucket</a>
|
||||
{% elif show_source and has_source and sourcename %}
|
||||
<a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
|
||||
<div role="navigation" aria-label="breadcrumbs navigation">
|
||||
<ul class="wy-breadcrumbs">
|
||||
<li><a href="{{ pathto(master_doc) }}">Docs</a> »</li>
|
||||
{% for doc in parents %}
|
||||
<li><a href="{{ doc.link|e }}">{{ doc.title }}</a> »</li>
|
||||
{% endfor %}
|
||||
<li>{{ title }}</li>
|
||||
<li class="wy-breadcrumbs-aside">
|
||||
{% if pagename != "search" %}
|
||||
{% if display_github %}
|
||||
<a href="https://{{ github_host|default("github.com") }}/{{ github_user }}/{{ github_repo }}/blob/{{ github_version }}{{ conf_py_path }}{{ pagename }}{{ source_suffix }}" class="fa fa-github"> Edit on GitHub</a>
|
||||
{% elif display_bitbucket %}
|
||||
<a href="https://bitbucket.org/{{ bitbucket_user }}/{{ bitbucket_repo }}/src/{{ bitbucket_version}}{{ conf_py_path }}{{ pagename }}{{ source_suffix }}" class="fa fa-bitbucket"> Edit on Bitbucket</a>
|
||||
{% elif show_source and source_url_prefix %}
|
||||
<a href="{{ source_url_prefix }}{{ pagename }}{{ source_suffix }}">View page source</a>
|
||||
{% elif show_source and has_source and sourcename %}
|
||||
<a href="{{ pathto('_sources/' + sourcename, true)|e }}" rel="nofollow"> View page source</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</li>
|
||||
</ul>
|
||||
<hr/>
|
||||
</div>
|
||||
|
||||
@@ -1,28 +1,40 @@
|
||||
<footer>
|
||||
{% if next or prev %}
|
||||
<div class="rst-footer-buttons">
|
||||
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
|
||||
{% if next %}
|
||||
<a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}"/>Next <span class="icon icon-circle-arrow-right"></span></a>
|
||||
<a href="{{ next.link|e }}" class="btn btn-neutral float-right" title="{{ next.title|striptags|e }}" accesskey="n">Next <span class="fa fa-arrow-circle-right"></span></a>
|
||||
{% endif %}
|
||||
{% if prev %}
|
||||
<a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}"><span class="icon icon-circle-arrow-left"></span> Previous</a>
|
||||
<a href="{{ prev.link|e }}" class="btn btn-neutral" title="{{ prev.title|striptags|e }}" accesskey="p"><span class="fa fa-arrow-circle-left"></span> Previous</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<hr/>
|
||||
|
||||
<p>
|
||||
© Copyright 2013-2014,
|
||||
<a href="https://scalability.llnl.gov/">Lawrence Livermore National Laboratory</a>.
|
||||
<br/>
|
||||
Written by Todd Gamblin, <a href="mailto:tgamblin@llnl.gov">tgamblin@llnl.gov</a>, LLNL-CODE-647188
|
||||
<br/>
|
||||
<div role="contentinfo">
|
||||
<p>
|
||||
{%- if show_copyright %}
|
||||
{%- if hasdoc('copyright') %}
|
||||
{% trans path=pathto('copyright'), copyright=copyright|e %}© <a href="{{ path }}">Copyright</a> {{ copyright }}.{% endtrans %}
|
||||
{%- else %}
|
||||
{% trans copyright=copyright|e %}© Copyright {{ copyright }}.{% endtrans %}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
|
||||
{%- if last_updated %}
|
||||
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
|
||||
<br/>
|
||||
Written by Todd Gamblin (<a href="mailto:tgamblin@llnl.gov">tgamblin@llnl.gov</a>) and
|
||||
many contributors. LLNL-CODE-647188.
|
||||
|
||||
{%- if last_updated %}
|
||||
<br/>
|
||||
{% trans last_updated=last_updated|e %}Last updated on {{ last_updated }}.{% endtrans %}
|
||||
{%- endif %}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{%- if show_sphinx %}
|
||||
{% trans %}Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>{% endtrans %}.
|
||||
{%- endif %}
|
||||
|
||||
{% trans %}<br/><a href="https://www.github.com/snide/sphinx_rtd_theme">Sphinx theme</a> provided by <a href="http://readthedocs.org">Read the Docs</a>{% endtrans %}
|
||||
</p>
|
||||
|
||||
</footer>
|
||||
|
||||
107
lib/spack/docs/_themes/sphinx_rtd_theme/layout.html
vendored
107
lib/spack/docs/_themes/sphinx_rtd_theme/layout.html
vendored
@@ -12,6 +12,7 @@
|
||||
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
{{ metatags }}
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{% block htmltitle %}
|
||||
<title>{{ title|striptags|e }}{{ titlesuffix }}</title>
|
||||
@@ -23,40 +24,28 @@
|
||||
{% endif %}
|
||||
|
||||
{# CSS #}
|
||||
<link href='https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700' rel='stylesheet' type='text/css'>
|
||||
|
||||
{# JS #}
|
||||
{# OPENSEARCH #}
|
||||
{% if not embedded %}
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'{{ url_root }}',
|
||||
VERSION:'{{ release|e }}',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
|
||||
HAS_SOURCE: {{ has_source|lower }}
|
||||
};
|
||||
</script>
|
||||
{%- for scriptfile in script_files %}
|
||||
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
|
||||
{%- endfor %}
|
||||
|
||||
{% if use_opensearch %}
|
||||
<link rel="search" type="application/opensearchdescription+xml" title="{% trans docstitle=docstitle|e %}Search within {{ docstitle }}{% endtrans %}" href="{{ pathto('_static/opensearch.xml', 1) }}"/>
|
||||
{% endif %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{# RTD hosts these file themselves, so just load on non RTD builds #}
|
||||
{# RTD hosts this file, so just load on non RTD builds #}
|
||||
{% if not READTHEDOCS %}
|
||||
<link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
|
||||
<script type="text/javascript" src="_static/js/theme.js"></script>
|
||||
{% endif %}
|
||||
|
||||
{% for cssfile in css_files %}
|
||||
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
|
||||
{% endfor %}
|
||||
|
||||
{% for cssfile in extra_css_files %}
|
||||
<link rel="stylesheet" href="{{ pathto(cssfile, 1) }}" type="text/css" />
|
||||
{% endfor %}
|
||||
|
||||
{%- block linktags %}
|
||||
{%- if hasdoc('about') %}
|
||||
<link rel="author" title="{{ _('About these documents') }}"
|
||||
@@ -85,29 +74,47 @@
|
||||
{%- endblock %}
|
||||
{%- block extrahead %} {% endblock %}
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.6.2/modernizr.min.js"></script>
|
||||
{# Keep modernizr in head - http://modernizr.com/docs/#installing #}
|
||||
<script src="_static/js/modernizr.min.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body class="wy-body-for-nav">
|
||||
<body class="wy-body-for-nav" role="document">
|
||||
|
||||
<div class="wy-grid-for-nav">
|
||||
|
||||
{# SIDE NAV, TOGGLES ON MOBILE #}
|
||||
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
|
||||
<div class="wy-side-nav-search">
|
||||
<a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}</a>
|
||||
{% block sidebartitle %}
|
||||
|
||||
{% if logo and theme_logo_only %}
|
||||
<a href="{{ pathto(master_doc) }}">
|
||||
{% else %}
|
||||
<a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}
|
||||
{% endif %}
|
||||
|
||||
{% if logo %}
|
||||
{# Not strictly valid HTML, but it's the only way to display/scale it properly, without weird scripting or heaps of work #}
|
||||
<img src="{{ pathto('_static/' + logo, 1) }}" class="logo" />
|
||||
{% endif %}
|
||||
</a>
|
||||
|
||||
{% include "searchbox.html" %}
|
||||
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix">
|
||||
{% set toctree = toctree(maxdepth=2, collapse=False, includehidden=True) %}
|
||||
{% if toctree %}
|
||||
{{ toctree }}
|
||||
{% else %}
|
||||
<!-- Local TOC -->
|
||||
<div class="local-toc">{{ toc }}</div>
|
||||
{% endif %}
|
||||
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
|
||||
{% block menu %}
|
||||
{% set toctree = toctree(maxdepth=4, collapse=False, includehidden=True) %}
|
||||
{% if toctree %}
|
||||
{{ toctree }}
|
||||
{% else %}
|
||||
<!-- Local TOC -->
|
||||
<div class="local-toc">{{ toc }}</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
@@ -115,8 +122,8 @@
|
||||
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
|
||||
|
||||
{# MOBILE NAV, TRIGGLES SIDE NAV ON TOGGLE #}
|
||||
<nav class="wy-nav-top">
|
||||
<i data-toggle="wy-nav-top" class="icon icon-reorder"></i>
|
||||
<nav class="wy-nav-top" role="navigation" aria-label="top navigation">
|
||||
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
|
||||
<a href="{{ pathto(master_doc) }}">{{ project }}</a>
|
||||
</nav>
|
||||
|
||||
@@ -125,7 +132,9 @@
|
||||
<div class="wy-nav-content">
|
||||
<div class="rst-content">
|
||||
{% include "breadcrumbs.html" %}
|
||||
{% block body %}{% endblock %}
|
||||
<div role="main" class="document">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
{% include "footer.html" %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,5 +143,39 @@
|
||||
|
||||
</div>
|
||||
{% include "versions.html" %}
|
||||
|
||||
{% if not embedded %}
|
||||
|
||||
<script type="text/javascript">
|
||||
var DOCUMENTATION_OPTIONS = {
|
||||
URL_ROOT:'{{ url_root }}',
|
||||
VERSION:'{{ release|e }}',
|
||||
COLLAPSE_INDEX:false,
|
||||
FILE_SUFFIX:'{{ '' if no_search_suffix else file_suffix }}',
|
||||
HAS_SOURCE: {{ has_source|lower }}
|
||||
};
|
||||
</script>
|
||||
{%- for scriptfile in script_files %}
|
||||
<script type="text/javascript" src="{{ pathto(scriptfile, 1) }}"></script>
|
||||
{%- endfor %}
|
||||
|
||||
{% endif %}
|
||||
|
||||
{# RTD hosts this file, so just load on non RTD builds #}
|
||||
{% if not READTHEDOCS %}
|
||||
<script type="text/javascript" src="{{ pathto('_static/js/theme.js', 1) }}"></script>
|
||||
{% endif %}
|
||||
|
||||
{# STICKY NAVIGATION #}
|
||||
{% if theme_sticky_navigation %}
|
||||
<script type="text/javascript">
|
||||
jQuery(function () {
|
||||
SphinxRtdTheme.StickyNav.enable();
|
||||
});
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{%- block footer %} {% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
{%- extends "layout.html" %}
|
||||
{% set title = _('Search') %}
|
||||
{% set script_files = script_files + ['_static/searchtools.js'] %}
|
||||
{% block extrahead %}
|
||||
{% block footer %}
|
||||
<script type="text/javascript">
|
||||
jQuery(function() { Search.loadIndex("{{ pathto('searchindex.js', 1) }}"); });
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<form id ="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
{%- if builder != 'singlehtml' %}
|
||||
<div role="search">
|
||||
<form id="rtd-search-form" class="wy-form" action="{{ pathto('search') }}" method="get">
|
||||
<input type="text" name="q" placeholder="Search docs" />
|
||||
<input type="hidden" name="check_keywords" value="yes" />
|
||||
<input type="hidden" name="area" value="default" />
|
||||
</form>
|
||||
</div>
|
||||
{%- endif %}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
.font-smooth,.icon:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:fontawesome-webfont;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#fontawesome-webfont") format("svg")}.icon:before{display:inline-block;font-family:fontawesome-webfont;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .icon{display:inline-block;text-decoration:inherit}li .icon{display:inline-block}li .icon-large:before,li .icon-large:before{width:1.875em}ul.icons{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.icons li .icon{width:0.8em}ul.icons li .icon-large:before,ul.icons li .icon-large:before{vertical-align:baseline}.icon-book:before{content:"\f02d"}.icon-caret-down:before{content:"\f0d7"}.icon-caret-up:before{content:"\f0d8"}.icon-caret-left:before{content:"\f0d9"}.icon-caret-right:before{content:"\f0da"}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980b9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27ae60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .icon{color:#fcfcfc}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#e74c3c;color:#fff}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}
|
||||
.fa:before{-webkit-font-smoothing:antialiased}.clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:""}.clearfix:after{clear:both}@font-face{font-family:FontAwesome;font-weight:normal;font-style:normal;src:url("../font/fontawesome_webfont.eot");src:url("../font/fontawesome_webfont.eot?#iefix") format("embedded-opentype"),url("../font/fontawesome_webfont.woff") format("woff"),url("../font/fontawesome_webfont.ttf") format("truetype"),url("../font/fontawesome_webfont.svg#FontAwesome") format("svg")}.fa:before{display:inline-block;font-family:FontAwesome;font-style:normal;font-weight:normal;line-height:1;text-decoration:inherit}a .fa{display:inline-block;text-decoration:inherit}li .fa{display:inline-block}li .fa-large:before,li .fa-large:before{width:1.875em}ul.fas{list-style-type:none;margin-left:2em;text-indent:-0.8em}ul.fas li .fa{width:0.8em}ul.fas li .fa-large:before,ul.fas li .fa-large:before{vertical-align:baseline}.fa-book:before{content:""}.icon-book:before{content:""}.fa-caret-down:before{content:""}.icon-caret-down:before{content:""}.fa-caret-up:before{content:""}.icon-caret-up:before{content:""}.fa-caret-left:before{content:""}.icon-caret-left:before{content:""}.fa-caret-right:before{content:""}.icon-caret-right:before{content:""}.rst-versions{position:fixed;bottom:0;left:0;width:300px;color:#fcfcfc;background:#1f1d1d;border-top:solid 10px #343131;font-family:"Lato","proxima-nova","Helvetica Neue",Arial,sans-serif;z-index:400}.rst-versions a{color:#2980B9;text-decoration:none}.rst-versions .rst-badge-small{display:none}.rst-versions .rst-current-version{padding:12px;background-color:#272525;display:block;text-align:right;font-size:90%;cursor:pointer;color:#27AE60;*zoom:1}.rst-versions .rst-current-version:before,.rst-versions .rst-current-version:after{display:table;content:""}.rst-versions .rst-current-version:after{clear:both}.rst-versions .rst-current-version .fa{color:#fcfcfc}.rst-versions .rst-current-version .fa-book{float:left}.rst-versions .rst-current-version .icon-book{float:left}.rst-versions .rst-current-version.rst-out-of-date{background-color:#E74C3C;color:#fff}.rst-versions .rst-current-version.rst-active-old-version{background-color:#F1C40F;color:#000}.rst-versions.shift-up .rst-other-versions{display:block}.rst-versions .rst-other-versions{font-size:90%;padding:12px;color:gray;display:none}.rst-versions .rst-other-versions hr{display:block;height:1px;border:0;margin:20px 0;padding:0;border-top:solid 1px #413d3d}.rst-versions .rst-other-versions dd{display:inline-block;margin:0}.rst-versions .rst-other-versions dd a{display:inline-block;padding:6px;color:#fcfcfc}.rst-versions.rst-badge{width:auto;bottom:20px;right:20px;left:auto;border:none;max-width:300px}.rst-versions.rst-badge .icon-book{float:none}.rst-versions.rst-badge .fa-book{float:none}.rst-versions.rst-badge.shift-up .rst-current-version{text-align:right}.rst-versions.rst-badge.shift-up .rst-current-version .fa-book{float:left}.rst-versions.rst-badge.shift-up .rst-current-version .icon-book{float:left}.rst-versions.rst-badge .rst-current-version{width:auto;height:30px;line-height:30px;padding:0 6px;display:block;text-align:center}@media screen and (max-width: 768px){.rst-versions{width:85%;display:none}.rst-versions.shift{display:block}img{width:100%;height:auto}}
|
||||
/*# sourceMappingURL=badge_only.css.map */
|
||||
|
||||
7
lib/spack/docs/_themes/sphinx_rtd_theme/static/css/badge_only.css.map
vendored
Normal file
7
lib/spack/docs/_themes/sphinx_rtd_theme/static/css/badge_only.css.map
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"version": 3,
|
||||
"mappings": "CAyDA,SAAY,EACV,qBAAsB,EAAE,UAAW,EAqDrC,QAAS,EARP,IAAK,EAAE,AAAC,EACR,+BAAS,EAEP,MAAO,EAAE,IAAK,EACd,MAAO,EAAE,CAAE,EACb,cAAO,EACL,IAAK,EAAE,GAAI,EC1Gb,SAkBC,EAjBC,UAAW,ECFJ,UAAW,EDGlB,UAAW,EAHqC,KAAM,EAItD,SAAU,EAJsD,KAAM,EAapE,EAAG,EAAE,qCAAwB,EAC7B,EAAG,EAAE,0PAAyE,ECZpF,SAAU,EACR,MAAO,EAAE,WAAY,EACrB,UAAW,EAAE,UAAW,EACxB,SAAU,EAAE,KAAM,EAClB,UAAW,EAAE,KAAM,EACnB,UAAW,EAAE,AAAC,EACd,cAAe,EAAE,MAAO,EAG1B,IAAK,EACH,MAAO,EAAE,WAAY,EACrB,cAAe,EAAE,MAAO,EAIxB,KAAG,EACD,MAAO,EAAE,WAAY,EACvB,sCAAiB,EAGf,IAAK,EAAE,MAAY,EAEvB,KAAM,EACJ,cAAe,EAAE,GAAI,EACrB,UAAW,EAAE,EAAG,EAChB,UAAW,EAAE,KAAM,EAEjB,YAAG,EACD,IAAK,EAAE,IAAI,EACb,oDAAiB,EAGf,aAAc,EAAE,OAAQ,EAG9B,cAAe,EACb,MAAO,EAAE,EAAO,EAElB,gBAAiB,EACf,MAAO,EAAE,EAAO,EAElB,oBAAqB,EACnB,MAAO,EAAE,EAAO,EAElB,sBAAuB,EACrB,MAAO,EAAE,EAAO,EAElB,kBAAmB,EACjB,MAAO,EAAE,EAAO,EAElB,oBAAqB,EACnB,MAAO,EAAE,EAAO,EAElB,oBAAqB,EACnB,MAAO,EAAE,EAAO,EAElB,sBAAuB,EACrB,MAAO,EAAE,EAAO,EAElB,qBAAsB,EACpB,MAAO,EAAE,EAAO,EAElB,uBAAwB,EACtB,MAAO,EAAE,EAAO,ECnElB,YAAa,EACX,OAAQ,EAAE,IAAK,EACf,KAAM,EAAE,AAAC,EACT,GAAI,EAAE,AAAC,EACP,IAAK,EC6E+B,IAAK,ED5EzC,IAAK,ECE+B,MAAyB,EDD7D,SAAU,EAAE,MAAkC,EAC9C,SAAU,EAAE,iBAAiC,EAC7C,UAAW,EEAyB,sDAAM,EFC1C,MAAO,EC+E6B,EAAG,ED9EvC,cAAC,EACC,IAAK,ECqE6B,MAAW,EDpE7C,cAAe,EAAE,GAAI,EACvB,6BAAgB,EACd,MAAO,EAAE,GAAI,EACf,iCAAoB,EAClB,MAAO,EAAE,GAAqB,EAC9B,eAAgB,EAAE,MAAkC,EACpD,MAAO,EAAE,IAAK,EACd,SAAU,EAAE,IAAK,EACjB,QAAS,EAAE,EAAG,EACd,KAAM,EAAE,MAAO,EACf,IAAK,ECiD6B,MAAM,EJgC1C,IAAK,EAAE,AAAC,EACR,iFAAS,EAEP,MAAO,EAAE,IAAK,EACd,MAAO,EAAE,CAAE,EACb,uCAAO,EACL,IAAK,EAAE,GAAI,EGrFX,qCAAG,EACD,IAAK,EClB2B,MAAyB,EDmB3D,0CAAQ,EACN,IAAK,EAAE,GAAI,EACb,4CAAU,EACR,IAAK,EAAE,GAAI,EACb,iDAAiB,EACf,eAAgB,ECQgB,MAAI,EDPpC,IAAK,EC0B2B,GAAM,EDzBxC,wDAAwB,EACtB,eAAgB,ECXgB,MAAO,EDYvC,IAAK,ECzB2B,GAAI,ED0BxC,yCAA8B,EAC5B,MAAO,EAAE,IAAK,EAChB,gCAAmB,EACjB,QAAS,EAAE,EAAG,EACd,MAAO,EAAE,GAAqB,EAC9B,IAAK,ECE6B,GAAwB,EDD1D,MAAO,EAAE,GAAI,EACb,mCAAE,EACA,MAAO,EAAE,IAAK,EACd,KAAM,EAAE,EAAG,EACX,KAAM,EAAE,AAAC,EACT,KAAM,EAAE,KAAM,EACd,MAAO,EAAE,AAAC,EACV,SAAU,EAAE,gBAA6C,EAC3D,mCAAE,EACA,MAAO,EAAE,WAAY,EACrB,KAAM,EAAE,AAAC,EACT,qCAAC,EACC,MAAO,EAAE,WAAY,EACrB,MAAO,EAAE,EAAqB,EAC9B,IAAK,ECjDyB,MAAyB,EDkD7D,sBAAW,EACT,IAAK,EAAE,GAAI,EACX,KAAM,EAAE,GAAI,EACZ,IAAK,EAAE,GAAI,EACX,GAAI,EAAE,GAAI,EACV,KAAM,EAAE,GAAI,EACZ,QAAS,ECkByB,IAAK,EDjBvC,iCAAU,EACR,IAAK,EAAE,GAAI,EACb,+BAAQ,EACN,IAAK,EAAE,GAAI,EACb,oDAA+B,EAC7B,SAAU,EAAE,IAAK,EACjB,6DAAQ,EACN,IAAK,EAAE,GAAI,EACb,+DAAU,EACR,IAAK,EAAE,GAAI,EACf,2CAAoB,EAClB,IAAK,EAAE,GAAI,EACX,KAAM,EAAE,GAAI,EACZ,UAAW,EAAE,GAAI,EACjB,MAAO,EAAE,IAAuB,EAChC,MAAO,EAAE,IAAK,EACd,SAAU,EAAE,KAAM,EGhDpB,mCAAsB,EHmDxB,YAAa,EACX,IAAK,EAAE,EAAG,EACV,MAAO,EAAE,GAAI,EACb,kBAAO,EACL,MAAO,EAAE,IAAK,EAClB,EAAG,EACD,IAAK,EAAE,GAAI,EACX,KAAM,EAAE,GAAI",
|
||||
"sources": ["../../../bower_components/wyrm/sass/wyrm_core/_mixin.sass","../../../bower_components/bourbon/dist/css3/_font-face.scss","../../../sass/_theme_badge_fa.sass","../../../sass/_theme_badge.sass","../../../bower_components/wyrm/sass/wyrm_core/_wy_variables.sass","../../../sass/_theme_variables.sass","../../../bower_components/neat/app/assets/stylesheets/grid/_media.scss"],
|
||||
"names": [],
|
||||
"file": "badge_only.css"
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
7
lib/spack/docs/_themes/sphinx_rtd_theme/static/css/theme.css.map
vendored
Normal file
7
lib/spack/docs/_themes/sphinx_rtd_theme/static/css/theme.css.map
vendored
Normal file
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/FontAwesome.otf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Inconsolata-Bold.ttf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Inconsolata.ttf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Lato-Bold.ttf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/Lato-Regular.ttf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Bold.ttf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/RobotoSlab-Regular.ttf
vendored
Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.eot
vendored
Normal file
Binary file not shown.
31
lib/spack/docs/_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.svg → lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
vendored
Executable file → Normal file
31
lib/spack/docs/_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.svg → lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.svg
vendored
Executable file → Normal file
@@ -280,8 +280,8 @@
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M640 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1280 320q0 -40 -12.5 -82t-43 -76t-72.5 -34t-72.5 34t-43 76t-12.5 82t12.5 82t43 76t72.5 34t72.5 -34t43 -76t12.5 -82zM1440 320 q0 120 -69 204t-187 84q-41 0 -195 -21q-71 -11 -157 -11t-157 11q-152 21 -195 21q-118 0 -187 -84t-69 -204q0 -88 32 -153.5t81 -103t122 -60t140 -29.5t149 -7h168q82 0 149 7t140 29.5t122 60t81 103t32 153.5zM1664 496q0 -207 -61 -331q-38 -77 -105.5 -133t-141 -86 t-170 -47.5t-171.5 -22t-167 -4.5q-78 0 -142 3t-147.5 12.5t-152.5 30t-137 51.5t-121 81t-86 115q-62 123 -62 331q0 237 136 396q-27 82 -27 170q0 116 51 218q108 0 190 -39.5t189 -123.5q147 35 309 35q148 0 280 -32q105 82 187 121t189 39q51 -102 51 -218 q0 -87 -27 -168q136 -160 136 -398z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1536 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68v-960q0 -40 28 -68t68 -28h1216q40 0 68 28t28 68zM1664 928v-704q0 -92 -66 -158t-158 -66h-1216q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320 q92 0 158 -66t66 -158v-32h672q92 0 158 -66t66 -158z" />
|
||||
<glyph unicode="" horiz-adv-x="1920" d="M1781 605q0 35 -53 35h-1088q-40 0 -85.5 -21.5t-71.5 -52.5l-294 -363q-18 -24 -18 -40q0 -35 53 -35h1088q40 0 86 22t71 53l294 363q18 22 18 39zM640 768h768v160q0 40 -28 68t-68 28h-576q-40 0 -68 28t-28 68v64q0 40 -28 68t-68 28h-320q-40 0 -68 -28t-28 -68 v-853l256 315q44 53 116 87.5t140 34.5zM1909 605q0 -62 -46 -120l-295 -363q-43 -53 -116 -87.5t-140 -34.5h-1088q-92 0 -158 66t-66 158v960q0 92 66 158t158 66h320q92 0 158 -66t66 -158v-32h544q92 0 158 -66t66 -158v-160h192q54 0 99 -24.5t67 -70.5q15 -32 15 -68z " />
|
||||
<glyph unicode="" horiz-adv-x="1152" d="M896 608v-64q0 -14 -9 -23t-23 -9h-224v-224q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v224h-224q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h224v224q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-224h224q14 0 23 -9t9 -23zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28 t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68zM1152 928v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704q93 0 158.5 -65.5t65.5 -158.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1152" d="M928 1152q93 0 158.5 -65.5t65.5 -158.5v-704q0 -92 -65.5 -158t-158.5 -66h-704q-93 0 -158.5 66t-65.5 158v704q0 93 65.5 158.5t158.5 65.5h704zM1024 224v704q0 40 -28 68t-68 28h-704q-40 0 -68 -28t-28 -68v-704q0 -40 28 -68t68 -28h704q40 0 68 28t28 68z M864 640q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-576q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h576z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" d="M1134 461q-37 -121 -138 -195t-228 -74t-228 74t-138 195q-8 25 4 48.5t38 31.5q25 8 48.5 -4t31.5 -38q25 -80 92.5 -129.5t151.5 -49.5t151.5 49.5t92.5 129.5q8 26 32 38t49 4t37 -31.5t4 -48.5zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5 t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5 t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M1134 307q8 -25 -4 -48.5t-37 -31.5t-49 4t-32 38q-25 80 -92.5 129.5t-151.5 49.5t-151.5 -49.5t-92.5 -129.5q-8 -26 -31.5 -38t-48.5 -4q-26 8 -38 31.5t-4 48.5q37 121 138 195t228 74t228 -74t138 -195zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204 t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M1152 448q0 -26 -19 -45t-45 -19h-640q-26 0 -45 19t-19 45t19 45t45 19h640q26 0 45 -19t19 -45zM640 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1152 896q0 -53 -37.5 -90.5t-90.5 -37.5t-90.5 37.5 t-37.5 90.5t37.5 90.5t90.5 37.5t90.5 -37.5t37.5 -90.5zM1408 640q0 130 -51 248.5t-136.5 204t-204 136.5t-248.5 51t-248.5 -51t-204 -136.5t-136.5 -204t-51 -248.5t51 -248.5t136.5 -204t204 -136.5t248.5 -51t248.5 51t204 136.5t136.5 204t51 248.5zM1536 640 q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
@@ -310,7 +310,7 @@
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M128 -128h1408v1024h-1408v-1024zM512 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1280 1088v288q0 14 -9 23t-23 9h-64q-14 0 -23 -9t-9 -23v-288q0 -14 9 -23t23 -9h64q14 0 23 9t9 23zM1664 1152v-1280 q0 -52 -38 -90t-90 -38h-1408q-52 0 -90 38t-38 90v1280q0 52 38 90t90 38h128v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h384v96q0 66 47 113t113 47h64q66 0 113 -47t47 -113v-96h128q52 0 90 -38t38 -90z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M512 1344q0 26 -19 45t-45 19t-45 -19t-19 -45t19 -45t45 -19t45 19t19 45zM1408 1376v-320q0 -16 -12 -25q-8 -7 -20 -7q-4 0 -7 1l-448 96q-11 2 -18 11t-7 20h-256v-102q111 -23 183.5 -111t72.5 -203v-800q0 -26 -19 -45t-45 -19h-512q-26 0 -45 19t-19 45v800 q0 106 62.5 190.5t161.5 114.5v111h-32q-59 0 -115 -23.5t-91.5 -53t-66 -66.5t-40.5 -53.5t-14 -24.5q-17 -35 -57 -35q-16 0 -29 7q-23 12 -31.5 37t3.5 49q5 10 14.5 26t37.5 53.5t60.5 70t85 67t108.5 52.5q-25 42 -25 86q0 66 47 113t113 47t113 -47t47 -113 q0 -33 -14 -64h302q0 11 7 20t18 11l448 96q3 1 7 1q12 0 20 -7q12 -9 12 -25z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1440 1088q0 40 -28 68t-68 28t-68 -28t-28 -68t28 -68t68 -28t68 28t28 68zM1664 1376q0 -249 -75.5 -430.5t-253.5 -360.5q-81 -80 -195 -176l-20 -379q-2 -16 -16 -26l-384 -224q-7 -4 -16 -4q-12 0 -23 9l-64 64q-13 14 -8 32l85 276l-281 281l-276 -85q-3 -1 -9 -1 q-14 0 -23 9l-64 64q-17 19 -5 39l224 384q10 14 26 16l379 20q96 114 176 195q188 187 358 258t431 71q14 0 24 -9.5t10 -22.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1708 881l-188 -881h-304l181 849q4 21 1 43q-4 20 -16 35q-10 14 -28 24q-18 9 -40 9h-197l-205 -960h-303l204 960h-304l-205 -960h-304l272 1280h1139q157 0 245 -118q86 -116 52 -281z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M1745 763l-164 -763h-334l178 832q13 56 -15 88q-27 33 -83 33h-169l-204 -953h-334l204 953h-286l-204 -953h-334l204 953l-153 327h1276q101 0 189.5 -40.5t147.5 -113.5q60 -73 81 -168.5t0 -194.5z" />
|
||||
<glyph unicode="" d="M909 141l102 102q19 19 19 45t-19 45l-307 307l307 307q19 19 19 45t-19 45l-102 102q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l454 -454q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M717 141l454 454q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-102 -102q-19 -19 -19 -45t19 -45l307 -307l-307 -307q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M1165 397l102 102q19 19 19 45t-19 45l-454 454q-19 19 -45 19t-45 -19l-454 -454q-19 -19 -19 -45t19 -45l102 -102q19 -19 45 -19t45 19l307 307l307 -307q19 -19 45 -19t45 19zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5 t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
@@ -342,7 +342,7 @@
|
||||
<glyph unicode="" horiz-adv-x="1024" d="M978 351q0 -153 -99.5 -263.5t-258.5 -136.5v-175q0 -14 -9 -23t-23 -9h-135q-13 0 -22.5 9.5t-9.5 22.5v175q-66 9 -127.5 31t-101.5 44.5t-74 48t-46.5 37.5t-17.5 18q-17 21 -2 41l103 135q7 10 23 12q15 2 24 -9l2 -2q113 -99 243 -125q37 -8 74 -8q81 0 142.5 43 t61.5 122q0 28 -15 53t-33.5 42t-58.5 37.5t-66 32t-80 32.5q-39 16 -61.5 25t-61.5 26.5t-62.5 31t-56.5 35.5t-53.5 42.5t-43.5 49t-35.5 58t-21 66.5t-8.5 78q0 138 98 242t255 134v180q0 13 9.5 22.5t22.5 9.5h135q14 0 23 -9t9 -23v-176q57 -6 110.5 -23t87 -33.5 t63.5 -37.5t39 -29t15 -14q17 -18 5 -38l-81 -146q-8 -15 -23 -16q-14 -3 -27 7q-3 3 -14.5 12t-39 26.5t-58.5 32t-74.5 26t-85.5 11.5q-95 0 -155 -43t-60 -111q0 -26 8.5 -48t29.5 -41.5t39.5 -33t56 -31t60.5 -27t70 -27.5q53 -20 81 -31.5t76 -35t75.5 -42.5t62 -50 t53 -63.5t31.5 -76.5t13 -94z" />
|
||||
<glyph unicode="" horiz-adv-x="898" d="M898 1066v-102q0 -14 -9 -23t-23 -9h-168q-23 -144 -129 -234t-276 -110q167 -178 459 -536q14 -16 4 -34q-8 -18 -29 -18h-195q-16 0 -25 12q-306 367 -498 571q-9 9 -9 22v127q0 13 9.5 22.5t22.5 9.5h112q132 0 212.5 43t102.5 125h-427q-14 0 -23 9t-9 23v102 q0 14 9 23t23 9h413q-57 113 -268 113h-145q-13 0 -22.5 9.5t-9.5 22.5v133q0 14 9 23t23 9h832q14 0 23 -9t9 -23v-102q0 -14 -9 -23t-23 -9h-233q47 -61 64 -144h171q14 0 23 -9t9 -23z" />
|
||||
<glyph unicode="" horiz-adv-x="1027" d="M603 0h-172q-13 0 -22.5 9t-9.5 23v330h-288q-13 0 -22.5 9t-9.5 23v103q0 13 9.5 22.5t22.5 9.5h288v85h-288q-13 0 -22.5 9t-9.5 23v104q0 13 9.5 22.5t22.5 9.5h214l-321 578q-8 16 0 32q10 16 28 16h194q19 0 29 -18l215 -425q19 -38 56 -125q10 24 30.5 68t27.5 61 l191 420q8 19 29 19h191q17 0 27 -16q9 -14 1 -31l-313 -579h215q13 0 22.5 -9.5t9.5 -22.5v-104q0 -14 -9.5 -23t-22.5 -9h-290v-85h290q13 0 22.5 -9.5t9.5 -22.5v-103q0 -14 -9.5 -23t-22.5 -9h-290v-330q0 -13 -9.5 -22.5t-22.5 -9.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1664 352v-32q0 -132 -94 -226t-226 -94h-128q-132 0 -226 94t-94 226v480h-224q-2 -102 -14.5 -190.5t-30.5 -156t-48.5 -126.5t-57 -99.5t-67.5 -77.5t-69.5 -58.5t-74 -44t-69 -32t-65.5 -25.5q-4 -2 -32 -13q-8 -2 -12 -2q-22 0 -30 20l-71 178q-5 13 0 25t17 17 q7 3 20 7.5t18 6.5q31 12 46.5 18.5t44.5 20t45.5 26t42 32.5t40.5 42.5t34.5 53.5t30.5 68.5t22.5 83.5t17 103t6.5 123h-256q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h1216q14 0 23 -9t9 -23v-160q0 -14 -9 -23t-23 -9h-224v-512q0 -26 19 -45t45 -19h128q26 0 45 19t19 45 v64q0 14 9 23t23 9h192q14 0 23 -9t9 -23zM1280 1376v-160q0 -14 -9 -23t-23 -9h-960q-14 0 -23 9t-9 23v160q0 14 9 23t23 9h960q14 0 23 -9t9 -23z" />
|
||||
<glyph unicode="" horiz-adv-x="1280" d="M1043 971q0 100 -65 162t-171 62h-320v-448h320q106 0 171 62t65 162zM1280 971q0 -193 -126.5 -315t-326.5 -122h-340v-118h505q14 0 23 -9t9 -23v-128q0 -14 -9 -23t-23 -9h-505v-192q0 -14 -9.5 -23t-22.5 -9h-167q-14 0 -23 9t-9 23v192h-224q-14 0 -23 9t-9 23v128 q0 14 9 23t23 9h224v118h-224q-14 0 -23 9t-9 23v149q0 13 9 22.5t23 9.5h224v629q0 14 9 23t23 9h539q200 0 326.5 -122t126.5 -315z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M514 341l81 299h-159l75 -300q1 -1 1 -3t1 -3q0 1 0.5 3.5t0.5 3.5zM630 768l35 128h-292l32 -128h225zM822 768h139l-35 128h-70zM1271 340l78 300h-162l81 -299q0 -1 0.5 -3.5t1.5 -3.5q0 1 0.5 3t0.5 3zM1382 768l33 128h-297l34 -128h230zM1792 736v-64q0 -14 -9 -23 t-23 -9h-213l-164 -616q-7 -24 -31 -24h-159q-24 0 -31 24l-166 616h-209l-167 -616q-7 -24 -31 -24h-159q-11 0 -19.5 7t-10.5 17l-160 616h-208q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h175l-33 128h-142q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h109l-89 344q-5 15 5 28 q10 12 26 12h137q26 0 31 -24l90 -360h359l97 360q7 24 31 24h126q24 0 31 -24l98 -360h365l93 360q5 24 31 24h137q16 0 26 -12q10 -13 5 -28l-91 -344h111q14 0 23 -9t9 -23v-64q0 -14 -9 -23t-23 -9h-145l-34 -128h179q14 0 23 -9t9 -23z" />
|
||||
<glyph unicode="" horiz-adv-x="1280" d="M1167 896q18 -182 -131 -258q117 -28 175 -103t45 -214q-7 -71 -32.5 -125t-64.5 -89t-97 -58.5t-121.5 -34.5t-145.5 -15v-255h-154v251q-80 0 -122 1v-252h-154v255q-18 0 -54 0.5t-55 0.5h-200l31 183h111q50 0 58 51v402h16q-6 1 -16 1v287q-13 68 -89 68h-111v164 l212 -1q64 0 97 1v252h154v-247q82 2 122 2v245h154v-252q79 -7 140 -22.5t113 -45t82.5 -78t36.5 -114.5zM952 351q0 36 -15 64t-37 46t-57.5 30.5t-65.5 18.5t-74 9t-69 3t-64.5 -1t-47.5 -1v-338q8 0 37 -0.5t48 -0.5t53 1.5t58.5 4t57 8.5t55.5 14t47.5 21t39.5 30 t24.5 40t9.5 51zM881 827q0 33 -12.5 58.5t-30.5 42t-48 28t-55 16.5t-61.5 8t-58 2.5t-54 -1t-39.5 -0.5v-307q5 0 34.5 -0.5t46.5 0t50 2t55 5.5t51.5 11t48.5 18.5t37 27t27 38.5t9 51z" />
|
||||
<glyph unicode="" horiz-adv-x="1280" d="M1280 768v-800q0 -40 -28 -68t-68 -28h-1088q-40 0 -68 28t-28 68v1344q0 40 28 68t68 28h544v-544q0 -40 28 -68t68 -28h544zM1277 896h-509v509q82 -15 132 -65l312 -312q50 -50 65 -132z" />
|
||||
@@ -390,10 +390,25 @@
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1632 576q0 -26 -19 -45t-45 -19h-224q0 -171 -67 -290l208 -209q19 -19 19 -45t-19 -45q-18 -19 -45 -19t-45 19l-198 197q-5 -5 -15 -13t-42 -28.5t-65 -36.5t-82 -29t-97 -13v896h-128v-896q-51 0 -101.5 13.5t-87 33t-66 39t-43.5 32.5l-15 14l-183 -207 q-20 -21 -48 -21q-24 0 -43 16q-19 18 -20.5 44.5t15.5 46.5l202 227q-58 114 -58 274h-224q-26 0 -45 19t-19 45t19 45t45 19h224v294l-173 173q-19 19 -19 45t19 45t45 19t45 -19l173 -173h844l173 173q19 19 45 19t45 -19t19 -45t-19 -45l-173 -173v-294h224q26 0 45 -19 t19 -45zM1152 1152h-640q0 133 93.5 226.5t226.5 93.5t226.5 -93.5t93.5 -226.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1920" d="M1917 1016q23 -64 -150 -294q-24 -32 -65 -85q-78 -100 -90 -131q-17 -41 14 -81q17 -21 81 -82h1l1 -1l1 -1l2 -2q141 -131 191 -221q3 -5 6.5 -12.5t7 -26.5t-0.5 -34t-25 -27.5t-59 -12.5l-256 -4q-24 -5 -56 5t-52 22l-20 12q-30 21 -70 64t-68.5 77.5t-61 58 t-56.5 15.5q-3 -1 -8 -3.5t-17 -14.5t-21.5 -29.5t-17 -52t-6.5 -77.5q0 -15 -3.5 -27.5t-7.5 -18.5l-4 -5q-18 -19 -53 -22h-115q-71 -4 -146 16.5t-131.5 53t-103 66t-70.5 57.5l-25 24q-10 10 -27.5 30t-71.5 91t-106 151t-122.5 211t-130.5 272q-6 16 -6 27t3 16l4 6 q15 19 57 19l274 2q12 -2 23 -6.5t16 -8.5l5 -3q16 -11 24 -32q20 -50 46 -103.5t41 -81.5l16 -29q29 -60 56 -104t48.5 -68.5t41.5 -38.5t34 -14t27 5q2 1 5 5t12 22t13.5 47t9.5 81t0 125q-2 40 -9 73t-14 46l-6 12q-25 34 -85 43q-13 2 5 24q17 19 38 30q53 26 239 24 q82 -1 135 -13q20 -5 33.5 -13.5t20.5 -24t10.5 -32t3.5 -45.5t-1 -55t-2.5 -70.5t-1.5 -82.5q0 -11 -1 -42t-0.5 -48t3.5 -40.5t11.5 -39t22.5 -24.5q8 -2 17 -4t26 11t38 34.5t52 67t68 107.5q60 104 107 225q4 10 10 17.5t11 10.5l4 3l5 2.5t13 3t20 0.5l288 2 q39 5 64 -2.5t31 -16.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" d="M675 252q21 34 11 69t-45 50q-34 14 -73 1t-60 -46q-22 -34 -13 -68.5t43 -50.5t74.5 -2.5t62.5 47.5zM769 373q8 13 3.5 26.5t-17.5 18.5q-14 5 -28.5 -0.5t-21.5 -18.5q-17 -31 13 -45q14 -5 29 0.5t22 18.5zM943 266q-45 -102 -158 -150t-224 -12 q-107 34 -147.5 126.5t6.5 187.5q47 93 151.5 139t210.5 19q111 -29 158.5 -119.5t2.5 -190.5zM1255 426q-9 96 -89 170t-208.5 109t-274.5 21q-223 -23 -369.5 -141.5t-132.5 -264.5q9 -96 89 -170t208.5 -109t274.5 -21q223 23 369.5 141.5t132.5 264.5zM1563 422 q0 -68 -37 -139.5t-109 -137t-168.5 -117.5t-226 -83t-270.5 -31t-275 33.5t-240.5 93t-171.5 151t-65 199.5q0 115 69.5 245t197.5 258q169 169 341.5 236t246.5 -7q65 -64 20 -209q-4 -14 -1 -20t10 -7t14.5 0.5t13.5 3.5l6 2q139 59 246 59t153 -61q45 -63 0 -178 q-2 -13 -4.5 -20t4.5 -12.5t12 -7.5t17 -6q57 -18 103 -47t80 -81.5t34 -116.5zM1489 1046q42 -47 54.5 -108.5t-6.5 -117.5q-8 -23 -29.5 -34t-44.5 -4q-23 8 -34 29.5t-4 44.5q20 63 -24 111t-107 35q-24 -5 -45 8t-25 37q-5 24 8 44.5t37 25.5q60 13 119 -5.5t101 -65.5z M1670 1209q87 -96 112.5 -222.5t-13.5 -241.5q-9 -27 -34 -40t-52 -4t-40 34t-5 52q28 82 10 172t-80 158q-62 69 -148 95.5t-173 8.5q-28 -6 -52 9.5t-30 43.5t9.5 51.5t43.5 29.5q123 26 244 -11.5t208 -134.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1920" d="M805 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM453 1176v-344q0 -179 -89.5 -326t-234.5 -217q-129 152 -129 351q0 200 129.5 352t323.5 184zM958 991q-128 -152 -128 -351q0 -201 128 -351q-145 70 -234.5 218t-89.5 328 v341q196 -33 324 -185zM1638 163q-122 -67 -261 -67q-141 0 -261 67q98 61 167 149t94 191q25 -103 94 -191t167 -149zM1286 1176v-344q0 -179 -91 -326t-237 -217v0q133 154 133 351q0 195 -133 351q129 151 328 185zM1920 640q0 -201 -129 -351q-145 70 -234.5 218 t-89.5 328v341q194 -32 323.5 -184t129.5 -352z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" d="M1133 -34q-171 -94 -368 -94q-196 0 -367 94q138 87 235.5 211t131.5 268q35 -144 132.5 -268t235.5 -211zM638 1394v-485q0 -252 -126.5 -459.5t-330.5 -306.5q-181 215 -181 495q0 187 83.5 349.5t229.5 269.5t325 137zM1536 638q0 -280 -181 -495 q-204 99 -330.5 306.5t-126.5 459.5v485q179 -30 325 -137t229.5 -269.5t83.5 -349.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M1402 433q-32 -80 -76 -138t-91 -88.5t-99 -46.5t-101.5 -14.5t-96.5 8.5t-86.5 22t-69.5 27.5t-46 22.5l-17 10q-113 -228 -289.5 -359.5t-384.5 -132.5q-19 0 -32 13t-13 32t13 31.5t32 12.5q173 1 322.5 107.5t251.5 294.5q-36 -14 -72 -23t-83 -13t-91 2.5t-93 28.5 t-92 59t-84.5 100t-74.5 146q114 47 214 57t167.5 -7.5t124.5 -56.5t88.5 -77t56.5 -82q53 131 79 291q-7 -1 -18 -2.5t-46.5 -2.5t-69.5 0.5t-81.5 10t-88.5 23t-84 42.5t-75 65t-54.5 94.5t-28.5 127.5q70 28 133.5 36.5t112.5 -1t92 -30t73.5 -50t56 -61t42 -63t27.5 -56 t16 -39.5l4 -16q12 122 12 195q-8 6 -21.5 16t-49 44.5t-63.5 71.5t-54 93t-33 112.5t12 127t70 138.5q73 -25 127.5 -61.5t84.5 -76.5t48 -85t20.5 -89t-0.5 -85.5t-13 -76.5t-19 -62t-17 -42l-7 -15q1 -5 1 -50.5t-1 -71.5q3 7 10 18.5t30.5 43t50.5 58t71 55.5t91.5 44.5 t112 14.5t132.5 -24q-2 -78 -21.5 -141.5t-50 -104.5t-69.5 -71.5t-81.5 -45.5t-84.5 -24t-80 -9.5t-67.5 1t-46.5 4.5l-17 3q-23 -147 -73 -283q6 7 18 18.5t49.5 41t77.5 52.5t99.5 42t117.5 20t129 -23.5t137 -77.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1280" d="M1259 283v-66q0 -85 -57.5 -144.5t-138.5 -59.5h-57l-260 -269v269h-529q-81 0 -138.5 59.5t-57.5 144.5v66h1238zM1259 609v-255h-1238v255h1238zM1259 937v-255h-1238v255h1238zM1259 1077v-67h-1238v67q0 84 57.5 143.5t138.5 59.5h846q81 0 138.5 -59.5t57.5 -143.5z " />
|
||||
<glyph unicode="" d="M1152 640q0 -14 -9 -23l-320 -320q-9 -9 -23 -9q-13 0 -22.5 9.5t-9.5 22.5v192h-352q-13 0 -22.5 9.5t-9.5 22.5v192q0 13 9.5 22.5t22.5 9.5h352v192q0 14 9 23t23 9q12 0 24 -10l319 -319q9 -9 9 -23zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M1152 736v-192q0 -13 -9.5 -22.5t-22.5 -9.5h-352v-192q0 -14 -9 -23t-23 -9q-12 0 -24 10l-319 319q-9 9 -9 23t9 23l320 320q9 9 23 9q13 0 22.5 -9.5t9.5 -22.5v-192h352q13 0 22.5 -9.5t9.5 -22.5zM1312 640q0 148 -73 273t-198 198t-273 73t-273 -73t-198 -198 t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273zM1536 640q0 -209 -103 -385.5t-279.5 -279.5t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" d="M1024 960v-640q0 -26 -19 -45t-45 -19q-20 0 -37 12l-448 320q-27 19 -27 52t27 52l448 320q17 12 37 12q26 0 45 -19t19 -45zM1280 160v960q0 13 -9.5 22.5t-22.5 9.5h-960q-13 0 -22.5 -9.5t-9.5 -22.5v-960q0 -13 9.5 -22.5t22.5 -9.5h960q13 0 22.5 9.5t9.5 22.5z M1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" d="M1024 640q0 -106 -75 -181t-181 -75t-181 75t-75 181t75 181t181 75t181 -75t75 -181zM768 1184q-148 0 -273 -73t-198 -198t-73 -273t73 -273t198 -198t273 -73t273 73t198 198t73 273t-73 273t-198 198t-273 73zM1536 640q0 -209 -103 -385.5t-279.5 -279.5 t-385.5 -103t-385.5 103t-279.5 279.5t-103 385.5t103 385.5t279.5 279.5t385.5 103t385.5 -103t279.5 -279.5t103 -385.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1664" d="M1023 349l102 -204q-58 -179 -210 -290t-339 -111q-156 0 -288.5 77.5t-210 210t-77.5 288.5q0 181 104.5 330t274.5 211l17 -131q-122 -54 -195 -165.5t-73 -244.5q0 -185 131.5 -316.5t316.5 -131.5q126 0 232.5 65t165 175.5t49.5 236.5zM1571 249l58 -114l-256 -128 q-13 -7 -29 -7q-40 0 -57 35l-239 477h-472q-24 0 -42.5 16.5t-21.5 40.5l-96 779q-2 16 6 42q14 51 57 82.5t97 31.5q66 0 113 -47t47 -113q0 -69 -52 -117.5t-120 -41.5l37 -289h423v-128h-407l16 -128h455q40 0 57 -35l228 -455z" />
|
||||
<glyph unicode="" d="M1254 899q16 85 -21 132q-52 65 -187 45q-17 -3 -41 -12.5t-57.5 -30.5t-64.5 -48.5t-59.5 -70t-44.5 -91.5q80 7 113.5 -16t26.5 -99q-5 -52 -52 -143q-43 -78 -71 -99q-44 -32 -87 14q-23 24 -37.5 64.5t-19 73t-10 84t-8.5 71.5q-23 129 -34 164q-12 37 -35.5 69 t-50.5 40q-57 16 -127 -25q-54 -32 -136.5 -106t-122.5 -102v-7q16 -8 25.5 -26t21.5 -20q21 -3 54.5 8.5t58 10.5t41.5 -30q11 -18 18.5 -38.5t15 -48t12.5 -40.5q17 -46 53 -187q36 -146 57 -197q42 -99 103 -125q43 -12 85 -1.5t76 31.5q131 77 250 237 q104 139 172.5 292.5t82.5 226.5zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1152" d="M1152 704q0 -191 -94.5 -353t-256.5 -256.5t-353 -94.5h-160q-14 0 -23 9t-9 23v611l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v93l-215 -66q-3 -1 -9 -1q-10 0 -19 6q-13 10 -13 26v128q0 23 23 31l233 71v250q0 14 9 23t23 9h160 q14 0 23 -9t9 -23v-181l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-93l375 116q15 5 28 -5t13 -26v-128q0 -23 -23 -31l-393 -121v-487q188 13 318 151t130 328q0 14 9 23t23 9h160q14 0 23 -9t9 -23z" />
|
||||
<glyph unicode="" horiz-adv-x="1408" d="M1152 736v-64q0 -14 -9 -23t-23 -9h-352v-352q0 -14 -9 -23t-23 -9h-64q-14 0 -23 9t-9 23v352h-352q-14 0 -23 9t-9 23v64q0 14 9 23t23 9h352v352q0 14 9 23t23 9h64q14 0 23 -9t9 -23v-352h352q14 0 23 -9t9 -23zM1280 288v832q0 66 -47 113t-113 47h-832 q-66 0 -113 -47t-47 -113v-832q0 -66 47 -113t113 -47h832q66 0 113 47t47 113zM1408 1120v-832q0 -119 -84.5 -203.5t-203.5 -84.5h-832q-119 0 -203.5 84.5t-84.5 203.5v832q0 119 84.5 203.5t203.5 84.5h832q119 0 203.5 -84.5t84.5 -203.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
<glyph unicode="" horiz-adv-x="1792" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 197 KiB |
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.ttf → lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
vendored
Executable file → Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/font/fontawesome_webfont.ttf → lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.ttf
vendored
Executable file → Normal file
Binary file not shown.
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
vendored
Normal file
BIN
lib/spack/docs/_themes/sphinx_rtd_theme/static/fonts/fontawesome-webfont.woff
vendored
Normal file
Binary file not shown.
4
lib/spack/docs/_themes/sphinx_rtd_theme/static/js/modernizr.min.js
vendored
Normal file
4
lib/spack/docs/_themes/sphinx_rtd_theme/static/js/modernizr.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -1,16 +1,113 @@
|
||||
$( document ).ready(function() {
|
||||
// Shift nav in mobile when clicking the menu.
|
||||
$("[data-toggle='wy-nav-top']").click(function() {
|
||||
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift");
|
||||
});
|
||||
// Close menu when you click a link.
|
||||
$(".wy-menu-vertical .current ul li a").click(function() {
|
||||
$("[data-toggle='wy-nav-shift']").removeClass("shift");
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift");
|
||||
});
|
||||
$("[data-toggle='rst-current-version']").click(function() {
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift-up");
|
||||
});
|
||||
$("table.docutils:not(.field-list").wrap("<div class='wy-table-responsive'></div>");
|
||||
function toggleCurrent (elem) {
|
||||
var parent_li = elem.closest('li');
|
||||
parent_li.siblings('li.current').removeClass('current');
|
||||
parent_li.siblings().find('li.current').removeClass('current');
|
||||
parent_li.find('> ul li.current').removeClass('current');
|
||||
parent_li.toggleClass('current');
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
// Shift nav in mobile when clicking the menu.
|
||||
$(document).on('click', "[data-toggle='wy-nav-top']", function() {
|
||||
$("[data-toggle='wy-nav-shift']").toggleClass("shift");
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift");
|
||||
});
|
||||
// Nav menu link click operations
|
||||
$(document).on('click', ".wy-menu-vertical .current ul li a", function() {
|
||||
var target = $(this);
|
||||
// Close menu when you click a link.
|
||||
$("[data-toggle='wy-nav-shift']").removeClass("shift");
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift");
|
||||
// Handle dynamic display of l3 and l4 nav lists
|
||||
toggleCurrent(target);
|
||||
if (typeof(window.SphinxRtdTheme) != 'undefined') {
|
||||
window.SphinxRtdTheme.StickyNav.hashChange();
|
||||
}
|
||||
});
|
||||
$(document).on('click', "[data-toggle='rst-current-version']", function() {
|
||||
$("[data-toggle='rst-versions']").toggleClass("shift-up");
|
||||
});
|
||||
// Make tables responsive
|
||||
$("table.docutils:not(.field-list)").wrap("<div class='wy-table-responsive'></div>");
|
||||
|
||||
// Add expand links to all parents of nested ul
|
||||
$('.wy-menu-vertical ul').siblings('a').each(function () {
|
||||
var link = $(this);
|
||||
expand = $('<span class="toctree-expand"></span>');
|
||||
expand.on('click', function (ev) {
|
||||
toggleCurrent(link);
|
||||
ev.stopPropagation();
|
||||
return false;
|
||||
});
|
||||
link.prepend(expand);
|
||||
});
|
||||
});
|
||||
|
||||
// Sphinx theme state
|
||||
window.SphinxRtdTheme = (function (jquery) {
|
||||
var stickyNav = (function () {
|
||||
var navBar,
|
||||
win,
|
||||
winScroll = false,
|
||||
linkScroll = false,
|
||||
winPosition = 0,
|
||||
enable = function () {
|
||||
init();
|
||||
reset();
|
||||
win.on('hashchange', reset);
|
||||
|
||||
// Set scrolling
|
||||
win.on('scroll', function () {
|
||||
if (!linkScroll) {
|
||||
winScroll = true;
|
||||
}
|
||||
});
|
||||
setInterval(function () {
|
||||
if (winScroll) {
|
||||
winScroll = false;
|
||||
var newWinPosition = win.scrollTop(),
|
||||
navPosition = navBar.scrollTop(),
|
||||
newNavPosition = navPosition + (newWinPosition - winPosition);
|
||||
navBar.scrollTop(newNavPosition);
|
||||
winPosition = newWinPosition;
|
||||
}
|
||||
}, 25);
|
||||
},
|
||||
init = function () {
|
||||
navBar = jquery('nav.wy-nav-side:first');
|
||||
win = jquery(window);
|
||||
},
|
||||
reset = function () {
|
||||
// Get anchor from URL and open up nested nav
|
||||
var anchor = encodeURI(window.location.hash);
|
||||
if (anchor) {
|
||||
try {
|
||||
var link = $('.wy-menu-vertical')
|
||||
.find('[href="' + anchor + '"]');
|
||||
$('.wy-menu-vertical li.toctree-l1 li.current')
|
||||
.removeClass('current');
|
||||
link.closest('li.toctree-l2').addClass('current');
|
||||
link.closest('li.toctree-l3').addClass('current');
|
||||
link.closest('li.toctree-l4').addClass('current');
|
||||
}
|
||||
catch (err) {
|
||||
console.log("Error expanding nav for anchor", err);
|
||||
}
|
||||
}
|
||||
},
|
||||
hashChange = function () {
|
||||
linkScroll = true;
|
||||
win.one('hashchange', function () {
|
||||
linkScroll = false;
|
||||
});
|
||||
};
|
||||
jquery(init);
|
||||
return {
|
||||
enable: enable,
|
||||
hashChange: hashChange
|
||||
};
|
||||
}());
|
||||
return {
|
||||
StickyNav: stickyNav
|
||||
};
|
||||
}($));
|
||||
|
||||
@@ -5,3 +5,5 @@ stylesheet = css/theme.css
|
||||
[options]
|
||||
typekit_id = hiw1hhg
|
||||
analytics_id =
|
||||
sticky_navigation = False
|
||||
logo_only =
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{% if READTHEDOCS %}
|
||||
{# Add rst-badge after rst-versions for small badge style. #}
|
||||
<div class="rst-versions" data-toggle="rst-versions">
|
||||
<div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="versions">
|
||||
<span class="rst-current-version" data-toggle="rst-current-version">
|
||||
<span class="icon icon-book"> Read the Docs</span>
|
||||
v: {{ current_version }}
|
||||
<span class="icon icon-caret-down"></span>
|
||||
<span class="fa fa-book"> Read the Docs</span>
|
||||
v: {{ current_version }}
|
||||
<span class="fa fa-caret-down"></span>
|
||||
</span>
|
||||
<div class="rst-other-versions">
|
||||
<dl>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
167
lib/spack/docs/case_studies.rst
Normal file
167
lib/spack/docs/case_studies.rst
Normal file
@@ -0,0 +1,167 @@
|
||||
Using Spack for CMake-based Development
|
||||
==========================================
|
||||
|
||||
These are instructions on how to use Spack to aid in the development
|
||||
of a CMake-based project. Spack is used to help find the dependencies
|
||||
for the project, configure it at development time, and then package it
|
||||
it in a way that others can install. Using Spack for CMake-based
|
||||
development consists of three parts:
|
||||
|
||||
1. Setting up the CMake build in your software
|
||||
2. Writing the Spack Package
|
||||
3. Using it from Spack.
|
||||
|
||||
|
||||
Setting Up the CMake Build
|
||||
---------------------------------------
|
||||
|
||||
You should follow standard CMake conventions in setting up your
|
||||
software, your CMake build should NOT depend on or require Spack to
|
||||
build. See here for an example:
|
||||
https://github.com/citibeth/icebin
|
||||
|
||||
Note that there's one exception here to the rule I mentioned above.
|
||||
In ``CMakeLists.txt``, I have the following line::
|
||||
|
||||
include_directories($ENV{CMAKE_TRANSITIVE_INCLUDE_PATH})
|
||||
|
||||
|
||||
This is a hook into Spack, and it ensures that all transitive
|
||||
dependencies are included in the include path. It's not needed if
|
||||
everything is in one tree, but it is (sometimes) in the Spack world;
|
||||
when running without Spack, it has no effect.
|
||||
|
||||
Note that this "feature" is controversial, could break with future
|
||||
versions of GNU ld, and probably not the best to use. The best
|
||||
practice is that you make sure that anything you #include is listed as
|
||||
a dependency in your CMakeLists.txt.
|
||||
|
||||
To be more specific: if you #inlcude something from package A and an
|
||||
installed HEADER FILE in A #includes something from package B, then
|
||||
you should also list B as a dependency in your CMake build. If you
|
||||
depend on A but header files exported by A do NOT #include things from
|
||||
B, then you do NOT need to list B as a dependency --- even if linking
|
||||
to A links in libB.so as well.
|
||||
|
||||
I also recommend that you set up your CMake build to use RPATHs
|
||||
correctly. Not only is this a good idea and nice, but it also ensures
|
||||
that your package will build the same with or without ``spack
|
||||
install``.
|
||||
|
||||
Writing the Spack Package
|
||||
---------------------------------------
|
||||
|
||||
Now that you have a CMake build, you want to tell Spack how to
|
||||
configure it. This is done by writing a Spack package for your
|
||||
software. See here for example:
|
||||
https://github.com/citibeth/spack/blob/efischer/develop/var/spack/repos/builtin/packages/icebin/package.py
|
||||
|
||||
You need to subclass ``CMakePackage``, as is done in this example.
|
||||
This enables advanced features of Spack for helping you in configuring
|
||||
your software (keep reading...). Instead of an ``install()`` method
|
||||
used when subclassing ``Package``, you write ``configure_args()``.
|
||||
See here for more info on how this works:
|
||||
https://github.com/LLNL/spack/pull/543/files
|
||||
|
||||
NOTE: if your software is not publicly available, you do not need to
|
||||
set the URL or version. Or you can set up bogus URLs and
|
||||
versions... whatever causes Spack to not crash.
|
||||
|
||||
|
||||
Using it from Spack
|
||||
--------------------------------
|
||||
|
||||
Now that you have a Spack package, you can get Spack to setup your
|
||||
CMake project for you. Use the following to setup, configure and
|
||||
build your project::
|
||||
|
||||
cd myproject
|
||||
spack spconfig myproject@local
|
||||
mkdir build; cd build
|
||||
../spconfig.py ..
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
Everything here should look pretty familiar here from a CMake
|
||||
perspective, except that ``spack spconfig`` creates the file
|
||||
``spconfig.py``, which calls CMake with arguments appropriate for your
|
||||
Spack configuration. Think of it as the equivalent to running a bunch
|
||||
of ``spack location -i`` commands. You will run ``spconfig.py``
|
||||
instead of running CMake directly.
|
||||
|
||||
If your project is publicly available (eg on GitHub), then you can
|
||||
ALSO use this setup to "just install" a release version without going
|
||||
through the manual configuration/build step. Just do:
|
||||
|
||||
1. Put tag(s) on the version(s) in your GitHub repo you want to be release versions.
|
||||
|
||||
2. Set the ``url`` in your ``package.py`` to download a tarball for
|
||||
the appropriate version. (GitHub will give you a tarball for any
|
||||
version in the repo, if you tickle it the right way). For example::
|
||||
|
||||
https://github.com/citibeth/icebin/tarball/v0.1.0
|
||||
|
||||
Set up versions as appropriate in your ``package.py``. (Manually
|
||||
download the tarball and run ``md5sum`` to determine the
|
||||
appropriate checksum for it).
|
||||
|
||||
3. Now you should be able to say ``spack install myproject@version``
|
||||
and things "just work."
|
||||
|
||||
NOTE... in order to use the features outlined in this post, you
|
||||
currently need to use the following branch of Spack:
|
||||
https://github.com/citibeth/spack/tree/efischer/develop
|
||||
|
||||
There is a pull request open on this branch (
|
||||
https://github.com/LLNL/spack/pull/543 ) and we are working to get it
|
||||
integrated into the main ``develop`` branch.
|
||||
|
||||
|
||||
Activating your Software
|
||||
-------------------------------------
|
||||
|
||||
Once you've built your software, you will want to load it up. You can
|
||||
use ``spack load mypackage@local`` for that in your ``.bashrc``, but
|
||||
that is slow. Try stuff like the following instead:
|
||||
|
||||
The following command will load the Spack-installed packages needed
|
||||
for basic Python use of IceBin::
|
||||
|
||||
module load `spack module find tcl icebin netcdf cmake@3.5.1`
|
||||
module load `spack module find --dependencies tcl py-basemap py-giss`
|
||||
|
||||
|
||||
You can speed up shell startup by turning these into ``module load`` commands.
|
||||
|
||||
1. Cut-n-paste the script ``make_spackenv``::
|
||||
|
||||
#!/bin/sh
|
||||
#
|
||||
# Generate commands to load the Spack environment
|
||||
|
||||
SPACKENV=$HOME/spackenv.sh
|
||||
|
||||
spack module find --shell tcl git icebin@local ibmisc netcdf cmake@3.5.1 >$SPACKENV
|
||||
spack module find --dependencies --shell tcl py-basemap py-giss >>$SPACKENV
|
||||
|
||||
2. Add the following to your ``.bashrc`` file::
|
||||
|
||||
source $HOME/spackenv.sh
|
||||
# Preferentially use your checked-out Python source
|
||||
export PYTHONPATH=$HOME/icebin/pylib:$PYTHONPATH
|
||||
|
||||
3. Run ``sh make_spackenv`` whenever your Spack installation changes (including right now).
|
||||
|
||||
|
||||
Giving Back
|
||||
-------------------
|
||||
|
||||
If your software is publicly available, you should submit the
|
||||
``package.py`` for it as a pull request to the main Spack GitHub
|
||||
project. This will ensure that anyone can install your software
|
||||
(almost) painlessly with a simple ``spack install`` command. See here
|
||||
for how that has turned into detailed instructions that have
|
||||
successfully enabled collaborators to install complex software:
|
||||
|
||||
https://github.com/citibeth/icebin/blob/develop/README.rst
|
||||
@@ -6,7 +6,7 @@
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -43,6 +43,7 @@
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
sys.path.insert(0, os.path.abspath('exts'))
|
||||
sys.path.insert(0, os.path.abspath('../external'))
|
||||
|
||||
# Add the Spack bin directory to the path so that we can use its output in docs.
|
||||
spack_root = '../../..'
|
||||
@@ -50,7 +51,8 @@
|
||||
os.environ['PATH'] += os.pathsep + '$SPACK_ROOT/bin'
|
||||
|
||||
spack_version = subprocess.Popen(
|
||||
['spack', '-V'], stderr=subprocess.PIPE).communicate()[1].strip().split('.')
|
||||
[spack_root + '/bin/spack', '-V'],
|
||||
stderr=subprocess.PIPE).communicate()[1].strip().split('.')
|
||||
|
||||
# Set an environment variable so that colify will print output like it would to
|
||||
# a terminal.
|
||||
@@ -87,14 +89,14 @@
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'Spack'
|
||||
copyright = u'2013-2014, Lawrence Livermore National Laboratory'
|
||||
copyright = u'2013-2015, Lawrence Livermore National Laboratory.'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@@ -149,7 +151,7 @@
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#html_theme_options = []
|
||||
html_theme_options = { 'logo_only' : True }
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
html_theme_path = ["_themes"]
|
||||
@@ -163,12 +165,12 @@
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
html_logo = '../../../share/spack/logo/spack-logo-white-text-48.png'
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
html_favicon = '../../../share/spack/logo/favicon.ico'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
@@ -203,7 +205,7 @@
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
#html_show_sphinx = False
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
236
lib/spack/docs/configuration.rst
Normal file
236
lib/spack/docs/configuration.rst
Normal file
@@ -0,0 +1,236 @@
|
||||
.. _configuration:
|
||||
|
||||
Configuration
|
||||
===================================
|
||||
|
||||
.. _temp-space:
|
||||
|
||||
Temporary space
|
||||
----------------------------
|
||||
|
||||
.. warning:: Temporary space configuration will eventually be moved to
|
||||
configuration files, but currently these settings are in
|
||||
``lib/spack/spack/__init__.py``
|
||||
|
||||
By default, Spack will try to do all of its building in temporary
|
||||
space. There are two main reasons for this. First, Spack is designed
|
||||
to run out of a user's home directory, and on may systems the home
|
||||
directory is network mounted and potentially not a very fast
|
||||
filesystem. We create build stages in a temporary directory to avoid
|
||||
this. Second, many systems impose quotas on home directories, and
|
||||
``/tmp`` or similar directories often have more available space. This
|
||||
helps conserve space for installations in users' home directories.
|
||||
|
||||
You can customize temporary directories by editing
|
||||
``lib/spack/spack/__init__.py``. Specifically, find this part of the file:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Whether to build in tmp space or directly in the stage_path.
|
||||
# If this is true, then spack will make stage directories in
|
||||
# a tmp filesystem, and it will symlink them into stage_path.
|
||||
use_tmp_stage = True
|
||||
|
||||
# Locations to use for staging and building, in order of preference
|
||||
# Use a %u to add a username to the stage paths here, in case this
|
||||
# is a shared filesystem. Spack will use the first of these paths
|
||||
# that it can create.
|
||||
tmp_dirs = ['/nfs/tmp2/%u/spack-stage',
|
||||
'/var/tmp/%u/spack-stage',
|
||||
'/tmp/%u/spack-stage']
|
||||
|
||||
The ``use_tmp_stage`` variable controls whether Spack builds
|
||||
**directly** inside the ``var/spack/`` directory. Normally, Spack
|
||||
will try to find a temporary directory for a build, then it *symlinks*
|
||||
that temporary directory into ``var/spack/`` so that you can keep
|
||||
track of what temporary directories Spack is using.
|
||||
|
||||
The ``tmp_dirs`` variable is a list of paths Spack should search when
|
||||
trying to find a temporary directory. They can optionally contain a
|
||||
``%u``, which will substitute the current user's name into the path.
|
||||
The list is searched in order, and Spack will create a temporary stage
|
||||
in the first directory it finds to which it has write access. Add
|
||||
more elements to the list to indicate where your own site's temporary
|
||||
directory is.
|
||||
|
||||
.. _sec-external_packages:
|
||||
|
||||
External Packages
|
||||
----------------------------
|
||||
Spack can be configured to use externally-installed
|
||||
packages rather than building its own packages. This may be desirable
|
||||
if machines ship with system packages, such as a customized MPI
|
||||
that should be used instead of Spack building its own MPI.
|
||||
|
||||
External packages are configured through the ``packages.yaml`` file found
|
||||
in a Spack installation's ``etc/spack/`` or a user's ``~/.spack/``
|
||||
directory. Here's an example of an external configuration:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
openmpi:
|
||||
paths:
|
||||
openmpi@1.4.3%gcc@4.4.7 arch=linux-x86_64-debian7: /opt/openmpi-1.4.3
|
||||
openmpi@1.4.3%gcc@4.4.7 arch=linux-x86_64-debian7+debug: /opt/openmpi-1.4.3-debug
|
||||
openmpi@1.6.5%intel@10.1 arch=linux-x86_64-debian7: /opt/openmpi-1.6.5-intel
|
||||
|
||||
This example lists three installations of OpenMPI, one built with gcc,
|
||||
one built with gcc and debug information, and another built with Intel.
|
||||
If Spack is asked to build a package that uses one of these MPIs as a
|
||||
dependency, it will use the the pre-installed OpenMPI in
|
||||
the given directory. Packages.yaml can also be used to specify modules
|
||||
|
||||
Each ``packages.yaml`` begins with a ``packages:`` token, followed
|
||||
by a list of package names. To specify externals, add a ``paths`` or ``modules``
|
||||
token under the package name, which lists externals in a
|
||||
``spec: /path`` or ``spec: module-name`` format. Each spec should be as
|
||||
well-defined as reasonably possible. If a
|
||||
package lacks a spec component, such as missing a compiler or
|
||||
package version, then Spack will guess the missing component based
|
||||
on its most-favored packages, and it may guess incorrectly.
|
||||
|
||||
Each package version and compilers listed in an external should
|
||||
have entries in Spack's packages and compiler configuration, even
|
||||
though the package and compiler may not every be built.
|
||||
|
||||
The packages configuration can tell Spack to use an external location
|
||||
for certain package versions, but it does not restrict Spack to using
|
||||
external packages. In the above example, if an OpenMPI 1.8.4 became
|
||||
available Spack may choose to start building and linking with that version
|
||||
rather than continue using the pre-installed OpenMPI versions.
|
||||
|
||||
To prevent this, the ``packages.yaml`` configuration also allows packages
|
||||
to be flagged as non-buildable. The previous example could be modified to
|
||||
be:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
openmpi:
|
||||
paths:
|
||||
openmpi@1.4.3%gcc@4.4.7 arch=linux-x86_64-debian7: /opt/openmpi-1.4.3
|
||||
openmpi@1.4.3%gcc@4.4.7 arch=linux-x86_64-debian7+debug: /opt/openmpi-1.4.3-debug
|
||||
openmpi@1.6.5%intel@10.1 arch=linux-x86_64-debian7: /opt/openmpi-1.6.5-intel
|
||||
buildable: False
|
||||
|
||||
The addition of the ``buildable`` flag tells Spack that it should never build
|
||||
its own version of OpenMPI, and it will instead always rely on a pre-built
|
||||
OpenMPI. Similar to ``paths``, ``buildable`` is specified as a property under
|
||||
a package name.
|
||||
|
||||
If an external module is specified as not buildable, then Spack will load the
|
||||
external module into the build environment which can be used for linking.
|
||||
|
||||
The ``buildable`` does not need to be paired with external packages.
|
||||
It could also be used alone to forbid packages that may be
|
||||
buggy or otherwise undesirable.
|
||||
|
||||
|
||||
Concretization Preferences
|
||||
--------------------------------
|
||||
|
||||
Spack can be configured to prefer certain compilers, package
|
||||
versions, depends_on, and variants during concretization.
|
||||
The preferred configuration can be controlled via the
|
||||
``~/.spack/packages.yaml`` file for user configuations, or the
|
||||
``etc/spack/packages.yaml`` site configuration.
|
||||
|
||||
|
||||
Here's an example packages.yaml file that sets preferred packages:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
packages:
|
||||
opencv:
|
||||
compiler: [gcc@4.9]
|
||||
variants: +debug
|
||||
gperftools:
|
||||
version: [2.2, 2.4, 2.3]
|
||||
all:
|
||||
compiler: [gcc@4.4.7, gcc@4.6:, intel, clang, pgi]
|
||||
providers:
|
||||
mpi: [mvapich, mpich, openmpi]
|
||||
|
||||
|
||||
At a high level, this example is specifying how packages should be
|
||||
concretized. The opencv package should prefer using gcc 4.9 and
|
||||
be built with debug options. The gperftools package should prefer version
|
||||
2.2 over 2.4. Every package on the system should prefer mvapich for
|
||||
its MPI and gcc 4.4.7 (except for opencv, which overrides this by preferring gcc 4.9).
|
||||
These options are used to fill in implicit defaults. Any of them can be overwritten
|
||||
on the command line if explicitly requested.
|
||||
|
||||
Each packages.yaml file begins with the string ``packages:`` and
|
||||
package names are specified on the next level. The special string ``all``
|
||||
applies settings to each package. Underneath each package name is
|
||||
one or more components: ``compiler``, ``variants``, ``version``,
|
||||
or ``providers``. Each component has an ordered list of spec
|
||||
``constraints``, with earlier entries in the list being preferred over
|
||||
later entries.
|
||||
|
||||
Sometimes a package installation may have constraints that forbid
|
||||
the first concretization rule, in which case Spack will use the first
|
||||
legal concretization rule. Going back to the example, if a user
|
||||
requests gperftools 2.3 or later, then Spack will install version 2.4
|
||||
as the 2.4 version of gperftools is preferred over 2.3.
|
||||
|
||||
An explicit concretization rule in the preferred section will always
|
||||
take preference over unlisted concretizations. In the above example,
|
||||
xlc isn't listed in the compiler list. Every listed compiler from
|
||||
gcc to pgi will thus be preferred over the xlc compiler.
|
||||
|
||||
The syntax for the ``provider`` section differs slightly from other
|
||||
concretization rules. A provider lists a value that packages may
|
||||
``depend_on`` (e.g, mpi) and a list of rules for fulfilling that
|
||||
dependency.
|
||||
|
||||
|
||||
Profiling
|
||||
------------------
|
||||
|
||||
Spack has some limited built-in support for profiling, and can report
|
||||
statistics using standard Python timing tools. To use this feature,
|
||||
supply ``-p`` to Spack on the command line, before any subcommands.
|
||||
|
||||
.. _spack-p:
|
||||
|
||||
``spack -p``
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
``spack -p`` output looks like this:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack -p graph dyninst
|
||||
o dyninst
|
||||
|\
|
||||
| |\
|
||||
| o | libdwarf
|
||||
|/ /
|
||||
o | libelf
|
||||
/
|
||||
o boost
|
||||
|
||||
307670 function calls (305943 primitive calls) in 0.127 seconds
|
||||
|
||||
Ordered by: internal time
|
||||
|
||||
ncalls tottime percall cumtime percall filename:lineno(function)
|
||||
853 0.021 0.000 0.066 0.000 inspect.py:472(getmodule)
|
||||
51197 0.011 0.000 0.018 0.000 inspect.py:51(ismodule)
|
||||
73961 0.010 0.000 0.010 0.000 {isinstance}
|
||||
1762 0.006 0.000 0.053 0.000 inspect.py:440(getsourcefile)
|
||||
32075 0.006 0.000 0.006 0.000 {hasattr}
|
||||
1760 0.004 0.000 0.004 0.000 {posix.stat}
|
||||
2240 0.004 0.000 0.004 0.000 {posix.lstat}
|
||||
2602 0.004 0.000 0.011 0.000 inspect.py:398(getfile)
|
||||
771 0.004 0.000 0.077 0.000 inspect.py:518(findsource)
|
||||
2656 0.004 0.000 0.004 0.000 {method 'match' of '_sre.SRE_Pattern' objects}
|
||||
30772 0.003 0.000 0.003 0.000 {method 'get' of 'dict' objects}
|
||||
...
|
||||
|
||||
The bottom of the output shows the top most time consuming functions,
|
||||
slowest on top. The profiling support is from Python's built-in tool,
|
||||
`cProfile
|
||||
<https://docs.python.org/2/library/profile.html#module-cProfile>`_.
|
||||
@@ -73,19 +73,33 @@ with a high level view of Spack's directory structure::
|
||||
spack/ <- installation root
|
||||
bin/
|
||||
spack <- main spack executable
|
||||
|
||||
etc/
|
||||
spack/ <- Spack config files.
|
||||
Can be overridden by files in ~/.spack.
|
||||
|
||||
var/
|
||||
spack/ <- build & stage directories
|
||||
repos/ <- contains package repositories
|
||||
builtin/ <- pkg repository that comes with Spack
|
||||
repo.yaml <- descriptor for the builtin repository
|
||||
packages/ <- directories under here contain packages
|
||||
cache/ <- saves resources downloaded during installs
|
||||
|
||||
opt/
|
||||
spack/ <- packages are installed here
|
||||
|
||||
lib/
|
||||
spack/
|
||||
docs/ <- source for this documentation
|
||||
env/ <- compiler wrappers for build environment
|
||||
|
||||
external/ <- external libs included in Spack distro
|
||||
llnl/ <- some general-use libraries
|
||||
|
||||
spack/ <- spack module; contains Python code
|
||||
cmd/ <- each file in here is a spack subcommand
|
||||
compilers/ <- compiler description files
|
||||
packages/ <- each file in here is a spack package
|
||||
test/ <- unit test modules
|
||||
util/ <- common code
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
|
||||
@@ -31,14 +31,21 @@ platform, all on the command line.
|
||||
# Specify a compiler (and its version), with %
|
||||
$ spack install mpileaks@1.1.2 %gcc@4.7.3
|
||||
|
||||
# Add special compile-time options with +
|
||||
# Add special compile-time options by name
|
||||
$ spack install mpileaks@1.1.2 %gcc@4.7.3 debug=True
|
||||
|
||||
# Add special boolean compile-time options with +
|
||||
$ spack install mpileaks@1.1.2 %gcc@4.7.3 +debug
|
||||
|
||||
# Cross-compile for a different architecture with =
|
||||
$ spack install mpileaks@1.1.2 =bgqos_0
|
||||
# Add compiler flags using the conventional names
|
||||
$ spack install mpileaks@1.1.2 %gcc@4.7.3 cppflags=\"-O3 -floop-block\"
|
||||
|
||||
Users can specify as many or few options as they care about. Spack
|
||||
will fill in the unspecified values with sensible defaults.
|
||||
# Cross-compile for a different architecture with arch=
|
||||
$ spack install mpileaks@1.1.2 arch=bgqos_0
|
||||
|
||||
Users can specify as many or few options as they care about. Spack
|
||||
will fill in the unspecified values with sensible defaults. The two listed
|
||||
syntaxes for variants are identical when the value is boolean.
|
||||
|
||||
|
||||
Customize dependencies
|
||||
@@ -103,7 +110,7 @@ creates a simple python file:
|
||||
It doesn't take much python coding to get from there to a working
|
||||
package:
|
||||
|
||||
.. literalinclude:: ../../../var/spack/packages/libelf/package.py
|
||||
.. literalinclude:: ../../../var/spack/repos/builtin/packages/libelf/package.py
|
||||
:lines: 25-
|
||||
|
||||
Spack also provides wrapper functions around common commands like
|
||||
|
||||
@@ -1,35 +1,98 @@
|
||||
Getting Started
|
||||
====================
|
||||
|
||||
Download
|
||||
Prerequisites
|
||||
---------------
|
||||
|
||||
Spack has the following minimum requirements, which must be installed
|
||||
before Spack is run:
|
||||
|
||||
1. Operating System: GNU/Linux or Macintosh
|
||||
2. Python 2.6 or 2.7
|
||||
3. A C/C++ compiler
|
||||
|
||||
These requirements can be easily installed on most modern Linux
|
||||
systems; on Macintosh, XCode is required.
|
||||
|
||||
|
||||
Installation
|
||||
--------------------
|
||||
|
||||
Getting spack is easy. You can clone it from the `github repository
|
||||
<https://github.com/scalability-llnl/spack>`_ using this command:
|
||||
<https://github.com/llnl/spack>`_ using this command:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ git clone https://github.com/scalability-llnl/spack.git
|
||||
$ git clone https://github.com/llnl/spack.git
|
||||
|
||||
This will create a directory called ``spack``. We'll assume that the
|
||||
full path to this directory is in some environment called
|
||||
``SPACK_HOME``. Add ``$SPACK_HOME/bin`` to your path and you're ready
|
||||
to go:
|
||||
This will create a directory called ``spack``. If you are using Spack
|
||||
for a specific purpose, you might have received different instructions
|
||||
on how to download Spack; if so, please follow those instructions.
|
||||
|
||||
Add Spack to Shell
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We'll assume that the full path to your downloaded Spack directory is
|
||||
in the ``SPACK_ROOT`` environment variable. Add ``$SPACK_ROOT/bin``
|
||||
to your path and you're ready to go:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ export PATH=spack/bin:$PATH
|
||||
$ export PATH=$SPACK_ROOT/bin:$PATH
|
||||
$ spack install libelf
|
||||
|
||||
In general, most of your interactions with Spack will be through the
|
||||
``spack`` command.
|
||||
For a richer experience, use Spack's `shell support
|
||||
<http://software.llnl.gov/spack/basic_usage.html#environment-modules>`_:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# For bash users
|
||||
$ . $SPACK_ROOT/share/spack/setup-env.sh
|
||||
|
||||
# For tcsh or csh users (note you must set SPACK_ROOT)
|
||||
$ setenv SPACK_ROOT /path/to/spack
|
||||
$ source $SPACK_ROOT/share/spack/setup-env.csh
|
||||
|
||||
This automatically adds Spack to your ``PATH``.
|
||||
|
||||
Clean Environment
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Many packages' installs can be broken by changing environment
|
||||
variables. For example, a packge might pick up the wrong build-time
|
||||
dependencies (most of them not specified) depending on the setting of
|
||||
``PATH``. ``GCC`` seems to be particularly vulnerable to these issues.
|
||||
|
||||
Therefore, it is recommended that Spack users run with a *clean
|
||||
environment*, especially for ``PATH``. Only software that comes with
|
||||
the system, or that you know you wish to use with Spack, should be
|
||||
included. This procedure will avoid many strange build errors that no
|
||||
one knows how to fix.
|
||||
|
||||
|
||||
Install
|
||||
--------------------
|
||||
Although Spack will work as soon as you clone it, it won't necessarily
|
||||
be able to install any packages. That is because Spack relies
|
||||
|
||||
You don't need to install Spack; it's ready to run as soon as you
|
||||
clone it from git.
|
||||
Check Installation
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
With Spack installed, you should be able to run some basic Spack commands. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack spec netcdf
|
||||
...
|
||||
netcdf@4.4.1%gcc@5.3.0~hdf4+mpi arch=linux-SuSE11-x86_64
|
||||
^curl@7.50.1%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^openssl@system%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^hdf5@1.10.0-patch1%gcc@5.3.0+cxx~debug+fortran+mpi+shared~szip~threadsafe arch=linux-SuSE11-x86_64
|
||||
^openmpi@1.10.1%gcc@5.3.0~mxm~pmi~psm~psm2~slurm~sqlite3~thread_multiple~tm+verbs+vt arch=linux-SuSE11-x86_64
|
||||
^m4@1.4.17%gcc@5.3.0+sigsegv arch=linux-SuSE11-x86_64
|
||||
^libsigsegv@2.10%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
|
||||
Optional: Alternate Prefix
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You may want to run it out of a prefix other than the git repository
|
||||
you cloned. The ``spack bootstrap`` command provides this
|
||||
@@ -39,6 +102,675 @@ functionality. To install spack in a new directory, simply type:
|
||||
|
||||
$ spack bootstrap /my/favorite/prefix
|
||||
|
||||
This will install a new spack script in /my/favorite/prefix/bin, which
|
||||
you can use just like you would the regular spack script. Each copy
|
||||
of spack installs packages into its own ``$PREFIX/opt`` directory.
|
||||
This will install a new spack script in ``/my/favorite/prefix/bin``,
|
||||
which you can use just like you would the regular spack script. Each
|
||||
copy of spack installs packages into its own ``$PREFIX/opt``
|
||||
directory.
|
||||
|
||||
|
||||
|
||||
|
||||
.. _compiler-config:
|
||||
|
||||
Compiler configuration
|
||||
-----------------------------------
|
||||
|
||||
Spack has the ability to build packages with multiple compilers and
|
||||
compiler versions. Spack searches for compilers on your machine
|
||||
automatically the first time it is run. It does this by inspecting
|
||||
your path.
|
||||
|
||||
.. _spack-compilers:
|
||||
|
||||
``spack compilers``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can see which compilers spack has found by running ``spack
|
||||
compilers`` or ``spack compiler list``::
|
||||
|
||||
$ spack compilers
|
||||
==> Available compilers
|
||||
-- gcc ---------------------------------------------------------
|
||||
gcc@4.9.0 gcc@4.8.0 gcc@4.7.0 gcc@4.6.2 gcc@4.4.7
|
||||
gcc@4.8.2 gcc@4.7.1 gcc@4.6.3 gcc@4.6.1 gcc@4.1.2
|
||||
-- intel -------------------------------------------------------
|
||||
intel@15.0.0 intel@14.0.0 intel@13.0.0 intel@12.1.0 intel@10.0
|
||||
intel@14.0.3 intel@13.1.1 intel@12.1.5 intel@12.0.4 intel@9.1
|
||||
intel@14.0.2 intel@13.1.0 intel@12.1.3 intel@11.1
|
||||
intel@14.0.1 intel@13.0.1 intel@12.1.2 intel@10.1
|
||||
-- clang -------------------------------------------------------
|
||||
clang@3.4 clang@3.3 clang@3.2 clang@3.1
|
||||
-- pgi ---------------------------------------------------------
|
||||
pgi@14.3-0 pgi@13.2-0 pgi@12.1-0 pgi@10.9-0 pgi@8.0-1
|
||||
pgi@13.10-0 pgi@13.1-1 pgi@11.10-0 pgi@10.2-0 pgi@7.1-3
|
||||
pgi@13.6-0 pgi@12.8-0 pgi@11.1-0 pgi@9.0-4 pgi@7.0-6
|
||||
|
||||
Any of these compilers can be used to build Spack packages. More on
|
||||
how this is done is in :ref:`sec-specs`.
|
||||
|
||||
.. _spack-compiler-add:
|
||||
|
||||
``spack compiler add``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
An alias for ``spack compiler find``.
|
||||
|
||||
.. _spack-compiler-find:
|
||||
|
||||
``spack compiler find``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you do not see a compiler in this list, but you want to use it with
|
||||
Spack, you can simply run ``spack compiler find`` with the path to
|
||||
where the compiler is installed. For example::
|
||||
|
||||
$ spack compiler find /usr/local/tools/ic-13.0.079
|
||||
==> Added 1 new compiler to /Users/gamblin2/.spack/compilers.yaml
|
||||
intel@13.0.079
|
||||
|
||||
Or you can run ``spack compiler find`` with no arguments to force
|
||||
auto-detection. This is useful if you do not know where compilers are
|
||||
installed, but you know that new compilers have been added to your
|
||||
``PATH``. For example, using dotkit, you might do this::
|
||||
|
||||
$ module load gcc-4.9.0
|
||||
$ spack compiler find
|
||||
==> Added 1 new compiler to /Users/gamblin2/.spack/compilers.yaml
|
||||
gcc@4.9.0
|
||||
|
||||
This loads the environment module for gcc-4.9.0 to add it to
|
||||
``PATH``, and then it adds the compiler to Spack.
|
||||
|
||||
.. _spack-compiler-info:
|
||||
|
||||
``spack compiler info``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to see specifics on a particular compiler, you can run
|
||||
``spack compiler info`` on it::
|
||||
|
||||
$ spack compiler info intel@15
|
||||
intel@15.0.0:
|
||||
cc = /usr/local/bin/icc-15.0.090
|
||||
cxx = /usr/local/bin/icpc-15.0.090
|
||||
f77 = /usr/local/bin/ifort-15.0.090
|
||||
fc = /usr/local/bin/ifort-15.0.090
|
||||
|
||||
This shows which C, C++, and Fortran compilers were detected by Spack.
|
||||
Notice also that we didn\'t have to be too specific about the
|
||||
version. We just said ``intel@15``, and information about the only
|
||||
matching Intel compiler was displayed.
|
||||
|
||||
|
||||
Manual Compiler Configuration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If auto-detection fails, you can manually configure a compiler by
|
||||
editing your ``~/.spack/compilers.yaml`` file. You can do this by running
|
||||
``spack config edit compilers``, which will open the file in your ``$EDITOR``.
|
||||
|
||||
Each compiler configuration in the file looks like this::
|
||||
|
||||
...
|
||||
compilers:
|
||||
- compiler:
|
||||
modules = []
|
||||
operating_system: OS
|
||||
paths:
|
||||
cc: /usr/local/bin/icc-15.0.024-beta
|
||||
cxx: /usr/local/bin/icpc-15.0.024-beta
|
||||
f77: /usr/local/bin/ifort-15.0.024-beta
|
||||
fc: /usr/local/bin/ifort-15.0.024-beta
|
||||
|
||||
spec: intel@15.0.0:
|
||||
|
||||
For compilers, like ``clang``, that do not support Fortran, put
|
||||
``None`` for ``f77`` and ``fc``::
|
||||
|
||||
clang@3.3svn:
|
||||
cc: /usr/bin/clang
|
||||
cxx: /usr/bin/clang++
|
||||
f77: None
|
||||
fc: None
|
||||
|
||||
Once you save the file, the configured compilers will show up in the
|
||||
list displayed by ``spack compilers``.
|
||||
|
||||
You can also add compiler flags to manually configured compilers. The
|
||||
valid flags are ``cflags``, ``cxxflags``, ``fflags``, ``cppflags``,
|
||||
``ldflags``, and ``ldlibs``. For example::
|
||||
|
||||
...
|
||||
compilers:
|
||||
- compiler:
|
||||
...
|
||||
intel@15.0.0:
|
||||
cc: /usr/local/bin/icc-15.0.024-beta
|
||||
cxx: /usr/local/bin/icpc-15.0.024-beta
|
||||
f77: /usr/local/bin/ifort-15.0.024-beta
|
||||
fc: /usr/local/bin/ifort-15.0.024-beta
|
||||
cppflags: -O3 -fPIC
|
||||
...
|
||||
|
||||
These flags will be treated by spack as if they were enterred from
|
||||
the command line each time this compiler is used. The compiler wrappers
|
||||
then inject those flags into the compiler command. Compiler flags
|
||||
enterred from the command line will be discussed in more detail in the
|
||||
following section.
|
||||
|
||||
|
||||
Build Your Own Compiler
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you are particular about which compiler/version you use, you might
|
||||
wish to have Spack build it for you. For example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
spack install gcc@4.9.3
|
||||
|
||||
Once that has finished, you will need to add it to your
|
||||
``compilers.yaml`` file. If this is your preferred compiler, in
|
||||
general future Spack builds will use it.
|
||||
|
||||
.. note::
|
||||
|
||||
If you are building your own compiler, it can be useful to have a
|
||||
Spack instance just for that. For example, create a new Spack in
|
||||
``~/spack-tools`` and then run ``~/spack-tools/bin/spack install
|
||||
gcc@4.9.3``. Once the compiler is built, don't build anything
|
||||
more in that Spack instance; instead, create a new "real" Spack
|
||||
instance, configure Spack to use the compiler you've just built,
|
||||
and then build your application software in the new Spack
|
||||
instance.
|
||||
|
||||
This tip is useful because sometimes you will find yourself
|
||||
rebuilding may pacakges due to Spack updates. Sometimes, you
|
||||
might even delete your entire Spack installation and start fresh.
|
||||
If your compiler was built in a separate Spack installation, you
|
||||
will never have to rebuild it --- as long as you wish to continue
|
||||
using that version of the compiler.
|
||||
|
||||
|
||||
Compilers Requiring Modules
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Many installed compilers will work regardless of the environment they
|
||||
are called with. However, some installed compilers require
|
||||
``$LD_LIBRARY_PATH`` or other environment variables to be set in order
|
||||
to run; Intel compilers are known for this. In such a case, you
|
||||
should tell Spack which module(s) to load in order to run the chosen
|
||||
compiler. Spack will load this module into the environment ONLY when
|
||||
the compiler is run, and NOT in general for a package's ``install()``
|
||||
method. See, for example, this ``compilers.yaml`` file:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
compilers:
|
||||
- compiler:
|
||||
modules: [other/comp/gcc-5.3-sp3]
|
||||
operating_system: SuSE11
|
||||
paths:
|
||||
cc: /usr/local/other/SLES11.3/gcc/5.3.0/bin/gcc
|
||||
cxx: /usr/local/other/SLES11.3/gcc/5.3.0/bin/g++
|
||||
f77: /usr/local/other/SLES11.3/gcc/5.3.0/bin/gfortran
|
||||
fc: /usr/local/other/SLES11.3/gcc/5.3.0/bin/gfortran
|
||||
spec: gcc@5.3.0
|
||||
|
||||
Some compilers require a module to be loaded not just to run, but also
|
||||
to execute any code built with the compiler, breaking packages that
|
||||
execute any bits of code they just compiled. Such compilers should be
|
||||
taken behind the barn and put out of their misery. If that is not
|
||||
possible or practical, the user (and anyone running code built by that
|
||||
compiler) will need to load the compiler's module into their
|
||||
environment. And ``spack install --dirty`` will need to be used.
|
||||
|
||||
Compiler Verification
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can verify that your compilers are configured properly by installing a
|
||||
simple package. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
spack install zlib%gcc@5.3.0
|
||||
|
||||
|
||||
System Packages
|
||||
-----------------
|
||||
|
||||
Once compilers are configured, one needs to determine which
|
||||
pre-installed system packages, if any, to use in builds. This is
|
||||
configured in the file `~/.spack/packages.yaml`. For example, to use
|
||||
an OpenMPI installed in /opt/local, one would use:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
openmpi:
|
||||
paths:
|
||||
openmpi@1.10.1: /opt/local
|
||||
buildable: False
|
||||
|
||||
In general, Spack is easier to use and more reliable if it builds all
|
||||
its own dependencies. However, there are two packages for which one
|
||||
commonly needs to use system versions:
|
||||
|
||||
MPI
|
||||
~~~
|
||||
|
||||
On supercomputers, sysadmins have already built MPI versions that take
|
||||
into account the specifics of that computer's hardware. Unless you
|
||||
know how they were built and can choose the correct Spack variants,
|
||||
you are unlikely to get a working MPI from Spack. Instead, use an
|
||||
appropraite pre-installed MPI.
|
||||
|
||||
If you choose a pre-installed MPI, you should consider using the
|
||||
pre-installed compiler used to build that MPI; see above on
|
||||
``compilers.yaml``.
|
||||
|
||||
OpenSSL
|
||||
~~~~~~~~
|
||||
|
||||
The ``openssl`` package underlies much of modern security in a modern
|
||||
OS; an attacker can easily "pwn" any computer on which can modify SSL.
|
||||
Therefore, any `openssl` used on a system should be created in a
|
||||
"trusted environment" --- for example, that of the OS vendor.
|
||||
|
||||
OpenSSL is also updated by the OS vendor from time to time, in
|
||||
response to security problems discovered in the wider community. It
|
||||
is in everyone's best interest to use any newly updated versions as
|
||||
soon as they come out. Modern Linux installations have standard
|
||||
procedures for security updates without user involvement.
|
||||
|
||||
Spack running at user-level is not a trusted environment, nor do Spack
|
||||
users generally keep up-to-date on the latest security holes in SSL.
|
||||
For these reasons, any Spack-installed OpenSSL should be considered
|
||||
untrusted.
|
||||
|
||||
As long as the system-provided SSL works, it is better to use it. One can check if it works by trying to download an ``https://``. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
curl -O https://github.com/ImageMagick/ImageMagick/archive/7.0.2-7.tar.gz
|
||||
|
||||
As long as it works, the recommended way to tell Spack to use the
|
||||
system-supplied OpenSSL is to add the following to ``packages.yaml``.
|
||||
Note that the ``@system`` "version" means "I don't care what version
|
||||
it is, just use what is there." This is appropraite for OpenSSL,
|
||||
which has a stable API.
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
# Recommended for security reasons
|
||||
# Do not install OpenSSL as non-root user.
|
||||
openssl:
|
||||
paths:
|
||||
openssl@system: /usr
|
||||
version: [system]
|
||||
buildable: False
|
||||
|
||||
|
||||
|
||||
Utilities Configuration
|
||||
-------------------------
|
||||
|
||||
Although Spack does not need installation *per se*, it does rely on
|
||||
other packages to be available on its host system. If those packages
|
||||
are out of date or missing, then Spack will not work. Sometimes, an
|
||||
appeal to the system's package manager can fix such problems. If not,
|
||||
the solution is have Spack install the required packages, and then
|
||||
have Spack use them.
|
||||
|
||||
For example, if `curl` doesn't work, one could use the following steps
|
||||
to provide Spack a working `curl`:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack install curl
|
||||
$ spack load curl
|
||||
|
||||
or alternately:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack module loads curl >>~/.bashrc
|
||||
|
||||
or if environment modules don't work:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ export PATH=`spack location -i curl`/bin:$PATH
|
||||
|
||||
|
||||
External commands are used by Spack in two places: within core Spack,
|
||||
and in the package recipes. The bootstrapping procedure for these two
|
||||
cases is somewhat different, and is treated separately below.
|
||||
|
||||
Core Spack Utilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Core Spack uses the following packages, aminly to download and unpack
|
||||
source code, and to load generated environment modules: ``curl``,
|
||||
``env``, ``git``, ``go``, ``hg``, ``svn``, ``tar``, ``unzip``,
|
||||
``patch``, ``environment-modules``.
|
||||
|
||||
As long as the user's environment is set up to successfully run these
|
||||
programs from outside of Spack, they should work inside of Spack as
|
||||
well. They can generally be activated as in the `curl` example above;
|
||||
or some systems might already have an appropriate hand-built
|
||||
environment module that may be loaded. Either way works.
|
||||
|
||||
A few notes on specific programs in this list:
|
||||
|
||||
cURL, git, Mercurial, etc.
|
||||
```````````````````````````
|
||||
|
||||
Spack depends on cURL to download tarballs, the format that most
|
||||
Spack-installed packages come in. Your system's cURL should always be
|
||||
able to download unencrypted ``http://``. However, the cURL on some
|
||||
systems has problems with SSL-enabled ``https://`` URLs, due to
|
||||
outdated / insecure versions of OpenSSL on those systems. This will
|
||||
prevent Spack from installing any software requiring ``https://``
|
||||
until a new cURL has been installed, using the technique above.
|
||||
|
||||
.. note::
|
||||
|
||||
``curl`` depends on ``openssl`` and ``zlib``, both of which are
|
||||
downloadable from non-SSL sources. Unfortunately, this
|
||||
Spack-built cURL should be considered untrustworthy for
|
||||
``https://`` sources becuase it relies on an OpenSSL built in user
|
||||
space. Luckily, Spack verifies checksums of the software it
|
||||
installs, and does not rely on a secure SSL implementation.
|
||||
|
||||
If your version of ``curl`` is not trustworthy, then you should
|
||||
not use it outside of Spack. Instead of putting it in your
|
||||
``.bashrc``, you might wish to create a short shell script that
|
||||
loads the appropariate module(s) and then launches Spack.
|
||||
|
||||
Some packages use source code control systems as their download
|
||||
method: ``git``, ``hg``, ``svn`` and occasionally ``go``. If you had
|
||||
to install a new ``curl``, then chances are the system-supplied
|
||||
version of these other programs will also not work, because they also
|
||||
rely on OpenSSL. Once ``curl`` has been installed, the others should
|
||||
also be installable.
|
||||
|
||||
|
||||
.. _InstallEnvironmentModules:
|
||||
|
||||
Environment Modules
|
||||
````````````````````
|
||||
|
||||
In order to use Spack's generated environment modules, you must have
|
||||
installed the *Environment Modules* package. On many Linux
|
||||
distributions, this can be installed from the vendor's repository.
|
||||
For example: ```yum install environment-modules``
|
||||
(Fedora/RHEL/CentOS). If your Linux distribution does not have
|
||||
Environment Modules, you can get it with Spack:
|
||||
|
||||
1. Consider using system tcl (as long as your system has Tcl version 8.0 or later):
|
||||
1. Identify its location using ``which tclsh``
|
||||
2. Identify its version using ``echo 'puts $tcl_version;exit 0' | tclsh``
|
||||
3. Add to ``~/.spack/packages.yaml`` and modify as appropriate:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
tcl:
|
||||
paths:
|
||||
tcl@8.5: /usr
|
||||
version: [8.5]
|
||||
buildable: False
|
||||
|
||||
2. Install with::
|
||||
.. code-block:: sh
|
||||
|
||||
spack install environment-modules
|
||||
|
||||
3. Activate with the following script (or apply the updates to your
|
||||
``.bashrc`` file manually)::
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
TMP=`tempfile`
|
||||
echo >$TMP
|
||||
MODULE_HOME=`spack location -i environment-modules`
|
||||
MODULE_VERSION=`ls -1 $MODULE_HOME/Modules | head -1`
|
||||
${MODULE_HOME}/Modules/${MODULE_VERSION}/bin/add.modules <$TMP
|
||||
cp .bashrc $TMP
|
||||
echo "MODULE_VERSION=${MODULE_VERSION}" > .bashrc
|
||||
cat $TMP >>.bashrc
|
||||
|
||||
This adds to your ``.bashrc`` (or similar) files, enabling Environment
|
||||
Modules when you log in. Re-load your .bashrc (or log out and in
|
||||
again), and then test that the ``module`` command is found with:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
module avail
|
||||
|
||||
|
||||
Package Utilities
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Spack can also encounter bootstrapping problems inside a package's
|
||||
``install()`` method. In this case, Spack will normally be running
|
||||
inside a *sanitized build environment*. This includes all of the
|
||||
package's dependencies, but none of the environment Spack inherited
|
||||
from the user: if you load a module or modify ``$PATH`` before
|
||||
launching Spack, it will have no effect.
|
||||
|
||||
In this case, you will likley need to use the ``--dirty`` flag when
|
||||
running ``spack install``, causing Spack to **not** santize the build
|
||||
environment. You are now responsible for making sure that environment
|
||||
does not do strange things to Spack or its installs.
|
||||
|
||||
Another way to get Spack to use its own version of something is to add that something to a package that needs it. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
depends_on('binutils', type='build')
|
||||
|
||||
This is considered best practice for some common build dependencies,
|
||||
such as ``autotools`` (if the ``autoreconf`` command is needed) and
|
||||
``cmake`` --- ``cmake`` especially, because different packages require
|
||||
a different version of CMake.
|
||||
|
||||
However, adding ``depends_on('binutils')`` to every package is not
|
||||
considered a best practice because every package written in
|
||||
C/C++/Fortran would need it. Loading a recent ``binutils`` into your
|
||||
environment is preferable here.
|
||||
|
||||
binutils
|
||||
~~~~~~~~~
|
||||
|
||||
# https://groups.google.com/forum/#!topic/spack/i_7l_kEEveI
|
||||
|
||||
Sometimes, strange error messages can happen while building a package.
|
||||
For exmaple, ``ld`` might crash. Or one receives a message like:
|
||||
|
||||
.. code-block::
|
||||
|
||||
ld: final link failed: Nonrepresentable section on output
|
||||
|
||||
These problems are often caused by an outdated ``binutils`` on your
|
||||
system: bootstrap as described above.
|
||||
|
||||
Install Environment Modules
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In order to use Spack's generated environment modules, you must have
|
||||
installed the *Environment Modules* package. On many Linux
|
||||
distributions, this can be installed from the vendor's repository.
|
||||
For example: ```yum install environment-modules``
|
||||
(Fedora/RHEL/CentOS). If your Linux distribution does not have
|
||||
Environment Modules, you can get it with Spack:
|
||||
|
||||
1. Consider using system tcl. If so, add to ``packages.yaml``::
|
||||
|
||||
packages:
|
||||
tcl:
|
||||
paths:
|
||||
tcl@8.5: /usr
|
||||
version: [8.5]
|
||||
buildable: False
|
||||
2. Install with::
|
||||
|
||||
spack install environment-modules
|
||||
|
||||
3. Activate with::
|
||||
|
||||
TMP=`tempfile`
|
||||
echo >$TMP
|
||||
MODULE_HOME=`spack location -i environment-modules`
|
||||
MODULE_VERSION=`ls -1 $MODULE_HOME/Modules | head -1`
|
||||
${MODULE_HOME}/Modules/${MODULE_VERSION}/bin/add.modules <$TMP
|
||||
cp .bashrc $TMP
|
||||
echo "MODULE_VERSION=${MODULE_VERSION}" > .bashrc
|
||||
cat $TMP >>.bashrc
|
||||
|
||||
This adds to your ``.bashrc`` (or similar) files, enabling Environment
|
||||
Modules when you log in. Re-load your .bashrc (or log out and in
|
||||
again), and then test that the ``module`` command is found with:
|
||||
|
||||
module avail
|
||||
|
||||
|
||||
Spack on Cray
|
||||
-----------------------------
|
||||
|
||||
Spack differs slightly when used on a Cray system. The architecture spec
|
||||
can differentiate between the front-end and back-end processor and operating system.
|
||||
For example, on Edison at NERSC, the back-end target processor
|
||||
is \"Ivy Bridge\", so you can specify to use the back-end this way:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
spack install zlib target=ivybridge
|
||||
|
||||
You can also use the operating system to build against the back-end:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
spack install zlib os=CNL10
|
||||
|
||||
Notice that the name includes both the operating system name and the major
|
||||
version number concatenated together.
|
||||
|
||||
Alternatively, if you want to build something for the front-end,
|
||||
you can specify the front-end target processor. The processor for a login node
|
||||
on Edison is \"Sandy bridge\" so we specify on the command line like so:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
spack install zlib target=sandybridge
|
||||
|
||||
And the front-end operating system is:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
spack install zlib os=SuSE11
|
||||
|
||||
|
||||
|
||||
Cray compiler detection
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Spack can detect compilers using two methods. For the front-end, we treat
|
||||
everything the same. The difference lies in back-end compiler detection.
|
||||
Back-end compiler detection is made via the Tcl module avail command.
|
||||
Once it detects the compiler it writes the appropriate PrgEnv and compiler
|
||||
module name to compilers.yaml and sets the paths to each compiler with Cray\'s
|
||||
compiler wrapper names (i.e. cc, CC, ftn). During build time, Spack will load
|
||||
the correct PrgEnv and compiler module and will call appropriate wrapper.
|
||||
|
||||
The compilers.yaml config file will also differ. There is a
|
||||
modules section that is filled with the compiler\'s Programming Environment
|
||||
and module name. On other systems, this field is empty []::
|
||||
|
||||
...
|
||||
- compiler:
|
||||
modules:
|
||||
- PrgEnv-intel
|
||||
- intel/15.0.109
|
||||
...
|
||||
|
||||
As mentioned earlier, the compiler paths will look different on a Cray system.
|
||||
Since most compilers are invoked using cc, CC and ftn, the paths for each
|
||||
compiler are replaced with their respective Cray compiler wrapper names::
|
||||
|
||||
...
|
||||
paths:
|
||||
cc: cc
|
||||
cxx: CC
|
||||
f77: ftn
|
||||
fc: ftn
|
||||
...
|
||||
|
||||
As opposed to an explicit path to the compiler executable. This allows Spack
|
||||
to call the Cray compiler wrappers during build time.
|
||||
|
||||
For more on compiler configuration, check out :ref:`compiler-config`.
|
||||
|
||||
Spack sets the default Cray link type to dynamic, to better match other
|
||||
other platforms. Individual packages can enable static linking (which is the
|
||||
default outside of Spack on cray systems) using the -static flag.
|
||||
|
||||
Setting defaults and using Cray modules
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you want to use default compilers for each PrgEnv and also be able
|
||||
to load cray external modules, you will need to set up a packages.yaml.
|
||||
|
||||
Here\'s an example of an external configuration for cray modules:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
mpi:
|
||||
modules:
|
||||
mpich@7.3.1%gcc@5.2.0 arch=cray_xc-haswell-CNL10: cray-mpich
|
||||
mpich@7.3.1%intel@16.0.0.109 arch=cray_xc-haswell-CNL10: cray-mpich
|
||||
|
||||
This tells Spack that for whatever package that depends on mpi, load the
|
||||
cray-mpich module into the environment. You can then be able to use whatever
|
||||
environment variables, libraries, etc, that are brought into the environment
|
||||
via module load.
|
||||
|
||||
You can set the default compiler that Spack can use for each compiler type.
|
||||
If you want to use the Cray defaults, then set them under *all:* in packages.yaml.
|
||||
In the compiler field, set the compiler specs in your order of preference.
|
||||
Whenever you build with that compiler type, Spack will concretize to that version.
|
||||
|
||||
Here is an example of a full packages.yaml used at NERSC
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
mpi:
|
||||
modules:
|
||||
mpich@7.3.1%gcc@5.2.0 arch=cray_xc-CNL10-ivybridge: cray-mpich
|
||||
mpich@7.3.1%intel@16.0.0.109 arch=cray_xc-SuSE11-ivybridge: cray-mpich
|
||||
buildable: False
|
||||
netcdf:
|
||||
modules:
|
||||
netcdf@4.3.3.1%gcc@5.2.0 arch=cray_xc-CNL10-ivybridge: cray-netcdf
|
||||
netcdf@4.3.3.1%intel@16.0.0.109 arch=cray_xc-CNL10-ivybridge: cray-netcdf
|
||||
buildable: False
|
||||
hdf5:
|
||||
modules:
|
||||
hdf5@1.8.14%gcc@5.2.0 arch=cray_xc-CNL10-ivybridge: cray-hdf5
|
||||
hdf5@1.8.14%intel@16.0.0.109 arch=cray_xc-CNL10-ivybridge: cray-hdf5
|
||||
buildable: False
|
||||
all:
|
||||
compiler: [gcc@5.2.0, intel@16.0.0.109]
|
||||
|
||||
Here we tell spack that whenever we want to build with gcc use version 5.2.0 or
|
||||
if we want to build with intel compilers, use version 16.0.0.109. We add a spec
|
||||
for each compiler type for each cray modules. This ensures that for each
|
||||
compiler on our system we can use that external module.
|
||||
|
||||
|
||||
For more on external packages check out the section :ref:`sec-external_packages`.
|
||||
|
||||
@@ -18,18 +18,18 @@ configurations can coexist on the same system.
|
||||
Most importantly, Spack is *simple*. It offers a simple *spec* syntax
|
||||
so that users can specify versions and configuration options
|
||||
concisely. Spack is also simple for package authors: package files
|
||||
are writtin in pure Python, and specs allow package authors to write a
|
||||
single build script for many different builds of the same package.
|
||||
are written in pure Python, and specs allow package authors to
|
||||
maintain a single file for many different builds of the same package.
|
||||
|
||||
See the :doc:`features` for examples and highlights.
|
||||
|
||||
Get spack from the `github repository
|
||||
<https://github.com/scalability-llnl/spack>`_ and install your first
|
||||
<https://github.com/llnl/spack>`_ and install your first
|
||||
package:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ git clone https://github.com/scalability-llnl/spack.git
|
||||
$ git clone https://github.com/llnl/spack.git
|
||||
$ cd spack/bin
|
||||
$ ./spack install libelf
|
||||
|
||||
@@ -46,9 +46,11 @@ Table of Contents
|
||||
getting_started
|
||||
basic_usage
|
||||
packaging_guide
|
||||
application_developer_support
|
||||
mirrors
|
||||
site_configuration
|
||||
configuration
|
||||
developer_guide
|
||||
case_studies
|
||||
command_index
|
||||
package_list
|
||||
API Docs <spack>
|
||||
|
||||
@@ -38,7 +38,7 @@ contains tarballs for each package, named after each package.
|
||||
|
||||
.. note::
|
||||
|
||||
Archives are **not** named exactly they were in the package's fetch
|
||||
Archives are **not** named exactly the way they were in the package's fetch
|
||||
URL. They have the form ``<name>-<version>.<extension>``, where
|
||||
``<name>`` is Spack's name for the package, ``<version>`` is the
|
||||
version of the tarball, and ``<extension>`` is whatever format the
|
||||
@@ -186,7 +186,7 @@ Each mirror has a name so that you can refer to it again later.
|
||||
``spack mirror list``
|
||||
----------------------------
|
||||
|
||||
If you want to see all the mirrors Spack knows about you can run ``spack mirror list``::
|
||||
To see all the mirrors Spack knows about, run ``spack mirror list``::
|
||||
|
||||
$ spack mirror list
|
||||
local_filesystem file:///Users/gamblin2/spack-mirror-2014-06-24
|
||||
@@ -196,7 +196,7 @@ If you want to see all the mirrors Spack knows about you can run ``spack mirror
|
||||
``spack mirror remove``
|
||||
----------------------------
|
||||
|
||||
And, if you want to remove a mirror, just remove it by name::
|
||||
To remove a mirror by name::
|
||||
|
||||
$ spack mirror remove local_filesystem
|
||||
$ spack mirror list
|
||||
@@ -205,13 +205,30 @@ And, if you want to remove a mirror, just remove it by name::
|
||||
Mirror precedence
|
||||
----------------------------
|
||||
|
||||
Adding a mirror really just adds a section in ``~/.spackconfig``::
|
||||
Adding a mirror really adds a line in ``~/.spack/mirrors.yaml``::
|
||||
|
||||
[mirror "local_filesystem"]
|
||||
url = file:///Users/gamblin2/spack-mirror-2014-06-24
|
||||
[mirror "remote_server"]
|
||||
url = https://example.com/some/web-hosted/directory/spack-mirror-2014-06-24
|
||||
mirrors:
|
||||
local_filesystem: file:///Users/gamblin2/spack-mirror-2014-06-24
|
||||
remote_server: https://example.com/some/web-hosted/directory/spack-mirror-2014-06-24
|
||||
|
||||
If you want to change the order in which mirrors are searched for
|
||||
packages, you can edit this file and reorder the sections. Spack will
|
||||
search the topmost mirror first and the bottom-most mirror last.
|
||||
|
||||
.. _caching:
|
||||
|
||||
Local Default Cache
|
||||
----------------------------
|
||||
|
||||
Spack caches resources that are downloaded as part of installs. The cache is
|
||||
a valid spack mirror: it uses the same directory structure and naming scheme
|
||||
as other Spack mirrors (so it can be copied anywhere and referenced with a URL
|
||||
like other mirrors). The mirror is maintained locally (within the Spack
|
||||
installation directory) at :file:`var/spack/cache/`. It is always enabled (and
|
||||
is always searched first when attempting to retrieve files for an installation)
|
||||
but can be cleared with :ref:`purge <spack-purge>`; the cache directory can also
|
||||
be deleted manually without issue.
|
||||
|
||||
Caching includes retrieved tarball archives and source control repositories, but
|
||||
only resources with an associated digest or commit ID (e.g. a revision number
|
||||
for SVN) will be cached.
|
||||
|
||||
@@ -36,10 +36,11 @@ Creating & editing packages
|
||||
``spack create``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The ``spack create`` command generates a boilerplate package template
|
||||
from a URL. The URL should point to a tarball or other software
|
||||
archive. In most cases, ``spack create`` plus a few modifications is
|
||||
all you need to get a package working.
|
||||
The ``spack create`` command creates a directory with the package name and
|
||||
generates a ``package.py`` file with a boilerplate package template from a URL.
|
||||
The URL should point to a tarball or other software archive. In most cases,
|
||||
``spack create`` plus a few modifications is all you need to get a package
|
||||
working.
|
||||
|
||||
Here's an example:
|
||||
|
||||
@@ -47,12 +48,16 @@ Here's an example:
|
||||
|
||||
$ spack create http://www.cmake.org/files/v2.8/cmake-2.8.12.1.tar.gz
|
||||
|
||||
Spack examines the tarball URL and tries to figure out the name of the
|
||||
package to be created. It also tries to determine what version strings
|
||||
look like for this package. Using this information, it will try to
|
||||
find *additional* versions by spidering the package's webpage. If it
|
||||
finds multiple versions, Spack prompts you to tell it how many
|
||||
versions you want to download and checksum:
|
||||
Spack examines the tarball URL and tries to figure out the name of the package
|
||||
to be created. Once the name is determined a directory in the appropriate
|
||||
repository is created with that name. Spack prefers, but does not require, that
|
||||
names be lower case so the directory name will be lower case when ``spack
|
||||
create`` generates it. In cases where it is desired to have mixed case or upper
|
||||
case simply rename the directory. Spack also tries to determine what version
|
||||
strings look like for this package. Using this information, it will try to find
|
||||
*additional* versions by spidering the package's webpage. If it finds multiple
|
||||
versions, Spack prompts you to tell it how many versions you want to download
|
||||
and checksum:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
@@ -84,7 +89,7 @@ always choose to download just one tarball initially, and run
|
||||
|
||||
If it fails entirely, you can get minimal boilerplate by using
|
||||
:ref:`spack-edit-f`, or you can manually create a directory and
|
||||
``package.py`` file for the package in ``var/spack/packages``.
|
||||
``package.py`` file for the package in ``var/spack/repos/builtin/packages``.
|
||||
|
||||
.. note::
|
||||
|
||||
@@ -203,7 +208,7 @@ edit`` command:
|
||||
So, if you used ``spack create`` to create a package, then saved and
|
||||
closed the resulting file, you can get back to it with ``spack edit``.
|
||||
The ``cmake`` package actually lives in
|
||||
``$SPACK_ROOT/var/spack/packages/cmake/package.py``, but this provides
|
||||
``$SPACK_ROOT/var/spack/repos/builtin/packages/cmake/package.py``, but this provides
|
||||
a much simpler shortcut and saves you the trouble of typing the full
|
||||
path.
|
||||
|
||||
@@ -269,18 +274,18 @@ live in Spack's directory structure. In general, `spack-create`_ and
|
||||
`spack-edit`_ handle creating package files for you, so you can skip
|
||||
most of the details here.
|
||||
|
||||
``var/spack/packages``
|
||||
``var/spack/repos/builtin/packages``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A Spack installation directory is structured like a standard UNIX
|
||||
install prefix (``bin``, ``lib``, ``include``, ``var``, ``opt``,
|
||||
etc.). Most of the code for Spack lives in ``$SPACK_ROOT/lib/spack``.
|
||||
Packages themselves live in ``$SPACK_ROOT/var/spack/packages``.
|
||||
Packages themselves live in ``$SPACK_ROOT/var/spack/repos/builtin/packages``.
|
||||
|
||||
If you ``cd`` to that directory, you will see directories for each
|
||||
package:
|
||||
|
||||
.. command-output:: cd $SPACK_ROOT/var/spack/packages; ls -CF
|
||||
.. command-output:: cd $SPACK_ROOT/var/spack/repos/builtin/packages; ls -CF
|
||||
:shell:
|
||||
:ellipsis: 10
|
||||
|
||||
@@ -288,7 +293,7 @@ Each directory contains a file called ``package.py``, which is where
|
||||
all the python code for the package goes. For example, the ``libelf``
|
||||
package lives in::
|
||||
|
||||
$SPACK_ROOT/var/spack/packages/libelf/package.py
|
||||
$SPACK_ROOT/var/spack/repos/builtin/packages/libelf/package.py
|
||||
|
||||
Alongside the ``package.py`` file, a package may contain extra
|
||||
directories or files (like patches) that it needs to build.
|
||||
@@ -297,11 +302,12 @@ directories or files (like patches) that it needs to build.
|
||||
Package Names
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Packages are named after the directory containing ``package.py``. So,
|
||||
``libelf``'s ``package.py`` lives in a directory called ``libelf``.
|
||||
The ``package.py`` file defines a class called ``Libelf``, which
|
||||
Packages are named after the directory containing ``package.py``. It is
|
||||
preferred, but not required, that the directory, and thus the package name, are
|
||||
lower case. So, ``libelf``'s ``package.py`` lives in a directory called
|
||||
``libelf``. The ``package.py`` file defines a class called ``Libelf``, which
|
||||
extends Spack's ``Package`` class. for example, here is
|
||||
``$SPACK_ROOT/var/spack/packages/libelf/package.py``:
|
||||
``$SPACK_ROOT/var/spack/repos/builtin/packages/libelf/package.py``:
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
@@ -328,7 +334,7 @@ these:
|
||||
$ spack install libelf@0.8.13
|
||||
|
||||
Spack sees the package name in the spec and looks for
|
||||
``libelf/package.py`` in ``var/spack/packages``. Likewise, if you say
|
||||
``libelf/package.py`` in ``var/spack/repos/builtin/packages``. Likewise, if you say
|
||||
``spack install py-numpy``, then Spack looks for
|
||||
``py-numpy/package.py``.
|
||||
|
||||
@@ -377,6 +383,8 @@ add a line like this in the package class:
|
||||
version('8.2.1', '4136d7b4c04df68b686570afa26988ac')
|
||||
...
|
||||
|
||||
Versions should be listed with the newest version first.
|
||||
|
||||
Version URLs
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -385,8 +393,22 @@ in the package. For example, Spack is smart enough to download
|
||||
version ``8.2.1.`` of the ``Foo`` package above from
|
||||
``http://example.com/foo-8.2.1.tar.gz``.
|
||||
|
||||
If spack *cannot* extrapolate the URL from the ``url`` field, or if
|
||||
the package doesn't have a ``url`` field, you can add a URL explicitly
|
||||
If spack *cannot* extrapolate the URL from the ``url`` field by
|
||||
default, you can write your own URL generation algorithm in place of
|
||||
the ``url`` declaration. For example:
|
||||
|
||||
.. code-block:: python
|
||||
:linenos:
|
||||
|
||||
class Foo(Package):
|
||||
version('8.2.1', '4136d7b4c04df68b686570afa26988ac')
|
||||
...
|
||||
def url_for_version(self, version):
|
||||
return 'http://example.com/version_%s/foo-%s.tar.gz' \
|
||||
% (version, version)
|
||||
...
|
||||
|
||||
If a URL cannot be derived systematically, you can add an explicit URL
|
||||
for a particular version:
|
||||
|
||||
.. code-block:: python
|
||||
@@ -401,6 +423,35 @@ construct the new one for ``8.2.1``.
|
||||
When you supply a custom URL for a version, Spack uses that URL
|
||||
*verbatim* and does not perform extrapolation.
|
||||
|
||||
Skipping the expand step
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Spack normally expands archives automatically after downloading
|
||||
them. If you want to skip this step (e.g., for self-extracting
|
||||
executables and other custom archive types), you can add
|
||||
``expand=False`` to a ``version`` directive.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
version('8.2.1', '4136d7b4c04df68b686570afa26988ac',
|
||||
url='http://example.com/foo-8.2.1-special-version.tar.gz', expand=False)
|
||||
|
||||
When ``expand`` is set to ``False``, Spack sets the current working
|
||||
directory to the directory containing the downloaded archive before it
|
||||
calls your ``install`` method. Within ``install``, the path to the
|
||||
downloaded archive is available as ``self.stage.archive_file``.
|
||||
|
||||
Here is an example snippet for packages distributed as self-extracting
|
||||
archives. The example sets permissions on the downloaded file to make
|
||||
it executable, then runs it with some arguments.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def install(self, spec, prefix):
|
||||
set_executable(self.stage.archive_file)
|
||||
installer = Executable(self.stage.archive_file)
|
||||
installer('--prefix=%s' % prefix, 'arg1', 'arg2', 'etc.')
|
||||
|
||||
Checksums
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -417,14 +468,25 @@ to use based on the hash length.
|
||||
``spack md5``
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
If you have a single file to checksum, you can use the ``spack md5``
|
||||
command to do it. Here's how you might download an archive and get a
|
||||
checksum for it:
|
||||
If you have one or more files to checksum, you can use the ``spack md5``
|
||||
command to do it:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ curl -O http://exmaple.com/foo-8.2.1.tar.gz'
|
||||
$ spack md5 foo-8.2.1.tar.gz
|
||||
$ spack md5 foo-8.2.1.tar.gz foo-8.2.2.tar.gz
|
||||
==> 2 MD5 checksums:
|
||||
4136d7b4c04df68b686570afa26988ac foo-8.2.1.tar.gz
|
||||
1586b70a49dfe05da5fcc29ef239dce0 foo-8.2.2.tar.gz
|
||||
|
||||
``spack md5`` also accepts one or more URLs and automatically downloads
|
||||
the files for you:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack md5 http://example.com/foo-8.2.1.tar.gz
|
||||
==> Trying to fetch from http://example.com/foo-8.2.1.tar.gz
|
||||
######################################################################## 100.0%
|
||||
==> 1 MD5 checksum:
|
||||
4136d7b4c04df68b686570afa26988ac foo-8.2.1.tar.gz
|
||||
|
||||
Doing this for lots of files, or whenever a new package version is
|
||||
@@ -518,7 +580,7 @@ The package author is responsible for coming up with a sensible name
|
||||
for each version to be fetched from a repository. For example, if
|
||||
you're fetching from a tag like ``v1.0``, you might call that ``1.0``.
|
||||
If you're fetching a nameless git commit or an older subversion
|
||||
revision, you might give the commit an intuitive name, like ``dev``
|
||||
revision, you might give the commit an intuitive name, like ``develop``
|
||||
for a development version, or ``some-fancy-new-feature`` if you want
|
||||
to be more specific.
|
||||
|
||||
@@ -528,6 +590,17 @@ branches move forward over time and you aren't guaranteed to get the
|
||||
same thing every time you fetch a particular version. Life isn't
|
||||
always simple, though, so this is not strictly enforced.
|
||||
|
||||
When fetching from from the branch corresponding to the development version
|
||||
(often called ``master``,``trunk`` or ``dev``), it is recommended to
|
||||
call this version ``develop``. Spack has special treatment for this version so
|
||||
that ``@develop`` will satisfy dependencies like
|
||||
``depends_on(abc, when="@x.y.z:")``. In other words, ``@develop`` is
|
||||
greater than any other version. The rationale is that certain features or
|
||||
options first appear in the development branch. Therefore if a package author
|
||||
wants to keep the package on the bleeding edge and provide support for new
|
||||
features, it is advised to use ``develop`` for such a version which will
|
||||
greatly simplify writing dependencies and version-related conditionals.
|
||||
|
||||
In some future release, Spack may support extrapolating repository
|
||||
versions as it does for tarball URLs, but currently this is not
|
||||
supported.
|
||||
@@ -543,6 +616,7 @@ Git fetching is enabled with the following parameters to ``version``:
|
||||
* ``tag``: name of a tag to fetch.
|
||||
* ``branch``: name of a branch to fetch.
|
||||
* ``commit``: SHA hash (or prefix) of a commit to fetch.
|
||||
* ``submodules``: Also fetch submodules when checking out this repository.
|
||||
|
||||
Only one of ``tag``, ``branch``, or ``commit`` can be used at a time.
|
||||
|
||||
@@ -553,7 +627,7 @@ Default branch
|
||||
|
||||
class Example(Package):
|
||||
...
|
||||
version('dev', git='https://github.com/example-project/example.git')
|
||||
version('develop', git='https://github.com/example-project/example.git')
|
||||
|
||||
This is not recommended, as the contents of the default branch
|
||||
change over time.
|
||||
@@ -599,6 +673,17 @@ Commits
|
||||
could just use the abbreviated commit hash. It's up to the package
|
||||
author to decide what makes the most sense.
|
||||
|
||||
Submodules
|
||||
|
||||
You can supply ``submodules=True`` to cause Spack to fetch submodules
|
||||
along with the repository at fetch time.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
version('1.0.1', git='https://github.com/example-project/example.git',
|
||||
tag='v1.0.1', submdoules=True)
|
||||
|
||||
|
||||
Installing
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
@@ -626,13 +711,13 @@ Default
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
version('hg-head', hg='https://jay.grs.rwth-aachen.de/hg/example')
|
||||
version('develop', hg='https://jay.grs.rwth-aachen.de/hg/example')
|
||||
|
||||
Note that this is not recommended; try to fetch a particular
|
||||
revision instead.
|
||||
|
||||
Revisions
|
||||
Add ``hg`` and ``revision``parameters:
|
||||
Add ``hg`` and ``revision`` parameters:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -658,7 +743,7 @@ Fetching the head
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
version('svn-head', svn='https://outreach.scidac.gov/svn/libmonitor/trunk')
|
||||
version('develop', svn='https://outreach.scidac.gov/svn/libmonitor/trunk')
|
||||
|
||||
This is not recommended, as the head will move forward over time.
|
||||
|
||||
@@ -668,12 +753,140 @@ Fetching a revision
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
version('svn-head', svn='https://outreach.scidac.gov/svn/libmonitor/trunk',
|
||||
version('develop', svn='https://outreach.scidac.gov/svn/libmonitor/trunk',
|
||||
revision=128)
|
||||
|
||||
Subversion branches are handled as part of the directory structure, so
|
||||
you can check out a branch or tag by changing the ``url``.
|
||||
|
||||
Automatic caching of files fetched during installation
|
||||
------------------------------------------------------
|
||||
|
||||
Spack maintains a cache (described :ref:`here <caching>`) which saves files
|
||||
retrieved during package installations to avoid re-downloading in the case that
|
||||
a package is installed with a different specification (but the same version) or
|
||||
reinstalled on account of a change in the hashing scheme.
|
||||
|
||||
.. _license:
|
||||
|
||||
Licensed software
|
||||
------------------------------------------
|
||||
|
||||
In order to install licensed software, Spack needs to know a few more
|
||||
details about a package. The following class attributes should be defined.
|
||||
|
||||
``license_required``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Boolean. If set to ``True``, this software requires a license. If set to
|
||||
``False``, all of the following attributes will be ignored. Defaults to
|
||||
``False``.
|
||||
|
||||
``license_comment``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
String. Contains the symbol used by the license manager to denote a comment.
|
||||
Defaults to ``#``.
|
||||
|
||||
``license_files``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
List of strings. These are files that the software searches for when
|
||||
looking for a license. All file paths must be relative to the installation
|
||||
directory. More complex packages like Intel may require multiple
|
||||
licenses for individual components. Defaults to the empty list.
|
||||
|
||||
``license_vars``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
List of strings. Environment variables that can be set to tell the software
|
||||
where to look for a license if it is not in the usual location. Defaults
|
||||
to the empty list.
|
||||
|
||||
``license_url``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
String. A URL pointing to license setup instructions for the software.
|
||||
Defaults to the empty string.
|
||||
|
||||
For example, let's take a look at the package for the PGI compilers.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Licensing
|
||||
license_required = True
|
||||
license_comment = '#'
|
||||
license_files = ['license.dat']
|
||||
license_vars = ['PGROUPD_LICENSE_FILE', 'LM_LICENSE_FILE']
|
||||
license_url = 'http://www.pgroup.com/doc/pgiinstall.pdf'
|
||||
|
||||
As you can see, PGI requires a license. Its license manager, FlexNet, uses
|
||||
the ``#`` symbol to denote a comment. It expects the license file to be
|
||||
named ``license.dat`` and to be located directly in the installation prefix.
|
||||
If you would like the installation file to be located elsewhere, simply set
|
||||
``PGROUPD_LICENSE_FILE`` or ``LM_LICENSE_FILE`` after installation. For
|
||||
further instructions on installation and licensing, see the URL provided.
|
||||
|
||||
Let's walk through a sample PGI installation to see exactly what Spack is
|
||||
and isn't capable of. Since PGI does not provide a download URL, it must
|
||||
be downloaded manually. It can either be added to a mirror or located in
|
||||
the current directory when ``spack install pgi`` is run. See :ref:`mirrors`
|
||||
for instructions on setting up a mirror.
|
||||
|
||||
After running ``spack install pgi``, the first thing that will happen is
|
||||
Spack will create a global license file located at
|
||||
``$SPACK_ROOT/etc/spack/licenses/pgi/license.dat``. It will then open up the
|
||||
file using the editor set in ``$EDITOR``, or vi if unset. It will look like
|
||||
this:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# A license is required to use pgi.
|
||||
#
|
||||
# The recommended solution is to store your license key in this global
|
||||
# license file. After installation, the following symlink(s) will be
|
||||
# added to point to this file (relative to the installation prefix):
|
||||
#
|
||||
# license.dat
|
||||
#
|
||||
# Alternatively, use one of the following environment variable(s):
|
||||
#
|
||||
# PGROUPD_LICENSE_FILE
|
||||
# LM_LICENSE_FILE
|
||||
#
|
||||
# If you choose to store your license in a non-standard location, you may
|
||||
# set one of these variable(s) to the full pathname to the license file, or
|
||||
# port@host if you store your license keys on a dedicated license server.
|
||||
# You will likely want to set this variable in a module file so that it
|
||||
# gets loaded every time someone tries to use pgi.
|
||||
#
|
||||
# For further information on how to acquire a license, please refer to:
|
||||
#
|
||||
# http://www.pgroup.com/doc/pgiinstall.pdf
|
||||
#
|
||||
# You may enter your license below.
|
||||
|
||||
You can add your license directly to this file, or tell FlexNet to use a
|
||||
license stored on a separate license server. Here is an example that
|
||||
points to a license server called licman1:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
SERVER licman1.mcs.anl.gov 00163eb7fba5 27200
|
||||
USE_SERVER
|
||||
|
||||
If your package requires the license to install, you can reference the
|
||||
location of this global license using ``self.global_license_file``.
|
||||
After installation, symlinks for all of the files given in
|
||||
``license_files`` will be created, pointing to this global license.
|
||||
If you install a different version or variant of the package, Spack
|
||||
will automatically detect and reuse the already existing global license.
|
||||
|
||||
If the software you are trying to package doesn't rely on license files,
|
||||
Spack will print a warning message, letting the user know that they
|
||||
need to set an environment variable or pointing them to installation
|
||||
documentation.
|
||||
|
||||
.. _patching:
|
||||
|
||||
Patches
|
||||
@@ -703,7 +916,7 @@ supply is a filename, then the patch needs to live within the spack
|
||||
source tree. For example, the patch above lives in a directory
|
||||
structure like this::
|
||||
|
||||
$SPACK_ROOT/var/spack/packages/
|
||||
$SPACK_ROOT/var/spack/repos/builtin/packages/
|
||||
mvapich2/
|
||||
package.py
|
||||
ad_lustre_rwcontig_open_source.patch
|
||||
@@ -1071,11 +1284,13 @@ just as easily provide a version range:
|
||||
|
||||
depends_on("libelf@0.8.2:0.8.4:")
|
||||
|
||||
Or a requirement for a particular variant:
|
||||
Or a requirement for a particular variant or compiler flags:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
depends_on("libelf@0.8+debug")
|
||||
depends_on('libelf debug=True')
|
||||
depends_on('libelf cppflags="-fPIC")
|
||||
|
||||
Both users *and* package authors can use the same spec syntax to refer
|
||||
to different package configurations. Users use the spec syntax on the
|
||||
@@ -1083,6 +1298,31 @@ command line to find installed packages or to install packages with
|
||||
particular constraints, and package authors can use specs to describe
|
||||
relationships between packages.
|
||||
|
||||
Additionally, dependencies may be specified for specific use cases:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
depends_on("cmake", type="build")
|
||||
depends_on("libelf", type=("build", "link"))
|
||||
depends_on("python", type="run")
|
||||
|
||||
The dependency types are:
|
||||
|
||||
* **"build"**: made available during the project's build. The package will
|
||||
be added to ``PATH``, the compiler include paths, and ``PYTHONPATH``.
|
||||
Other projects which depend on this one will not have these modified
|
||||
(building project X doesn't need project Y's build dependencies).
|
||||
* **"link"**: the project is linked to by the project. The package will be
|
||||
added to the current package's ``rpath``.
|
||||
* **"run"**: the project is used by the project at runtime. The package will
|
||||
be added to ``PATH`` and ``PYTHONPATH``.
|
||||
|
||||
If not specified, ``type`` is assumed to be ``("build", "link")``. This is the
|
||||
common case for compiled language usage. Also available are the aliases
|
||||
``"alldeps"`` for all dependency types and ``"nolink"`` (``("build", "run")``)
|
||||
for use by dependencies which are not expressed via a linker (e.g., Python or
|
||||
Lua module loading).
|
||||
|
||||
.. _setup-dependent-environment:
|
||||
|
||||
``setup_dependent_environment()``
|
||||
@@ -1187,6 +1427,19 @@ Now, the ``py-numpy`` package can be used as an argument to ``spack
|
||||
activate``. When it is activated, all the files in its prefix will be
|
||||
symbolically linked into the prefix of the python package.
|
||||
|
||||
Many packages produce Python extensions for *some* variants, but not
|
||||
others: they should extend ``python`` only if the apropriate
|
||||
variant(s) are selected. This may be accomplished with conditional
|
||||
``extends()`` declarations:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class FooLib(Package):
|
||||
variant('python', default=True, description= \
|
||||
'Build the Python extension Module')
|
||||
extends('python', when='+python')
|
||||
...
|
||||
|
||||
Sometimes, certain files in one package will conflict with those in
|
||||
another, which means they cannot both be activated (symlinked) at the
|
||||
same time. In this case, you can tell Spack to ignore those files
|
||||
@@ -1473,21 +1726,21 @@ the user runs ``spack install`` and the time the ``install()`` method
|
||||
is called. The concretized version of the spec above might look like
|
||||
this::
|
||||
|
||||
mpileaks@2.3%gcc@4.7.3=linux-ppc64
|
||||
^callpath@1.0%gcc@4.7.3+debug=linux-ppc64
|
||||
^dyninst@8.1.2%gcc@4.7.3=linux-ppc64
|
||||
^libdwarf@20130729%gcc@4.7.3=linux-ppc64
|
||||
^libelf@0.8.11%gcc@4.7.3=linux-ppc64
|
||||
^mpich@3.0.4%gcc@4.7.3=linux-ppc64
|
||||
mpileaks@2.3%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
^callpath@1.0%gcc@4.7.3+debug arch=linux-debian7-x86_64
|
||||
^dyninst@8.1.2%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
^libdwarf@20130729%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
^libelf@0.8.11%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
^mpich@3.0.4%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
|
||||
.. graphviz::
|
||||
|
||||
digraph {
|
||||
"mpileaks@2.3\n%gcc@4.7.3\n=linux-ppc64" -> "mpich@3.0.4\n%gcc@4.7.3\n=linux-ppc64"
|
||||
"mpileaks@2.3\n%gcc@4.7.3\n=linux-ppc64" -> "callpath@1.0\n%gcc@4.7.3+debug\n=linux-ppc64" -> "mpich@3.0.4\n%gcc@4.7.3\n=linux-ppc64"
|
||||
"callpath@1.0\n%gcc@4.7.3+debug\n=linux-ppc64" -> "dyninst@8.1.2\n%gcc@4.7.3\n=linux-ppc64"
|
||||
"dyninst@8.1.2\n%gcc@4.7.3\n=linux-ppc64" -> "libdwarf@20130729\n%gcc@4.7.3\n=linux-ppc64" -> "libelf@0.8.11\n%gcc@4.7.3\n=linux-ppc64"
|
||||
"dyninst@8.1.2\n%gcc@4.7.3\n=linux-ppc64" -> "libelf@0.8.11\n%gcc@4.7.3\n=linux-ppc64"
|
||||
"mpileaks@2.3\n%gcc@4.7.3\n arch=linux-debian7-x86_64" -> "mpich@3.0.4\n%gcc@4.7.3\n arch=linux-debian7-x86_64"
|
||||
"mpileaks@2.3\n%gcc@4.7.3\n arch=linux-debian7-x86_64" -> "callpath@1.0\n%gcc@4.7.3+debug\n arch=linux-debian7-x86_64" -> "mpich@3.0.4\n%gcc@4.7.3\n arch=linux-debian7-x86_64"
|
||||
"callpath@1.0\n%gcc@4.7.3+debug\n arch=linux-debian7-x86_64" -> "dyninst@8.1.2\n%gcc@4.7.3\n arch=linux-debian7-x86_64"
|
||||
"dyninst@8.1.2\n%gcc@4.7.3\n arch=linux-debian7-x86_64" -> "libdwarf@20130729\n%gcc@4.7.3\n arch=linux-debian7-x86_64" -> "libelf@0.8.11\n%gcc@4.7.3\n arch=linux-debian7-x86_64"
|
||||
"dyninst@8.1.2\n%gcc@4.7.3\n arch=linux-debian7-x86_64" -> "libelf@0.8.11\n%gcc@4.7.3\n arch=linux-debian7-x86_64"
|
||||
}
|
||||
|
||||
Here, all versions, compilers, and platforms are filled in, and there
|
||||
@@ -1498,8 +1751,8 @@ point will Spack call the ``install()`` method for your package.
|
||||
Concretization in Spack is based on certain selection policies that
|
||||
tell Spack how to select, e.g., a version, when one is not specified
|
||||
explicitly. Concretization policies are discussed in more detail in
|
||||
:ref:`site-configuration`. Sites using Spack can customize them to
|
||||
match the preferences of their own users.
|
||||
:ref:`configuration`. Sites using Spack can customize them to match
|
||||
the preferences of their own users.
|
||||
|
||||
.. _spack-spec:
|
||||
|
||||
@@ -1516,14 +1769,25 @@ running ``spack spec``. For example:
|
||||
^libdwarf
|
||||
^libelf
|
||||
|
||||
dyninst@8.0.1%gcc@4.7.3=linux-ppc64
|
||||
^libdwarf@20130729%gcc@4.7.3=linux-ppc64
|
||||
^libelf@0.8.13%gcc@4.7.3=linux-ppc64
|
||||
dyninst@8.0.1%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
^libdwarf@20130729%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
^libelf@0.8.13%gcc@4.7.3 arch=linux-debian7-x86_64
|
||||
|
||||
This is useful when you want to know exactly what Spack will do when
|
||||
you ask for a particular spec.
|
||||
|
||||
|
||||
``Concretization Policies``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A user may have certain preferences for how packages should
|
||||
be concretized on their system. For example, one user may prefer packages
|
||||
built with OpenMPI and the Intel compiler. Another user may prefer
|
||||
packages be built with MVAPICH and GCC.
|
||||
|
||||
See the `documentation in the config section <concretization-preferences_>`_
|
||||
for more details.
|
||||
|
||||
.. _install-method:
|
||||
|
||||
Implementing the ``install`` method
|
||||
@@ -1533,7 +1797,7 @@ The last element of a package is its ``install()`` method. This is
|
||||
where the real work of installation happens, and it's the main part of
|
||||
the package you'll need to customize for each piece of software.
|
||||
|
||||
.. literalinclude:: ../../../var/spack/packages/libelf/package.py
|
||||
.. literalinclude:: ../../../var/spack/repos/builtin/packages/libelf/package.py
|
||||
:start-after: 0.8.12
|
||||
:linenos:
|
||||
|
||||
@@ -1681,7 +1945,7 @@ discover its dependencies.
|
||||
|
||||
If you want to see the environment that a package will build with, or
|
||||
if you want to run commands in that environment to test them out, you
|
||||
can use the :ref:```spack env`` <spack-env>` command, documented
|
||||
can use the :ref:`spack env <spack-env>` command, documented
|
||||
below.
|
||||
|
||||
.. _compiler-wrappers:
|
||||
@@ -1711,15 +1975,15 @@ Compile-time library search paths
|
||||
* ``-L$dep_prefix/lib``
|
||||
* ``-L$dep_prefix/lib64``
|
||||
Runtime library search paths (RPATHs)
|
||||
* ``-Wl,-rpath=$dep_prefix/lib``
|
||||
* ``-Wl,-rpath=$dep_prefix/lib64``
|
||||
* ``$rpath_flag$dep_prefix/lib``
|
||||
* ``$rpath_flag$dep_prefix/lib64``
|
||||
Include search paths
|
||||
* ``-I$dep_prefix/include``
|
||||
|
||||
An example of this would be the ``libdwarf`` build, which has one
|
||||
dependency: ``libelf``. Every call to ``cc`` in the ``libdwarf``
|
||||
build will have ``-I$LIBELF_PREFIX/include``,
|
||||
``-L$LIBELF_PREFIX/lib``, and ``-Wl,-rpath=$LIBELF_PREFIX/lib``
|
||||
``-L$LIBELF_PREFIX/lib``, and ``$rpath_flag$LIBELF_PREFIX/lib``
|
||||
inserted on the command line. This is done transparently to the
|
||||
project's build system, which will just think it's using a system
|
||||
where ``libelf`` is readily available. Because of this, you **do
|
||||
@@ -1739,6 +2003,67 @@ successfully find ``libdwarf.h`` and ``libdwarf.so``, without the
|
||||
packager having to provide ``--with-libdwarf=/path/to/libdwarf`` on
|
||||
the command line.
|
||||
|
||||
.. note::
|
||||
|
||||
For most compilers, ``$rpath_flag`` is ``-Wl,-rpath,``. However, NAG
|
||||
passes its flags to GCC instead of passing them directly to the linker.
|
||||
Therefore, its ``$rpath_flag`` is doubly wrapped: ``-Wl,-Wl,,-rpath,``.
|
||||
``$rpath_flag`` can be overriden on a compiler specific basis in
|
||||
``lib/spack/spack/compilers/$compiler.py``.
|
||||
|
||||
The compiler wrappers also pass the compiler flags specified by the user from
|
||||
the command line (``cflags``, ``cxxflags``, ``fflags``, ``cppflags``, ``ldflags``,
|
||||
and/or ``ldlibs``). They do not override the canonical autotools flags with the
|
||||
same names (but in ALL-CAPS) that may be passed into the build by particularly
|
||||
challenging package scripts.
|
||||
|
||||
Compiler flags
|
||||
~~~~~~~~~~~~~~
|
||||
In rare circumstances such as compiling and running small unit tests, a package
|
||||
developer may need to know what are the appropriate compiler flags to enable
|
||||
features like ``OpenMP``, ``c++11``, ``c++14`` and alike. To that end the
|
||||
compiler classes in ``spack`` implement the following _properties_ :
|
||||
``openmp_flag``, ``cxx11_flag``, ``cxx14_flag``, which can be accessed in a
|
||||
package by ``self.compiler.cxx11_flag`` and alike. Note that the implementation
|
||||
is such that if a given compiler version does not support this feature, an
|
||||
error will be produced. Therefore package developers can also use these properties
|
||||
to assert that a compiler supports the requested feature. This is handy when a
|
||||
package supports additional variants like
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
variant('openmp', default=True, description="Enable OpenMP support.")
|
||||
|
||||
Message Parsing Interface (MPI)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
It is common for high performance computing software/packages to use ``MPI``.
|
||||
As a result of conretization, a given package can be built using different
|
||||
implementations of MPI such as ``Openmpi``, ``MPICH`` or ``IntelMPI``.
|
||||
In some scenarios to configure a package one have to provide it with appropriate MPI
|
||||
compiler wrappers such as ``mpicc``, ``mpic++``.
|
||||
However different implementations of ``MPI`` may have different names for those
|
||||
wrappers. In order to make package's ``install()`` method indifferent to the
|
||||
choice ``MPI`` implementation, each package which implements ``MPI`` sets up
|
||||
``self.spec.mpicc``, ``self.spec.mpicxx``, ``self.spec.mpifc`` and ``self.spec.mpif77``
|
||||
to point to ``C``, ``C++``, ``Fortran 90`` and ``Fortran 77`` ``MPI`` wrappers.
|
||||
Package developers are advised to use these variables, for example ``self.spec['mpi'].mpicc``
|
||||
instead of hard-coding ``join_path(self.spec['mpi'].prefix.bin, 'mpicc')`` for
|
||||
the reasons outlined above.
|
||||
|
||||
|
||||
Blas and Lapack libraries
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Different packages provide implementation of ``Blas`` and ``Lapack`` routines.
|
||||
The names of the resulting static and/or shared libraries differ from package
|
||||
to package. In order to make ``install()`` method indifferent to the
|
||||
choice of ``Blas`` implementation, each package which provides it
|
||||
sets up ``self.spec.blas_shared_lib`` and ``self.spec.blas_static_lib `` to
|
||||
point to the shared and static ``Blas`` libraries, respectively. The same
|
||||
applies to packages which provide ``Lapack``. Package developers are advised to
|
||||
use these variables, for example ``spec['blas'].blas_shared_lib`` instead of
|
||||
hard-coding ``join_path(spec['blas'].prefix.lib, 'libopenblas.so')``.
|
||||
|
||||
|
||||
Forking ``install()``
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -1752,6 +2077,20 @@ dedicated process.
|
||||
|
||||
.. _prefix-objects:
|
||||
|
||||
|
||||
Failing the build
|
||||
----------------------
|
||||
|
||||
Sometimes you don't want a package to successfully install unless some
|
||||
condition is true. You can explicitly cause the build to fail from
|
||||
``install()`` by raising an ``InstallError``, for example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
if spec.architecture.startswith('darwin'):
|
||||
raise InstallError('This package does not build on Mac OS X!')
|
||||
|
||||
|
||||
Prefix objects
|
||||
----------------------
|
||||
|
||||
@@ -1937,12 +2276,12 @@ example:
|
||||
def install(self, prefix):
|
||||
# Do default install
|
||||
|
||||
@when('=chaos_5_x86_64_ib')
|
||||
@when('arch=linux-debian7-x86_64')
|
||||
def install(self, prefix):
|
||||
# This will be executed instead of the default install if
|
||||
# the package's sys_type() is chaos_5_x86_64_ib.
|
||||
|
||||
@when('=bgqos_0")
|
||||
@when('arch=linux-debian7-x86_64")
|
||||
def install(self, prefix):
|
||||
# This will be executed if the package's sys_type is bgqos_0
|
||||
|
||||
@@ -2068,6 +2407,62 @@ package, this allows us to avoid race conditions in the library's
|
||||
build system.
|
||||
|
||||
|
||||
.. _sanity-checks:
|
||||
|
||||
Sanity checking an installation
|
||||
--------------------------------
|
||||
|
||||
By default, Spack assumes that a build has failed if nothing is
|
||||
written to the install prefix, and that it has succeeded if anything
|
||||
(a file, a directory, etc.) is written to the install prefix after
|
||||
``install()`` completes.
|
||||
|
||||
Consider a simple autotools build like this:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def install(self, spec, prefix):
|
||||
configure("--prefix=" + prefix)
|
||||
make()
|
||||
make("install")
|
||||
|
||||
If you are using using standard autotools or CMake, ``configure`` and
|
||||
``make`` will not write anything to the install prefix. Only ``make
|
||||
install`` writes the files, and only once the build is already
|
||||
complete. Not all builds are like this. Many builds of scientific
|
||||
software modify the install prefix *before* ``make install``. Builds
|
||||
like this can falsely report that they were successfully installed if
|
||||
an error occurs before the install is complete but after files have
|
||||
been written to the ``prefix``.
|
||||
|
||||
|
||||
``sanity_check_is_file`` and ``sanity_check_is_dir``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You can optionally specify *sanity checks* to deal with this problem.
|
||||
Add properties like this to your package:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
class MyPackage(Package):
|
||||
...
|
||||
|
||||
sanity_check_is_file = ['include/libelf.h']
|
||||
sanity_check_is_dir = [lib]
|
||||
|
||||
def install(self, spec, prefix):
|
||||
configure("--prefix=" + prefix)
|
||||
make()
|
||||
make("install")
|
||||
|
||||
Now, after ``install()`` runs, Spack will check whether
|
||||
``$prefix/include/libelf.h`` exists and is a file, and whether
|
||||
``$prefix/lib`` exists and is a directory. If the checks fail, then
|
||||
the build will fail and the install prefix will be removed. If they
|
||||
succeed, Spack considers the build succeeful and keeps the prefix in
|
||||
place.
|
||||
|
||||
|
||||
.. _file-manipulation:
|
||||
|
||||
File manipulation functions
|
||||
@@ -2108,6 +2503,15 @@ Filtering functions
|
||||
|
||||
Examples:
|
||||
|
||||
#. Filtering a Makefile to force it to use Spack's compiler wrappers:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
filter_file(r'^CC\s*=.*', spack_cc, 'Makefile')
|
||||
filter_file(r'^CXX\s*=.*', spack_cxx, 'Makefile')
|
||||
filter_file(r'^F77\s*=.*', spack_f77, 'Makefile')
|
||||
filter_file(r'^FC\s*=.*', spack_fc, 'Makefile')
|
||||
|
||||
#. Replacing ``#!/usr/bin/perl`` with ``#!/usr/bin/env perl`` in ``bib2xhtml``:
|
||||
|
||||
.. code-block:: python
|
||||
@@ -2221,6 +2625,59 @@ File functions
|
||||
|
||||
.. _package-lifecycle:
|
||||
|
||||
Coding Style Guidelines
|
||||
---------------------------
|
||||
|
||||
The following guidelines are provided, in the interests of making
|
||||
Spack packages work in a consistent manner:
|
||||
|
||||
|
||||
Variant Names
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Spack packages with variants similar to already-existing Spack
|
||||
packages should use the same name for their variants. Standard
|
||||
variant names are:
|
||||
|
||||
======= ======== ========================
|
||||
Name Default Description
|
||||
======= ======== ========================
|
||||
shared True Build shared libraries
|
||||
static Build static libraries
|
||||
mpi Use MPI
|
||||
python Build Python extension
|
||||
======= ======== ========================
|
||||
|
||||
If specified in this table, the corresponding default should be used
|
||||
when declaring a variant.
|
||||
|
||||
|
||||
Version Lists
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Spack packges should list supported versions with the newest first.
|
||||
|
||||
Special Versions
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
The following *special* version names may be used when building a package:
|
||||
|
||||
* *@system*: Indicates a hook to the OS-installed version of the
|
||||
package. This is useful, for example, to tell Spack to use the
|
||||
OS-installed version in ``packages.yaml``::
|
||||
|
||||
openssl:
|
||||
paths:
|
||||
openssl@system: /usr
|
||||
buildable: False
|
||||
|
||||
Certain Spack internals look for the *@system* version and do
|
||||
appropriate things in that case.
|
||||
|
||||
* *@local*: Indicates the version was built manually from some source
|
||||
tree of unknown provenance (see ``spack setup``).
|
||||
|
||||
|
||||
Packaging workflow commands
|
||||
---------------------------------
|
||||
|
||||
@@ -2315,11 +2772,16 @@ build process will start from scratch.
|
||||
|
||||
``spack purge``
|
||||
~~~~~~~~~~~~~~~~~
|
||||
Cleans up all of Spack's temporary files. Use this to recover disk
|
||||
space if temporary files from interrupted or failed installs
|
||||
accumulate in the staging area. This is equivalent to running ``spack
|
||||
clean`` for every package you have fetched or staged.
|
||||
Cleans up all of Spack's temporary and cached files. This can be used to
|
||||
recover disk space if temporary files from interrupted or failed installs
|
||||
accumulate in the staging area.
|
||||
|
||||
When called with ``--stage`` or ``--all`` (or without arguments, in which case
|
||||
the default is ``--all``) this removes all staged files; this is equivalent to
|
||||
running ``spack clean`` for every package you have fetched or staged.
|
||||
|
||||
When called with ``--cache`` or ``--all`` this will clear all resources
|
||||
:ref:`cached <caching>` during installs.
|
||||
|
||||
Keeping the stage directory on success
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -2467,11 +2929,11 @@ build it:
|
||||
$ spack stage libelf
|
||||
==> Trying to fetch from http://www.mr511.de/software/libelf-0.8.13.tar.gz
|
||||
######################################################################## 100.0%
|
||||
==> Staging archive: /Users/gamblin2/src/spack/var/spack/stage/libelf@0.8.13%gcc@4.8.3=linux-ppc64/libelf-0.8.13.tar.gz
|
||||
==> Created stage in /Users/gamblin2/src/spack/var/spack/stage/libelf@0.8.13%gcc@4.8.3=linux-ppc64.
|
||||
==> Staging archive: /Users/gamblin2/src/spack/var/spack/stage/libelf@0.8.13%gcc@4.8.3 arch=linux-debian7-x86_64/libelf-0.8.13.tar.gz
|
||||
==> Created stage in /Users/gamblin2/src/spack/var/spack/stage/libelf@0.8.13%gcc@4.8.3 arch=linux-debian7-x86_64.
|
||||
$ spack cd libelf
|
||||
$ pwd
|
||||
/Users/gamblin2/src/spack/var/spack/stage/libelf@0.8.13%gcc@4.8.3=linux-ppc64/libelf-0.8.13
|
||||
/Users/gamblin2/src/spack/var/spack/stage/libelf@0.8.13%gcc@4.8.3 arch=linux-debian7-x86_64/libelf-0.8.13
|
||||
|
||||
``spack cd`` here changed he current working directory to the
|
||||
directory containing the expanded ``libelf`` source code. There are a
|
||||
@@ -2536,3 +2998,4 @@ might write:
|
||||
DWARF_PREFIX = $(spack location -i libdwarf)
|
||||
CXXFLAGS += -I$DWARF_PREFIX/include
|
||||
CXXFLAGS += -L$DWARF_PREFIX/lib
|
||||
|
||||
|
||||
@@ -1,187 +0,0 @@
|
||||
.. _site-configuration:
|
||||
|
||||
Site configuration
|
||||
===================================
|
||||
|
||||
.. _temp-space:
|
||||
|
||||
Temporary space
|
||||
----------------------------
|
||||
|
||||
.. warning:: Temporary space configuration will eventually be moved to
|
||||
configuration files, but currently these settings are in
|
||||
``lib/spack/spack/__init__.py``
|
||||
|
||||
By default, Spack will try to do all of its building in temporary
|
||||
space. There are two main reasons for this. First, Spack is designed
|
||||
to run out of a user's home directory, and on may systems the home
|
||||
directory is network mounted and potentially not a very fast
|
||||
filesystem. We create build stages in a temporary directory to avoid
|
||||
this. Second, many systems impose quotas on home directories, and
|
||||
``/tmp`` or similar directories often have more available space. This
|
||||
helps conserve space for installations in users' home directories.
|
||||
|
||||
You can customize temporary directories by editing
|
||||
``lib/spack/spack/__init__.py``. Specifically, find this part of the file:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# Whether to build in tmp space or directly in the stage_path.
|
||||
# If this is true, then spack will make stage directories in
|
||||
# a tmp filesystem, and it will symlink them into stage_path.
|
||||
use_tmp_stage = True
|
||||
|
||||
# Locations to use for staging and building, in order of preference
|
||||
# Use a %u to add a username to the stage paths here, in case this
|
||||
# is a shared filesystem. Spack will use the first of these paths
|
||||
# that it can create.
|
||||
tmp_dirs = ['/nfs/tmp2/%u/spack-stage',
|
||||
'/var/tmp/%u/spack-stage',
|
||||
'/tmp/%u/spack-stage']
|
||||
|
||||
The ``use_tmp_stage`` variable controls whether Spack builds
|
||||
**directly** inside the ``var/spack/`` directory. Normally, Spack
|
||||
will try to find a temporary directory for a build, then it *symlinks*
|
||||
that temporary directory into ``var/spack/`` so that you can keep
|
||||
track of what temporary directories Spack is using.
|
||||
|
||||
The ``tmp_dirs`` variable is a list of paths Spack should search when
|
||||
trying to find a temporary directory. They can optionally contain a
|
||||
``%u``, which will substitute the current user's name into the path.
|
||||
The list is searched in order, and Spack will create a temporary stage
|
||||
in the first directory it finds to which it has write access. Add
|
||||
more elements to the list to indicate where your own site's temporary
|
||||
directory is.
|
||||
|
||||
|
||||
.. _concretization-policies:
|
||||
|
||||
Concretization policies
|
||||
----------------------------
|
||||
|
||||
When a user asks for a package like ``mpileaks`` to be installed,
|
||||
Spack has to make decisions like what version should be installed,
|
||||
what compiler to use, and how its dependencies should be configured.
|
||||
This process is called *concretization*, and it's covered in detail in
|
||||
:ref:`its own section <abstract-and-concrete>`.
|
||||
|
||||
The default concretization policies are in the
|
||||
:py:mod:`spack.concretize` module, specifically in the
|
||||
:py:class:`spack.concretize.DefaultConcretizer` class. These are the
|
||||
important methods used in the concretization process:
|
||||
|
||||
* :py:meth:`concretize_version(self, spec) <spack.concretize.DefaultConcretizer.concretize_version>`
|
||||
* :py:meth:`concretize_architecture(self, spec) <spack.concretize.DefaultConcretizer.concretize_architecture>`
|
||||
* :py:meth:`concretize_compiler(self, spec) <spack.concretize.DefaultConcretizer.concretize_compiler>`
|
||||
* :py:meth:`choose_provider(self, spec, providers) <spack.concretize.DefaultConcretizer.choose_provider>`
|
||||
|
||||
The first three take a :py:class:`Spec <spack.spec.Spec>` object and
|
||||
modify it by adding constraints for the version. For example, if the
|
||||
input spec had a version range like `1.0:5.0.3`, then the
|
||||
``concretize_version`` method should set the spec's version to a
|
||||
*single* version in that range. Likewise, ``concretize_architecture``
|
||||
selects an architecture when the input spec does not have one, and
|
||||
``concretize_compiler`` needs to set both a concrete compiler and a
|
||||
concrete compiler version.
|
||||
|
||||
``choose_provider()`` affects how concrete implementations are chosen
|
||||
based on a virtual dependency spec. The input spec is some virtual
|
||||
dependency and the ``providers`` index is a :py:class:`ProviderIndex
|
||||
<spack.packages.ProviderIndex>` object. The ``ProviderIndex`` maps
|
||||
the virtual spec to specs for possible implementations, and
|
||||
``choose_provider()`` should simply choose one of these. The
|
||||
``concretize_*`` methods will be called on the chosen implementation
|
||||
later, so there is no need to fully concretize the spec when returning
|
||||
it.
|
||||
|
||||
The ``DefaultConcretizer`` is intended to provide sensible defaults
|
||||
for each policy, but there are certain choices that it can't know
|
||||
about. For example, one site might prefer ``OpenMPI`` over ``MPICH``,
|
||||
or another might prefer an old version of some packages. These types
|
||||
of special cases can be integrated with custom concretizers.
|
||||
|
||||
Writing a custom concretizer
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To write your own concretizer, you need only subclass
|
||||
``DefaultConcretizer`` and override the methods you want to change.
|
||||
For example, you might write a class like this to change *only* the
|
||||
``concretize_version()`` behavior:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from spack.concretize import DefaultConcretizer
|
||||
|
||||
class MyConcretizer(DefaultConcretizer):
|
||||
def concretize_version(self, spec):
|
||||
# implement custom logic here.
|
||||
|
||||
Once you have written your custom concretizer, you can make Spack use
|
||||
it by editing ``globals.py``. Find this part of the file:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
#
|
||||
# This controls how things are concretized in spack.
|
||||
# Replace it with a subclass if you want different
|
||||
# policies.
|
||||
#
|
||||
concretizer = DefaultConcretizer()
|
||||
|
||||
Set concretizer to *your own* class instead of the default:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
concretizer = MyConcretizer()
|
||||
|
||||
The next time you run Spack, your changes should take effect.
|
||||
|
||||
|
||||
Profiling
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Spack has some limited built-in support for profiling, and can report
|
||||
statistics using standard Python timing tools. To use this feature,
|
||||
supply ``-p`` to Spack on the command line, before any subcommands.
|
||||
|
||||
.. _spack-p:
|
||||
|
||||
``spack -p``
|
||||
^^^^^^^^^^^^^^^^^^
|
||||
|
||||
``spack -p`` output looks like this:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack -p graph dyninst
|
||||
o dyninst
|
||||
|\
|
||||
| |\
|
||||
| o | libdwarf
|
||||
|/ /
|
||||
o | libelf
|
||||
/
|
||||
o boost
|
||||
|
||||
307670 function calls (305943 primitive calls) in 0.127 seconds
|
||||
|
||||
Ordered by: internal time
|
||||
|
||||
ncalls tottime percall cumtime percall filename:lineno(function)
|
||||
853 0.021 0.000 0.066 0.000 inspect.py:472(getmodule)
|
||||
51197 0.011 0.000 0.018 0.000 inspect.py:51(ismodule)
|
||||
73961 0.010 0.000 0.010 0.000 {isinstance}
|
||||
1762 0.006 0.000 0.053 0.000 inspect.py:440(getsourcefile)
|
||||
32075 0.006 0.000 0.006 0.000 {hasattr}
|
||||
1760 0.004 0.000 0.004 0.000 {posix.stat}
|
||||
2240 0.004 0.000 0.004 0.000 {posix.lstat}
|
||||
2602 0.004 0.000 0.011 0.000 inspect.py:398(getfile)
|
||||
771 0.004 0.000 0.077 0.000 inspect.py:518(findsource)
|
||||
2656 0.004 0.000 0.004 0.000 {method 'match' of '_sre.SRE_Pattern' objects}
|
||||
30772 0.003 0.000 0.003 0.000 {method 'get' of 'dict' objects}
|
||||
...
|
||||
|
||||
The bottom of the output shows the top most time consuming functions,
|
||||
slowest on top. The profiling support is from Python's built-in tool,
|
||||
`cProfile
|
||||
<https://docs.python.org/2/library/profile.html#module-cProfile>`_.
|
||||
576
lib/spack/docs/spack_workflows.rst
Normal file
576
lib/spack/docs/spack_workflows.rst
Normal file
@@ -0,0 +1,576 @@
|
||||
Spack Workflows
|
||||
===============================
|
||||
|
||||
The process of using Spack involves building packages, running
|
||||
binaries from those packages, and developing software that depends on
|
||||
those packages. For example, one might use Spack to build the
|
||||
`netcdf` package, use `spack load` to run the `ncdump` binary, and
|
||||
finally, write a small C program to read/write a particular NetCDF file.
|
||||
|
||||
Spack supports a variety of workflows to suit a variety of situaions
|
||||
and user preferences, there is no single way to do all these things.
|
||||
This chapter demonstrates different workflows that have been
|
||||
developed, pointing out the pros and cons of them.
|
||||
|
||||
|
||||
Definitions
|
||||
############
|
||||
|
||||
First some basic definitions.
|
||||
|
||||
Package, Concrete Spec, Installed Package
|
||||
------------------------------------------
|
||||
|
||||
In Spack, a package is an abstract recipe to build one piece of software.
|
||||
Spack packages may be used to build, in principle, any version of that
|
||||
software with any set of variants. Examples of packages include
|
||||
``curl`` and ``zlib``.
|
||||
|
||||
A package may be *instantiated* to produce a concrete spec; one
|
||||
possible realization of a particular package, out of combinatorially
|
||||
many other realizations. For example, here is a concrete spec
|
||||
instantiated from ``curl``:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
curl@7.50.1%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^openssl@system%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
|
||||
Spack's core concretization algorithm generates concrete specs by
|
||||
instantiating packages from its repo, based on a set of "hints",
|
||||
including user input and the ``packages.yaml`` file. This algorithm
|
||||
may be accessed at any time with the ``spack spec`` command. For
|
||||
example:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ spack spec curl
|
||||
curl@7.50.1%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^openssl@system%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
|
||||
Every time Spack installs a package, that installation corresponds to
|
||||
a concrete spec. Only a vanishingly small fraction of possible
|
||||
concrete specs will be installed at any one Spack site.
|
||||
|
||||
Consistent Sets
|
||||
----------------
|
||||
|
||||
A set of Spack specs is said to be *consistent* if each package is
|
||||
only instantiated one way within it --- that is, if two specs in the
|
||||
set have the same package, then they must also have the same version,
|
||||
variant, compiler, etc. For example, the following set is consistent:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
curl@7.50.1%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^openssl@system%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
|
||||
The following set is not consistent:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
curl@7.50.1%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^openssl@system%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
^zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
zlib@1.2.7%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
|
||||
The compatibility of a set of installed packages determines what may
|
||||
be done with it. It is always possible to ``spack load`` any set of
|
||||
installed packages, whether or not they are consistent, and run their
|
||||
binaries from the command line. However, a set of installed packages
|
||||
can only be linked together in one binary if it is consistent.
|
||||
|
||||
If the user produces a series of `spack spec` or `spack load`
|
||||
commands, in general there is no guarantee of consistency between
|
||||
them. Spack's concretization procedure guarantees that the results of
|
||||
any *single* `spack spec` call will be consistent. Therefore, the
|
||||
best way to ensure a consistent set of specs is to create a Spack
|
||||
package with dependencies, and then instantiate that package. We will
|
||||
use this technique below.
|
||||
|
||||
|
||||
Building Packages
|
||||
##################
|
||||
|
||||
Suppose you are tasked with installing a set of software packages on a
|
||||
system in order to support one application -- both a core application
|
||||
program, plus software to prepare input and analyze output. The
|
||||
required software might be summed up as a series of ``spack install``
|
||||
commands in a script. If needed, this script can always be run again
|
||||
in the future. For example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
spack install modele-utils
|
||||
spack install emacs
|
||||
spack install ncview
|
||||
spack install nco
|
||||
spack install modele-control
|
||||
spack install py-numpy
|
||||
|
||||
In most cases, this script will not correctly install software
|
||||
according to your specific needs: choices need to be made for
|
||||
variants, versions and virtual dependency choices may be needed. It
|
||||
*is* possible to specify these choices by extending specs on the
|
||||
command line; however, the same choices must be specified repeatedly.
|
||||
For example, if you wish to use ``openmpi`` to satisfy the ``mpi``
|
||||
dependency, then ``^openmpi`` will have to appear on *every* ``spack
|
||||
install`` line that uses MPI. It can get repetitve fast.
|
||||
|
||||
Custimizing Spack installation options is easier to do in the
|
||||
``~/.spack/packages.yaml`` file. In this file, you can specify
|
||||
preferred versions and variants to use for packages. For exmaple:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
packages:
|
||||
python:
|
||||
version: [3.5.1]
|
||||
modele-utils:
|
||||
version: [cmake]
|
||||
|
||||
everytrace:
|
||||
version: [develop]
|
||||
eigen:
|
||||
variants: ~suitesparse
|
||||
netcdf:
|
||||
variants: +mpi
|
||||
|
||||
all:
|
||||
compiler: [gcc@5.3.0]
|
||||
providers:
|
||||
mpi: [openmpi]
|
||||
blas: [openblas]
|
||||
lapack: [openblas]
|
||||
|
||||
|
||||
This approach will work as long as you are building packages for just
|
||||
one application.
|
||||
|
||||
Multiple Applications
|
||||
-----------------------
|
||||
|
||||
Suppose instead you're building multiple inconsistent applications.
|
||||
For example, users want package A to be built with ``openmpi`` and
|
||||
package B with ``mpich`` --- but still share many other lower-level
|
||||
dependencies. In this case, a single ``packages.yaml`` file will not
|
||||
work. Plans are to implement *per-project* ``packages.yaml`` files.
|
||||
In the meantime, one could write shell scripts to switch
|
||||
``packages.yaml`` between multiple versions as needed, using symlinks.
|
||||
|
||||
|
||||
Combinatorial Sets
|
||||
--------------------------
|
||||
|
||||
Suppose that you are now tasked with systematically building many
|
||||
incompatible versions of packages. For example, you need to build
|
||||
``petsc`` 9 times for 3 different MPI implementations on 3 different
|
||||
compilers, in order to support user needs. In this case, you will
|
||||
need to either create 9 different ``packages.yaml`` files; or more
|
||||
likely, create 9 different ``spack install`` command lines with the
|
||||
correct options in the spec.
|
||||
|
||||
|
||||
|
||||
Loading Packages
|
||||
#################
|
||||
|
||||
Once Spack packages have been built, the next step is to use them. As
|
||||
with buiding packages, there are many ways to use them, depending on
|
||||
the use case.
|
||||
|
||||
Simple Loads
|
||||
--------------
|
||||
|
||||
Suppose that Spack has been used to install a set of command-line
|
||||
programs, which users now wish to use. One can in principle put a
|
||||
number of ``spack load`` commands into ``.bashrc``, for example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
spack load modele-utils
|
||||
spack load emacs
|
||||
spack load ncview
|
||||
spack load nco
|
||||
spack load modele-control
|
||||
|
||||
Although simple load scripts like this are useful in many cases, the
|
||||
have some drawbacks:
|
||||
|
||||
1. The set of modules loaded by them will in general not be
|
||||
consistent. They are a decent way to load commands to be called
|
||||
from command shells. See below for better ways to assemble a
|
||||
consistent set of packages for building application programs.
|
||||
|
||||
2. The ``spack spec`` and ``spack install`` commands use a
|
||||
sophisticated concretization algorithm that chooses the "best"
|
||||
among several options, taking into account ``packages.yaml`` file.
|
||||
The ``spack load`` and ``spack module loads`` commands, on the
|
||||
other thand, are not very smart: if the user-supplied spec matches
|
||||
more than one installed package, then ``spack module loads`` will
|
||||
fail. This may change in the future. For now, the workaround is to
|
||||
be more specific on any ``spack module loads`` lines that fail.
|
||||
|
||||
|
||||
Cached Simple Loads
|
||||
----------------------
|
||||
|
||||
Anoter problem with using `spack load` is, it is slow; a typical user
|
||||
environment could take several seconds to load, and would not be
|
||||
appropriate to put into ``.bashrc`` directly. It is preferable to use
|
||||
a series of ``spack module loads`` commands to pre-compute which
|
||||
modules to load. These can be put in a script that is run whenever
|
||||
installed Spack packages change. For example:
|
||||
|
||||
.. code-block:: sh
|
||||
#!/bin/sh
|
||||
#
|
||||
# Generate module load commands in ~/env/spackenv
|
||||
|
||||
cat <<EOF | /bin/sh >$HOME/env/spackenv
|
||||
FIND='spack module loads --prefix linux-SuSE11-x86_64/'
|
||||
|
||||
\$FIND modele-utils
|
||||
\$FIND emacs
|
||||
\$FIND ncview
|
||||
\$FIND nco
|
||||
\$FIND modele-control
|
||||
EOF
|
||||
|
||||
The output of this file is written in ``~/env/spackenv``:
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# binutils@2.25%gcc@5.3.0+gold~krellpatch~libiberty arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/binutils-2.25-gcc-5.3.0-6w5d2t4
|
||||
# python@2.7.12%gcc@5.3.0~tk~ucs4 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/python-2.7.12-gcc-5.3.0-2azoju2
|
||||
# ncview@2.1.7%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/ncview-2.1.7-gcc-5.3.0-uw3knq2
|
||||
# nco@4.5.5%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/nco-4.5.5-gcc-5.3.0-7aqmimu
|
||||
# modele-control@develop%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/modele-control-develop-gcc-5.3.0-7rddsij
|
||||
# zlib@1.2.8%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/zlib-1.2.8-gcc-5.3.0-fe5onbi
|
||||
# curl@7.50.1%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/curl-7.50.1-gcc-5.3.0-4vlev55
|
||||
# hdf5@1.10.0-patch1%gcc@5.3.0+cxx~debug+fortran+mpi+shared~szip~threadsafe arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/hdf5-1.10.0-patch1-gcc-5.3.0-pwnsr4w
|
||||
# netcdf@4.4.1%gcc@5.3.0~hdf4+mpi arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/netcdf-4.4.1-gcc-5.3.0-rl5canv
|
||||
# netcdf-fortran@4.4.4%gcc@5.3.0 arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/netcdf-fortran-4.4.4-gcc-5.3.0-stdk2xq
|
||||
# modele-utils@cmake%gcc@5.3.0+aux+diags+ic arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/modele-utils-cmake-gcc-5.3.0-idyjul5
|
||||
# everytrace@develop%gcc@5.3.0+fortran+mpi arch=linux-SuSE11-x86_64
|
||||
module load linux-SuSE11-x86_64/everytrace-develop-gcc-5.3.0-p5wmb25
|
||||
|
||||
Users may now put ``source ~/env/spackenv`` into ``.bashrc``.
|
||||
|
||||
.. note ::
|
||||
|
||||
Some module systems put a prefix on the names of modules created
|
||||
by Spack. For example, that prefix is ``linux-SuSE11-x86_64/`` in
|
||||
the above case. If a prefix is not needed, you may omit the
|
||||
``--prefix`` flag from ``spack module loads``.
|
||||
|
||||
|
||||
Transitive Dependencies
|
||||
---------------------------
|
||||
|
||||
In the script above, each ``spack module loads`` command generates a
|
||||
*single* ``module load`` line. Transitive dependencies do not usually
|
||||
need to be load, only modules the user needs in in ``$PATH``. This is
|
||||
because Spack builds binaries with RPATH. Spack's RPATH policy has
|
||||
some nice features:
|
||||
|
||||
1. Modules for multiple inconsistent applications may be loaded
|
||||
simultaneously. In the above example (Multiple Applications),
|
||||
package A and package B can coexist together in the user's $PATH,
|
||||
even though they use different MPIs.
|
||||
|
||||
2. RPATH eliminates a whole class of strange errors that can happen
|
||||
in non-RPATH binaries when the wrong ``LD_LIBRARY_PATH`` is
|
||||
loaded.
|
||||
|
||||
3. Recursive module systems such as LMod are not necessary.
|
||||
|
||||
4. Modules are not needed at all to execute binaries. If a path to a
|
||||
binary is known, it may be executed. For example, the path for a
|
||||
Spack-built compiler can be given to an IDE without requiring the
|
||||
IDE to load that compiler's module.
|
||||
|
||||
Unfortunately, Spacks' RPATH support does not work in all case. For example:
|
||||
|
||||
1. Software comes in many forms --- not just compiled ELF binaries,
|
||||
but also as interpreted code in Python, R, JVM bytecode, etc.
|
||||
Those systems almost universally use an environment variable
|
||||
analogous to ``LD_LIBRARY_PATH`` to dynamically load libraries.
|
||||
|
||||
2. Although Spack generally builds binaries with RPATH, it does not
|
||||
currently do so for compiled Python extensions (for example,
|
||||
``py-numpy``). Any libraries that these extensions depend on
|
||||
(``openblas`` in this case, for example) must be specified in the
|
||||
``LD_LIBRARY_PATH``.`
|
||||
|
||||
3. In some cases, Spack-generated binaries end up without a
|
||||
functional RPATH for no discernable reason.
|
||||
|
||||
In cases where RPATH support doesn't make things "just work," it can
|
||||
be necessary to load a module's dependencies as well as the module
|
||||
itself. This is done by adding the ``--dependencies`` flag to the
|
||||
``spack module loads`` command. For example, the following line,
|
||||
added to the script above, would be used to load Numpy, along with
|
||||
core Python, Setup TOols and a number of other packages:
|
||||
|
||||
.. code-block:: sh
|
||||
\$FIND --dependencies py-numpy
|
||||
|
||||
Extension Packages
|
||||
---------------------
|
||||
|
||||
Extensions (::ref:`packaging_extension` section) may be used as as an
|
||||
alternative to loading Python packages directly. If extensions are
|
||||
activated, then ``spack load python`` will also load all the
|
||||
extensions activated for the given ``python``. However, Spack
|
||||
extensions have two potential drawbacks:
|
||||
|
||||
1. Activated packages that involve compiled C extensions may still
|
||||
need their dependencies to be loaded manually. For example,
|
||||
``spack load openblas`` might be required to make ``py-numpy``
|
||||
work.
|
||||
|
||||
2. Extensions "break" a core feature of Spack, which is that multiple
|
||||
versions of a package can co-exist side-by-side. For example,
|
||||
suppose you wish to run a Python in two different environments but
|
||||
the same basic Python --- one with ``py-numpy@1.7`` and one with
|
||||
``py-numpy@1.8``. Spack extensions will not support this potential
|
||||
debugging use case.
|
||||
|
||||
|
||||
|
||||
Filesystem Views
|
||||
-------------------------------
|
||||
|
||||
The above
|
||||
|
||||
.. Maybe this is not the right location for this documentation.
|
||||
|
||||
The Spack installation area allows for many package installation trees
|
||||
to coexist and gives the user choices as to what versions and variants
|
||||
of packages to use. To use them, the user must rely on a way to
|
||||
aggregate a subset of those packages. The section on Environment
|
||||
Modules gives one good way to do that which relies on setting various
|
||||
environment variables. An alternative way to aggregate is through
|
||||
**filesystem views**.
|
||||
|
||||
A filesystem view is a single directory tree which is the union of the
|
||||
directory hierarchies of the individual package installation trees
|
||||
that have been included. The files of the view's installed packages
|
||||
are brought into the view by symbolic or hard links back to their
|
||||
location in the original Spack installation area. As the view is
|
||||
formed, any clashes due to a file having the exact same path in its
|
||||
package installation tree are handled in a first-come-first-served
|
||||
basis and a warning is printed. Packages and their dependencies can
|
||||
be both added and removed. During removal, empty directories will be
|
||||
purged. These operations can be limited to pertain to just the
|
||||
packages listed by the user or to exclude specific dependencies and
|
||||
they allow for software installed outside of Spack to coexist inside
|
||||
the filesystem view tree.
|
||||
|
||||
By its nature, a filesystem view represents a particular choice of one
|
||||
set of packages among all the versions and variants that are available
|
||||
in the Spack installation area. It is thus equivalent to the
|
||||
directory hiearchy that might exist under ``/usr/local``. While this
|
||||
limits a view to including only one version/variant of any package, it
|
||||
provides the benefits of having a simpler and traditional layout which
|
||||
may be used without any particular knowledge that its packages were
|
||||
built by Spack.
|
||||
|
||||
Views can be used for a variety of purposes including:
|
||||
|
||||
- A central installation in a traditional layout, eg ``/usr/local`` maintained over time by the sysadmin.
|
||||
- A self-contained installation area which may for the basis of a top-level atomic versioning scheme, eg ``/opt/pro`` vs ``/opt/dev``.
|
||||
- Providing an atomic and monolithic binary distribution, eg for delivery as a single tarball.
|
||||
- Producing ephemeral testing or developing environments.
|
||||
|
||||
Using Filesystem Views
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A filesystem view is created and packages are linked in by the ``spack
|
||||
view`` command's ``symlink`` and ``hardlink`` sub-commands. The
|
||||
``spack view remove`` command can be used to unlink some or all of the
|
||||
filesystem view.
|
||||
|
||||
The following example creates a filesystem view based
|
||||
on an installed ``cmake`` package and then removes from the view the
|
||||
files in the ``cmake`` package while retaining its dependencies.
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
|
||||
$ spack view -v symlink myview cmake@3.5.2
|
||||
==> Linking package: "ncurses"
|
||||
==> Linking package: "zlib"
|
||||
==> Linking package: "openssl"
|
||||
==> Linking package: "cmake"
|
||||
|
||||
$ ls myview/
|
||||
bin doc etc include lib share
|
||||
|
||||
$ ls myview/bin/
|
||||
captoinfo clear cpack ctest infotocap openssl tabs toe tset
|
||||
ccmake cmake c_rehash infocmp ncurses6-config reset tic tput
|
||||
|
||||
$ spack view -v -d false rm myview cmake@3.5.2
|
||||
==> Removing package: "cmake"
|
||||
|
||||
$ ls myview/bin/
|
||||
captoinfo c_rehash infotocap openssl tabs toe tset
|
||||
clear infocmp ncurses6-config reset tic tput
|
||||
|
||||
|
||||
Limitations of Filesystem Views
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This section describes some limitations that should be considered in
|
||||
using filesystems views.
|
||||
|
||||
Filesystem views are merely organizational. The binary executable
|
||||
programs, shared libraries and other build products found in a view
|
||||
are mere links into the "real" Spack installation area. If a view is
|
||||
built with symbolic links it requires the Spack-installed package to
|
||||
be kept in place. Building a view with hardlinks removes this
|
||||
requirement but any internal paths (eg, rpath or ``#!`` interpreter
|
||||
specifications) will still require the Spack-installed package files
|
||||
to be in place.
|
||||
|
||||
.. FIXME: reference the relocation work of Hegner and Gartung.
|
||||
|
||||
As described above, when a view is built only a single instance of a
|
||||
file may exist in the unified filesystem tree. If more than one
|
||||
package provides a file at the same path (relative to its own root)
|
||||
then it is the first package added to the view that "wins". A warning
|
||||
is printed and it is up to the user to determine if the conflict
|
||||
matters.
|
||||
|
||||
It is up to the user to assure a consistent view is produced. In
|
||||
particular if the user excludes packages, limits the following of
|
||||
dependencies or removes packages the view may become inconsistent. In
|
||||
particular, if two packages require the same sub-tree of dependencies,
|
||||
removing one package (recursively) will remove its dependencies and
|
||||
leave the other package broken.
|
||||
|
||||
|
||||
|
||||
Build System Configuration Support
|
||||
----------------------------------
|
||||
|
||||
Imagine a developer creating a CMake-based (or Autotools) project in a local
|
||||
directory, which depends on libraries A-Z. Once Spack has installed
|
||||
those dependencies, one would like to run ``cmake`` with appropriate
|
||||
command line and environment so CMake can find them. The ``spack
|
||||
setup`` command does this conveniently, producing a CMake
|
||||
configuration that is essentially the same as how Spack *would have*
|
||||
configured the project. This can be demonstrated with a usage
|
||||
example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cd myproject
|
||||
spack setup myproject@local
|
||||
mkdir build; cd build
|
||||
../spconfig.py ..
|
||||
make
|
||||
make install
|
||||
|
||||
Notes:
|
||||
* Spack must have ``myproject/package.py`` in its repository for
|
||||
this to work.
|
||||
* ``spack setup`` produces the executable script ``spconfig.py`` in
|
||||
the local directory, and also creates the module file for the
|
||||
package. ``spconfig.py`` is normally run from the user's
|
||||
out-of-source build directory.
|
||||
* The version number given to ``spack setup`` is arbitrary, just
|
||||
like ``spack diy``. ``myproject/package.py`` does not need to
|
||||
have any valid downloadable versions listed (typical when a
|
||||
project is new).
|
||||
* spconfig.py produces a CMake configuration that *does not* use the
|
||||
Spack wrappers. Any resulting binaries *will not* use RPATH,
|
||||
unless the user has enabled it. This is recommended for
|
||||
development purposes, not production.
|
||||
* ``spconfig.py`` is human readable, and can serve as a developer
|
||||
reference of what dependencies are being used.
|
||||
* ``make install`` installs the package into the Spack repository,
|
||||
where it may be used by other Spack packages.
|
||||
* CMake-generated makefiles re-run CMake in some circumstances. Use
|
||||
of ``spconfig.py`` breaks this behavior, requiring the developer
|
||||
to manually re-run ``spconfig.py`` when a ``CMakeLists.txt`` file
|
||||
has changed.
|
||||
|
||||
CMakePackage
|
||||
~~~~~~~~~~~~
|
||||
|
||||
In order ot enable ``spack setup`` functionality, the author of
|
||||
``myproject/package.py`` must subclass from ``CMakePackage`` instead
|
||||
of the standard ``Package`` superclass. Because CMake is
|
||||
standardized, the packager does not need to tell Spack how to run
|
||||
``cmake; make; make install``. Instead the packager only needs to
|
||||
create (optional) methods ``configure_args()`` and ``configure_env()``, which
|
||||
provide the arguments (as a list) and extra environment variables (as
|
||||
a dict) to provide to the ``cmake`` command. Usually, these will
|
||||
translate variant flags into CMake definitions. For example:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
def configure_args(self):
|
||||
spec = self.spec
|
||||
return [
|
||||
'-DUSE_EVERYTRACE=%s' % ('YES' if '+everytrace' in spec else 'NO'),
|
||||
'-DBUILD_PYTHON=%s' % ('YES' if '+python' in spec else 'NO'),
|
||||
'-DBUILD_GRIDGEN=%s' % ('YES' if '+gridgen' in spec else 'NO'),
|
||||
'-DBUILD_COUPLER=%s' % ('YES' if '+coupler' in spec else 'NO'),
|
||||
'-DUSE_PISM=%s' % ('YES' if '+pism' in spec else 'NO')]
|
||||
|
||||
If needed, a packager may also override methods defined in
|
||||
``StagedPackage`` (see below).
|
||||
|
||||
|
||||
StagedPackage
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
``CMakePackage`` is implemented by subclassing the ``StagedPackage``
|
||||
superclass, which breaks down the standard ``Package.install()``
|
||||
method into several sub-stages: ``setup``, ``configure``, ``build``
|
||||
and ``install``. Details:
|
||||
|
||||
* Instead of implementing the standard ``install()`` method, package
|
||||
authors implement the methods for the sub-stages
|
||||
``install_setup()``, ``install_configure()``,
|
||||
``install_build()``, and ``install_install()``.
|
||||
|
||||
* The ``spack install`` command runs the sub-stages ``configure``,
|
||||
``build`` and ``install`` in order. (The ``setup`` stage is
|
||||
not run by default; see below).
|
||||
* The ``spack setup`` command runs the sub-stages ``setup``
|
||||
and a dummy install (to create the module file).
|
||||
* The sub-stage install methods take no arguments (other than
|
||||
``self``). The arguments ``spec`` and ``prefix`` to the standard
|
||||
``install()`` method may be accessed via ``self.spec`` and
|
||||
``self.prefix``.
|
||||
|
||||
GNU Autotools
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
The ``setup`` functionality is currently only available for
|
||||
CMake-based packages. Extending this functionality to GNU
|
||||
Autotools-based packages would be easy (and should be done by a
|
||||
developer who actively uses Autotools). Packages that use
|
||||
non-standard build systems can gain ``setup`` functionality by
|
||||
subclassing ``StagedPackage`` directly.
|
||||
|
||||
403
lib/spack/env/cc
vendored
403
lib/spack/env/cc
vendored
@@ -1,27 +1,27 @@
|
||||
#!/bin/bash
|
||||
##############################################################################
|
||||
# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
|
||||
# Copyright (c) 2013-2016, Lawrence Livermore National Security, LLC.
|
||||
# Produced at the Lawrence Livermore National Laboratory.
|
||||
#
|
||||
# This file is part of Spack.
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License (as published by
|
||||
# the Free Software Foundation) version 2.1 dated February 1999.
|
||||
# it under the terms of the GNU Lesser General Public License (as
|
||||
# published by the Free Software Foundation) version 2.1, February 1999.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
|
||||
# conditions of the GNU General Public License for more details.
|
||||
# conditions of the GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
##############################################################################
|
||||
#
|
||||
# Spack compiler wrapper script.
|
||||
@@ -38,19 +38,27 @@
|
||||
# -Wl,-rpath arguments for dependency /lib directories.
|
||||
#
|
||||
|
||||
# This is the list of environment variables that need to be set before
|
||||
# the script runs. They are set by routines in spack.build_environment
|
||||
# This is an array of environment variables that need to be set before
|
||||
# the script runs. They are set by routines in spack.build_environment
|
||||
# as part of spack.package.Package.do_install().
|
||||
parameters="
|
||||
SPACK_PREFIX
|
||||
SPACK_ENV_PATH
|
||||
SPACK_DEBUG_LOG_DIR
|
||||
SPACK_COMPILER_SPEC
|
||||
SPACK_SHORT_SPEC"
|
||||
parameters=(
|
||||
SPACK_PREFIX
|
||||
SPACK_ENV_PATH
|
||||
SPACK_DEBUG_LOG_DIR
|
||||
SPACK_COMPILER_SPEC
|
||||
SPACK_CC_RPATH_ARG
|
||||
SPACK_CXX_RPATH_ARG
|
||||
SPACK_F77_RPATH_ARG
|
||||
SPACK_FC_RPATH_ARG
|
||||
SPACK_SHORT_SPEC
|
||||
)
|
||||
|
||||
# The compiler input variables are checked for sanity later:
|
||||
# SPACK_CC, SPACK_CXX, SPACK_F77, SPACK_FC
|
||||
# Debug flag is optional; set to true for debug logging:
|
||||
# The default compiler flags are passed from these variables:
|
||||
# SPACK_CFLAGS, SPACK_CXXFLAGS, SPACK_FCFLAGS, SPACK_FFLAGS,
|
||||
# SPACK_LDFLAGS, SPACK_LDLIBS
|
||||
# Debug env var is optional; set to true for debug logging:
|
||||
# SPACK_DEBUG
|
||||
# Test command is used to unit test the compiler script.
|
||||
# SPACK_TEST_COMMAND
|
||||
@@ -64,13 +72,12 @@ function die {
|
||||
exit 1
|
||||
}
|
||||
|
||||
for param in $parameters; do
|
||||
if [ -z "${!param}" ]; then
|
||||
die "Spack compiler must be run from spack! Input $param was missing!"
|
||||
for param in ${parameters[@]}; do
|
||||
if [[ -z ${!param} ]]; then
|
||||
die "Spack compiler must be run from Spack! Input '$param' is missing."
|
||||
fi
|
||||
done
|
||||
|
||||
#
|
||||
# Figure out the type of compiler, the language, and the mode so that
|
||||
# the compiler script knows what to do.
|
||||
#
|
||||
@@ -78,33 +85,43 @@ done
|
||||
# 'command' is set based on the input command to $SPACK_[CC|CXX|F77|F90]
|
||||
#
|
||||
# 'mode' is set to one of:
|
||||
# vcheck version check
|
||||
# cpp preprocess
|
||||
# cc compile
|
||||
# as assemble
|
||||
# ld link
|
||||
# ccld compile & link
|
||||
# cpp preprocessor
|
||||
# vcheck version check
|
||||
#
|
||||
|
||||
command=$(basename "$0")
|
||||
comp="CC"
|
||||
case "$command" in
|
||||
cc|gcc|c89|c99|clang)
|
||||
command="$SPACK_CC"
|
||||
language="C"
|
||||
;;
|
||||
c++|CC|g++|clang++)
|
||||
command="$SPACK_CXX"
|
||||
language="C++"
|
||||
;;
|
||||
f77)
|
||||
command="$SPACK_F77"
|
||||
language="Fortran 77"
|
||||
;;
|
||||
fc|f90|f95)
|
||||
command="$SPACK_FC"
|
||||
language="Fortran 90"
|
||||
;;
|
||||
cpp)
|
||||
mode=cpp
|
||||
;;
|
||||
cc|c89|c99|gcc|clang|icc|pgcc|xlc)
|
||||
command="$SPACK_CC"
|
||||
language="C"
|
||||
comp="CC"
|
||||
lang_flags=C
|
||||
;;
|
||||
c++|CC|g++|clang++|icpc|pgc++|xlc++)
|
||||
command="$SPACK_CXX"
|
||||
language="C++"
|
||||
comp="CXX"
|
||||
lang_flags=CXX
|
||||
;;
|
||||
ftn|f90|fc|f95|gfortran|ifort|pgfortran|xlf90|nagfor)
|
||||
command="$SPACK_FC"
|
||||
language="Fortran 90"
|
||||
comp="FC"
|
||||
lang_flags=F
|
||||
;;
|
||||
f77|gfortran|ifort|pgfortran|xlf|nagfor|ftn)
|
||||
command="$SPACK_F77"
|
||||
language="Fortran 77"
|
||||
comp="F77"
|
||||
lang_flags=F
|
||||
;;
|
||||
ld)
|
||||
mode=ld
|
||||
;;
|
||||
@@ -113,179 +130,177 @@ case "$command" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# Finish setting up the mode.
|
||||
if [ -z "$mode" ]; then
|
||||
mode=ccld
|
||||
# If any of the arguments below are present, then the mode is vcheck.
|
||||
# In vcheck mode, nothing is added in terms of extra search paths or
|
||||
# libraries.
|
||||
if [[ -z $mode ]]; then
|
||||
for arg in "$@"; do
|
||||
if [ "$arg" = -v -o "$arg" = -V -o "$arg" = --version -o "$arg" = -dumpversion ]; then
|
||||
if [[ $arg == -v || $arg == -V || $arg == --version || $arg == -dumpversion ]]; then
|
||||
mode=vcheck
|
||||
break
|
||||
elif [ "$arg" = -E ]; then
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Finish setting up the mode.
|
||||
if [[ -z $mode ]]; then
|
||||
mode=ccld
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == -E ]]; then
|
||||
mode=cpp
|
||||
break
|
||||
elif [ "$arg" = -c ]; then
|
||||
elif [[ $arg == -S ]]; then
|
||||
mode=as
|
||||
break
|
||||
elif [[ $arg == -c ]]; then
|
||||
mode=cc
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Dump the version and exist if we're in testing mode.
|
||||
if [ "$SPACK_TEST_COMMAND" = "dump-mode" ]; then
|
||||
# Set up rpath variable according to language.
|
||||
eval rpath=\$SPACK_${comp}_RPATH_ARG
|
||||
|
||||
# Dump the version and exit if we're in testing mode.
|
||||
if [[ $SPACK_TEST_COMMAND == dump-mode ]]; then
|
||||
echo "$mode"
|
||||
exit
|
||||
fi
|
||||
|
||||
# Check that at least one of the real commands was actually selected,
|
||||
# otherwise we don't know what to execute.
|
||||
if [ -z "$command" ]; then
|
||||
if [[ -z $command ]]; then
|
||||
die "ERROR: Compiler '$SPACK_COMPILER_SPEC' does not support compiling $language programs."
|
||||
fi
|
||||
|
||||
#
|
||||
# Filter '.' and Spack environment directories out of PATH so that
|
||||
# this script doesn't just call itself
|
||||
#
|
||||
IFS=':' read -ra env_path <<< "$PATH"
|
||||
IFS=':' read -ra spack_env_dirs <<< "$SPACK_ENV_PATH"
|
||||
spack_env_dirs+=("" ".")
|
||||
PATH=""
|
||||
for dir in "${env_path[@]}"; do
|
||||
addpath=true
|
||||
for env_dir in "${spack_env_dirs[@]}"; do
|
||||
if [[ $dir == $env_dir ]]; then
|
||||
addpath=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
if $addpath; then
|
||||
PATH="${PATH:+$PATH:}$dir"
|
||||
fi
|
||||
done
|
||||
export PATH
|
||||
|
||||
if [[ $mode == vcheck ]]; then
|
||||
exec ${command} "$@"
|
||||
fi
|
||||
|
||||
# Darwin's linker has a -r argument that merges object files together.
|
||||
# It doesn't work with -rpath.
|
||||
# This variable controls whether they are added.
|
||||
add_rpaths=true
|
||||
if [[ $mode == ld && "$SPACK_SHORT_SPEC" =~ "darwin" ]]; then
|
||||
for arg in "$@"; do
|
||||
if [[ $arg == -r ]]; then
|
||||
add_rpaths=false
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
# Save original command for debug logging
|
||||
input_command="$@"
|
||||
args=("$@")
|
||||
|
||||
#
|
||||
# Now do real parsing of the command line args, trying hard to keep
|
||||
# non-rpath linker arguments in the proper order w.r.t. other command
|
||||
# line arguments. This is important for things like groups.
|
||||
#
|
||||
includes=()
|
||||
libraries=()
|
||||
libs=()
|
||||
rpaths=()
|
||||
other_args=()
|
||||
# Prepend cppflags, cflags, cxxflags, fcflags, fflags, and ldflags
|
||||
|
||||
while [ -n "$1" ]; do
|
||||
case "$1" in
|
||||
-I*)
|
||||
arg="${1#-I}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
includes+=("$arg")
|
||||
;;
|
||||
-L*)
|
||||
arg="${1#-L}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
libraries+=("$arg")
|
||||
;;
|
||||
-l*)
|
||||
arg="${1#-l}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
libs+=("$arg")
|
||||
;;
|
||||
-Wl,*)
|
||||
arg="${1#-Wl,}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
if [[ "$arg" = -rpath=* ]]; then
|
||||
rpaths+=("${arg#-rpath=}")
|
||||
elif [[ "$arg" = -rpath ]]; then
|
||||
shift; arg="$1"
|
||||
if [[ "$arg" != -Wl,* ]]; then
|
||||
die "-Wl,-rpath was not followed by -Wl,*"
|
||||
fi
|
||||
rpaths+=("${arg#-Wl,}")
|
||||
else
|
||||
other_args+=("-Wl,$arg")
|
||||
fi
|
||||
;;
|
||||
-Xlinker,*)
|
||||
arg="${1#-Xlinker,}"
|
||||
if [ -z "$arg" ]; then shift; arg="$1"; fi
|
||||
if [[ "$arg" = -rpath=* ]]; then
|
||||
rpaths+=("${arg#-rpath=}")
|
||||
elif [[ "$arg" = -rpath ]]; then
|
||||
shift; arg="$1"
|
||||
if [[ "$arg" != -Xlinker,* ]]; then
|
||||
die "-Xlinker,-rpath was not followed by -Xlinker,*"
|
||||
fi
|
||||
rpaths+=("${arg#-Xlinker,}")
|
||||
else
|
||||
other_args+=("-Xlinker,$arg")
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
other_args+=("$1")
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
# Add ldflags
|
||||
case "$mode" in
|
||||
ld|ccld)
|
||||
args=(${SPACK_LDFLAGS[@]} "${args[@]}") ;;
|
||||
esac
|
||||
|
||||
# Dump parsed values for unit testing if asked for
|
||||
if [ -n "$SPACK_TEST_COMMAND" ]; then
|
||||
IFS=$'\n'
|
||||
case "$SPACK_TEST_COMMAND" in
|
||||
dump-includes) echo "${includes[*]}";;
|
||||
dump-libraries) echo "${libraries[*]}";;
|
||||
dump-libs) echo "${libs[*]}";;
|
||||
dump-rpaths) echo "${rpaths[*]}";;
|
||||
dump-other-args) echo "${other_args[*]}";;
|
||||
dump-all)
|
||||
echo "INCLUDES:"
|
||||
echo "${includes[*]}"
|
||||
echo
|
||||
echo "LIBRARIES:"
|
||||
echo "${libraries[*]}"
|
||||
echo
|
||||
echo "LIBS:"
|
||||
echo "${libs[*]}"
|
||||
echo
|
||||
echo "RPATHS:"
|
||||
echo "${rpaths[*]}"
|
||||
echo
|
||||
echo "ARGS:"
|
||||
echo "${other_args[*]}"
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Unknown test command"
|
||||
exit 1 ;;
|
||||
esac
|
||||
exit
|
||||
fi
|
||||
# Add compiler flags.
|
||||
case "$mode" in
|
||||
cc|ccld)
|
||||
# Add c, cxx, fc, and f flags
|
||||
case $lang_flags in
|
||||
C)
|
||||
args=(${SPACK_CFLAGS[@]} "${args[@]}") ;;
|
||||
CXX)
|
||||
args=(${SPACK_CXXFLAGS[@]} "${args[@]}") ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Add cppflags
|
||||
case "$mode" in
|
||||
cpp|as|cc|ccld)
|
||||
args=(${SPACK_CPPFLAGS[@]} "${args[@]}") ;;
|
||||
esac
|
||||
|
||||
case "$mode" in cc|ccld)
|
||||
# Add fortran flags
|
||||
case $lang_flags in
|
||||
F)
|
||||
args=(${SPACK_FFLAGS[@]} "${args[@]}") ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
|
||||
# Read spack dependencies from the path environment variable
|
||||
IFS=':' read -ra deps <<< "$SPACK_DEPENDENCIES"
|
||||
for dep in "${deps[@]}"; do
|
||||
if [ -d "$dep/include" ]; then
|
||||
includes+=("$dep/include")
|
||||
# Prepend include directories
|
||||
if [[ -d $dep/include ]]; then
|
||||
if [[ $mode == cpp || $mode == cc || $mode == as || $mode == ccld ]]; then
|
||||
args=("-I$dep/include" "${args[@]}")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$dep/lib" ]; then
|
||||
libraries+=("$dep/lib")
|
||||
rpaths+=("$dep/lib")
|
||||
# Prepend lib and RPATH directories
|
||||
if [[ -d $dep/lib ]]; then
|
||||
if [[ $mode == ccld ]]; then
|
||||
$add_rpaths && args=("$rpath$dep/lib" "${args[@]}")
|
||||
args=("-L$dep/lib" "${args[@]}")
|
||||
elif [[ $mode == ld ]]; then
|
||||
$add_rpaths && args=("-rpath" "$dep/lib" "${args[@]}")
|
||||
args=("-L$dep/lib" "${args[@]}")
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "$dep/lib64" ]; then
|
||||
libraries+=("$dep/lib64")
|
||||
rpaths+=("$dep/lib64")
|
||||
# Prepend lib64 and RPATH directories
|
||||
if [[ -d $dep/lib64 ]]; then
|
||||
if [[ $mode == ccld ]]; then
|
||||
$add_rpaths && args=("$rpath$dep/lib64" "${args[@]}")
|
||||
args=("-L$dep/lib64" "${args[@]}")
|
||||
elif [[ $mode == ld ]]; then
|
||||
$add_rpaths && args=("-rpath" "$dep/lib64" "${args[@]}")
|
||||
args=("-L$dep/lib64" "${args[@]}")
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Include all -L's and prefix/whatever dirs in rpath
|
||||
for dir in "${libraries[@]}"; do
|
||||
[ "$dir" != "." ] && rpaths+=("$dir")
|
||||
done
|
||||
rpaths+=("$SPACK_PREFIX/lib")
|
||||
rpaths+=("$SPACK_PREFIX/lib64")
|
||||
|
||||
# Put the arguments together
|
||||
args=()
|
||||
for dir in "${includes[@]}"; do args+=("-I$dir"); done
|
||||
args+=("${other_args[@]}")
|
||||
for dir in "${libraries[@]}"; do args+=("-L$dir"); done
|
||||
for lib in "${libs[@]}"; do args+=("-l$lib"); done
|
||||
|
||||
if [ "$mode" = ccld ]; then
|
||||
for dir in "${rpaths[@]}"; do
|
||||
args+=("-Wl,-rpath")
|
||||
args+=("-Wl,$dir");
|
||||
done
|
||||
elif [ "$mode" = ld ]; then
|
||||
for dir in "${rpaths[@]}"; do
|
||||
args+=("-rpath")
|
||||
args+=("$dir");
|
||||
done
|
||||
if [[ $mode == ccld ]]; then
|
||||
$add_rpaths && args=("$rpath$SPACK_PREFIX/lib64" "${args[@]}")
|
||||
$add_rpaths && args=("$rpath$SPACK_PREFIX/lib" "${args[@]}")
|
||||
elif [[ $mode == ld ]]; then
|
||||
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib64" "${args[@]}")
|
||||
$add_rpaths && args=("-rpath" "$SPACK_PREFIX/lib" "${args[@]}")
|
||||
fi
|
||||
|
||||
# Add SPACK_LDLIBS to args
|
||||
case "$mode" in
|
||||
ld|ccld)
|
||||
args=("${args[@]}" ${SPACK_LDLIBS[@]}) ;;
|
||||
esac
|
||||
|
||||
#
|
||||
# Unset pesky environment variables that could affect build sanity.
|
||||
#
|
||||
@@ -293,40 +308,24 @@ unset LD_LIBRARY_PATH
|
||||
unset LD_RUN_PATH
|
||||
unset DYLD_LIBRARY_PATH
|
||||
|
||||
#
|
||||
# Filter '.' and Spack environment directories out of PATH so that
|
||||
# this script doesn't just call itself
|
||||
#
|
||||
IFS=':' read -ra env_path <<< "$PATH"
|
||||
IFS=':' read -ra spack_env_dirs <<< "$SPACK_ENV_PATH"
|
||||
spack_env_dirs+=(".")
|
||||
PATH=""
|
||||
for dir in "${env_path[@]}"; do
|
||||
remove=""
|
||||
for rm_dir in "${spack_env_dirs[@]}"; do
|
||||
if [ "$dir" = "$rm_dir" ]; then remove=True; fi
|
||||
done
|
||||
if [ -z "$remove" ]; then
|
||||
if [ -z "$PATH" ]; then
|
||||
PATH="$dir"
|
||||
else
|
||||
PATH="$PATH:$dir"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
export PATH
|
||||
full_command=("$command" "${args[@]}")
|
||||
|
||||
full_command=("$command")
|
||||
full_command+=("${args[@]}")
|
||||
# In test command mode, write out full command for Spack tests.
|
||||
if [[ $SPACK_TEST_COMMAND == dump-args ]]; then
|
||||
echo "${full_command[@]}"
|
||||
exit
|
||||
elif [[ -n $SPACK_TEST_COMMAND ]]; then
|
||||
die "ERROR: Unknown test command"
|
||||
fi
|
||||
|
||||
#
|
||||
# Write the input and output commands to debug logs if it's asked for.
|
||||
#
|
||||
if [ "$SPACK_DEBUG" = "TRUE" ]; then
|
||||
if [[ $SPACK_DEBUG == TRUE ]]; then
|
||||
input_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_SHORT_SPEC.in.log"
|
||||
output_log="$SPACK_DEBUG_LOG_DIR/spack-cc-$SPACK_SHORT_SPEC.out.log"
|
||||
echo "$input_command" >> $input_log
|
||||
echo "$mode ${full_command[@]}" >> $output_log
|
||||
echo "[$mode] $command $input_command" >> "$input_log"
|
||||
echo "[$mode] ${full_command[@]}" >> "$output_log"
|
||||
fi
|
||||
|
||||
exec "${full_command[@]}"
|
||||
|
||||
1
lib/spack/env/clang/clang
vendored
Symbolic link
1
lib/spack/env/clang/clang
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/clang/clang++
vendored
Symbolic link
1
lib/spack/env/clang/clang++
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/cray/CC
vendored
Symbolic link
1
lib/spack/env/cray/CC
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/cray/cc
vendored
Symbolic link
1
lib/spack/env/cray/cc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/cray/ftn
vendored
Symbolic link
1
lib/spack/env/cray/ftn
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/craype/CC
vendored
Symbolic link
1
lib/spack/env/craype/CC
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/craype/cc
vendored
Symbolic link
1
lib/spack/env/craype/cc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/craype/ftn
vendored
Symbolic link
1
lib/spack/env/craype/ftn
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/gcc/g++
vendored
Symbolic link
1
lib/spack/env/gcc/g++
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/gcc/gcc
vendored
Symbolic link
1
lib/spack/env/gcc/gcc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/gcc/gfortran
vendored
Symbolic link
1
lib/spack/env/gcc/gfortran
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/intel/icc
vendored
Symbolic link
1
lib/spack/env/intel/icc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/intel/icpc
vendored
Symbolic link
1
lib/spack/env/intel/icpc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/intel/ifort
vendored
Symbolic link
1
lib/spack/env/intel/ifort
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/nag/nagfor
vendored
Symbolic link
1
lib/spack/env/nag/nagfor
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/pgi/pgc++
vendored
Symbolic link
1
lib/spack/env/pgi/pgc++
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/pgi/pgcc
vendored
Symbolic link
1
lib/spack/env/pgi/pgcc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/pgi/pgfortran
vendored
Symbolic link
1
lib/spack/env/pgi/pgfortran
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/xl/xlc
vendored
Symbolic link
1
lib/spack/env/xl/xlc
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/xl/xlc++
vendored
Symbolic link
1
lib/spack/env/xl/xlc++
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/xl/xlf
vendored
Symbolic link
1
lib/spack/env/xl/xlf
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
1
lib/spack/env/xl/xlf90
vendored
Symbolic link
1
lib/spack/env/xl/xlf90
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../cc
|
||||
11
lib/spack/external/__init__.py
vendored
11
lib/spack/external/__init__.py
vendored
@@ -6,7 +6,7 @@
|
||||
# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
|
||||
# LLNL-CODE-647188
|
||||
#
|
||||
# For details, see https://scalability-llnl.github.io/spack
|
||||
# For details, see https://github.com/llnl/spack
|
||||
# Please also see the LICENSE file for our notice and the LGPL.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@@ -28,6 +28,11 @@
|
||||
|
||||
So far:
|
||||
argparse: We include our own version to be Python 2.6 compatible.
|
||||
pyqver2: External script to query required python version of python source code.
|
||||
Used for ensuring 2.6 compatibility.
|
||||
|
||||
pyqver2: External script to query required python version of
|
||||
python source code. Used for ensuring 2.6 compatibility.
|
||||
|
||||
functools: Used for implementation of total_ordering.
|
||||
|
||||
yaml: Used for config files.
|
||||
"""
|
||||
|
||||
22
lib/spack/external/argparse.py
vendored
22
lib/spack/external/argparse.py
vendored
@@ -1067,9 +1067,13 @@ class _SubParsersAction(Action):
|
||||
|
||||
class _ChoicesPseudoAction(Action):
|
||||
|
||||
def __init__(self, name, help):
|
||||
def __init__(self, name, aliases, help):
|
||||
metavar = dest = name
|
||||
if aliases:
|
||||
metavar += ' (%s)' % ', '.join(aliases)
|
||||
sup = super(_SubParsersAction._ChoicesPseudoAction, self)
|
||||
sup.__init__(option_strings=[], dest=name, help=help)
|
||||
sup.__init__(option_strings=[], dest=dest, help=help,
|
||||
metavar=metavar)
|
||||
|
||||
def __init__(self,
|
||||
option_strings,
|
||||
@@ -1097,15 +1101,22 @@ def add_parser(self, name, **kwargs):
|
||||
if kwargs.get('prog') is None:
|
||||
kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
|
||||
|
||||
aliases = kwargs.pop('aliases', ())
|
||||
|
||||
# create a pseudo-action to hold the choice help
|
||||
if 'help' in kwargs:
|
||||
help = kwargs.pop('help')
|
||||
choice_action = self._ChoicesPseudoAction(name, help)
|
||||
choice_action = self._ChoicesPseudoAction(name, aliases, help)
|
||||
self._choices_actions.append(choice_action)
|
||||
|
||||
# create the parser and add it to the map
|
||||
parser = self._parser_class(**kwargs)
|
||||
self._name_parser_map[name] = parser
|
||||
|
||||
# make parser available under aliases also
|
||||
for alias in aliases:
|
||||
self._name_parser_map[alias] = parser
|
||||
|
||||
return parser
|
||||
|
||||
def _get_subactions(self):
|
||||
@@ -1123,8 +1134,9 @@ def __call__(self, parser, namespace, values, option_string=None):
|
||||
try:
|
||||
parser = self._name_parser_map[parser_name]
|
||||
except KeyError:
|
||||
tup = parser_name, ', '.join(self._name_parser_map)
|
||||
msg = _('unknown parser %r (choices: %s)' % tup)
|
||||
args = {'parser_name': parser_name,
|
||||
'choices': ', '.join(self._name_parser_map)}
|
||||
msg = _('unknown parser %(parser_name)r (choices: %(choices)s)') % args
|
||||
raise ArgumentError(self, msg)
|
||||
|
||||
# parse all the remaining options into the namespace
|
||||
|
||||
19
lib/spack/external/jsonschema/COPYING
vendored
Normal file
19
lib/spack/external/jsonschema/COPYING
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2013 Julian Berman
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
104
lib/spack/external/jsonschema/README.rst
vendored
Normal file
104
lib/spack/external/jsonschema/README.rst
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
==========
|
||||
jsonschema
|
||||
==========
|
||||
|
||||
``jsonschema`` is an implementation of `JSON Schema <http://json-schema.org>`_
|
||||
for Python (supporting 2.6+ including Python 3).
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
>>> from jsonschema import validate
|
||||
|
||||
>>> # A sample schema, like what we'd get from json.load()
|
||||
>>> schema = {
|
||||
... "type" : "object",
|
||||
... "properties" : {
|
||||
... "price" : {"type" : "number"},
|
||||
... "name" : {"type" : "string"},
|
||||
... },
|
||||
... }
|
||||
|
||||
>>> # If no exception is raised by validate(), the instance is valid.
|
||||
>>> validate({"name" : "Eggs", "price" : 34.99}, schema)
|
||||
|
||||
>>> validate(
|
||||
... {"name" : "Eggs", "price" : "Invalid"}, schema
|
||||
... ) # doctest: +IGNORE_EXCEPTION_DETAIL
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValidationError: 'Invalid' is not of type 'number'
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Full support for
|
||||
`Draft 3 <https://python-jsonschema.readthedocs.org/en/latest/validate/#jsonschema.Draft3Validator>`_
|
||||
**and** `Draft 4 <https://python-jsonschema.readthedocs.org/en/latest/validate/#jsonschema.Draft4Validator>`_
|
||||
of the schema.
|
||||
|
||||
* `Lazy validation <https://python-jsonschema.readthedocs.org/en/latest/validate/#jsonschema.IValidator.iter_errors>`_
|
||||
that can iteratively report *all* validation errors.
|
||||
|
||||
* Small and extensible
|
||||
|
||||
* `Programmatic querying <https://python-jsonschema.readthedocs.org/en/latest/errors/#module-jsonschema>`_
|
||||
of which properties or items failed validation.
|
||||
|
||||
|
||||
Release Notes
|
||||
-------------
|
||||
|
||||
* A simple CLI was added for validation
|
||||
* Validation errors now keep full absolute paths and absolute schema paths in
|
||||
their ``absolute_path`` and ``absolute_schema_path`` attributes. The ``path``
|
||||
and ``schema_path`` attributes are deprecated in favor of ``relative_path``
|
||||
and ``relative_schema_path``\ .
|
||||
|
||||
*Note:* Support for Python 3.2 was dropped in this release, and installation
|
||||
now uses setuptools.
|
||||
|
||||
|
||||
Running the Test Suite
|
||||
----------------------
|
||||
|
||||
``jsonschema`` uses the wonderful `Tox <http://tox.readthedocs.org>`_ for its
|
||||
test suite. (It really is wonderful, if for some reason you haven't heard of
|
||||
it, you really should use it for your projects).
|
||||
|
||||
Assuming you have ``tox`` installed (perhaps via ``pip install tox`` or your
|
||||
package manager), just run ``tox`` in the directory of your source checkout to
|
||||
run ``jsonschema``'s test suite on all of the versions of Python ``jsonschema``
|
||||
supports. Note that you'll need to have all of those versions installed in
|
||||
order to run the tests on each of them, otherwise ``tox`` will skip (and fail)
|
||||
the tests on that version.
|
||||
|
||||
Of course you're also free to just run the tests on a single version with your
|
||||
favorite test runner. The tests live in the ``jsonschema.tests`` package.
|
||||
|
||||
|
||||
Community
|
||||
---------
|
||||
|
||||
There's a `mailing list <https://groups.google.com/forum/#!forum/jsonschema>`_
|
||||
for this implementation on Google Groups.
|
||||
|
||||
Please join, and feel free to send questions there.
|
||||
|
||||
|
||||
Contributing
|
||||
------------
|
||||
|
||||
I'm Julian Berman.
|
||||
|
||||
``jsonschema`` is on `GitHub <http://github.com/Julian/jsonschema>`_.
|
||||
|
||||
Get in touch, via GitHub or otherwise, if you've got something to contribute,
|
||||
it'd be most welcome!
|
||||
|
||||
You can also generally find me on Freenode (nick: ``tos9``) in various
|
||||
channels, including ``#python``.
|
||||
|
||||
If you feel overwhelmingly grateful, you can woo me with beer money on
|
||||
`Gittip <https://www.gittip.com/Julian/>`_ or via Google Wallet with the email
|
||||
in my GitHub profile.
|
||||
26
lib/spack/external/jsonschema/__init__.py
vendored
Normal file
26
lib/spack/external/jsonschema/__init__.py
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
"""
|
||||
An implementation of JSON Schema for Python
|
||||
|
||||
The main functionality is provided by the validator classes for each of the
|
||||
supported JSON Schema versions.
|
||||
|
||||
Most commonly, :func:`validate` is the quickest way to simply validate a given
|
||||
instance under a schema, and will create a validator for you.
|
||||
|
||||
"""
|
||||
|
||||
from jsonschema.exceptions import (
|
||||
ErrorTree, FormatError, RefResolutionError, SchemaError, ValidationError
|
||||
)
|
||||
from jsonschema._format import (
|
||||
FormatChecker, draft3_format_checker, draft4_format_checker,
|
||||
)
|
||||
from jsonschema.validators import (
|
||||
Draft3Validator, Draft4Validator, RefResolver, validate
|
||||
)
|
||||
|
||||
|
||||
__version__ = "2.4.0"
|
||||
|
||||
|
||||
# flake8: noqa
|
||||
2
lib/spack/external/jsonschema/__main__.py
vendored
Normal file
2
lib/spack/external/jsonschema/__main__.py
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
from jsonschema.cli import main
|
||||
main()
|
||||
240
lib/spack/external/jsonschema/_format.py
vendored
Normal file
240
lib/spack/external/jsonschema/_format.py
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
import datetime
|
||||
import re
|
||||
import socket
|
||||
|
||||
from jsonschema.compat import str_types
|
||||
from jsonschema.exceptions import FormatError
|
||||
|
||||
|
||||
class FormatChecker(object):
|
||||
"""
|
||||
A ``format`` property checker.
|
||||
|
||||
JSON Schema does not mandate that the ``format`` property actually do any
|
||||
validation. If validation is desired however, instances of this class can
|
||||
be hooked into validators to enable format validation.
|
||||
|
||||
:class:`FormatChecker` objects always return ``True`` when asked about
|
||||
formats that they do not know how to validate.
|
||||
|
||||
To check a custom format using a function that takes an instance and
|
||||
returns a ``bool``, use the :meth:`FormatChecker.checks` or
|
||||
:meth:`FormatChecker.cls_checks` decorators.
|
||||
|
||||
:argument iterable formats: the known formats to validate. This argument
|
||||
can be used to limit which formats will be used
|
||||
during validation.
|
||||
|
||||
"""
|
||||
|
||||
checkers = {}
|
||||
|
||||
def __init__(self, formats=None):
|
||||
if formats is None:
|
||||
self.checkers = self.checkers.copy()
|
||||
else:
|
||||
self.checkers = dict((k, self.checkers[k]) for k in formats)
|
||||
|
||||
def checks(self, format, raises=()):
|
||||
"""
|
||||
Register a decorated function as validating a new format.
|
||||
|
||||
:argument str format: the format that the decorated function will check
|
||||
:argument Exception raises: the exception(s) raised by the decorated
|
||||
function when an invalid instance is found. The exception object
|
||||
will be accessible as the :attr:`ValidationError.cause` attribute
|
||||
of the resulting validation error.
|
||||
|
||||
"""
|
||||
|
||||
def _checks(func):
|
||||
self.checkers[format] = (func, raises)
|
||||
return func
|
||||
return _checks
|
||||
|
||||
cls_checks = classmethod(checks)
|
||||
|
||||
def check(self, instance, format):
|
||||
"""
|
||||
Check whether the instance conforms to the given format.
|
||||
|
||||
:argument instance: the instance to check
|
||||
:type: any primitive type (str, number, bool)
|
||||
:argument str format: the format that instance should conform to
|
||||
:raises: :exc:`FormatError` if instance does not conform to format
|
||||
|
||||
"""
|
||||
|
||||
if format not in self.checkers:
|
||||
return
|
||||
|
||||
func, raises = self.checkers[format]
|
||||
result, cause = None, None
|
||||
try:
|
||||
result = func(instance)
|
||||
except raises as e:
|
||||
cause = e
|
||||
if not result:
|
||||
raise FormatError(
|
||||
"%r is not a %r" % (instance, format), cause=cause,
|
||||
)
|
||||
|
||||
def conforms(self, instance, format):
|
||||
"""
|
||||
Check whether the instance conforms to the given format.
|
||||
|
||||
:argument instance: the instance to check
|
||||
:type: any primitive type (str, number, bool)
|
||||
:argument str format: the format that instance should conform to
|
||||
:rtype: bool
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
self.check(instance, format)
|
||||
except FormatError:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
|
||||
_draft_checkers = {"draft3": [], "draft4": []}
|
||||
|
||||
|
||||
def _checks_drafts(both=None, draft3=None, draft4=None, raises=()):
|
||||
draft3 = draft3 or both
|
||||
draft4 = draft4 or both
|
||||
|
||||
def wrap(func):
|
||||
if draft3:
|
||||
_draft_checkers["draft3"].append(draft3)
|
||||
func = FormatChecker.cls_checks(draft3, raises)(func)
|
||||
if draft4:
|
||||
_draft_checkers["draft4"].append(draft4)
|
||||
func = FormatChecker.cls_checks(draft4, raises)(func)
|
||||
return func
|
||||
return wrap
|
||||
|
||||
|
||||
@_checks_drafts("email")
|
||||
def is_email(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return "@" in instance
|
||||
|
||||
|
||||
_ipv4_re = re.compile(r"^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$")
|
||||
|
||||
@_checks_drafts(draft3="ip-address", draft4="ipv4")
|
||||
def is_ipv4(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
if not _ipv4_re.match(instance):
|
||||
return False
|
||||
return all(0 <= int(component) <= 255 for component in instance.split("."))
|
||||
|
||||
|
||||
if hasattr(socket, "inet_pton"):
|
||||
@_checks_drafts("ipv6", raises=socket.error)
|
||||
def is_ipv6(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return socket.inet_pton(socket.AF_INET6, instance)
|
||||
|
||||
|
||||
_host_name_re = re.compile(r"^[A-Za-z0-9][A-Za-z0-9\.\-]{1,255}$")
|
||||
|
||||
@_checks_drafts(draft3="host-name", draft4="hostname")
|
||||
def is_host_name(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
if not _host_name_re.match(instance):
|
||||
return False
|
||||
components = instance.split(".")
|
||||
for component in components:
|
||||
if len(component) > 63:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
try:
|
||||
import rfc3987
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
@_checks_drafts("uri", raises=ValueError)
|
||||
def is_uri(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return rfc3987.parse(instance, rule="URI")
|
||||
|
||||
|
||||
try:
|
||||
import strict_rfc3339
|
||||
except ImportError:
|
||||
try:
|
||||
import isodate
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
@_checks_drafts("date-time", raises=(ValueError, isodate.ISO8601Error))
|
||||
def is_date(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return isodate.parse_datetime(instance)
|
||||
else:
|
||||
@_checks_drafts("date-time")
|
||||
def is_date(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return strict_rfc3339.validate_rfc3339(instance)
|
||||
|
||||
|
||||
@_checks_drafts("regex", raises=re.error)
|
||||
def is_regex(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return re.compile(instance)
|
||||
|
||||
|
||||
@_checks_drafts(draft3="date", raises=ValueError)
|
||||
def is_date(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return datetime.datetime.strptime(instance, "%Y-%m-%d")
|
||||
|
||||
|
||||
@_checks_drafts(draft3="time", raises=ValueError)
|
||||
def is_time(instance):
|
||||
if not isinstance(instance, str_types):
|
||||
return True
|
||||
return datetime.datetime.strptime(instance, "%H:%M:%S")
|
||||
|
||||
|
||||
try:
|
||||
import webcolors
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
def is_css_color_code(instance):
|
||||
return webcolors.normalize_hex(instance)
|
||||
|
||||
|
||||
@_checks_drafts(draft3="color", raises=(ValueError, TypeError))
|
||||
def is_css21_color(instance):
|
||||
if (
|
||||
not isinstance(instance, str_types) or
|
||||
instance.lower() in webcolors.css21_names_to_hex
|
||||
):
|
||||
return True
|
||||
return is_css_color_code(instance)
|
||||
|
||||
|
||||
def is_css3_color(instance):
|
||||
if instance.lower() in webcolors.css3_names_to_hex:
|
||||
return True
|
||||
return is_css_color_code(instance)
|
||||
|
||||
|
||||
draft3_format_checker = FormatChecker(_draft_checkers["draft3"])
|
||||
draft4_format_checker = FormatChecker(_draft_checkers["draft4"])
|
||||
155
lib/spack/external/jsonschema/_reflect.py
vendored
Normal file
155
lib/spack/external/jsonschema/_reflect.py
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
# -*- test-case-name: twisted.test.test_reflect -*-
|
||||
# Copyright (c) Twisted Matrix Laboratories.
|
||||
# See LICENSE for details.
|
||||
|
||||
"""
|
||||
Standardized versions of various cool and/or strange things that you can do
|
||||
with Python's reflection capabilities.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
from jsonschema.compat import PY3
|
||||
|
||||
|
||||
class _NoModuleFound(Exception):
|
||||
"""
|
||||
No module was found because none exists.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class InvalidName(ValueError):
|
||||
"""
|
||||
The given name is not a dot-separated list of Python objects.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class ModuleNotFound(InvalidName):
|
||||
"""
|
||||
The module associated with the given name doesn't exist and it can't be
|
||||
imported.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class ObjectNotFound(InvalidName):
|
||||
"""
|
||||
The object associated with the given name doesn't exist and it can't be
|
||||
imported.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
if PY3:
|
||||
def reraise(exception, traceback):
|
||||
raise exception.with_traceback(traceback)
|
||||
else:
|
||||
exec("""def reraise(exception, traceback):
|
||||
raise exception.__class__, exception, traceback""")
|
||||
|
||||
reraise.__doc__ = """
|
||||
Re-raise an exception, with an optional traceback, in a way that is compatible
|
||||
with both Python 2 and Python 3.
|
||||
|
||||
Note that on Python 3, re-raised exceptions will be mutated, with their
|
||||
C{__traceback__} attribute being set.
|
||||
|
||||
@param exception: The exception instance.
|
||||
@param traceback: The traceback to use, or C{None} indicating a new traceback.
|
||||
"""
|
||||
|
||||
|
||||
def _importAndCheckStack(importName):
|
||||
"""
|
||||
Import the given name as a module, then walk the stack to determine whether
|
||||
the failure was the module not existing, or some code in the module (for
|
||||
example a dependent import) failing. This can be helpful to determine
|
||||
whether any actual application code was run. For example, to distiguish
|
||||
administrative error (entering the wrong module name), from programmer
|
||||
error (writing buggy code in a module that fails to import).
|
||||
|
||||
@param importName: The name of the module to import.
|
||||
@type importName: C{str}
|
||||
@raise Exception: if something bad happens. This can be any type of
|
||||
exception, since nobody knows what loading some arbitrary code might
|
||||
do.
|
||||
@raise _NoModuleFound: if no module was found.
|
||||
"""
|
||||
try:
|
||||
return __import__(importName)
|
||||
except ImportError:
|
||||
excType, excValue, excTraceback = sys.exc_info()
|
||||
while excTraceback:
|
||||
execName = excTraceback.tb_frame.f_globals["__name__"]
|
||||
# in Python 2 execName is None when an ImportError is encountered,
|
||||
# where in Python 3 execName is equal to the importName.
|
||||
if execName is None or execName == importName:
|
||||
reraise(excValue, excTraceback)
|
||||
excTraceback = excTraceback.tb_next
|
||||
raise _NoModuleFound()
|
||||
|
||||
|
||||
|
||||
def namedAny(name):
|
||||
"""
|
||||
Retrieve a Python object by its fully qualified name from the global Python
|
||||
module namespace. The first part of the name, that describes a module,
|
||||
will be discovered and imported. Each subsequent part of the name is
|
||||
treated as the name of an attribute of the object specified by all of the
|
||||
name which came before it. For example, the fully-qualified name of this
|
||||
object is 'twisted.python.reflect.namedAny'.
|
||||
|
||||
@type name: L{str}
|
||||
@param name: The name of the object to return.
|
||||
|
||||
@raise InvalidName: If the name is an empty string, starts or ends with
|
||||
a '.', or is otherwise syntactically incorrect.
|
||||
|
||||
@raise ModuleNotFound: If the name is syntactically correct but the
|
||||
module it specifies cannot be imported because it does not appear to
|
||||
exist.
|
||||
|
||||
@raise ObjectNotFound: If the name is syntactically correct, includes at
|
||||
least one '.', but the module it specifies cannot be imported because
|
||||
it does not appear to exist.
|
||||
|
||||
@raise AttributeError: If an attribute of an object along the way cannot be
|
||||
accessed, or a module along the way is not found.
|
||||
|
||||
@return: the Python object identified by 'name'.
|
||||
"""
|
||||
if not name:
|
||||
raise InvalidName('Empty module name')
|
||||
|
||||
names = name.split('.')
|
||||
|
||||
# if the name starts or ends with a '.' or contains '..', the __import__
|
||||
# will raise an 'Empty module name' error. This will provide a better error
|
||||
# message.
|
||||
if '' in names:
|
||||
raise InvalidName(
|
||||
"name must be a string giving a '.'-separated list of Python "
|
||||
"identifiers, not %r" % (name,))
|
||||
|
||||
topLevelPackage = None
|
||||
moduleNames = names[:]
|
||||
while not topLevelPackage:
|
||||
if moduleNames:
|
||||
trialname = '.'.join(moduleNames)
|
||||
try:
|
||||
topLevelPackage = _importAndCheckStack(trialname)
|
||||
except _NoModuleFound:
|
||||
moduleNames.pop()
|
||||
else:
|
||||
if len(names) == 1:
|
||||
raise ModuleNotFound("No module named %r" % (name,))
|
||||
else:
|
||||
raise ObjectNotFound('%r does not name an object' % (name,))
|
||||
|
||||
obj = topLevelPackage
|
||||
for n in names[1:]:
|
||||
obj = getattr(obj, n)
|
||||
|
||||
return obj
|
||||
213
lib/spack/external/jsonschema/_utils.py
vendored
Normal file
213
lib/spack/external/jsonschema/_utils.py
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
import itertools
|
||||
import json
|
||||
import pkgutil
|
||||
import re
|
||||
|
||||
from jsonschema.compat import str_types, MutableMapping, urlsplit
|
||||
|
||||
|
||||
class URIDict(MutableMapping):
|
||||
"""
|
||||
Dictionary which uses normalized URIs as keys.
|
||||
|
||||
"""
|
||||
|
||||
def normalize(self, uri):
|
||||
return urlsplit(uri).geturl()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.store = dict()
|
||||
self.store.update(*args, **kwargs)
|
||||
|
||||
def __getitem__(self, uri):
|
||||
return self.store[self.normalize(uri)]
|
||||
|
||||
def __setitem__(self, uri, value):
|
||||
self.store[self.normalize(uri)] = value
|
||||
|
||||
def __delitem__(self, uri):
|
||||
del self.store[self.normalize(uri)]
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.store)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.store)
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self.store)
|
||||
|
||||
|
||||
class Unset(object):
|
||||
"""
|
||||
An as-of-yet unset attribute or unprovided default parameter.
|
||||
|
||||
"""
|
||||
|
||||
def __repr__(self):
|
||||
return "<unset>"
|
||||
|
||||
|
||||
def load_schema(name):
|
||||
"""
|
||||
Load a schema from ./schemas/``name``.json and return it.
|
||||
|
||||
"""
|
||||
|
||||
data = pkgutil.get_data(__package__, "schemas/{0}.json".format(name))
|
||||
return json.loads(data.decode("utf-8"))
|
||||
|
||||
|
||||
def indent(string, times=1):
|
||||
"""
|
||||
A dumb version of :func:`textwrap.indent` from Python 3.3.
|
||||
|
||||
"""
|
||||
|
||||
return "\n".join(" " * (4 * times) + line for line in string.splitlines())
|
||||
|
||||
|
||||
def format_as_index(indices):
|
||||
"""
|
||||
Construct a single string containing indexing operations for the indices.
|
||||
|
||||
For example, [1, 2, "foo"] -> [1][2]["foo"]
|
||||
|
||||
:type indices: sequence
|
||||
|
||||
"""
|
||||
|
||||
if not indices:
|
||||
return ""
|
||||
return "[%s]" % "][".join(repr(index) for index in indices)
|
||||
|
||||
|
||||
def find_additional_properties(instance, schema):
|
||||
"""
|
||||
Return the set of additional properties for the given ``instance``.
|
||||
|
||||
Weeds out properties that should have been validated by ``properties`` and
|
||||
/ or ``patternProperties``.
|
||||
|
||||
Assumes ``instance`` is dict-like already.
|
||||
|
||||
"""
|
||||
|
||||
properties = schema.get("properties", {})
|
||||
patterns = "|".join(schema.get("patternProperties", {}))
|
||||
for property in instance:
|
||||
if property not in properties:
|
||||
if patterns and re.search(patterns, property):
|
||||
continue
|
||||
yield property
|
||||
|
||||
|
||||
def extras_msg(extras):
|
||||
"""
|
||||
Create an error message for extra items or properties.
|
||||
|
||||
"""
|
||||
|
||||
if len(extras) == 1:
|
||||
verb = "was"
|
||||
else:
|
||||
verb = "were"
|
||||
return ", ".join(repr(extra) for extra in extras), verb
|
||||
|
||||
|
||||
def types_msg(instance, types):
|
||||
"""
|
||||
Create an error message for a failure to match the given types.
|
||||
|
||||
If the ``instance`` is an object and contains a ``name`` property, it will
|
||||
be considered to be a description of that object and used as its type.
|
||||
|
||||
Otherwise the message is simply the reprs of the given ``types``.
|
||||
|
||||
"""
|
||||
|
||||
reprs = []
|
||||
for type in types:
|
||||
try:
|
||||
reprs.append(repr(type["name"]))
|
||||
except Exception:
|
||||
reprs.append(repr(type))
|
||||
return "%r is not of type %s" % (instance, ", ".join(reprs))
|
||||
|
||||
|
||||
def flatten(suitable_for_isinstance):
|
||||
"""
|
||||
isinstance() can accept a bunch of really annoying different types:
|
||||
* a single type
|
||||
* a tuple of types
|
||||
* an arbitrary nested tree of tuples
|
||||
|
||||
Return a flattened tuple of the given argument.
|
||||
|
||||
"""
|
||||
|
||||
types = set()
|
||||
|
||||
if not isinstance(suitable_for_isinstance, tuple):
|
||||
suitable_for_isinstance = (suitable_for_isinstance,)
|
||||
for thing in suitable_for_isinstance:
|
||||
if isinstance(thing, tuple):
|
||||
types.update(flatten(thing))
|
||||
else:
|
||||
types.add(thing)
|
||||
return tuple(types)
|
||||
|
||||
|
||||
def ensure_list(thing):
|
||||
"""
|
||||
Wrap ``thing`` in a list if it's a single str.
|
||||
|
||||
Otherwise, return it unchanged.
|
||||
|
||||
"""
|
||||
|
||||
if isinstance(thing, str_types):
|
||||
return [thing]
|
||||
return thing
|
||||
|
||||
|
||||
def unbool(element, true=object(), false=object()):
|
||||
"""
|
||||
A hack to make True and 1 and False and 0 unique for ``uniq``.
|
||||
|
||||
"""
|
||||
|
||||
if element is True:
|
||||
return true
|
||||
elif element is False:
|
||||
return false
|
||||
return element
|
||||
|
||||
|
||||
def uniq(container):
|
||||
"""
|
||||
Check if all of a container's elements are unique.
|
||||
|
||||
Successively tries first to rely that the elements are hashable, then
|
||||
falls back on them being sortable, and finally falls back on brute
|
||||
force.
|
||||
|
||||
"""
|
||||
|
||||
try:
|
||||
return len(set(unbool(i) for i in container)) == len(container)
|
||||
except TypeError:
|
||||
try:
|
||||
sort = sorted(unbool(i) for i in container)
|
||||
sliced = itertools.islice(sort, 1, None)
|
||||
for i, j in zip(sort, sliced):
|
||||
if i == j:
|
||||
return False
|
||||
except (NotImplementedError, TypeError):
|
||||
seen = []
|
||||
for e in container:
|
||||
e = unbool(e)
|
||||
if e in seen:
|
||||
return False
|
||||
seen.append(e)
|
||||
return True
|
||||
358
lib/spack/external/jsonschema/_validators.py
vendored
Normal file
358
lib/spack/external/jsonschema/_validators.py
vendored
Normal file
@@ -0,0 +1,358 @@
|
||||
import re
|
||||
|
||||
from jsonschema import _utils
|
||||
from jsonschema.exceptions import FormatError, ValidationError
|
||||
from jsonschema.compat import iteritems
|
||||
|
||||
|
||||
FLOAT_TOLERANCE = 10 ** -15
|
||||
|
||||
|
||||
def patternProperties(validator, patternProperties, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
|
||||
for pattern, subschema in iteritems(patternProperties):
|
||||
for k, v in iteritems(instance):
|
||||
if re.search(pattern, k):
|
||||
for error in validator.descend(
|
||||
v, subschema, path=k, schema_path=pattern,
|
||||
):
|
||||
yield error
|
||||
|
||||
|
||||
def additionalProperties(validator, aP, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
|
||||
extras = set(_utils.find_additional_properties(instance, schema))
|
||||
|
||||
if validator.is_type(aP, "object"):
|
||||
for extra in extras:
|
||||
for error in validator.descend(instance[extra], aP, path=extra):
|
||||
yield error
|
||||
elif not aP and extras:
|
||||
error = "Additional properties are not allowed (%s %s unexpected)"
|
||||
yield ValidationError(error % _utils.extras_msg(extras))
|
||||
|
||||
|
||||
def items(validator, items, instance, schema):
|
||||
if not validator.is_type(instance, "array"):
|
||||
return
|
||||
|
||||
if validator.is_type(items, "object"):
|
||||
for index, item in enumerate(instance):
|
||||
for error in validator.descend(item, items, path=index):
|
||||
yield error
|
||||
else:
|
||||
for (index, item), subschema in zip(enumerate(instance), items):
|
||||
for error in validator.descend(
|
||||
item, subschema, path=index, schema_path=index,
|
||||
):
|
||||
yield error
|
||||
|
||||
|
||||
def additionalItems(validator, aI, instance, schema):
|
||||
if (
|
||||
not validator.is_type(instance, "array") or
|
||||
validator.is_type(schema.get("items", {}), "object")
|
||||
):
|
||||
return
|
||||
|
||||
len_items = len(schema.get("items", []))
|
||||
if validator.is_type(aI, "object"):
|
||||
for index, item in enumerate(instance[len_items:], start=len_items):
|
||||
for error in validator.descend(item, aI, path=index):
|
||||
yield error
|
||||
elif not aI and len(instance) > len(schema.get("items", [])):
|
||||
error = "Additional items are not allowed (%s %s unexpected)"
|
||||
yield ValidationError(
|
||||
error %
|
||||
_utils.extras_msg(instance[len(schema.get("items", [])):])
|
||||
)
|
||||
|
||||
|
||||
def minimum(validator, minimum, instance, schema):
|
||||
if not validator.is_type(instance, "number"):
|
||||
return
|
||||
|
||||
if schema.get("exclusiveMinimum", False):
|
||||
failed = float(instance) <= minimum
|
||||
cmp = "less than or equal to"
|
||||
else:
|
||||
failed = float(instance) < minimum
|
||||
cmp = "less than"
|
||||
|
||||
if failed:
|
||||
yield ValidationError(
|
||||
"%r is %s the minimum of %r" % (instance, cmp, minimum)
|
||||
)
|
||||
|
||||
|
||||
def maximum(validator, maximum, instance, schema):
|
||||
if not validator.is_type(instance, "number"):
|
||||
return
|
||||
|
||||
if schema.get("exclusiveMaximum", False):
|
||||
failed = instance >= maximum
|
||||
cmp = "greater than or equal to"
|
||||
else:
|
||||
failed = instance > maximum
|
||||
cmp = "greater than"
|
||||
|
||||
if failed:
|
||||
yield ValidationError(
|
||||
"%r is %s the maximum of %r" % (instance, cmp, maximum)
|
||||
)
|
||||
|
||||
|
||||
def multipleOf(validator, dB, instance, schema):
|
||||
if not validator.is_type(instance, "number"):
|
||||
return
|
||||
|
||||
if isinstance(dB, float):
|
||||
mod = instance % dB
|
||||
failed = (mod > FLOAT_TOLERANCE) and (dB - mod) > FLOAT_TOLERANCE
|
||||
else:
|
||||
failed = instance % dB
|
||||
|
||||
if failed:
|
||||
yield ValidationError("%r is not a multiple of %r" % (instance, dB))
|
||||
|
||||
|
||||
def minItems(validator, mI, instance, schema):
|
||||
if validator.is_type(instance, "array") and len(instance) < mI:
|
||||
yield ValidationError("%r is too short" % (instance,))
|
||||
|
||||
|
||||
def maxItems(validator, mI, instance, schema):
|
||||
if validator.is_type(instance, "array") and len(instance) > mI:
|
||||
yield ValidationError("%r is too long" % (instance,))
|
||||
|
||||
|
||||
def uniqueItems(validator, uI, instance, schema):
|
||||
if (
|
||||
uI and
|
||||
validator.is_type(instance, "array") and
|
||||
not _utils.uniq(instance)
|
||||
):
|
||||
yield ValidationError("%r has non-unique elements" % instance)
|
||||
|
||||
|
||||
def pattern(validator, patrn, instance, schema):
|
||||
if (
|
||||
validator.is_type(instance, "string") and
|
||||
not re.search(patrn, instance)
|
||||
):
|
||||
yield ValidationError("%r does not match %r" % (instance, patrn))
|
||||
|
||||
|
||||
def format(validator, format, instance, schema):
|
||||
if validator.format_checker is not None:
|
||||
try:
|
||||
validator.format_checker.check(instance, format)
|
||||
except FormatError as error:
|
||||
yield ValidationError(error.message, cause=error.cause)
|
||||
|
||||
|
||||
def minLength(validator, mL, instance, schema):
|
||||
if validator.is_type(instance, "string") and len(instance) < mL:
|
||||
yield ValidationError("%r is too short" % (instance,))
|
||||
|
||||
|
||||
def maxLength(validator, mL, instance, schema):
|
||||
if validator.is_type(instance, "string") and len(instance) > mL:
|
||||
yield ValidationError("%r is too long" % (instance,))
|
||||
|
||||
|
||||
def dependencies(validator, dependencies, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
|
||||
for property, dependency in iteritems(dependencies):
|
||||
if property not in instance:
|
||||
continue
|
||||
|
||||
if validator.is_type(dependency, "object"):
|
||||
for error in validator.descend(
|
||||
instance, dependency, schema_path=property,
|
||||
):
|
||||
yield error
|
||||
else:
|
||||
dependencies = _utils.ensure_list(dependency)
|
||||
for dependency in dependencies:
|
||||
if dependency not in instance:
|
||||
yield ValidationError(
|
||||
"%r is a dependency of %r" % (dependency, property)
|
||||
)
|
||||
|
||||
|
||||
def enum(validator, enums, instance, schema):
|
||||
if instance not in enums:
|
||||
yield ValidationError("%r is not one of %r" % (instance, enums))
|
||||
|
||||
|
||||
def ref(validator, ref, instance, schema):
|
||||
with validator.resolver.resolving(ref) as resolved:
|
||||
for error in validator.descend(instance, resolved):
|
||||
yield error
|
||||
|
||||
|
||||
def type_draft3(validator, types, instance, schema):
|
||||
types = _utils.ensure_list(types)
|
||||
|
||||
all_errors = []
|
||||
for index, type in enumerate(types):
|
||||
if type == "any":
|
||||
return
|
||||
if validator.is_type(type, "object"):
|
||||
errors = list(validator.descend(instance, type, schema_path=index))
|
||||
if not errors:
|
||||
return
|
||||
all_errors.extend(errors)
|
||||
else:
|
||||
if validator.is_type(instance, type):
|
||||
return
|
||||
else:
|
||||
yield ValidationError(
|
||||
_utils.types_msg(instance, types), context=all_errors,
|
||||
)
|
||||
|
||||
|
||||
def properties_draft3(validator, properties, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
|
||||
for property, subschema in iteritems(properties):
|
||||
if property in instance:
|
||||
for error in validator.descend(
|
||||
instance[property],
|
||||
subschema,
|
||||
path=property,
|
||||
schema_path=property,
|
||||
):
|
||||
yield error
|
||||
elif subschema.get("required", False):
|
||||
error = ValidationError("%r is a required property" % property)
|
||||
error._set(
|
||||
validator="required",
|
||||
validator_value=subschema["required"],
|
||||
instance=instance,
|
||||
schema=schema,
|
||||
)
|
||||
error.path.appendleft(property)
|
||||
error.schema_path.extend([property, "required"])
|
||||
yield error
|
||||
|
||||
|
||||
def disallow_draft3(validator, disallow, instance, schema):
|
||||
for disallowed in _utils.ensure_list(disallow):
|
||||
if validator.is_valid(instance, {"type" : [disallowed]}):
|
||||
yield ValidationError(
|
||||
"%r is disallowed for %r" % (disallowed, instance)
|
||||
)
|
||||
|
||||
|
||||
def extends_draft3(validator, extends, instance, schema):
|
||||
if validator.is_type(extends, "object"):
|
||||
for error in validator.descend(instance, extends):
|
||||
yield error
|
||||
return
|
||||
for index, subschema in enumerate(extends):
|
||||
for error in validator.descend(instance, subschema, schema_path=index):
|
||||
yield error
|
||||
|
||||
|
||||
def type_draft4(validator, types, instance, schema):
|
||||
types = _utils.ensure_list(types)
|
||||
|
||||
if not any(validator.is_type(instance, type) for type in types):
|
||||
yield ValidationError(_utils.types_msg(instance, types))
|
||||
|
||||
|
||||
def properties_draft4(validator, properties, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
|
||||
for property, subschema in iteritems(properties):
|
||||
if property in instance:
|
||||
for error in validator.descend(
|
||||
instance[property],
|
||||
subschema,
|
||||
path=property,
|
||||
schema_path=property,
|
||||
):
|
||||
yield error
|
||||
|
||||
|
||||
def required_draft4(validator, required, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
for property in required:
|
||||
if property not in instance:
|
||||
yield ValidationError("%r is a required property" % property)
|
||||
|
||||
|
||||
def minProperties_draft4(validator, mP, instance, schema):
|
||||
if validator.is_type(instance, "object") and len(instance) < mP:
|
||||
yield ValidationError(
|
||||
"%r does not have enough properties" % (instance,)
|
||||
)
|
||||
|
||||
|
||||
def maxProperties_draft4(validator, mP, instance, schema):
|
||||
if not validator.is_type(instance, "object"):
|
||||
return
|
||||
if validator.is_type(instance, "object") and len(instance) > mP:
|
||||
yield ValidationError("%r has too many properties" % (instance,))
|
||||
|
||||
|
||||
def allOf_draft4(validator, allOf, instance, schema):
|
||||
for index, subschema in enumerate(allOf):
|
||||
for error in validator.descend(instance, subschema, schema_path=index):
|
||||
yield error
|
||||
|
||||
|
||||
def oneOf_draft4(validator, oneOf, instance, schema):
|
||||
subschemas = enumerate(oneOf)
|
||||
all_errors = []
|
||||
for index, subschema in subschemas:
|
||||
errs = list(validator.descend(instance, subschema, schema_path=index))
|
||||
if not errs:
|
||||
first_valid = subschema
|
||||
break
|
||||
all_errors.extend(errs)
|
||||
else:
|
||||
yield ValidationError(
|
||||
"%r is not valid under any of the given schemas" % (instance,),
|
||||
context=all_errors,
|
||||
)
|
||||
|
||||
more_valid = [s for i, s in subschemas if validator.is_valid(instance, s)]
|
||||
if more_valid:
|
||||
more_valid.append(first_valid)
|
||||
reprs = ", ".join(repr(schema) for schema in more_valid)
|
||||
yield ValidationError(
|
||||
"%r is valid under each of %s" % (instance, reprs)
|
||||
)
|
||||
|
||||
|
||||
def anyOf_draft4(validator, anyOf, instance, schema):
|
||||
all_errors = []
|
||||
for index, subschema in enumerate(anyOf):
|
||||
errs = list(validator.descend(instance, subschema, schema_path=index))
|
||||
if not errs:
|
||||
break
|
||||
all_errors.extend(errs)
|
||||
else:
|
||||
yield ValidationError(
|
||||
"%r is not valid under any of the given schemas" % (instance,),
|
||||
context=all_errors,
|
||||
)
|
||||
|
||||
|
||||
def not_draft4(validator, not_schema, instance, schema):
|
||||
if validator.is_valid(instance, not_schema):
|
||||
yield ValidationError(
|
||||
"%r is not allowed for %r" % (not_schema, instance)
|
||||
)
|
||||
72
lib/spack/external/jsonschema/cli.py
vendored
Normal file
72
lib/spack/external/jsonschema/cli.py
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
from __future__ import absolute_import
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
|
||||
from jsonschema._reflect import namedAny
|
||||
from jsonschema.validators import validator_for
|
||||
|
||||
|
||||
def _namedAnyWithDefault(name):
|
||||
if "." not in name:
|
||||
name = "jsonschema." + name
|
||||
return namedAny(name)
|
||||
|
||||
|
||||
def _json_file(path):
|
||||
with open(path) as file:
|
||||
return json.load(file)
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="JSON Schema Validation CLI",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i", "--instance",
|
||||
action="append",
|
||||
dest="instances",
|
||||
type=_json_file,
|
||||
help="a path to a JSON instance to validate "
|
||||
"(may be specified multiple times)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-F", "--error-format",
|
||||
default="{error.instance}: {error.message}\n",
|
||||
help="the format to use for each error output message, specified in "
|
||||
"a form suitable for passing to str.format, which will be called "
|
||||
"with 'error' for each error",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-V", "--validator",
|
||||
type=_namedAnyWithDefault,
|
||||
help="the fully qualified object name of a validator to use, or, for "
|
||||
"validators that are registered with jsonschema, simply the name "
|
||||
"of the class.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"schema",
|
||||
help="the JSON Schema to validate with",
|
||||
type=_json_file,
|
||||
)
|
||||
|
||||
|
||||
def parse_args(args):
|
||||
arguments = vars(parser.parse_args(args=args or ["--help"]))
|
||||
if arguments["validator"] is None:
|
||||
arguments["validator"] = validator_for(arguments["schema"])
|
||||
return arguments
|
||||
|
||||
|
||||
def main(args=sys.argv[1:]):
|
||||
sys.exit(run(arguments=parse_args(args=args)))
|
||||
|
||||
|
||||
def run(arguments, stdout=sys.stdout, stderr=sys.stderr):
|
||||
error_format = arguments["error_format"]
|
||||
validator = arguments["validator"](schema=arguments["schema"])
|
||||
errored = False
|
||||
for instance in arguments["instances"] or ():
|
||||
for error in validator.iter_errors(instance):
|
||||
stderr.write(error_format.format(error=error))
|
||||
errored = True
|
||||
return errored
|
||||
53
lib/spack/external/jsonschema/compat.py
vendored
Normal file
53
lib/spack/external/jsonschema/compat.py
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
from __future__ import unicode_literals
|
||||
import sys
|
||||
import operator
|
||||
|
||||
try:
|
||||
from collections import MutableMapping, Sequence # noqa
|
||||
except ImportError:
|
||||
from collections.abc import MutableMapping, Sequence # noqa
|
||||
|
||||
PY3 = sys.version_info[0] >= 3
|
||||
|
||||
if PY3:
|
||||
zip = zip
|
||||
from io import StringIO
|
||||
from urllib.parse import (
|
||||
unquote, urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit
|
||||
)
|
||||
from urllib.request import urlopen
|
||||
str_types = str,
|
||||
int_types = int,
|
||||
iteritems = operator.methodcaller("items")
|
||||
else:
|
||||
from itertools import izip as zip # noqa
|
||||
from StringIO import StringIO
|
||||
from urlparse import (
|
||||
urljoin, urlunsplit, SplitResult, urlsplit as _urlsplit # noqa
|
||||
)
|
||||
from urllib import unquote # noqa
|
||||
from urllib2 import urlopen # noqa
|
||||
str_types = basestring
|
||||
int_types = int, long
|
||||
iteritems = operator.methodcaller("iteritems")
|
||||
|
||||
|
||||
# On python < 3.3 fragments are not handled properly with unknown schemes
|
||||
def urlsplit(url):
|
||||
scheme, netloc, path, query, fragment = _urlsplit(url)
|
||||
if "#" in path:
|
||||
path, fragment = path.split("#", 1)
|
||||
return SplitResult(scheme, netloc, path, query, fragment)
|
||||
|
||||
|
||||
def urldefrag(url):
|
||||
if "#" in url:
|
||||
s, n, p, q, frag = urlsplit(url)
|
||||
defrag = urlunsplit((s, n, p, q, ''))
|
||||
else:
|
||||
defrag = url
|
||||
frag = ''
|
||||
return defrag, frag
|
||||
|
||||
|
||||
# flake8: noqa
|
||||
264
lib/spack/external/jsonschema/exceptions.py
vendored
Normal file
264
lib/spack/external/jsonschema/exceptions.py
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
from collections import defaultdict, deque
|
||||
import itertools
|
||||
import pprint
|
||||
import textwrap
|
||||
|
||||
from jsonschema import _utils
|
||||
from jsonschema.compat import PY3, iteritems
|
||||
|
||||
|
||||
WEAK_MATCHES = frozenset(["anyOf", "oneOf"])
|
||||
STRONG_MATCHES = frozenset()
|
||||
|
||||
_unset = _utils.Unset()
|
||||
|
||||
|
||||
class _Error(Exception):
|
||||
def __init__(
|
||||
self,
|
||||
message,
|
||||
validator=_unset,
|
||||
path=(),
|
||||
cause=None,
|
||||
context=(),
|
||||
validator_value=_unset,
|
||||
instance=_unset,
|
||||
schema=_unset,
|
||||
schema_path=(),
|
||||
parent=None,
|
||||
):
|
||||
self.message = message
|
||||
self.path = self.relative_path = deque(path)
|
||||
self.schema_path = self.relative_schema_path = deque(schema_path)
|
||||
self.context = list(context)
|
||||
self.cause = self.__cause__ = cause
|
||||
self.validator = validator
|
||||
self.validator_value = validator_value
|
||||
self.instance = instance
|
||||
self.schema = schema
|
||||
self.parent = parent
|
||||
|
||||
for error in context:
|
||||
error.parent = self
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s: %r>" % (self.__class__.__name__, self.message)
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self).encode("utf-8")
|
||||
|
||||
def __unicode__(self):
|
||||
essential_for_verbose = (
|
||||
self.validator, self.validator_value, self.instance, self.schema,
|
||||
)
|
||||
if any(m is _unset for m in essential_for_verbose):
|
||||
return self.message
|
||||
|
||||
pschema = pprint.pformat(self.schema, width=72)
|
||||
pinstance = pprint.pformat(self.instance, width=72)
|
||||
return self.message + textwrap.dedent("""
|
||||
|
||||
Failed validating %r in schema%s:
|
||||
%s
|
||||
|
||||
On instance%s:
|
||||
%s
|
||||
""".rstrip()
|
||||
) % (
|
||||
self.validator,
|
||||
_utils.format_as_index(list(self.relative_schema_path)[:-1]),
|
||||
_utils.indent(pschema),
|
||||
_utils.format_as_index(self.relative_path),
|
||||
_utils.indent(pinstance),
|
||||
)
|
||||
|
||||
if PY3:
|
||||
__str__ = __unicode__
|
||||
|
||||
@classmethod
|
||||
def create_from(cls, other):
|
||||
return cls(**other._contents())
|
||||
|
||||
@property
|
||||
def absolute_path(self):
|
||||
parent = self.parent
|
||||
if parent is None:
|
||||
return self.relative_path
|
||||
|
||||
path = deque(self.relative_path)
|
||||
path.extendleft(parent.absolute_path)
|
||||
return path
|
||||
|
||||
@property
|
||||
def absolute_schema_path(self):
|
||||
parent = self.parent
|
||||
if parent is None:
|
||||
return self.relative_schema_path
|
||||
|
||||
path = deque(self.relative_schema_path)
|
||||
path.extendleft(parent.absolute_schema_path)
|
||||
return path
|
||||
|
||||
def _set(self, **kwargs):
|
||||
for k, v in iteritems(kwargs):
|
||||
if getattr(self, k) is _unset:
|
||||
setattr(self, k, v)
|
||||
|
||||
def _contents(self):
|
||||
attrs = (
|
||||
"message", "cause", "context", "validator", "validator_value",
|
||||
"path", "schema_path", "instance", "schema", "parent",
|
||||
)
|
||||
return dict((attr, getattr(self, attr)) for attr in attrs)
|
||||
|
||||
|
||||
class ValidationError(_Error):
|
||||
pass
|
||||
|
||||
|
||||
class SchemaError(_Error):
|
||||
pass
|
||||
|
||||
|
||||
class RefResolutionError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class UnknownType(Exception):
|
||||
def __init__(self, type, instance, schema):
|
||||
self.type = type
|
||||
self.instance = instance
|
||||
self.schema = schema
|
||||
|
||||
def __str__(self):
|
||||
return unicode(self).encode("utf-8")
|
||||
|
||||
def __unicode__(self):
|
||||
pschema = pprint.pformat(self.schema, width=72)
|
||||
pinstance = pprint.pformat(self.instance, width=72)
|
||||
return textwrap.dedent("""
|
||||
Unknown type %r for validator with schema:
|
||||
%s
|
||||
|
||||
While checking instance:
|
||||
%s
|
||||
""".rstrip()
|
||||
) % (self.type, _utils.indent(pschema), _utils.indent(pinstance))
|
||||
|
||||
if PY3:
|
||||
__str__ = __unicode__
|
||||
|
||||
|
||||
|
||||
class FormatError(Exception):
|
||||
def __init__(self, message, cause=None):
|
||||
super(FormatError, self).__init__(message, cause)
|
||||
self.message = message
|
||||
self.cause = self.__cause__ = cause
|
||||
|
||||
def __str__(self):
|
||||
return self.message.encode("utf-8")
|
||||
|
||||
def __unicode__(self):
|
||||
return self.message
|
||||
|
||||
if PY3:
|
||||
__str__ = __unicode__
|
||||
|
||||
|
||||
class ErrorTree(object):
|
||||
"""
|
||||
ErrorTrees make it easier to check which validations failed.
|
||||
|
||||
"""
|
||||
|
||||
_instance = _unset
|
||||
|
||||
def __init__(self, errors=()):
|
||||
self.errors = {}
|
||||
self._contents = defaultdict(self.__class__)
|
||||
|
||||
for error in errors:
|
||||
container = self
|
||||
for element in error.path:
|
||||
container = container[element]
|
||||
container.errors[error.validator] = error
|
||||
|
||||
self._instance = error.instance
|
||||
|
||||
def __contains__(self, index):
|
||||
"""
|
||||
Check whether ``instance[index]`` has any errors.
|
||||
|
||||
"""
|
||||
|
||||
return index in self._contents
|
||||
|
||||
def __getitem__(self, index):
|
||||
"""
|
||||
Retrieve the child tree one level down at the given ``index``.
|
||||
|
||||
If the index is not in the instance that this tree corresponds to and
|
||||
is not known by this tree, whatever error would be raised by
|
||||
``instance.__getitem__`` will be propagated (usually this is some
|
||||
subclass of :class:`LookupError`.
|
||||
|
||||
"""
|
||||
|
||||
if self._instance is not _unset and index not in self:
|
||||
self._instance[index]
|
||||
return self._contents[index]
|
||||
|
||||
def __setitem__(self, index, value):
|
||||
self._contents[index] = value
|
||||
|
||||
def __iter__(self):
|
||||
"""
|
||||
Iterate (non-recursively) over the indices in the instance with errors.
|
||||
|
||||
"""
|
||||
|
||||
return iter(self._contents)
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Same as :attr:`total_errors`.
|
||||
|
||||
"""
|
||||
|
||||
return self.total_errors
|
||||
|
||||
def __repr__(self):
|
||||
return "<%s (%s total errors)>" % (self.__class__.__name__, len(self))
|
||||
|
||||
@property
|
||||
def total_errors(self):
|
||||
"""
|
||||
The total number of errors in the entire tree, including children.
|
||||
|
||||
"""
|
||||
|
||||
child_errors = sum(len(tree) for _, tree in iteritems(self._contents))
|
||||
return len(self.errors) + child_errors
|
||||
|
||||
|
||||
def by_relevance(weak=WEAK_MATCHES, strong=STRONG_MATCHES):
|
||||
def relevance(error):
|
||||
validator = error.validator
|
||||
return -len(error.path), validator not in weak, validator in strong
|
||||
return relevance
|
||||
|
||||
|
||||
relevance = by_relevance()
|
||||
|
||||
|
||||
def best_match(errors, key=relevance):
|
||||
errors = iter(errors)
|
||||
best = next(errors, None)
|
||||
if best is None:
|
||||
return
|
||||
best = max(itertools.chain([best], errors), key=key)
|
||||
|
||||
while best.context:
|
||||
best = min(best.context, key=key)
|
||||
return best
|
||||
201
lib/spack/external/jsonschema/schemas/draft3.json
vendored
Normal file
201
lib/spack/external/jsonschema/schemas/draft3.json
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-03/schema#",
|
||||
"dependencies": {
|
||||
"exclusiveMaximum": "maximum",
|
||||
"exclusiveMinimum": "minimum"
|
||||
},
|
||||
"id": "http://json-schema.org/draft-03/schema#",
|
||||
"properties": {
|
||||
"$ref": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"$schema": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"additionalItems": {
|
||||
"default": {},
|
||||
"type": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
"boolean"
|
||||
]
|
||||
},
|
||||
"additionalProperties": {
|
||||
"default": {},
|
||||
"type": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
"boolean"
|
||||
]
|
||||
},
|
||||
"default": {
|
||||
"type": "any"
|
||||
},
|
||||
"dependencies": {
|
||||
"additionalProperties": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": [
|
||||
"string",
|
||||
"array",
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
},
|
||||
"default": {},
|
||||
"type": [
|
||||
"string",
|
||||
"array",
|
||||
"object"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"disallow": {
|
||||
"items": {
|
||||
"type": [
|
||||
"string",
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": [
|
||||
"string",
|
||||
"array"
|
||||
],
|
||||
"uniqueItems": true
|
||||
},
|
||||
"divisibleBy": {
|
||||
"default": 1,
|
||||
"exclusiveMinimum": true,
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"enum": {
|
||||
"minItems": 1,
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"extends": {
|
||||
"default": {},
|
||||
"items": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
"array"
|
||||
]
|
||||
},
|
||||
"format": {
|
||||
"type": "string"
|
||||
},
|
||||
"id": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"items": {
|
||||
"default": {},
|
||||
"items": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"type": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
"array"
|
||||
]
|
||||
},
|
||||
"maxDecimal": {
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"maxItems": {
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"maxLength": {
|
||||
"type": "integer"
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minItems": {
|
||||
"default": 0,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"minLength": {
|
||||
"default": 0,
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"pattern": {
|
||||
"format": "regex",
|
||||
"type": "string"
|
||||
},
|
||||
"patternProperties": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"properties": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#",
|
||||
"type": "object"
|
||||
},
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"required": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"default": "any",
|
||||
"items": {
|
||||
"type": [
|
||||
"string",
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": [
|
||||
"string",
|
||||
"array"
|
||||
],
|
||||
"uniqueItems": true
|
||||
},
|
||||
"uniqueItems": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
221
lib/spack/external/jsonschema/schemas/draft4.json
vendored
Normal file
221
lib/spack/external/jsonschema/schemas/draft4.json
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"default": {},
|
||||
"definitions": {
|
||||
"positiveInteger": {
|
||||
"minimum": 0,
|
||||
"type": "integer"
|
||||
},
|
||||
"positiveIntegerDefault0": {
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/positiveInteger"
|
||||
},
|
||||
{
|
||||
"default": 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"schemaArray": {
|
||||
"items": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array"
|
||||
},
|
||||
"simpleTypes": {
|
||||
"enum": [
|
||||
"array",
|
||||
"boolean",
|
||||
"integer",
|
||||
"null",
|
||||
"number",
|
||||
"object",
|
||||
"string"
|
||||
]
|
||||
},
|
||||
"stringArray": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"exclusiveMaximum": [
|
||||
"maximum"
|
||||
],
|
||||
"exclusiveMinimum": [
|
||||
"minimum"
|
||||
]
|
||||
},
|
||||
"description": "Core schema meta-schema",
|
||||
"id": "http://json-schema.org/draft-04/schema#",
|
||||
"properties": {
|
||||
"$schema": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"additionalItems": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "boolean"
|
||||
},
|
||||
{
|
||||
"$ref": "#"
|
||||
}
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"allOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"anyOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"default": {},
|
||||
"definitions": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"dependencies": {
|
||||
"additionalProperties": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/stringArray"
|
||||
}
|
||||
]
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"enum": {
|
||||
"minItems": 1,
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
},
|
||||
"exclusiveMaximum": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"exclusiveMinimum": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"id": {
|
||||
"format": "uri",
|
||||
"type": "string"
|
||||
},
|
||||
"items": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#"
|
||||
},
|
||||
{
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
}
|
||||
],
|
||||
"default": {}
|
||||
},
|
||||
"maxItems": {
|
||||
"$ref": "#/definitions/positiveInteger"
|
||||
},
|
||||
"maxLength": {
|
||||
"$ref": "#/definitions/positiveInteger"
|
||||
},
|
||||
"maxProperties": {
|
||||
"$ref": "#/definitions/positiveInteger"
|
||||
},
|
||||
"maximum": {
|
||||
"type": "number"
|
||||
},
|
||||
"minItems": {
|
||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
||||
},
|
||||
"minLength": {
|
||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
||||
},
|
||||
"minProperties": {
|
||||
"$ref": "#/definitions/positiveIntegerDefault0"
|
||||
},
|
||||
"minimum": {
|
||||
"type": "number"
|
||||
},
|
||||
"multipleOf": {
|
||||
"exclusiveMinimum": true,
|
||||
"minimum": 0,
|
||||
"type": "number"
|
||||
},
|
||||
"not": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"oneOf": {
|
||||
"$ref": "#/definitions/schemaArray"
|
||||
},
|
||||
"pattern": {
|
||||
"format": "regex",
|
||||
"type": "string"
|
||||
},
|
||||
"patternProperties": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"properties": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#"
|
||||
},
|
||||
"default": {},
|
||||
"type": "object"
|
||||
},
|
||||
"required": {
|
||||
"$ref": "#/definitions/stringArray"
|
||||
},
|
||||
"title": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/simpleTypes"
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"$ref": "#/definitions/simpleTypes"
|
||||
},
|
||||
"minItems": 1,
|
||||
"type": "array",
|
||||
"uniqueItems": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"uniqueItems": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
}
|
||||
15
lib/spack/external/jsonschema/tests/compat.py
vendored
Normal file
15
lib/spack/external/jsonschema/tests/compat.py
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import sys
|
||||
|
||||
|
||||
if sys.version_info[:2] < (2, 7): # pragma: no cover
|
||||
import unittest2 as unittest
|
||||
else:
|
||||
import unittest
|
||||
|
||||
try:
|
||||
from unittest import mock
|
||||
except ImportError:
|
||||
import mock
|
||||
|
||||
|
||||
# flake8: noqa
|
||||
110
lib/spack/external/jsonschema/tests/test_cli.py
vendored
Normal file
110
lib/spack/external/jsonschema/tests/test_cli.py
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
from jsonschema import Draft4Validator, ValidationError, cli
|
||||
from jsonschema.compat import StringIO
|
||||
from jsonschema.tests.compat import mock, unittest
|
||||
|
||||
|
||||
def fake_validator(*errors):
|
||||
errors = list(reversed(errors))
|
||||
|
||||
class FakeValidator(object):
|
||||
def __init__(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
def iter_errors(self, instance):
|
||||
if errors:
|
||||
return errors.pop()
|
||||
return []
|
||||
return FakeValidator
|
||||
|
||||
|
||||
class TestParser(unittest.TestCase):
|
||||
FakeValidator = fake_validator()
|
||||
|
||||
def setUp(self):
|
||||
mock_open = mock.mock_open()
|
||||
patch_open = mock.patch.object(cli, "open", mock_open, create=True)
|
||||
patch_open.start()
|
||||
self.addCleanup(patch_open.stop)
|
||||
|
||||
mock_json_load = mock.Mock()
|
||||
mock_json_load.return_value = {}
|
||||
patch_json_load = mock.patch("json.load")
|
||||
patch_json_load.start()
|
||||
self.addCleanup(patch_json_load.stop)
|
||||
|
||||
def test_find_validator_by_fully_qualified_object_name(self):
|
||||
arguments = cli.parse_args(
|
||||
[
|
||||
"--validator",
|
||||
"jsonschema.tests.test_cli.TestParser.FakeValidator",
|
||||
"--instance", "foo.json",
|
||||
"schema.json",
|
||||
]
|
||||
)
|
||||
self.assertIs(arguments["validator"], self.FakeValidator)
|
||||
|
||||
def test_find_validator_in_jsonschema(self):
|
||||
arguments = cli.parse_args(
|
||||
[
|
||||
"--validator", "Draft4Validator",
|
||||
"--instance", "foo.json",
|
||||
"schema.json",
|
||||
]
|
||||
)
|
||||
self.assertIs(arguments["validator"], Draft4Validator)
|
||||
|
||||
|
||||
class TestCLI(unittest.TestCase):
|
||||
def test_successful_validation(self):
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
exit_code = cli.run(
|
||||
{
|
||||
"validator": fake_validator(),
|
||||
"schema": {},
|
||||
"instances": [1],
|
||||
"error_format": "{error.message}",
|
||||
},
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
)
|
||||
self.assertFalse(stdout.getvalue())
|
||||
self.assertFalse(stderr.getvalue())
|
||||
self.assertEqual(exit_code, 0)
|
||||
|
||||
def test_unsuccessful_validation(self):
|
||||
error = ValidationError("I am an error!", instance=1)
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
exit_code = cli.run(
|
||||
{
|
||||
"validator": fake_validator([error]),
|
||||
"schema": {},
|
||||
"instances": [1],
|
||||
"error_format": "{error.instance} - {error.message}",
|
||||
},
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
)
|
||||
self.assertFalse(stdout.getvalue())
|
||||
self.assertEqual(stderr.getvalue(), "1 - I am an error!")
|
||||
self.assertEqual(exit_code, 1)
|
||||
|
||||
def test_unsuccessful_validation_multiple_instances(self):
|
||||
first_errors = [
|
||||
ValidationError("9", instance=1),
|
||||
ValidationError("8", instance=1),
|
||||
]
|
||||
second_errors = [ValidationError("7", instance=2)]
|
||||
stdout, stderr = StringIO(), StringIO()
|
||||
exit_code = cli.run(
|
||||
{
|
||||
"validator": fake_validator(first_errors, second_errors),
|
||||
"schema": {},
|
||||
"instances": [1, 2],
|
||||
"error_format": "{error.instance} - {error.message}\t",
|
||||
},
|
||||
stdout=stdout,
|
||||
stderr=stderr,
|
||||
)
|
||||
self.assertFalse(stdout.getvalue())
|
||||
self.assertEqual(stderr.getvalue(), "1 - 9\t1 - 8\t2 - 7\t")
|
||||
self.assertEqual(exit_code, 1)
|
||||
382
lib/spack/external/jsonschema/tests/test_exceptions.py
vendored
Normal file
382
lib/spack/external/jsonschema/tests/test_exceptions.py
vendored
Normal file
@@ -0,0 +1,382 @@
|
||||
import textwrap
|
||||
|
||||
from jsonschema import Draft4Validator, exceptions
|
||||
from jsonschema.compat import PY3
|
||||
from jsonschema.tests.compat import mock, unittest
|
||||
|
||||
|
||||
class TestBestMatch(unittest.TestCase):
|
||||
def best_match(self, errors):
|
||||
errors = list(errors)
|
||||
best = exceptions.best_match(errors)
|
||||
reversed_best = exceptions.best_match(reversed(errors))
|
||||
self.assertEqual(
|
||||
best,
|
||||
reversed_best,
|
||||
msg="Didn't return a consistent best match!\n"
|
||||
"Got: {0}\n\nThen: {1}".format(best, reversed_best),
|
||||
)
|
||||
return best
|
||||
|
||||
def test_shallower_errors_are_better_matches(self):
|
||||
validator = Draft4Validator(
|
||||
{
|
||||
"properties" : {
|
||||
"foo" : {
|
||||
"minProperties" : 2,
|
||||
"properties" : {"bar" : {"type" : "object"}},
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
best = self.best_match(validator.iter_errors({"foo" : {"bar" : []}}))
|
||||
self.assertEqual(best.validator, "minProperties")
|
||||
|
||||
def test_oneOf_and_anyOf_are_weak_matches(self):
|
||||
"""
|
||||
A property you *must* match is probably better than one you have to
|
||||
match a part of.
|
||||
|
||||
"""
|
||||
|
||||
validator = Draft4Validator(
|
||||
{
|
||||
"minProperties" : 2,
|
||||
"anyOf" : [{"type" : "string"}, {"type" : "number"}],
|
||||
"oneOf" : [{"type" : "string"}, {"type" : "number"}],
|
||||
}
|
||||
)
|
||||
best = self.best_match(validator.iter_errors({}))
|
||||
self.assertEqual(best.validator, "minProperties")
|
||||
|
||||
def test_if_the_most_relevant_error_is_anyOf_it_is_traversed(self):
|
||||
"""
|
||||
If the most relevant error is an anyOf, then we traverse its context
|
||||
and select the otherwise *least* relevant error, since in this case
|
||||
that means the most specific, deep, error inside the instance.
|
||||
|
||||
I.e. since only one of the schemas must match, we look for the most
|
||||
relevant one.
|
||||
|
||||
"""
|
||||
|
||||
validator = Draft4Validator(
|
||||
{
|
||||
"properties" : {
|
||||
"foo" : {
|
||||
"anyOf" : [
|
||||
{"type" : "string"},
|
||||
{"properties" : {"bar" : {"type" : "array"}}},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
best = self.best_match(validator.iter_errors({"foo" : {"bar" : 12}}))
|
||||
self.assertEqual(best.validator_value, "array")
|
||||
|
||||
def test_if_the_most_relevant_error_is_oneOf_it_is_traversed(self):
|
||||
"""
|
||||
If the most relevant error is an oneOf, then we traverse its context
|
||||
and select the otherwise *least* relevant error, since in this case
|
||||
that means the most specific, deep, error inside the instance.
|
||||
|
||||
I.e. since only one of the schemas must match, we look for the most
|
||||
relevant one.
|
||||
|
||||
"""
|
||||
|
||||
validator = Draft4Validator(
|
||||
{
|
||||
"properties" : {
|
||||
"foo" : {
|
||||
"oneOf" : [
|
||||
{"type" : "string"},
|
||||
{"properties" : {"bar" : {"type" : "array"}}},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
best = self.best_match(validator.iter_errors({"foo" : {"bar" : 12}}))
|
||||
self.assertEqual(best.validator_value, "array")
|
||||
|
||||
def test_if_the_most_relevant_error_is_allOf_it_is_traversed(self):
|
||||
"""
|
||||
Now, if the error is allOf, we traverse but select the *most* relevant
|
||||
error from the context, because all schemas here must match anyways.
|
||||
|
||||
"""
|
||||
|
||||
validator = Draft4Validator(
|
||||
{
|
||||
"properties" : {
|
||||
"foo" : {
|
||||
"allOf" : [
|
||||
{"type" : "string"},
|
||||
{"properties" : {"bar" : {"type" : "array"}}},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
best = self.best_match(validator.iter_errors({"foo" : {"bar" : 12}}))
|
||||
self.assertEqual(best.validator_value, "string")
|
||||
|
||||
def test_nested_context_for_oneOf(self):
|
||||
validator = Draft4Validator(
|
||||
{
|
||||
"properties" : {
|
||||
"foo" : {
|
||||
"oneOf" : [
|
||||
{"type" : "string"},
|
||||
{
|
||||
"oneOf" : [
|
||||
{"type" : "string"},
|
||||
{
|
||||
"properties" : {
|
||||
"bar" : {"type" : "array"}
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
best = self.best_match(validator.iter_errors({"foo" : {"bar" : 12}}))
|
||||
self.assertEqual(best.validator_value, "array")
|
||||
|
||||
def test_one_error(self):
|
||||
validator = Draft4Validator({"minProperties" : 2})
|
||||
error, = validator.iter_errors({})
|
||||
self.assertEqual(
|
||||
exceptions.best_match(validator.iter_errors({})).validator,
|
||||
"minProperties",
|
||||
)
|
||||
|
||||
def test_no_errors(self):
|
||||
validator = Draft4Validator({})
|
||||
self.assertIsNone(exceptions.best_match(validator.iter_errors({})))
|
||||
|
||||
|
||||
class TestByRelevance(unittest.TestCase):
|
||||
def test_short_paths_are_better_matches(self):
|
||||
shallow = exceptions.ValidationError("Oh no!", path=["baz"])
|
||||
deep = exceptions.ValidationError("Oh yes!", path=["foo", "bar"])
|
||||
match = max([shallow, deep], key=exceptions.relevance)
|
||||
self.assertIs(match, shallow)
|
||||
|
||||
match = max([deep, shallow], key=exceptions.relevance)
|
||||
self.assertIs(match, shallow)
|
||||
|
||||
def test_global_errors_are_even_better_matches(self):
|
||||
shallow = exceptions.ValidationError("Oh no!", path=[])
|
||||
deep = exceptions.ValidationError("Oh yes!", path=["foo"])
|
||||
|
||||
errors = sorted([shallow, deep], key=exceptions.relevance)
|
||||
self.assertEqual(
|
||||
[list(error.path) for error in errors],
|
||||
[["foo"], []],
|
||||
)
|
||||
|
||||
errors = sorted([deep, shallow], key=exceptions.relevance)
|
||||
self.assertEqual(
|
||||
[list(error.path) for error in errors],
|
||||
[["foo"], []],
|
||||
)
|
||||
|
||||
def test_weak_validators_are_lower_priority(self):
|
||||
weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
|
||||
normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
|
||||
|
||||
best_match = exceptions.by_relevance(weak="a")
|
||||
|
||||
match = max([weak, normal], key=best_match)
|
||||
self.assertIs(match, normal)
|
||||
|
||||
match = max([normal, weak], key=best_match)
|
||||
self.assertIs(match, normal)
|
||||
|
||||
def test_strong_validators_are_higher_priority(self):
|
||||
weak = exceptions.ValidationError("Oh no!", path=[], validator="a")
|
||||
normal = exceptions.ValidationError("Oh yes!", path=[], validator="b")
|
||||
strong = exceptions.ValidationError("Oh fine!", path=[], validator="c")
|
||||
|
||||
best_match = exceptions.by_relevance(weak="a", strong="c")
|
||||
|
||||
match = max([weak, normal, strong], key=best_match)
|
||||
self.assertIs(match, strong)
|
||||
|
||||
match = max([strong, normal, weak], key=best_match)
|
||||
self.assertIs(match, strong)
|
||||
|
||||
|
||||
class TestErrorTree(unittest.TestCase):
|
||||
def test_it_knows_how_many_total_errors_it_contains(self):
|
||||
errors = [mock.MagicMock() for _ in range(8)]
|
||||
tree = exceptions.ErrorTree(errors)
|
||||
self.assertEqual(tree.total_errors, 8)
|
||||
|
||||
def test_it_contains_an_item_if_the_item_had_an_error(self):
|
||||
errors = [exceptions.ValidationError("a message", path=["bar"])]
|
||||
tree = exceptions.ErrorTree(errors)
|
||||
self.assertIn("bar", tree)
|
||||
|
||||
def test_it_does_not_contain_an_item_if_the_item_had_no_error(self):
|
||||
errors = [exceptions.ValidationError("a message", path=["bar"])]
|
||||
tree = exceptions.ErrorTree(errors)
|
||||
self.assertNotIn("foo", tree)
|
||||
|
||||
def test_validators_that_failed_appear_in_errors_dict(self):
|
||||
error = exceptions.ValidationError("a message", validator="foo")
|
||||
tree = exceptions.ErrorTree([error])
|
||||
self.assertEqual(tree.errors, {"foo" : error})
|
||||
|
||||
def test_it_creates_a_child_tree_for_each_nested_path(self):
|
||||
errors = [
|
||||
exceptions.ValidationError("a bar message", path=["bar"]),
|
||||
exceptions.ValidationError("a bar -> 0 message", path=["bar", 0]),
|
||||
]
|
||||
tree = exceptions.ErrorTree(errors)
|
||||
self.assertIn(0, tree["bar"])
|
||||
self.assertNotIn(1, tree["bar"])
|
||||
|
||||
def test_children_have_their_errors_dicts_built(self):
|
||||
e1, e2 = (
|
||||
exceptions.ValidationError("1", validator="foo", path=["bar", 0]),
|
||||
exceptions.ValidationError("2", validator="quux", path=["bar", 0]),
|
||||
)
|
||||
tree = exceptions.ErrorTree([e1, e2])
|
||||
self.assertEqual(tree["bar"][0].errors, {"foo" : e1, "quux" : e2})
|
||||
|
||||
def test_it_does_not_contain_subtrees_that_are_not_in_the_instance(self):
|
||||
error = exceptions.ValidationError("123", validator="foo", instance=[])
|
||||
tree = exceptions.ErrorTree([error])
|
||||
|
||||
with self.assertRaises(IndexError):
|
||||
tree[0]
|
||||
|
||||
def test_if_its_in_the_tree_anyhow_it_does_not_raise_an_error(self):
|
||||
"""
|
||||
If a validator is dumb (like :validator:`required` in draft 3) and
|
||||
refers to a path that isn't in the instance, the tree still properly
|
||||
returns a subtree for that path.
|
||||
|
||||
"""
|
||||
|
||||
error = exceptions.ValidationError(
|
||||
"a message", validator="foo", instance={}, path=["foo"],
|
||||
)
|
||||
tree = exceptions.ErrorTree([error])
|
||||
self.assertIsInstance(tree["foo"], exceptions.ErrorTree)
|
||||
|
||||
|
||||
class TestErrorReprStr(unittest.TestCase):
|
||||
def make_error(self, **kwargs):
|
||||
defaults = dict(
|
||||
message=u"hello",
|
||||
validator=u"type",
|
||||
validator_value=u"string",
|
||||
instance=5,
|
||||
schema={u"type": u"string"},
|
||||
)
|
||||
defaults.update(kwargs)
|
||||
return exceptions.ValidationError(**defaults)
|
||||
|
||||
def assertShows(self, expected, **kwargs):
|
||||
if PY3:
|
||||
expected = expected.replace("u'", "'")
|
||||
expected = textwrap.dedent(expected).rstrip("\n")
|
||||
|
||||
error = self.make_error(**kwargs)
|
||||
message_line, _, rest = str(error).partition("\n")
|
||||
self.assertEqual(message_line, error.message)
|
||||
self.assertEqual(rest, expected)
|
||||
|
||||
def test_repr(self):
|
||||
self.assertEqual(
|
||||
repr(exceptions.ValidationError(message="Hello!")),
|
||||
"<ValidationError: %r>" % "Hello!",
|
||||
)
|
||||
|
||||
def test_unset_error(self):
|
||||
error = exceptions.ValidationError("message")
|
||||
self.assertEqual(str(error), "message")
|
||||
|
||||
kwargs = {
|
||||
"validator": "type",
|
||||
"validator_value": "string",
|
||||
"instance": 5,
|
||||
"schema": {"type": "string"}
|
||||
}
|
||||
# Just the message should show if any of the attributes are unset
|
||||
for attr in kwargs:
|
||||
k = dict(kwargs)
|
||||
del k[attr]
|
||||
error = exceptions.ValidationError("message", **k)
|
||||
self.assertEqual(str(error), "message")
|
||||
|
||||
def test_empty_paths(self):
|
||||
self.assertShows(
|
||||
"""
|
||||
Failed validating u'type' in schema:
|
||||
{u'type': u'string'}
|
||||
|
||||
On instance:
|
||||
5
|
||||
""",
|
||||
path=[],
|
||||
schema_path=[],
|
||||
)
|
||||
|
||||
def test_one_item_paths(self):
|
||||
self.assertShows(
|
||||
"""
|
||||
Failed validating u'type' in schema:
|
||||
{u'type': u'string'}
|
||||
|
||||
On instance[0]:
|
||||
5
|
||||
""",
|
||||
path=[0],
|
||||
schema_path=["items"],
|
||||
)
|
||||
|
||||
def test_multiple_item_paths(self):
|
||||
self.assertShows(
|
||||
"""
|
||||
Failed validating u'type' in schema[u'items'][0]:
|
||||
{u'type': u'string'}
|
||||
|
||||
On instance[0][u'a']:
|
||||
5
|
||||
""",
|
||||
path=[0, u"a"],
|
||||
schema_path=[u"items", 0, 1],
|
||||
)
|
||||
|
||||
def test_uses_pprint(self):
|
||||
with mock.patch("pprint.pformat") as pformat:
|
||||
str(self.make_error())
|
||||
self.assertEqual(pformat.call_count, 2) # schema + instance
|
||||
|
||||
def test_str_works_with_instances_having_overriden_eq_operator(self):
|
||||
"""
|
||||
Check for https://github.com/Julian/jsonschema/issues/164 which
|
||||
rendered exceptions unusable when a `ValidationError` involved
|
||||
instances with an `__eq__` method that returned truthy values.
|
||||
|
||||
"""
|
||||
|
||||
instance = mock.MagicMock()
|
||||
error = exceptions.ValidationError(
|
||||
"a message",
|
||||
validator="foo",
|
||||
instance=instance,
|
||||
validator_value="some",
|
||||
schema="schema",
|
||||
)
|
||||
str(error)
|
||||
self.assertFalse(instance.__eq__.called)
|
||||
63
lib/spack/external/jsonschema/tests/test_format.py
vendored
Normal file
63
lib/spack/external/jsonschema/tests/test_format.py
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
"""
|
||||
Tests for the parts of jsonschema related to the :validator:`format` property.
|
||||
|
||||
"""
|
||||
|
||||
from jsonschema.tests.compat import mock, unittest
|
||||
|
||||
from jsonschema import FormatError, ValidationError, FormatChecker
|
||||
from jsonschema.validators import Draft4Validator
|
||||
|
||||
|
||||
class TestFormatChecker(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.fn = mock.Mock()
|
||||
|
||||
def test_it_can_validate_no_formats(self):
|
||||
checker = FormatChecker(formats=())
|
||||
self.assertFalse(checker.checkers)
|
||||
|
||||
def test_it_raises_a_key_error_for_unknown_formats(self):
|
||||
with self.assertRaises(KeyError):
|
||||
FormatChecker(formats=["o noes"])
|
||||
|
||||
def test_it_can_register_cls_checkers(self):
|
||||
with mock.patch.dict(FormatChecker.checkers, clear=True):
|
||||
FormatChecker.cls_checks("new")(self.fn)
|
||||
self.assertEqual(FormatChecker.checkers, {"new" : (self.fn, ())})
|
||||
|
||||
def test_it_can_register_checkers(self):
|
||||
checker = FormatChecker()
|
||||
checker.checks("new")(self.fn)
|
||||
self.assertEqual(
|
||||
checker.checkers,
|
||||
dict(FormatChecker.checkers, new=(self.fn, ()))
|
||||
)
|
||||
|
||||
def test_it_catches_registered_errors(self):
|
||||
checker = FormatChecker()
|
||||
cause = self.fn.side_effect = ValueError()
|
||||
|
||||
checker.checks("foo", raises=ValueError)(self.fn)
|
||||
|
||||
with self.assertRaises(FormatError) as cm:
|
||||
checker.check("bar", "foo")
|
||||
|
||||
self.assertIs(cm.exception.cause, cause)
|
||||
self.assertIs(cm.exception.__cause__, cause)
|
||||
|
||||
# Unregistered errors should not be caught
|
||||
self.fn.side_effect = AttributeError
|
||||
with self.assertRaises(AttributeError):
|
||||
checker.check("bar", "foo")
|
||||
|
||||
def test_format_error_causes_become_validation_error_causes(self):
|
||||
checker = FormatChecker()
|
||||
checker.checks("foo", raises=ValueError)(self.fn)
|
||||
cause = self.fn.side_effect = ValueError()
|
||||
validator = Draft4Validator({"format" : "foo"}, format_checker=checker)
|
||||
|
||||
with self.assertRaises(ValidationError) as cm:
|
||||
validator.validate("bar")
|
||||
|
||||
self.assertIs(cm.exception.__cause__, cause)
|
||||
290
lib/spack/external/jsonschema/tests/test_jsonschema_test_suite.py
vendored
Normal file
290
lib/spack/external/jsonschema/tests/test_jsonschema_test_suite.py
vendored
Normal file
@@ -0,0 +1,290 @@
|
||||
"""
|
||||
Test runner for the JSON Schema official test suite
|
||||
|
||||
Tests comprehensive correctness of each draft's validator.
|
||||
|
||||
See https://github.com/json-schema/JSON-Schema-Test-Suite for details.
|
||||
|
||||
"""
|
||||
|
||||
from contextlib import closing
|
||||
from decimal import Decimal
|
||||
import glob
|
||||
import json
|
||||
import io
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
try:
|
||||
from sys import pypy_version_info
|
||||
except ImportError:
|
||||
pypy_version_info = None
|
||||
|
||||
from jsonschema import (
|
||||
FormatError, SchemaError, ValidationError, Draft3Validator,
|
||||
Draft4Validator, FormatChecker, draft3_format_checker,
|
||||
draft4_format_checker, validate,
|
||||
)
|
||||
from jsonschema.compat import PY3
|
||||
from jsonschema.tests.compat import mock, unittest
|
||||
import jsonschema
|
||||
|
||||
|
||||
REPO_ROOT = os.path.join(os.path.dirname(jsonschema.__file__), os.path.pardir)
|
||||
SUITE = os.getenv("JSON_SCHEMA_TEST_SUITE", os.path.join(REPO_ROOT, "json"))
|
||||
|
||||
if not os.path.isdir(SUITE):
|
||||
raise ValueError(
|
||||
"Can't find the JSON-Schema-Test-Suite directory. Set the "
|
||||
"'JSON_SCHEMA_TEST_SUITE' environment variable or run the tests from "
|
||||
"alongside a checkout of the suite."
|
||||
)
|
||||
|
||||
TESTS_DIR = os.path.join(SUITE, "tests")
|
||||
JSONSCHEMA_SUITE = os.path.join(SUITE, "bin", "jsonschema_suite")
|
||||
|
||||
remotes_stdout = subprocess.Popen(
|
||||
["python", JSONSCHEMA_SUITE, "remotes"], stdout=subprocess.PIPE,
|
||||
).stdout
|
||||
|
||||
with closing(remotes_stdout):
|
||||
if PY3:
|
||||
remotes_stdout = io.TextIOWrapper(remotes_stdout)
|
||||
REMOTES = json.load(remotes_stdout)
|
||||
|
||||
|
||||
def make_case(schema, data, valid, name):
|
||||
if valid:
|
||||
def test_case(self):
|
||||
kwargs = getattr(self, "validator_kwargs", {})
|
||||
validate(data, schema, cls=self.validator_class, **kwargs)
|
||||
else:
|
||||
def test_case(self):
|
||||
kwargs = getattr(self, "validator_kwargs", {})
|
||||
with self.assertRaises(ValidationError):
|
||||
validate(data, schema, cls=self.validator_class, **kwargs)
|
||||
|
||||
if not PY3:
|
||||
name = name.encode("utf-8")
|
||||
test_case.__name__ = name
|
||||
|
||||
return test_case
|
||||
|
||||
|
||||
def maybe_skip(skip, test_case, case, test):
|
||||
if skip is not None:
|
||||
reason = skip(case, test)
|
||||
if reason is not None:
|
||||
test_case = unittest.skip(reason)(test_case)
|
||||
return test_case
|
||||
|
||||
|
||||
def load_json_cases(tests_glob, ignore_glob="", basedir=TESTS_DIR, skip=None):
|
||||
if ignore_glob:
|
||||
ignore_glob = os.path.join(basedir, ignore_glob)
|
||||
|
||||
def add_test_methods(test_class):
|
||||
ignored = set(glob.iglob(ignore_glob))
|
||||
|
||||
for filename in glob.iglob(os.path.join(basedir, tests_glob)):
|
||||
if filename in ignored:
|
||||
continue
|
||||
|
||||
validating, _ = os.path.splitext(os.path.basename(filename))
|
||||
id = itertools.count(1)
|
||||
|
||||
with open(filename) as test_file:
|
||||
for case in json.load(test_file):
|
||||
for test in case["tests"]:
|
||||
name = "test_%s_%s_%s" % (
|
||||
validating,
|
||||
next(id),
|
||||
re.sub(r"[\W ]+", "_", test["description"]),
|
||||
)
|
||||
assert not hasattr(test_class, name), name
|
||||
|
||||
test_case = make_case(
|
||||
data=test["data"],
|
||||
schema=case["schema"],
|
||||
valid=test["valid"],
|
||||
name=name,
|
||||
)
|
||||
test_case = maybe_skip(skip, test_case, case, test)
|
||||
setattr(test_class, name, test_case)
|
||||
|
||||
return test_class
|
||||
return add_test_methods
|
||||
|
||||
|
||||
class TypesMixin(object):
|
||||
@unittest.skipIf(PY3, "In Python 3 json.load always produces unicode")
|
||||
def test_string_a_bytestring_is_a_string(self):
|
||||
self.validator_class({"type" : "string"}).validate(b"foo")
|
||||
|
||||
|
||||
class DecimalMixin(object):
|
||||
def test_it_can_validate_with_decimals(self):
|
||||
schema = {"type" : "number"}
|
||||
validator = self.validator_class(
|
||||
schema, types={"number" : (int, float, Decimal)}
|
||||
)
|
||||
|
||||
for valid in [1, 1.1, Decimal(1) / Decimal(8)]:
|
||||
validator.validate(valid)
|
||||
|
||||
for invalid in ["foo", {}, [], True, None]:
|
||||
with self.assertRaises(ValidationError):
|
||||
validator.validate(invalid)
|
||||
|
||||
|
||||
def missing_format(checker):
|
||||
def missing_format(case, test):
|
||||
format = case["schema"].get("format")
|
||||
if format not in checker.checkers:
|
||||
return "Format checker {0!r} not found.".format(format)
|
||||
elif (
|
||||
format == "date-time" and
|
||||
pypy_version_info is not None and
|
||||
pypy_version_info[:2] <= (1, 9)
|
||||
):
|
||||
# datetime.datetime is overzealous about typechecking in <=1.9
|
||||
return "datetime.datetime is broken on this version of PyPy."
|
||||
return missing_format
|
||||
|
||||
|
||||
class FormatMixin(object):
|
||||
def test_it_returns_true_for_formats_it_does_not_know_about(self):
|
||||
validator = self.validator_class(
|
||||
{"format" : "carrot"}, format_checker=FormatChecker(),
|
||||
)
|
||||
validator.validate("bugs")
|
||||
|
||||
def test_it_does_not_validate_formats_by_default(self):
|
||||
validator = self.validator_class({})
|
||||
self.assertIsNone(validator.format_checker)
|
||||
|
||||
def test_it_validates_formats_if_a_checker_is_provided(self):
|
||||
checker = mock.Mock(spec=FormatChecker)
|
||||
validator = self.validator_class(
|
||||
{"format" : "foo"}, format_checker=checker,
|
||||
)
|
||||
|
||||
validator.validate("bar")
|
||||
|
||||
checker.check.assert_called_once_with("bar", "foo")
|
||||
|
||||
cause = ValueError()
|
||||
checker.check.side_effect = FormatError('aoeu', cause=cause)
|
||||
|
||||
with self.assertRaises(ValidationError) as cm:
|
||||
validator.validate("bar")
|
||||
# Make sure original cause is attached
|
||||
self.assertIs(cm.exception.cause, cause)
|
||||
|
||||
def test_it_validates_formats_of_any_type(self):
|
||||
checker = mock.Mock(spec=FormatChecker)
|
||||
validator = self.validator_class(
|
||||
{"format" : "foo"}, format_checker=checker,
|
||||
)
|
||||
|
||||
validator.validate([1, 2, 3])
|
||||
|
||||
checker.check.assert_called_once_with([1, 2, 3], "foo")
|
||||
|
||||
cause = ValueError()
|
||||
checker.check.side_effect = FormatError('aoeu', cause=cause)
|
||||
|
||||
with self.assertRaises(ValidationError) as cm:
|
||||
validator.validate([1, 2, 3])
|
||||
# Make sure original cause is attached
|
||||
self.assertIs(cm.exception.cause, cause)
|
||||
|
||||
|
||||
if sys.maxunicode == 2 ** 16 - 1: # This is a narrow build.
|
||||
def narrow_unicode_build(case, test):
|
||||
if "supplementary Unicode" in test["description"]:
|
||||
return "Not running surrogate Unicode case, this Python is narrow."
|
||||
else:
|
||||
def narrow_unicode_build(case, test): # This isn't, skip nothing.
|
||||
return
|
||||
|
||||
|
||||
@load_json_cases(
|
||||
"draft3/*.json",
|
||||
skip=narrow_unicode_build,
|
||||
ignore_glob="draft3/refRemote.json",
|
||||
)
|
||||
@load_json_cases(
|
||||
"draft3/optional/format.json", skip=missing_format(draft3_format_checker)
|
||||
)
|
||||
@load_json_cases("draft3/optional/bignum.json")
|
||||
@load_json_cases("draft3/optional/zeroTerminatedFloats.json")
|
||||
class TestDraft3(unittest.TestCase, TypesMixin, DecimalMixin, FormatMixin):
|
||||
validator_class = Draft3Validator
|
||||
validator_kwargs = {"format_checker" : draft3_format_checker}
|
||||
|
||||
def test_any_type_is_valid_for_type_any(self):
|
||||
validator = self.validator_class({"type" : "any"})
|
||||
validator.validate(mock.Mock())
|
||||
|
||||
# TODO: we're in need of more meta schema tests
|
||||
def test_invalid_properties(self):
|
||||
with self.assertRaises(SchemaError):
|
||||
validate({}, {"properties": {"test": True}},
|
||||
cls=self.validator_class)
|
||||
|
||||
def test_minItems_invalid_string(self):
|
||||
with self.assertRaises(SchemaError):
|
||||
# needs to be an integer
|
||||
validate([1], {"minItems" : "1"}, cls=self.validator_class)
|
||||
|
||||
|
||||
@load_json_cases(
|
||||
"draft4/*.json",
|
||||
skip=narrow_unicode_build,
|
||||
ignore_glob="draft4/refRemote.json",
|
||||
)
|
||||
@load_json_cases(
|
||||
"draft4/optional/format.json", skip=missing_format(draft4_format_checker)
|
||||
)
|
||||
@load_json_cases("draft4/optional/bignum.json")
|
||||
@load_json_cases("draft4/optional/zeroTerminatedFloats.json")
|
||||
class TestDraft4(unittest.TestCase, TypesMixin, DecimalMixin, FormatMixin):
|
||||
validator_class = Draft4Validator
|
||||
validator_kwargs = {"format_checker" : draft4_format_checker}
|
||||
|
||||
# TODO: we're in need of more meta schema tests
|
||||
def test_invalid_properties(self):
|
||||
with self.assertRaises(SchemaError):
|
||||
validate({}, {"properties": {"test": True}},
|
||||
cls=self.validator_class)
|
||||
|
||||
def test_minItems_invalid_string(self):
|
||||
with self.assertRaises(SchemaError):
|
||||
# needs to be an integer
|
||||
validate([1], {"minItems" : "1"}, cls=self.validator_class)
|
||||
|
||||
|
||||
class RemoteRefResolutionMixin(object):
|
||||
def setUp(self):
|
||||
patch = mock.patch("jsonschema.validators.requests")
|
||||
requests = patch.start()
|
||||
requests.get.side_effect = self.resolve
|
||||
self.addCleanup(patch.stop)
|
||||
|
||||
def resolve(self, reference):
|
||||
_, _, reference = reference.partition("http://localhost:1234/")
|
||||
return mock.Mock(**{"json.return_value" : REMOTES.get(reference)})
|
||||
|
||||
|
||||
@load_json_cases("draft3/refRemote.json")
|
||||
class Draft3RemoteResolution(RemoteRefResolutionMixin, unittest.TestCase):
|
||||
validator_class = Draft3Validator
|
||||
|
||||
|
||||
@load_json_cases("draft4/refRemote.json")
|
||||
class Draft4RemoteResolution(RemoteRefResolutionMixin, unittest.TestCase):
|
||||
validator_class = Draft4Validator
|
||||
786
lib/spack/external/jsonschema/tests/test_validators.py
vendored
Normal file
786
lib/spack/external/jsonschema/tests/test_validators.py
vendored
Normal file
@@ -0,0 +1,786 @@
|
||||
from collections import deque
|
||||
from contextlib import contextmanager
|
||||
import json
|
||||
|
||||
from jsonschema import FormatChecker, ValidationError
|
||||
from jsonschema.tests.compat import mock, unittest
|
||||
from jsonschema.validators import (
|
||||
RefResolutionError, UnknownType, Draft3Validator,
|
||||
Draft4Validator, RefResolver, create, extend, validator_for, validate,
|
||||
)
|
||||
|
||||
|
||||
class TestCreateAndExtend(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.meta_schema = {u"properties" : {u"smelly" : {}}}
|
||||
self.smelly = mock.MagicMock()
|
||||
self.validators = {u"smelly" : self.smelly}
|
||||
self.types = {u"dict" : dict}
|
||||
self.Validator = create(
|
||||
meta_schema=self.meta_schema,
|
||||
validators=self.validators,
|
||||
default_types=self.types,
|
||||
)
|
||||
|
||||
self.validator_value = 12
|
||||
self.schema = {u"smelly" : self.validator_value}
|
||||
self.validator = self.Validator(self.schema)
|
||||
|
||||
def test_attrs(self):
|
||||
self.assertEqual(self.Validator.VALIDATORS, self.validators)
|
||||
self.assertEqual(self.Validator.META_SCHEMA, self.meta_schema)
|
||||
self.assertEqual(self.Validator.DEFAULT_TYPES, self.types)
|
||||
|
||||
def test_init(self):
|
||||
self.assertEqual(self.validator.schema, self.schema)
|
||||
|
||||
def test_iter_errors(self):
|
||||
instance = "hello"
|
||||
|
||||
self.smelly.return_value = []
|
||||
self.assertEqual(list(self.validator.iter_errors(instance)), [])
|
||||
|
||||
error = mock.Mock()
|
||||
self.smelly.return_value = [error]
|
||||
self.assertEqual(list(self.validator.iter_errors(instance)), [error])
|
||||
|
||||
self.smelly.assert_called_with(
|
||||
self.validator, self.validator_value, instance, self.schema,
|
||||
)
|
||||
|
||||
def test_if_a_version_is_provided_it_is_registered(self):
|
||||
with mock.patch("jsonschema.validators.validates") as validates:
|
||||
validates.side_effect = lambda version : lambda cls : cls
|
||||
Validator = create(meta_schema={u"id" : ""}, version="my version")
|
||||
validates.assert_called_once_with("my version")
|
||||
self.assertEqual(Validator.__name__, "MyVersionValidator")
|
||||
|
||||
def test_if_a_version_is_not_provided_it_is_not_registered(self):
|
||||
with mock.patch("jsonschema.validators.validates") as validates:
|
||||
create(meta_schema={u"id" : "id"})
|
||||
self.assertFalse(validates.called)
|
||||
|
||||
def test_extend(self):
|
||||
validators = dict(self.Validator.VALIDATORS)
|
||||
new = mock.Mock()
|
||||
|
||||
Extended = extend(self.Validator, validators={u"a new one" : new})
|
||||
|
||||
validators.update([(u"a new one", new)])
|
||||
self.assertEqual(Extended.VALIDATORS, validators)
|
||||
self.assertNotIn(u"a new one", self.Validator.VALIDATORS)
|
||||
|
||||
self.assertEqual(Extended.META_SCHEMA, self.Validator.META_SCHEMA)
|
||||
self.assertEqual(Extended.DEFAULT_TYPES, self.Validator.DEFAULT_TYPES)
|
||||
|
||||
|
||||
class TestIterErrors(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self.validator = Draft3Validator({})
|
||||
|
||||
def test_iter_errors(self):
|
||||
instance = [1, 2]
|
||||
schema = {
|
||||
u"disallow" : u"array",
|
||||
u"enum" : [["a", "b", "c"], ["d", "e", "f"]],
|
||||
u"minItems" : 3
|
||||
}
|
||||
|
||||
got = (e.message for e in self.validator.iter_errors(instance, schema))
|
||||
expected = [
|
||||
"%r is disallowed for [1, 2]" % (schema["disallow"],),
|
||||
"[1, 2] is too short",
|
||||
"[1, 2] is not one of %r" % (schema["enum"],),
|
||||
]
|
||||
self.assertEqual(sorted(got), sorted(expected))
|
||||
|
||||
def test_iter_errors_multiple_failures_one_validator(self):
|
||||
instance = {"foo" : 2, "bar" : [1], "baz" : 15, "quux" : "spam"}
|
||||
schema = {
|
||||
u"properties" : {
|
||||
"foo" : {u"type" : "string"},
|
||||
"bar" : {u"minItems" : 2},
|
||||
"baz" : {u"maximum" : 10, u"enum" : [2, 4, 6, 8]},
|
||||
}
|
||||
}
|
||||
|
||||
errors = list(self.validator.iter_errors(instance, schema))
|
||||
self.assertEqual(len(errors), 4)
|
||||
|
||||
|
||||
class TestValidationErrorMessages(unittest.TestCase):
|
||||
def message_for(self, instance, schema, *args, **kwargs):
|
||||
kwargs.setdefault("cls", Draft3Validator)
|
||||
with self.assertRaises(ValidationError) as e:
|
||||
validate(instance, schema, *args, **kwargs)
|
||||
return e.exception.message
|
||||
|
||||
def test_single_type_failure(self):
|
||||
message = self.message_for(instance=1, schema={u"type" : u"string"})
|
||||
self.assertEqual(message, "1 is not of type %r" % u"string")
|
||||
|
||||
def test_single_type_list_failure(self):
|
||||
message = self.message_for(instance=1, schema={u"type" : [u"string"]})
|
||||
self.assertEqual(message, "1 is not of type %r" % u"string")
|
||||
|
||||
def test_multiple_type_failure(self):
|
||||
types = u"string", u"object"
|
||||
message = self.message_for(instance=1, schema={u"type" : list(types)})
|
||||
self.assertEqual(message, "1 is not of type %r, %r" % types)
|
||||
|
||||
def test_object_without_title_type_failure(self):
|
||||
type = {u"type" : [{u"minimum" : 3}]}
|
||||
message = self.message_for(instance=1, schema={u"type" : [type]})
|
||||
self.assertEqual(message, "1 is not of type %r" % (type,))
|
||||
|
||||
def test_object_with_name_type_failure(self):
|
||||
name = "Foo"
|
||||
schema = {u"type" : [{u"name" : name, u"minimum" : 3}]}
|
||||
message = self.message_for(instance=1, schema=schema)
|
||||
self.assertEqual(message, "1 is not of type %r" % (name,))
|
||||
|
||||
def test_minimum(self):
|
||||
message = self.message_for(instance=1, schema={"minimum" : 2})
|
||||
self.assertEqual(message, "1 is less than the minimum of 2")
|
||||
|
||||
def test_maximum(self):
|
||||
message = self.message_for(instance=1, schema={"maximum" : 0})
|
||||
self.assertEqual(message, "1 is greater than the maximum of 0")
|
||||
|
||||
def test_dependencies_failure_has_single_element_not_list(self):
|
||||
depend, on = "bar", "foo"
|
||||
schema = {u"dependencies" : {depend : on}}
|
||||
message = self.message_for({"bar" : 2}, schema)
|
||||
self.assertEqual(message, "%r is a dependency of %r" % (on, depend))
|
||||
|
||||
def test_additionalItems_single_failure(self):
|
||||
message = self.message_for(
|
||||
[2], {u"items" : [], u"additionalItems" : False},
|
||||
)
|
||||
self.assertIn("(2 was unexpected)", message)
|
||||
|
||||
def test_additionalItems_multiple_failures(self):
|
||||
message = self.message_for(
|
||||
[1, 2, 3], {u"items" : [], u"additionalItems" : False}
|
||||
)
|
||||
self.assertIn("(1, 2, 3 were unexpected)", message)
|
||||
|
||||
def test_additionalProperties_single_failure(self):
|
||||
additional = "foo"
|
||||
schema = {u"additionalProperties" : False}
|
||||
message = self.message_for({additional : 2}, schema)
|
||||
self.assertIn("(%r was unexpected)" % (additional,), message)
|
||||
|
||||
def test_additionalProperties_multiple_failures(self):
|
||||
schema = {u"additionalProperties" : False}
|
||||
message = self.message_for(dict.fromkeys(["foo", "bar"]), schema)
|
||||
|
||||
self.assertIn(repr("foo"), message)
|
||||
self.assertIn(repr("bar"), message)
|
||||
self.assertIn("were unexpected)", message)
|
||||
|
||||
def test_invalid_format_default_message(self):
|
||||
checker = FormatChecker(formats=())
|
||||
check_fn = mock.Mock(return_value=False)
|
||||
checker.checks(u"thing")(check_fn)
|
||||
|
||||
schema = {u"format" : u"thing"}
|
||||
message = self.message_for("bla", schema, format_checker=checker)
|
||||
|
||||
self.assertIn(repr("bla"), message)
|
||||
self.assertIn(repr("thing"), message)
|
||||
self.assertIn("is not a", message)
|
||||
|
||||
|
||||
class TestValidationErrorDetails(unittest.TestCase):
|
||||
# TODO: These really need unit tests for each individual validator, rather
|
||||
# than just these higher level tests.
|
||||
def test_anyOf(self):
|
||||
instance = 5
|
||||
schema = {
|
||||
"anyOf": [
|
||||
{"minimum": 20},
|
||||
{"type": "string"}
|
||||
]
|
||||
}
|
||||
|
||||
validator = Draft4Validator(schema)
|
||||
errors = list(validator.iter_errors(instance))
|
||||
self.assertEqual(len(errors), 1)
|
||||
e = errors[0]
|
||||
|
||||
self.assertEqual(e.validator, "anyOf")
|
||||
self.assertEqual(e.validator_value, schema["anyOf"])
|
||||
self.assertEqual(e.instance, instance)
|
||||
self.assertEqual(e.schema, schema)
|
||||
self.assertIsNone(e.parent)
|
||||
|
||||
self.assertEqual(e.path, deque([]))
|
||||
self.assertEqual(e.relative_path, deque([]))
|
||||
self.assertEqual(e.absolute_path, deque([]))
|
||||
|
||||
self.assertEqual(e.schema_path, deque(["anyOf"]))
|
||||
self.assertEqual(e.relative_schema_path, deque(["anyOf"]))
|
||||
self.assertEqual(e.absolute_schema_path, deque(["anyOf"]))
|
||||
|
||||
self.assertEqual(len(e.context), 2)
|
||||
|
||||
e1, e2 = sorted_errors(e.context)
|
||||
|
||||
self.assertEqual(e1.validator, "minimum")
|
||||
self.assertEqual(e1.validator_value, schema["anyOf"][0]["minimum"])
|
||||
self.assertEqual(e1.instance, instance)
|
||||
self.assertEqual(e1.schema, schema["anyOf"][0])
|
||||
self.assertIs(e1.parent, e)
|
||||
|
||||
self.assertEqual(e1.path, deque([]))
|
||||
self.assertEqual(e1.absolute_path, deque([]))
|
||||
self.assertEqual(e1.relative_path, deque([]))
|
||||
|
||||
self.assertEqual(e1.schema_path, deque([0, "minimum"]))
|
||||
self.assertEqual(e1.relative_schema_path, deque([0, "minimum"]))
|
||||
self.assertEqual(
|
||||
e1.absolute_schema_path, deque(["anyOf", 0, "minimum"]),
|
||||
)
|
||||
|
||||
self.assertFalse(e1.context)
|
||||
|
||||
self.assertEqual(e2.validator, "type")
|
||||
self.assertEqual(e2.validator_value, schema["anyOf"][1]["type"])
|
||||
self.assertEqual(e2.instance, instance)
|
||||
self.assertEqual(e2.schema, schema["anyOf"][1])
|
||||
self.assertIs(e2.parent, e)
|
||||
|
||||
self.assertEqual(e2.path, deque([]))
|
||||
self.assertEqual(e2.relative_path, deque([]))
|
||||
self.assertEqual(e2.absolute_path, deque([]))
|
||||
|
||||
self.assertEqual(e2.schema_path, deque([1, "type"]))
|
||||
self.assertEqual(e2.relative_schema_path, deque([1, "type"]))
|
||||
self.assertEqual(e2.absolute_schema_path, deque(["anyOf", 1, "type"]))
|
||||
|
||||
self.assertEqual(len(e2.context), 0)
|
||||
|
||||
def test_type(self):
|
||||
instance = {"foo": 1}
|
||||
schema = {
|
||||
"type": [
|
||||
{"type": "integer"},
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"foo": {"enum": [2]}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = list(validator.iter_errors(instance))
|
||||
self.assertEqual(len(errors), 1)
|
||||
e = errors[0]
|
||||
|
||||
self.assertEqual(e.validator, "type")
|
||||
self.assertEqual(e.validator_value, schema["type"])
|
||||
self.assertEqual(e.instance, instance)
|
||||
self.assertEqual(e.schema, schema)
|
||||
self.assertIsNone(e.parent)
|
||||
|
||||
self.assertEqual(e.path, deque([]))
|
||||
self.assertEqual(e.relative_path, deque([]))
|
||||
self.assertEqual(e.absolute_path, deque([]))
|
||||
|
||||
self.assertEqual(e.schema_path, deque(["type"]))
|
||||
self.assertEqual(e.relative_schema_path, deque(["type"]))
|
||||
self.assertEqual(e.absolute_schema_path, deque(["type"]))
|
||||
|
||||
self.assertEqual(len(e.context), 2)
|
||||
|
||||
e1, e2 = sorted_errors(e.context)
|
||||
|
||||
self.assertEqual(e1.validator, "type")
|
||||
self.assertEqual(e1.validator_value, schema["type"][0]["type"])
|
||||
self.assertEqual(e1.instance, instance)
|
||||
self.assertEqual(e1.schema, schema["type"][0])
|
||||
self.assertIs(e1.parent, e)
|
||||
|
||||
self.assertEqual(e1.path, deque([]))
|
||||
self.assertEqual(e1.relative_path, deque([]))
|
||||
self.assertEqual(e1.absolute_path, deque([]))
|
||||
|
||||
self.assertEqual(e1.schema_path, deque([0, "type"]))
|
||||
self.assertEqual(e1.relative_schema_path, deque([0, "type"]))
|
||||
self.assertEqual(e1.absolute_schema_path, deque(["type", 0, "type"]))
|
||||
|
||||
self.assertFalse(e1.context)
|
||||
|
||||
self.assertEqual(e2.validator, "enum")
|
||||
self.assertEqual(e2.validator_value, [2])
|
||||
self.assertEqual(e2.instance, 1)
|
||||
self.assertEqual(e2.schema, {u"enum" : [2]})
|
||||
self.assertIs(e2.parent, e)
|
||||
|
||||
self.assertEqual(e2.path, deque(["foo"]))
|
||||
self.assertEqual(e2.relative_path, deque(["foo"]))
|
||||
self.assertEqual(e2.absolute_path, deque(["foo"]))
|
||||
|
||||
self.assertEqual(
|
||||
e2.schema_path, deque([1, "properties", "foo", "enum"]),
|
||||
)
|
||||
self.assertEqual(
|
||||
e2.relative_schema_path, deque([1, "properties", "foo", "enum"]),
|
||||
)
|
||||
self.assertEqual(
|
||||
e2.absolute_schema_path,
|
||||
deque(["type", 1, "properties", "foo", "enum"]),
|
||||
)
|
||||
|
||||
self.assertFalse(e2.context)
|
||||
|
||||
def test_single_nesting(self):
|
||||
instance = {"foo" : 2, "bar" : [1], "baz" : 15, "quux" : "spam"}
|
||||
schema = {
|
||||
"properties" : {
|
||||
"foo" : {"type" : "string"},
|
||||
"bar" : {"minItems" : 2},
|
||||
"baz" : {"maximum" : 10, "enum" : [2, 4, 6, 8]},
|
||||
}
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = validator.iter_errors(instance)
|
||||
e1, e2, e3, e4 = sorted_errors(errors)
|
||||
|
||||
self.assertEqual(e1.path, deque(["bar"]))
|
||||
self.assertEqual(e2.path, deque(["baz"]))
|
||||
self.assertEqual(e3.path, deque(["baz"]))
|
||||
self.assertEqual(e4.path, deque(["foo"]))
|
||||
|
||||
self.assertEqual(e1.relative_path, deque(["bar"]))
|
||||
self.assertEqual(e2.relative_path, deque(["baz"]))
|
||||
self.assertEqual(e3.relative_path, deque(["baz"]))
|
||||
self.assertEqual(e4.relative_path, deque(["foo"]))
|
||||
|
||||
self.assertEqual(e1.absolute_path, deque(["bar"]))
|
||||
self.assertEqual(e2.absolute_path, deque(["baz"]))
|
||||
self.assertEqual(e3.absolute_path, deque(["baz"]))
|
||||
self.assertEqual(e4.absolute_path, deque(["foo"]))
|
||||
|
||||
self.assertEqual(e1.validator, "minItems")
|
||||
self.assertEqual(e2.validator, "enum")
|
||||
self.assertEqual(e3.validator, "maximum")
|
||||
self.assertEqual(e4.validator, "type")
|
||||
|
||||
def test_multiple_nesting(self):
|
||||
instance = [1, {"foo" : 2, "bar" : {"baz" : [1]}}, "quux"]
|
||||
schema = {
|
||||
"type" : "string",
|
||||
"items" : {
|
||||
"type" : ["string", "object"],
|
||||
"properties" : {
|
||||
"foo" : {"enum" : [1, 3]},
|
||||
"bar" : {
|
||||
"type" : "array",
|
||||
"properties" : {
|
||||
"bar" : {"required" : True},
|
||||
"baz" : {"minItems" : 2},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = validator.iter_errors(instance)
|
||||
e1, e2, e3, e4, e5, e6 = sorted_errors(errors)
|
||||
|
||||
self.assertEqual(e1.path, deque([]))
|
||||
self.assertEqual(e2.path, deque([0]))
|
||||
self.assertEqual(e3.path, deque([1, "bar"]))
|
||||
self.assertEqual(e4.path, deque([1, "bar", "bar"]))
|
||||
self.assertEqual(e5.path, deque([1, "bar", "baz"]))
|
||||
self.assertEqual(e6.path, deque([1, "foo"]))
|
||||
|
||||
self.assertEqual(e1.schema_path, deque(["type"]))
|
||||
self.assertEqual(e2.schema_path, deque(["items", "type"]))
|
||||
self.assertEqual(
|
||||
list(e3.schema_path), ["items", "properties", "bar", "type"],
|
||||
)
|
||||
self.assertEqual(
|
||||
list(e4.schema_path),
|
||||
["items", "properties", "bar", "properties", "bar", "required"],
|
||||
)
|
||||
self.assertEqual(
|
||||
list(e5.schema_path),
|
||||
["items", "properties", "bar", "properties", "baz", "minItems"]
|
||||
)
|
||||
self.assertEqual(
|
||||
list(e6.schema_path), ["items", "properties", "foo", "enum"],
|
||||
)
|
||||
|
||||
self.assertEqual(e1.validator, "type")
|
||||
self.assertEqual(e2.validator, "type")
|
||||
self.assertEqual(e3.validator, "type")
|
||||
self.assertEqual(e4.validator, "required")
|
||||
self.assertEqual(e5.validator, "minItems")
|
||||
self.assertEqual(e6.validator, "enum")
|
||||
|
||||
def test_additionalProperties(self):
|
||||
instance = {"bar": "bar", "foo": 2}
|
||||
schema = {
|
||||
"additionalProperties" : {"type": "integer", "minimum": 5}
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = validator.iter_errors(instance)
|
||||
e1, e2 = sorted_errors(errors)
|
||||
|
||||
self.assertEqual(e1.path, deque(["bar"]))
|
||||
self.assertEqual(e2.path, deque(["foo"]))
|
||||
|
||||
self.assertEqual(e1.validator, "type")
|
||||
self.assertEqual(e2.validator, "minimum")
|
||||
|
||||
def test_patternProperties(self):
|
||||
instance = {"bar": 1, "foo": 2}
|
||||
schema = {
|
||||
"patternProperties" : {
|
||||
"bar": {"type": "string"},
|
||||
"foo": {"minimum": 5}
|
||||
}
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = validator.iter_errors(instance)
|
||||
e1, e2 = sorted_errors(errors)
|
||||
|
||||
self.assertEqual(e1.path, deque(["bar"]))
|
||||
self.assertEqual(e2.path, deque(["foo"]))
|
||||
|
||||
self.assertEqual(e1.validator, "type")
|
||||
self.assertEqual(e2.validator, "minimum")
|
||||
|
||||
def test_additionalItems(self):
|
||||
instance = ["foo", 1]
|
||||
schema = {
|
||||
"items": [],
|
||||
"additionalItems" : {"type": "integer", "minimum": 5}
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = validator.iter_errors(instance)
|
||||
e1, e2 = sorted_errors(errors)
|
||||
|
||||
self.assertEqual(e1.path, deque([0]))
|
||||
self.assertEqual(e2.path, deque([1]))
|
||||
|
||||
self.assertEqual(e1.validator, "type")
|
||||
self.assertEqual(e2.validator, "minimum")
|
||||
|
||||
def test_additionalItems_with_items(self):
|
||||
instance = ["foo", "bar", 1]
|
||||
schema = {
|
||||
"items": [{}],
|
||||
"additionalItems" : {"type": "integer", "minimum": 5}
|
||||
}
|
||||
|
||||
validator = Draft3Validator(schema)
|
||||
errors = validator.iter_errors(instance)
|
||||
e1, e2 = sorted_errors(errors)
|
||||
|
||||
self.assertEqual(e1.path, deque([1]))
|
||||
self.assertEqual(e2.path, deque([2]))
|
||||
|
||||
self.assertEqual(e1.validator, "type")
|
||||
self.assertEqual(e2.validator, "minimum")
|
||||
|
||||
|
||||
class ValidatorTestMixin(object):
|
||||
def setUp(self):
|
||||
self.instance = mock.Mock()
|
||||
self.schema = {}
|
||||
self.resolver = mock.Mock()
|
||||
self.validator = self.validator_class(self.schema)
|
||||
|
||||
def test_valid_instances_are_valid(self):
|
||||
errors = iter([])
|
||||
|
||||
with mock.patch.object(
|
||||
self.validator, "iter_errors", return_value=errors,
|
||||
):
|
||||
self.assertTrue(
|
||||
self.validator.is_valid(self.instance, self.schema)
|
||||
)
|
||||
|
||||
def test_invalid_instances_are_not_valid(self):
|
||||
errors = iter([mock.Mock()])
|
||||
|
||||
with mock.patch.object(
|
||||
self.validator, "iter_errors", return_value=errors,
|
||||
):
|
||||
self.assertFalse(
|
||||
self.validator.is_valid(self.instance, self.schema)
|
||||
)
|
||||
|
||||
def test_non_existent_properties_are_ignored(self):
|
||||
instance, my_property, my_value = mock.Mock(), mock.Mock(), mock.Mock()
|
||||
validate(instance=instance, schema={my_property : my_value})
|
||||
|
||||
def test_it_creates_a_ref_resolver_if_not_provided(self):
|
||||
self.assertIsInstance(self.validator.resolver, RefResolver)
|
||||
|
||||
def test_it_delegates_to_a_ref_resolver(self):
|
||||
resolver = RefResolver("", {})
|
||||
schema = {"$ref" : mock.Mock()}
|
||||
|
||||
@contextmanager
|
||||
def resolving():
|
||||
yield {"type": "integer"}
|
||||
|
||||
with mock.patch.object(resolver, "resolving") as resolve:
|
||||
resolve.return_value = resolving()
|
||||
with self.assertRaises(ValidationError):
|
||||
self.validator_class(schema, resolver=resolver).validate(None)
|
||||
|
||||
resolve.assert_called_once_with(schema["$ref"])
|
||||
|
||||
def test_is_type_is_true_for_valid_type(self):
|
||||
self.assertTrue(self.validator.is_type("foo", "string"))
|
||||
|
||||
def test_is_type_is_false_for_invalid_type(self):
|
||||
self.assertFalse(self.validator.is_type("foo", "array"))
|
||||
|
||||
def test_is_type_evades_bool_inheriting_from_int(self):
|
||||
self.assertFalse(self.validator.is_type(True, "integer"))
|
||||
self.assertFalse(self.validator.is_type(True, "number"))
|
||||
|
||||
def test_is_type_raises_exception_for_unknown_type(self):
|
||||
with self.assertRaises(UnknownType):
|
||||
self.validator.is_type("foo", object())
|
||||
|
||||
|
||||
class TestDraft3Validator(ValidatorTestMixin, unittest.TestCase):
|
||||
validator_class = Draft3Validator
|
||||
|
||||
def test_is_type_is_true_for_any_type(self):
|
||||
self.assertTrue(self.validator.is_valid(mock.Mock(), {"type": "any"}))
|
||||
|
||||
def test_is_type_does_not_evade_bool_if_it_is_being_tested(self):
|
||||
self.assertTrue(self.validator.is_type(True, "boolean"))
|
||||
self.assertTrue(self.validator.is_valid(True, {"type": "any"}))
|
||||
|
||||
def test_non_string_custom_types(self):
|
||||
schema = {'type': [None]}
|
||||
cls = self.validator_class(schema, types={None: type(None)})
|
||||
cls.validate(None, schema)
|
||||
|
||||
|
||||
class TestDraft4Validator(ValidatorTestMixin, unittest.TestCase):
|
||||
validator_class = Draft4Validator
|
||||
|
||||
|
||||
class TestBuiltinFormats(unittest.TestCase):
|
||||
"""
|
||||
The built-in (specification-defined) formats do not raise type errors.
|
||||
|
||||
If an instance or value is not a string, it should be ignored.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
for format in FormatChecker.checkers:
|
||||
def test(self, format=format):
|
||||
v = Draft4Validator({"format": format}, format_checker=FormatChecker())
|
||||
v.validate(123)
|
||||
|
||||
name = "test_{0}_ignores_non_strings".format(format)
|
||||
test.__name__ = name
|
||||
setattr(TestBuiltinFormats, name, test)
|
||||
del test # Ugh py.test. Stop discovering top level tests.
|
||||
|
||||
|
||||
class TestValidatorFor(unittest.TestCase):
|
||||
def test_draft_3(self):
|
||||
schema = {"$schema" : "http://json-schema.org/draft-03/schema"}
|
||||
self.assertIs(validator_for(schema), Draft3Validator)
|
||||
|
||||
schema = {"$schema" : "http://json-schema.org/draft-03/schema#"}
|
||||
self.assertIs(validator_for(schema), Draft3Validator)
|
||||
|
||||
def test_draft_4(self):
|
||||
schema = {"$schema" : "http://json-schema.org/draft-04/schema"}
|
||||
self.assertIs(validator_for(schema), Draft4Validator)
|
||||
|
||||
schema = {"$schema" : "http://json-schema.org/draft-04/schema#"}
|
||||
self.assertIs(validator_for(schema), Draft4Validator)
|
||||
|
||||
def test_custom_validator(self):
|
||||
Validator = create(meta_schema={"id" : "meta schema id"}, version="12")
|
||||
schema = {"$schema" : "meta schema id"}
|
||||
self.assertIs(validator_for(schema), Validator)
|
||||
|
||||
def test_validator_for_jsonschema_default(self):
|
||||
self.assertIs(validator_for({}), Draft4Validator)
|
||||
|
||||
def test_validator_for_custom_default(self):
|
||||
self.assertIs(validator_for({}, default=None), None)
|
||||
|
||||
|
||||
class TestValidate(unittest.TestCase):
|
||||
def test_draft3_validator_is_chosen(self):
|
||||
schema = {"$schema" : "http://json-schema.org/draft-03/schema#"}
|
||||
with mock.patch.object(Draft3Validator, "check_schema") as chk_schema:
|
||||
validate({}, schema)
|
||||
chk_schema.assert_called_once_with(schema)
|
||||
# Make sure it works without the empty fragment
|
||||
schema = {"$schema" : "http://json-schema.org/draft-03/schema"}
|
||||
with mock.patch.object(Draft3Validator, "check_schema") as chk_schema:
|
||||
validate({}, schema)
|
||||
chk_schema.assert_called_once_with(schema)
|
||||
|
||||
def test_draft4_validator_is_chosen(self):
|
||||
schema = {"$schema" : "http://json-schema.org/draft-04/schema#"}
|
||||
with mock.patch.object(Draft4Validator, "check_schema") as chk_schema:
|
||||
validate({}, schema)
|
||||
chk_schema.assert_called_once_with(schema)
|
||||
|
||||
def test_draft4_validator_is_the_default(self):
|
||||
with mock.patch.object(Draft4Validator, "check_schema") as chk_schema:
|
||||
validate({}, {})
|
||||
chk_schema.assert_called_once_with({})
|
||||
|
||||
|
||||
class TestRefResolver(unittest.TestCase):
|
||||
|
||||
base_uri = ""
|
||||
stored_uri = "foo://stored"
|
||||
stored_schema = {"stored" : "schema"}
|
||||
|
||||
def setUp(self):
|
||||
self.referrer = {}
|
||||
self.store = {self.stored_uri : self.stored_schema}
|
||||
self.resolver = RefResolver(self.base_uri, self.referrer, self.store)
|
||||
|
||||
def test_it_does_not_retrieve_schema_urls_from_the_network(self):
|
||||
ref = Draft3Validator.META_SCHEMA["id"]
|
||||
with mock.patch.object(self.resolver, "resolve_remote") as remote:
|
||||
with self.resolver.resolving(ref) as resolved:
|
||||
self.assertEqual(resolved, Draft3Validator.META_SCHEMA)
|
||||
self.assertFalse(remote.called)
|
||||
|
||||
def test_it_resolves_local_refs(self):
|
||||
ref = "#/properties/foo"
|
||||
self.referrer["properties"] = {"foo" : object()}
|
||||
with self.resolver.resolving(ref) as resolved:
|
||||
self.assertEqual(resolved, self.referrer["properties"]["foo"])
|
||||
|
||||
def test_it_resolves_local_refs_with_id(self):
|
||||
schema = {"id": "foo://bar/schema#", "a": {"foo": "bar"}}
|
||||
resolver = RefResolver.from_schema(schema)
|
||||
with resolver.resolving("#/a") as resolved:
|
||||
self.assertEqual(resolved, schema["a"])
|
||||
with resolver.resolving("foo://bar/schema#/a") as resolved:
|
||||
self.assertEqual(resolved, schema["a"])
|
||||
|
||||
def test_it_retrieves_stored_refs(self):
|
||||
with self.resolver.resolving(self.stored_uri) as resolved:
|
||||
self.assertIs(resolved, self.stored_schema)
|
||||
|
||||
self.resolver.store["cached_ref"] = {"foo" : 12}
|
||||
with self.resolver.resolving("cached_ref#/foo") as resolved:
|
||||
self.assertEqual(resolved, 12)
|
||||
|
||||
def test_it_retrieves_unstored_refs_via_requests(self):
|
||||
ref = "http://bar#baz"
|
||||
schema = {"baz" : 12}
|
||||
|
||||
with mock.patch("jsonschema.validators.requests") as requests:
|
||||
requests.get.return_value.json.return_value = schema
|
||||
with self.resolver.resolving(ref) as resolved:
|
||||
self.assertEqual(resolved, 12)
|
||||
requests.get.assert_called_once_with("http://bar")
|
||||
|
||||
def test_it_retrieves_unstored_refs_via_urlopen(self):
|
||||
ref = "http://bar#baz"
|
||||
schema = {"baz" : 12}
|
||||
|
||||
with mock.patch("jsonschema.validators.requests", None):
|
||||
with mock.patch("jsonschema.validators.urlopen") as urlopen:
|
||||
urlopen.return_value.read.return_value = (
|
||||
json.dumps(schema).encode("utf8"))
|
||||
with self.resolver.resolving(ref) as resolved:
|
||||
self.assertEqual(resolved, 12)
|
||||
urlopen.assert_called_once_with("http://bar")
|
||||
|
||||
def test_it_can_construct_a_base_uri_from_a_schema(self):
|
||||
schema = {"id" : "foo"}
|
||||
resolver = RefResolver.from_schema(schema)
|
||||
self.assertEqual(resolver.base_uri, "foo")
|
||||
with resolver.resolving("") as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
with resolver.resolving("#") as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
with resolver.resolving("foo") as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
with resolver.resolving("foo#") as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
|
||||
def test_it_can_construct_a_base_uri_from_a_schema_without_id(self):
|
||||
schema = {}
|
||||
resolver = RefResolver.from_schema(schema)
|
||||
self.assertEqual(resolver.base_uri, "")
|
||||
with resolver.resolving("") as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
with resolver.resolving("#") as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
|
||||
def test_custom_uri_scheme_handlers(self):
|
||||
schema = {"foo": "bar"}
|
||||
ref = "foo://bar"
|
||||
foo_handler = mock.Mock(return_value=schema)
|
||||
resolver = RefResolver("", {}, handlers={"foo": foo_handler})
|
||||
with resolver.resolving(ref) as resolved:
|
||||
self.assertEqual(resolved, schema)
|
||||
foo_handler.assert_called_once_with(ref)
|
||||
|
||||
def test_cache_remote_on(self):
|
||||
ref = "foo://bar"
|
||||
foo_handler = mock.Mock()
|
||||
resolver = RefResolver(
|
||||
"", {}, cache_remote=True, handlers={"foo" : foo_handler},
|
||||
)
|
||||
with resolver.resolving(ref):
|
||||
pass
|
||||
with resolver.resolving(ref):
|
||||
pass
|
||||
foo_handler.assert_called_once_with(ref)
|
||||
|
||||
def test_cache_remote_off(self):
|
||||
ref = "foo://bar"
|
||||
foo_handler = mock.Mock()
|
||||
resolver = RefResolver(
|
||||
"", {}, cache_remote=False, handlers={"foo" : foo_handler},
|
||||
)
|
||||
with resolver.resolving(ref):
|
||||
pass
|
||||
with resolver.resolving(ref):
|
||||
pass
|
||||
self.assertEqual(foo_handler.call_count, 2)
|
||||
|
||||
def test_if_you_give_it_junk_you_get_a_resolution_error(self):
|
||||
ref = "foo://bar"
|
||||
foo_handler = mock.Mock(side_effect=ValueError("Oh no! What's this?"))
|
||||
resolver = RefResolver("", {}, handlers={"foo" : foo_handler})
|
||||
with self.assertRaises(RefResolutionError) as err:
|
||||
with resolver.resolving(ref):
|
||||
pass
|
||||
self.assertEqual(str(err.exception), "Oh no! What's this?")
|
||||
|
||||
|
||||
def sorted_errors(errors):
|
||||
def key(error):
|
||||
return (
|
||||
[str(e) for e in error.path],
|
||||
[str(e) for e in error.schema_path]
|
||||
)
|
||||
return sorted(errors, key=key)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user