Show More
@@ -1,204 +1,205 b'' | |||||
1 | 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A= |
|
1 | 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0 iD8DBQBEYmO2ywK+sNU5EO8RAnaYAKCO7x15xUn5mnhqWNXqk/ehlhRt2QCfRDfY0LrUq2q4oK/KypuJYPHgq1A= | |
2 | 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk= |
|
2 | 2be3001847cb18a23c403439d9e7d0ace30804e9 0 iD8DBQBExUbjywK+sNU5EO8RAhzxAKCtyHAQUzcTSZTqlfJ0by6vhREwWQCghaQFHfkfN0l9/40EowNhuMOKnJk= | |
3 | 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys= |
|
3 | 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0 iD8DBQBFfL2QywK+sNU5EO8RAjYFAKCoGlaWRTeMsjdmxAjUYx6diZxOBwCfY6IpBYsKvPTwB3oktnPt5Rmrlys= | |
4 | 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4= |
|
4 | 27230c29bfec36d5540fbe1c976810aefecfd1d2 0 iD8DBQBFheweywK+sNU5EO8RAt7VAKCrqJQWT2/uo2RWf0ZI4bLp6v82jACgjrMdsaTbxRsypcmEsdPhlG6/8F4= | |
5 | fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I= |
|
5 | fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0 iD8DBQBGgHicywK+sNU5EO8RAgNxAJ0VG8ixAaeudx4sZbhngI1syu49HQCeNUJQfWBgA8bkJ2pvsFpNxwYaX3I= | |
6 | 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU= |
|
6 | 23889160905a1b09fffe1c07378e9fc1827606eb 0 iD8DBQBHGTzoywK+sNU5EO8RAr/UAJ0Y8s4jQtzgS+G9vM8z6CWBThZ8fwCcCT5XDj2XwxKkz/0s6UELwjsO3LU= | |
7 | bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0= |
|
7 | bae2e9c838e90a393bae3973a7850280413e091a 0 iD8DBQBH6DO5ywK+sNU5EO8RAsfrAJ0e4r9c9GF/MJsM7Xjd3NesLRC3+ACffj6+6HXdZf8cswAoFPO+DY00oD0= | |
8 | d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE= |
|
8 | d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 0 iD8DBQBINdwsywK+sNU5EO8RAjIUAKCPmlFJSpsPAAUKF+iNHAwVnwmzeQCdEXrL27CWclXuUKdbQC8De7LICtE= | |
9 | d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc= |
|
9 | d2375bbee6d47e62ba8e415c86e83a465dc4dce9 0 iD8DBQBIo1wpywK+sNU5EO8RAmRNAJ94x3OFt6blbqu/yBoypm/AJ44fuACfUaldXcV5z9tht97hSp22DVTEPGc= | |
10 | 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu |
|
10 | 2a67430f92f15ea5159c26b09ec4839a0c549a26 0 iEYEABECAAYFAkk1hykACgkQywK+sNU5EO85QACeNJNUanjc2tl4wUoPHNuv+lSj0ZMAoIm93wSTc/feyYnO2YCaQ1iyd9Nu | |
11 | 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE |
|
11 | 3773e510d433969e277b1863c317b674cbee2065 0 iEYEABECAAYFAklNbbAACgkQywK+sNU5EO8o+gCfeb2/lfIJZMvyDA1m+G1CsBAxfFsAoIa6iAMG8SBY7hW1Q85Yf/LXEvaE | |
12 | 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx |
|
12 | 11a4eb81fb4f4742451591489e2797dc47903277 0 iEYEABECAAYFAklcAnsACgkQywK+sNU5EO+uXwCbBVHNNsLy1g7BlAyQJwadYVyHOXoAoKvtAVO71+bv7EbVoukwTzT+P4Sx | |
13 | 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx |
|
13 | 11efa41037e280d08cfb07c09ad485df30fb0ea8 0 iEYEABECAAYFAkmvJRQACgkQywK+sNU5EO9XZwCeLMgDgPSMWMm6vgjL4lDs2pEc5+0AnRxfiFbpbBfuEFTqKz9nbzeyoBlx | |
14 | 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje |
|
14 | 02981000012e3adf40c4849bd7b3d5618f9ce82d 0 iEYEABECAAYFAknEH3wACgkQywK+sNU5EO+uXwCeI+LbLMmhjU1lKSfU3UWJHjjUC7oAoIZLvYDGOL/tNZFUuatc3RnZ2eje | |
15 | 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM |
|
15 | 196d40e7c885fa6e95f89134809b3ec7bdbca34b 0 iEYEABECAAYFAkpL2X4ACgkQywK+sNU5EO9FOwCfXJycjyKJXsvQqKkHrglwOQhEKS4An36GfKzptfN8b1qNc3+ya/5c2WOM | |
16 | 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA |
|
16 | 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 0 iEYEABECAAYFAkpopLIACgkQywK+sNU5EO8QSgCfZ0ztsd071rOa2lhmp9Fyue/WoI0AoLTei80/xrhRlB8L/rZEf2KBl8dA | |
17 | 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m |
|
17 | 31ec469f9b556f11819937cf68ee53f2be927ebf 0 iEYEABECAAYFAksBuxAACgkQywK+sNU5EO+mBwCfagB+A0txzWZ6dRpug3LEoK7Z1QsAoKpbk8vsLjv6/oRDicSk/qBu33+m | |
18 | 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw |
|
18 | 439d7ea6fe3aa4ab9ec274a68846779153789de9 0 iEYEABECAAYFAksVw0kACgkQywK+sNU5EO/oZwCfdfBEkgp38xq6wN2F4nj+SzofrJIAnjmxt04vaJSeOOeHylHvk6lzuQsw | |
19 | 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq |
|
19 | 296a0b14a68621f6990c54fdba0083f6f20935bf 0 iEYEABECAAYFAks+jCoACgkQywK+sNU5EO9J8wCeMUGF9E/gS2UBsqIz56WS4HMPRPUAoI5J95mwEIK8Clrl7qFRidNI6APq | |
20 | 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O |
|
20 | 4aa619c4c2c09907034d9824ebb1dd0e878206eb 0 iEYEABECAAYFAktm9IsACgkQywK+sNU5EO9XGgCgk4HclRQhexEtooPE5GcUCdB6M8EAn2ptOhMVbIoO+JncA+tNACPFXh0O | |
21 | ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh |
|
21 | ff2704a8ded37fbebd8b6eb5ec733731d725da8a 0 iEYEABECAAYFAkuRoSQACgkQywK+sNU5EO//3QCeJDc5r2uFyFCtAlpSA27DEE5rrxAAn2FSwTy9fhrB3QAdDQlwkEZcQzDh | |
22 | 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW |
|
22 | 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 0 iEYEABECAAYFAku1IwIACgkQywK+sNU5EO9MjgCdHLVwkTZlNHxhcznZKBL1rjN+J7cAoLLWi9LTL6f/TgBaPSKOy1ublbaW | |
23 | 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk |
|
23 | 39f725929f0c48c5fb3b90c071fc3066012456ca 0 iEYEABECAAYFAkvclvsACgkQywK+sNU5EO9FSwCeL9i5x8ALW/LE5+lCX6MFEAe4MhwAn1ev5o6SX6GrNdDfKweiemfO2VBk | |
24 | fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO |
|
24 | fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 0 iEYEABECAAYFAkvsKTkACgkQywK+sNU5EO9qEACgiSiRGvTG2vXGJ65tUSOIYihTuFAAnRzRIqEVSw8M8/RGeUXRps0IzaCO | |
25 | 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy |
|
25 | 24fe2629c6fd0c74c90bd066e77387c2b02e8437 0 iEYEABECAAYFAkwFLRsACgkQywK+sNU5EO+pJACgp13tPI+pbwKZV+LeMjcQ4H6tCZYAoJebzhd6a8yYx6qiwpJxA9BXZNXy | |
26 | f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL |
|
26 | f786fc4b8764cd2a5526d259cf2f94d8a66924d9 0 iEYEABECAAYFAkwsyxcACgkQywK+sNU5EO+crACfUpNAF57PmClkSri9nJcBjb2goN4AniPCNaKvnki7TnUsi1u2oxltpKKL | |
27 | bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd |
|
27 | bf1774d95bde614af3956d92b20e2a0c68c5fec7 0 iEYEABECAAYFAkxVwccACgkQywK+sNU5EO+oFQCeJzwZ+we1fIIyBGCddHceOUAN++cAnjvT6A8ZWW0zV21NXIFF1qQmjxJd | |
28 | c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf |
|
28 | c00f03a4982e467fb6b6bd45908767db6df4771d 0 iEYEABECAAYFAkxXDqsACgkQywK+sNU5EO/GJACfT9Rz4hZOxPQEs91JwtmfjevO84gAmwSmtfo5mmWSm8gtTUebCcdTv0Kf | |
29 | ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A= |
|
29 | ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 0 iD8DBQBMdo+qywK+sNU5EO8RAqQpAJ975BL2CCAiWMz9SXthNQ9xG181IwCgp4O+KViHPkufZVFn2aTKMNvcr1A= | |
30 | 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4= |
|
30 | 93d8bff78c96fe7e33237b257558ee97290048a4 0 iD8DBQBMpfvdywK+sNU5EO8RAsxVAJ0UaL1XB51C76JUBhafc9GBefuMxwCdEWkTOzwvE0SarJBe9i008jhbqW4= | |
31 | 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo= |
|
31 | 333421b9e0f96c7bc788e5667c146a58a9440a55 0 iD8DBQBMz0HOywK+sNU5EO8RAlsEAJ0USh6yOG7OrWkADGunVt9QimBQnwCbBqeMnKgSbwEw8jZwE3Iz1mdrYlo= | |
32 | 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw= |
|
32 | 4438875ec01bd0fc32be92b0872eb6daeed4d44f 0 iD8DBQBM4WYUywK+sNU5EO8RAhCVAJ0dJswachwFAHALmk1x0RJehxzqPQCbBNskP9n/X689jB+btNTZTyKU/fw= | |
33 | 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug= |
|
33 | 6aff4f144ad356311318b0011df0bb21f2c97429 0 iD8DBQBM9uxXywK+sNU5EO8RAv+4AKCDj4qKP16GdPaq1tP6BUwpM/M1OACfRyzLPp/qiiN8xJTWoWYSe/XjJug= | |
34 | e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8= |
|
34 | e3bf16703e2601de99e563cdb3a5d50b64e6d320 0 iD8DBQBNH8WqywK+sNU5EO8RAiQTAJ9sBO+TeiGro4si77VVaQaA6jcRUgCfSA28dBbjj0oFoQwvPoZjANiZBH8= | |
35 | a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok= |
|
35 | a6c855c32ea081da3c3b8ff628f1847ff271482f 0 iD8DBQBNSJJ+ywK+sNU5EO8RAoJaAKCweDEF70fu+r1Zn7pYDXdlk5RuSgCeO9gK/eit8Lin/1n3pO7aYguFLok= | |
36 | 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg= |
|
36 | 2b2155623ee2559caf288fd333f30475966c4525 0 iD8DBQBNSJeBywK+sNU5EO8RAm1KAJ4hW9Cm9nHaaGJguchBaPLlAr+O3wCgqgmMok8bdAS06N6PL60PSTM//Gg= | |
37 | 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4= |
|
37 | 2616325766e3504c8ae7c84bd15ee610901fe91d 0 iD8DBQBNbWy9ywK+sNU5EO8RAlWCAJ4mW8HbzjJj9GpK98muX7k+7EvEHwCfaTLbC/DH3QEsZBhEP+M8tzL6RU4= | |
38 | aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0= |
|
38 | aa1f3be38ab127280761889d2dca906ca465b5f4 0 iD8DBQBNeQq7ywK+sNU5EO8RAlEOAJ4tlEDdetE9lKfjGgjbkcR8PrC3egCfXCfF3qNVvU/2YYjpgvRwevjvDy0= | |
39 | b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is= |
|
39 | b032bec2c0a651ca0ddecb65714bfe6770f67d70 0 iD8DBQBNlg5kywK+sNU5EO8RAnGEAJ9gmEx6MfaR4XcG2m/93vwtfyzs3gCgltzx8/YdHPwqDwRX/WbpYgi33is= | |
40 | 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI= |
|
40 | 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 0 iD8DBQBNvTy4ywK+sNU5EO8RAmp8AJ9QnxK4jTJ7G722MyeBxf0UXEdGwACgtlM7BKtNQfbEH/fOW5y+45W88VI= | |
41 | 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU= |
|
41 | 733af5d9f6b22387913e1d11350fb8cb7c1487dd 0 iD8DBQBN5q/8ywK+sNU5EO8RArRGAKCNGT94GKIYtSuwZ57z1sQbcw6uLACfffpbMV4NAPMl8womAwg+7ZPKnIU= | |
42 | de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4= |
|
42 | de9eb6b1da4fc522b1cab16d86ca166204c24f25 0 iD8DBQBODhfhywK+sNU5EO8RAr2+AJ4ugbAj8ae8/K0bYZzx3sascIAg1QCeK3b+zbbVVqd3b7CDpwFnaX8kTd4= | |
43 | 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik= |
|
43 | 4a43e23b8c55b4566b8200bf69fe2158485a2634 0 iD8DBQBONzIMywK+sNU5EO8RAj5SAJ0aPS3+JHnyI6bHB2Fl0LImbDmagwCdGbDLp1S7TFobxXudOH49bX45Iik= | |
44 | d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM= |
|
44 | d629f1e89021103f1753addcef6b310e4435b184 0 iD8DBQBOWAsBywK+sNU5EO8RAht4AJwJl9oNFopuGkj5m8aKuf7bqPkoAQCeNrEm7UhFsZKYT5iUOjnMV7s2LaM= | |
45 | 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg= |
|
45 | 351a9292e430e35766c552066ed3e87c557b803b 0 iD8DBQBOh3zUywK+sNU5EO8RApFMAKCD3Y/u3avDFndznwqfG5UeTHMlvACfUivPIVQZyDZnhZMq0UhC6zhCEQg= | |
46 | 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI= |
|
46 | 384082750f2c51dc917d85a7145748330fa6ef4d 0 iD8DBQBOmd+OywK+sNU5EO8RAgDgAJ9V/X+G7VLwhTpHrZNiOHabzSyzYQCdE2kKfIevJUYB9QLAWCWP6DPwrwI= | |
47 | 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4= |
|
47 | 41453d55b481ddfcc1dacb445179649e24ca861d 0 iD8DBQBOsFhpywK+sNU5EO8RAqM6AKCyfxUae3/zLuiLdQz+JR78690eMACfQ6JTBQib4AbE+rUDdkeFYg9K/+4= | |
48 | 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo= |
|
48 | 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 0 iD8DBQBO1/fWywK+sNU5EO8RAmoPAKCR5lpv1D6JLURHD8KVLSV4GRVEBgCgnd0Sy78ligNfqAMafmACRDvj7vo= | |
49 | 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0= |
|
49 | 6344043924497cd06d781d9014c66802285072e4 0 iD8DBQBPALgmywK+sNU5EO8RAlfhAJ9nYOdWnhfVDHYtDTJAyJtXBAQS9wCgnefoSQt7QABkbGxM+Q85UYEBuD0= | |
50 | db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y= |
|
50 | db33555eafeaf9df1e18950e29439eaa706d399b 0 iD8DBQBPGdzxywK+sNU5EO8RAppkAJ9jOXhUVE/97CPgiMA0pMGiIYnesQCfengAszcBiSiKGugiI8Okc9ghU+Y= | |
51 | 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q= |
|
51 | 2aa5b51f310fb3befd26bed99c02267f5c12c734 0 iD8DBQBPKZ9bywK+sNU5EO8RAt1TAJ45r1eJ0YqSkInzrrayg4TVCh0SnQCgm0GA/Ua74jnnDwVQ60lAwROuz1Q= | |
52 | 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q= |
|
52 | 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 0 iD8DBQBPT/fvywK+sNU5EO8RAnfYAKCn7d0vwqIb100YfWm1F7nFD5B+FACeM02YHpQLSNsztrBCObtqcnfod7Q= | |
53 | b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc= |
|
53 | b9bd95e61b49c221c4cca24e6da7c946fc02f992 0 iD8DBQBPeLsIywK+sNU5EO8RAvpNAKCtKe2gitz8dYn52IRF0hFOPCR7AQCfRJL/RWCFweu2T1vH/mUOCf8SXXc= | |
54 | d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono= |
|
54 | d9e2f09d5488c395ae9ddbb320ceacd24757e055 0 iD8DBQBPju/dywK+sNU5EO8RArBYAJ9xtifdbk+hCOJO8OZa4JfHX8OYZQCeKPMBaBWiT8N/WHoOm1XU0q+iono= | |
55 | 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg= |
|
55 | 00182b3d087909e3c3ae44761efecdde8f319ef3 0 iD8DBQBPoFhIywK+sNU5EO8RAhzhAKCBj1n2jxPTkZNJJ5pSp3soa+XHIgCgsZZpAQxOpXwCp0eCdNGe0+pmxmg= | |
56 | 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0= |
|
56 | 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 0 iD8DBQBPovNWywK+sNU5EO8RAhgiAJ980T91FdPTRMmVONDhpkMsZwVIMACgg3bKvoWSeuCW28llUhAJtUjrMv0= | |
57 | 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w= |
|
57 | 85a358df5bbbe404ca25730c9c459b34263441dc 0 iD8DBQBPyZsWywK+sNU5EO8RAnpLAJ48qrGDJRT+pteS0mSQ11haqHstPwCdG4ccGbk+0JHb7aNy8/NRGAOqn9w= | |
58 | b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA= |
|
58 | b013baa3898e117959984fc64c29d8c784d2f28b 0 iD8DBQBP8QOPywK+sNU5EO8RAqimAKCFRSx0lvG6y8vne2IhNG062Hn0dACeMLI5/zhpWpHBIVeAAquYfx2XFeA= | |
59 | 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM= |
|
59 | 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 0 iD8DBQBQGiL8ywK+sNU5EO8RAq5oAJ4rMMCPx6O+OuzNXVOexogedWz/QgCeIiIxLd76I4pXO48tdXhr0hQcBuM= | |
60 | 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc= |
|
60 | 072209ae4ddb654eb2d5fd35bff358c738414432 0 iD8DBQBQQkq0ywK+sNU5EO8RArDTAJ9nk5CySnNAjAXYvqvx4uWCw9ThZwCgqmFRehH/l+oTwj3f8nw8u8qTCdc= | |
61 | b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k= |
|
61 | b3f0f9a39c4e1d0250048cd803ab03542d6f140a 0 iD8DBQBQamltywK+sNU5EO8RAlsqAJ4qF/m6aFu4mJCOKTiAP5RvZFK02ACfawYShUZO6OXEFfveU0aAxDR0M1k= | |
62 | d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38= |
|
62 | d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 0 iD8DBQBQgPV5ywK+sNU5EO8RArylAJ0abcx5NlDjyv3ZDWpAfRIHyRsJtQCgn4TMuEayqgxzrvadQZHdTEU2g38= | |
63 | 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0= |
|
63 | 195ad823b5d58c68903a6153a25e3fb4ed25239d 0 iD8DBQBQkuT9ywK+sNU5EO8RAhB4AKCeerItoK2Jipm2cVf4euGofAa/WACeJj3TVd4pFILpb+ogj7ebweFLJi0= | |
64 | 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM= |
|
64 | 0c10cf8191469e7c3c8844922e17e71a176cb7cb 0 iD8DBQBQvQWoywK+sNU5EO8RAnq3AJoCn98u4geFx5YaQaeh99gFhCd7bQCgjoBwBSUyOvGd0yBy60E3Vv3VZhM= | |
65 | a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0= |
|
65 | a4765077b65e6ae29ba42bab7834717b5072d5ba 0 iD8DBQBQ486sywK+sNU5EO8RAhmJAJ90aLfLKZhmcZN7kqphigQJxiFOQACeJ5IUZxjGKH4xzi3MrgIcx9n+dB0= | |
66 | f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg= |
|
66 | f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 0 iD8DBQBQ+yuYywK+sNU5EO8RAm9JAJoD/UciWvpGeKBcpGtZJBFJVcL/HACghDXSgQ+xQDjB+6uGrdgAQsRR1Lg= | |
67 | a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA= |
|
67 | a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 0 iD8DBQBRDDROywK+sNU5EO8RAh75AJ9uJCGoCWnP0Lv/+XuYs4hvUl+sAgCcD36QgAnuw8IQXrvv684BAXAnHcA= | |
68 | 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM= |
|
68 | 7511d4df752e61fe7ae4f3682e0a0008573b0402 0 iD8DBQBRFYaoywK+sNU5EO8RAuErAJoDyhXn+lptU3+AevVdwAIeNFyR2gCdHzPHyWd+JDeWCUR+pSOBi8O2ppM= | |
69 | 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg= |
|
69 | 5b7175377babacce80a6c1e12366d8032a6d4340 0 iD8DBQBRMCYgywK+sNU5EO8RAq1/AKCWKlt9ysibyQgYwoxxIOZv5J8rpwCcDSHQaaf1fFZUTnQsOePwcM2Y/Sg= | |
70 | 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I= |
|
70 | 50c922c1b5145dab8baefefb0437d363b6a6c21c 0 iD8DBQBRWnUnywK+sNU5EO8RAuQRAJwM42cJqJPeqJ0jVNdMqKMDqr4dSACeP0cRVGz1gitMuV0x8f3mrZrqc7I= | |
71 | 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU= |
|
71 | 8a7bd2dccd44ed571afe7424cd7f95594f27c092 0 iD8DBQBRXfBvywK+sNU5EO8RAn+LAKCsMmflbuXjYRxlzFwId5ptm8TZcwCdGkyLbZcASBOkzQUm/WW1qfknJHU= | |
72 | 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM= |
|
72 | 292cd385856d98bacb2c3086f8897bc660c2beea 0 iD8DBQBRcM0BywK+sNU5EO8RAjp4AKCJBykQbvXhKuvLSMxKx3a2TBiXcACfbr/kLg5GlZTF/XDPmY+PyHgI/GM= | |
73 | 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI= |
|
73 | 23f785b38af38d2fca6b8f3db56b8007a84cd73a 0 iD8DBQBRgZwNywK+sNU5EO8RAmO4AJ4u2ILGuimRP6MJgE2t65LZ5dAdkACgiENEstIdrlFC80p+sWKD81kKIYI= | |
74 | ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI= |
|
74 | ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 0 iD8DBQBRkswvywK+sNU5EO8RAiYYAJsHTHyHbJeAgmGvBTmDrfcKu4doUgCeLm7eGBjx7yAPUvEtxef8rAkQmXI= | |
75 | cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk= |
|
75 | cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 0 iD8DBQBRqnFLywK+sNU5EO8RAsWNAJ9RR6t+y1DLFc2HeH0eN9VfZAKF9gCeJ8ezvhtKq/LMs0/nvcgKQc/d5jk= | |
76 | 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4= |
|
76 | 009794acc6e37a650f0fae37872e733382ac1c0c 0 iD8DBQBR0guxywK+sNU5EO8RArNkAKCq9pMihVzP8Os5kCmgbWpe5C37wgCgqzuPZTHvAsXF5wTyaSTMVa9Ccq4= | |
77 | f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0= |
|
77 | f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0= | |
78 | f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI= |
|
78 | f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI= | |
79 | 335a558f81dc73afeab4d7be63617392b130117f 0 iQIVAwUAUiZrIyBXgaxoKi1yAQK2iw//cquNqqSkc8Re5/TZT9I6NH+lh6DbOKjJP0Xl1Wqq0K+KSIUgZG4G32ovaEb2l5X0uY+3unRPiZ0ebl0YSw4Fb2ZiPIADXLBTOYRrY2Wwd3tpJeGI6wEgZt3SfcITV/g7NJrCjT3FlYoSOIayrExM80InSdcEM0Q3Rx6HKzY2acyxzgZeAtAW5ohFvHilSvY6p5Gcm4+QptMxvw45GPdreUmjeXZxNXNXZ8P+MjMz/QJbai/N7PjmK8lqnhkBsT48Ng/KhhmOkGntNJ2/ImBWLFGcWngSvJ7sfWwnyhndvGhe0Hq1NcCf7I8TjNDxU5TR+m+uW7xjXdLoDbUjBdX4sKXnh8ZjbYiODKBOrrDq25cf8nA/tnpKyE/qsVy60kOk6loY4XKiYmn1V49Ta0emmDx0hqo3HgxHHsHX0NDnGdWGol7cPRET0RzVobKq1A0jnrhPooWidvLh9bPzLonrWDo+ib+DuySoRkuYUK4pgZJ2mbg6daFOBEZygkSyRB8bo1UQUP7EgQDrWe4khb/5GHEfDkrQz3qu/sXvc0Ir1mOUWBFPHC2DjjCn/oMJuUkG1SwM8l2Bfv7h67ssES6YQ2+RjOix4yid7EXS/Ogl45PzCIPSI5+BbNs10JhE0w5uErBHlF53EDTe/TSLc+GU6DB6PP6dH912Njdr3jpNSUQ= |
|
79 | 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 |
@@ -1,217 +1,218 b'' | |||||
1 | d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f |
|
1 | d40cc5aacc31ed673d9b5b24f98bee78c283062c 0.4f | |
2 | 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e |
|
2 | 1c590d34bf61e2ea12c71738e5a746cd74586157 0.4e | |
3 | 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d |
|
3 | 7eca4cfa8aad5fce9a04f7d8acadcd0452e2f34e 0.4d | |
4 | b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c |
|
4 | b4d0c3786ad3e47beacf8412157326a32b6d25a4 0.4c | |
5 | f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5 |
|
5 | f40273b0ad7b3a6d3012fd37736d0611f41ecf54 0.5 | |
6 | 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b |
|
6 | 0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 0.5b | |
7 | 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6 |
|
7 | 12e0fdbc57a0be78f0e817fd1d170a3615cd35da 0.6 | |
8 | 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b |
|
8 | 4ccf3de52989b14c3d84e1097f59e39a992e00bd 0.6b | |
9 | eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c |
|
9 | eac9c8efcd9bd8244e72fb6821f769f450457a32 0.6c | |
10 | 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7 |
|
10 | 979c049974485125e1f9357f6bbe9c1b548a64c3 0.7 | |
11 | 3a56574f329a368d645853e0f9e09472aee62349 0.8 |
|
11 | 3a56574f329a368d645853e0f9e09472aee62349 0.8 | |
12 | 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1 |
|
12 | 6a03cff2b0f5d30281e6addefe96b993582f2eac 0.8.1 | |
13 | 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9 |
|
13 | 35fb62a3a673d5322f6274a44ba6456e5e4b3b37 0.9 | |
14 | 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1 |
|
14 | 2be3001847cb18a23c403439d9e7d0ace30804e9 0.9.1 | |
15 | 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2 |
|
15 | 36a957364b1b89c150f2d0e60a99befe0ee08bd3 0.9.2 | |
16 | 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3 |
|
16 | 27230c29bfec36d5540fbe1c976810aefecfd1d2 0.9.3 | |
17 | fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4 |
|
17 | fb4b6d5fe100b0886f8bc3d6731ec0e5ed5c4694 0.9.4 | |
18 | 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5 |
|
18 | 23889160905a1b09fffe1c07378e9fc1827606eb 0.9.5 | |
19 | bae2e9c838e90a393bae3973a7850280413e091a 1.0 |
|
19 | bae2e9c838e90a393bae3973a7850280413e091a 1.0 | |
20 | d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1 |
|
20 | d5cbbe2c49cee22a9fbeb9ea41daa0ac4e26b846 1.0.1 | |
21 | d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2 |
|
21 | d2375bbee6d47e62ba8e415c86e83a465dc4dce9 1.0.2 | |
22 | 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1 |
|
22 | 2a67430f92f15ea5159c26b09ec4839a0c549a26 1.1 | |
23 | 3773e510d433969e277b1863c317b674cbee2065 1.1.1 |
|
23 | 3773e510d433969e277b1863c317b674cbee2065 1.1.1 | |
24 | 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2 |
|
24 | 11a4eb81fb4f4742451591489e2797dc47903277 1.1.2 | |
25 | 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2 |
|
25 | 11efa41037e280d08cfb07c09ad485df30fb0ea8 1.2 | |
26 | 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1 |
|
26 | 02981000012e3adf40c4849bd7b3d5618f9ce82d 1.2.1 | |
27 | 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3 |
|
27 | 196d40e7c885fa6e95f89134809b3ec7bdbca34b 1.3 | |
28 | 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1 |
|
28 | 3ef6c14a1e8e83a31226f5881b7fe6095bbfa6f6 1.3.1 | |
29 | 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4 |
|
29 | 31ec469f9b556f11819937cf68ee53f2be927ebf 1.4 | |
30 | 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1 |
|
30 | 439d7ea6fe3aa4ab9ec274a68846779153789de9 1.4.1 | |
31 | 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2 |
|
31 | 296a0b14a68621f6990c54fdba0083f6f20935bf 1.4.2 | |
32 | 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3 |
|
32 | 4aa619c4c2c09907034d9824ebb1dd0e878206eb 1.4.3 | |
33 | ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5 |
|
33 | ff2704a8ded37fbebd8b6eb5ec733731d725da8a 1.5 | |
34 | 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1 |
|
34 | 2b01dab594167bc0dd33331dbaa6dca3dca1b3aa 1.5.1 | |
35 | 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2 |
|
35 | 39f725929f0c48c5fb3b90c071fc3066012456ca 1.5.2 | |
36 | fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3 |
|
36 | fdcf80f26604f233dc4d8f0a5ef9d7470e317e8a 1.5.3 | |
37 | 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4 |
|
37 | 24fe2629c6fd0c74c90bd066e77387c2b02e8437 1.5.4 | |
38 | f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6 |
|
38 | f786fc4b8764cd2a5526d259cf2f94d8a66924d9 1.6 | |
39 | bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1 |
|
39 | bf1774d95bde614af3956d92b20e2a0c68c5fec7 1.6.1 | |
40 | c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2 |
|
40 | c00f03a4982e467fb6b6bd45908767db6df4771d 1.6.2 | |
41 | ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3 |
|
41 | ff5cec76b1c5b6be9c3bb923aae8c3c6d079d6b9 1.6.3 | |
42 | 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4 |
|
42 | 93d8bff78c96fe7e33237b257558ee97290048a4 1.6.4 | |
43 | 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7 |
|
43 | 333421b9e0f96c7bc788e5667c146a58a9440a55 1.7 | |
44 | 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1 |
|
44 | 4438875ec01bd0fc32be92b0872eb6daeed4d44f 1.7.1 | |
45 | 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2 |
|
45 | 6aff4f144ad356311318b0011df0bb21f2c97429 1.7.2 | |
46 | e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3 |
|
46 | e3bf16703e2601de99e563cdb3a5d50b64e6d320 1.7.3 | |
47 | a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4 |
|
47 | a6c855c32ea081da3c3b8ff628f1847ff271482f 1.7.4 | |
48 | 2b2155623ee2559caf288fd333f30475966c4525 1.7.5 |
|
48 | 2b2155623ee2559caf288fd333f30475966c4525 1.7.5 | |
49 | 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8 |
|
49 | 2616325766e3504c8ae7c84bd15ee610901fe91d 1.8 | |
50 | aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1 |
|
50 | aa1f3be38ab127280761889d2dca906ca465b5f4 1.8.1 | |
51 | b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2 |
|
51 | b032bec2c0a651ca0ddecb65714bfe6770f67d70 1.8.2 | |
52 | 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3 |
|
52 | 3cb1e95676ad089596bd81d0937cad37d6e3b7fb 1.8.3 | |
53 | 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4 |
|
53 | 733af5d9f6b22387913e1d11350fb8cb7c1487dd 1.8.4 | |
54 | de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9 |
|
54 | de9eb6b1da4fc522b1cab16d86ca166204c24f25 1.9 | |
55 | 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1 |
|
55 | 4a43e23b8c55b4566b8200bf69fe2158485a2634 1.9.1 | |
56 | d629f1e89021103f1753addcef6b310e4435b184 1.9.2 |
|
56 | d629f1e89021103f1753addcef6b310e4435b184 1.9.2 | |
57 | 351a9292e430e35766c552066ed3e87c557b803b 1.9.3 |
|
57 | 351a9292e430e35766c552066ed3e87c557b803b 1.9.3 | |
58 | 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc |
|
58 | 384082750f2c51dc917d85a7145748330fa6ef4d 2.0-rc | |
59 | 41453d55b481ddfcc1dacb445179649e24ca861d 2.0 |
|
59 | 41453d55b481ddfcc1dacb445179649e24ca861d 2.0 | |
60 | 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1 |
|
60 | 195dbd1cef0c2f9f8bcf4ea303238105f716bda3 2.0.1 | |
61 | 6344043924497cd06d781d9014c66802285072e4 2.0.2 |
|
61 | 6344043924497cd06d781d9014c66802285072e4 2.0.2 | |
62 | db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc |
|
62 | db33555eafeaf9df1e18950e29439eaa706d399b 2.1-rc | |
63 | 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1 |
|
63 | 2aa5b51f310fb3befd26bed99c02267f5c12c734 2.1 | |
64 | 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1 |
|
64 | 53e2cd303ecf8ca7c7eeebd785c34e5ed6b0f4a4 2.1.1 | |
65 | b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2 |
|
65 | b9bd95e61b49c221c4cca24e6da7c946fc02f992 2.1.2 | |
66 | d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc |
|
66 | d9e2f09d5488c395ae9ddbb320ceacd24757e055 2.2-rc | |
67 | 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2 |
|
67 | 00182b3d087909e3c3ae44761efecdde8f319ef3 2.2 | |
68 | 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1 |
|
68 | 5983de86462c5a9f42a3ad0f5e90ce5b1d221d25 2.2.1 | |
69 | 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2 |
|
69 | 85a358df5bbbe404ca25730c9c459b34263441dc 2.2.2 | |
70 | b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3 |
|
70 | b013baa3898e117959984fc64c29d8c784d2f28b 2.2.3 | |
71 | a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc |
|
71 | a06e2681dd1786e2354d84a5fa9c1c88dd4fa3e0 2.3-rc | |
72 | 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3 |
|
72 | 7f5094bb3f423fc799e471aac2aee81a7ce57a0b 2.3 | |
73 | 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1 |
|
73 | 072209ae4ddb654eb2d5fd35bff358c738414432 2.3.1 | |
74 | b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2 |
|
74 | b3f0f9a39c4e1d0250048cd803ab03542d6f140a 2.3.2 | |
75 | d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc |
|
75 | d118a4f4fd16d9b558ec3f3e87bfee772861d2b7 2.4-rc | |
76 | 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4 |
|
76 | 195ad823b5d58c68903a6153a25e3fb4ed25239d 2.4 | |
77 | 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1 |
|
77 | 0c10cf8191469e7c3c8844922e17e71a176cb7cb 2.4.1 | |
78 | a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2 |
|
78 | a4765077b65e6ae29ba42bab7834717b5072d5ba 2.4.2 | |
79 | f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc |
|
79 | f5fbe15ca7449f2c9a3cf817c86d0ae68b307214 2.5-rc | |
80 | a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5 |
|
80 | a6088c05e43a8aee0472ca3a4f6f8d7dd914ebbf 2.5 | |
81 | 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1 |
|
81 | 7511d4df752e61fe7ae4f3682e0a0008573b0402 2.5.1 | |
82 | 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2 |
|
82 | 5b7175377babacce80a6c1e12366d8032a6d4340 2.5.2 | |
83 | 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3 |
|
83 | 50c922c1b5145dab8baefefb0437d363b6a6c21c 2.5.3 | |
84 | 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4 |
|
84 | 8a7bd2dccd44ed571afe7424cd7f95594f27c092 2.5.4 | |
85 | 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc |
|
85 | 292cd385856d98bacb2c3086f8897bc660c2beea 2.6-rc | |
86 | 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6 |
|
86 | 23f785b38af38d2fca6b8f3db56b8007a84cd73a 2.6 | |
87 | ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1 |
|
87 | ddc7a6be20212d18f3e27d9d7e6f079a66d96f21 2.6.1 | |
88 | cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2 |
|
88 | cceaf7af4c9e9e6fa2dbfdcfe9856c5da69c4ffd 2.6.2 | |
89 | 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3 |
|
89 | 009794acc6e37a650f0fae37872e733382ac1c0c 2.6.3 | |
90 | f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc |
|
90 | f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc | |
91 | f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7 |
|
91 | f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7 | |
92 | 335a558f81dc73afeab4d7be63617392b130117f 2.7.1 |
|
92 | 335a558f81dc73afeab4d7be63617392b130117f 2.7.1 | |
93 | e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2 |
|
93 | e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2 | |
94 | 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc |
|
94 | 1596f2d8f2421314b1ddead8f7d0c91009358994 2.8-rc | |
95 | d825e4025e39d1c39db943cdc89818abd0a87c27 2.8 |
|
95 | d825e4025e39d1c39db943cdc89818abd0a87c27 2.8 | |
96 | 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1 |
|
96 | 209e04a06467e2969c0cc6501335be0406d46ef0 2.8.1 | |
97 | ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2 |
|
97 | ca387377df7a3a67dbb90b6336b781cdadc3ef41 2.8.2 | |
98 | 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc |
|
98 | 8862469e16f9236208581b20de5f96bd13cc039d 2.9-rc | |
99 | 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9 |
|
99 | 3cec5134e9c4bceab6a00c60f52a4f80677a78f2 2.9 | |
100 | b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1 |
|
100 | b96cb15ec9e04d8ac5ee08b34fcbbe4200588965 2.9.1 | |
101 | 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2 |
|
101 | 3f83fc5cfe715d292069ee8417c83804f6c6c1e4 2.9.2 | |
102 | 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc |
|
102 | 564f55b251224f16508dd1311452db7780dafe2b 3.0-rc | |
103 | 2195ac506c6ababe86985b932f4948837c0891b5 3.0 |
|
103 | 2195ac506c6ababe86985b932f4948837c0891b5 3.0 | |
104 | 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1 |
|
104 | 269c80ee5b3cb3684fa8edc61501b3506d02eb10 3.0.1 | |
105 | 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2 |
|
105 | 2d8cd3d0e83c7336c0cb45a9f88638363f993848 3.0.2 | |
106 | 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc |
|
106 | 6c36dc6cd61a0e1b563f1d51e55bdf4dacf12162 3.1-rc | |
107 | 3178e49892020336491cdc6945885c4de26ffa8b 3.1 |
|
107 | 3178e49892020336491cdc6945885c4de26ffa8b 3.1 | |
108 | 5dc91146f35369949ea56b40172308158b59063a 3.1.1 |
|
108 | 5dc91146f35369949ea56b40172308158b59063a 3.1.1 | |
109 | f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2 |
|
109 | f768c888aaa68d12dd7f509dcc7f01c9584357d0 3.1.2 | |
110 | 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc |
|
110 | 7f8d16af8cae246fa5a48e723d48d58b015aed94 3.2-rc | |
111 | ced632394371a36953ce4d394f86278ae51a2aae 3.2 |
|
111 | ced632394371a36953ce4d394f86278ae51a2aae 3.2 | |
112 | 643c58303fb0ec020907af28b9e486be299ba043 3.2.1 |
|
112 | 643c58303fb0ec020907af28b9e486be299ba043 3.2.1 | |
113 | 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2 |
|
113 | 902554884335e5ca3661d63be9978eb4aec3f68a 3.2.2 | |
114 | 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3 |
|
114 | 6dad422ecc5adb63d9fa649eeb8e05a5f9bc4900 3.2.3 | |
115 | 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4 |
|
115 | 1265a3a71d75396f5d4cf6935ae7d9ba5407a547 3.2.4 | |
116 | db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc |
|
116 | db8e3f7948b1fdeb9ad12d448fc3525759908b9f 3.3-rc | |
117 | fbdd5195528fae4f41feebc1838215c110b25d6a 3.3 |
|
117 | fbdd5195528fae4f41feebc1838215c110b25d6a 3.3 | |
118 | 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1 |
|
118 | 5b4ed033390bf6e2879c8f5c28c84e1ee3b87231 3.3.1 | |
119 | 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2 |
|
119 | 07a92bbd02e5e3a625e0820389b47786b02b2cea 3.3.2 | |
120 | 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3 |
|
120 | 2e2e9a0750f91a6fe0ad88e4de34f8efefdcab08 3.3.3 | |
121 | e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc |
|
121 | e89f909edffad558b56f4affa8239e4832f88de0 3.4-rc | |
122 | 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4 |
|
122 | 8cc6036bca532e06681c5a8fa37efaa812de67b5 3.4 | |
123 | ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1 |
|
123 | ed18f4acf435a2824c6f49fba40f42b9df5da7ad 3.4.1 | |
124 | 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2 |
|
124 | 540cd0ddac49c1125b2e013aa2ff18ecbd4dd954 3.4.2 | |
125 | 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc |
|
125 | 96a38d44ba093bd1d1ecfd34119e94056030278b 3.5-rc | |
126 | 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5 |
|
126 | 21aa1c313b05b1a85f8ffa1120d51579ddf6bf24 3.5 | |
127 | 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1 |
|
127 | 1a45e49a6bed023deb229102a8903234d18054d3 3.5.1 | |
128 | 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2 |
|
128 | 9a466b9f9792e3ad7ae3fc6c43c3ff2e136b718d 3.5.2 | |
129 | b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc |
|
129 | b66e3ca0b90c3095ea28dfd39aa24247bebf5c20 3.6-rc | |
130 | 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6 |
|
130 | 47dd34f2e7272be9e3b2a5a83cd0d20be44293f4 3.6 | |
131 | 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1 |
|
131 | 1aa5083cbebbe7575c88f3402ab377539b484897 3.6.1 | |
132 | 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2 |
|
132 | 2d437a0f3355834a9485bbbeb30a52a052c98f19 3.6.2 | |
133 | ea389970c08449440587712117f178d33bab3f1e 3.6.3 |
|
133 | ea389970c08449440587712117f178d33bab3f1e 3.6.3 | |
134 | 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc |
|
134 | 158bdc8965720ca4061f8f8d806563cfc7cdb62e 3.7-rc | |
135 | 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7 |
|
135 | 2408645de650d8a29a6ce9e7dce601d8dd0d1474 3.7 | |
136 | b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1 |
|
136 | b698abf971e7377d9b7ec7fc8c52df45255b0329 3.7.1 | |
137 | d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2 |
|
137 | d493d64757eb45ada99fcb3693e479a51b7782da 3.7.2 | |
138 | ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3 |
|
138 | ae279d4a19e9683214cbd1fe8298cf0b50571432 3.7.3 | |
139 | 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc |
|
139 | 740156eedf2c450aee58b1a90b0e826f47c5da64 3.8-rc | |
140 | f85de28eae32e7d3064b1a1321309071bbaaa069 3.8 |
|
140 | f85de28eae32e7d3064b1a1321309071bbaaa069 3.8 | |
141 | a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1 |
|
141 | a56296f55a5e1038ea5016dace2076b693c28a56 3.8.1 | |
142 | aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2 |
|
142 | aaabed77791a75968a12b8c43ad263631a23ee81 3.8.2 | |
143 | a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3 |
|
143 | a9764ab80e11bcf6a37255db7dd079011f767c6c 3.8.3 | |
144 | 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4 |
|
144 | 26a5d605b8683a292bb89aea11f37a81b06ac016 3.8.4 | |
145 | 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc |
|
145 | 519bb4f9d3a47a6e83c2b414d58811ed38f503c2 3.9-rc | |
146 | 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9 |
|
146 | 299546f84e68dbb9bd026f0f3a974ce4bdb93686 3.9 | |
147 | ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1 |
|
147 | ccd436f7db6d5d7b9af89715179b911d031d44f1 3.9.1 | |
148 | 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2 |
|
148 | 149433e68974eb5c63ccb03f794d8b57339a80c4 3.9.2 | |
149 | 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc |
|
149 | 438173c415874f6ac653efc1099dec9c9150e90f 4.0-rc | |
150 | eab27446995210c334c3d06f1a659e3b9b5da769 4.0 |
|
150 | eab27446995210c334c3d06f1a659e3b9b5da769 4.0 | |
151 | b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1 |
|
151 | b3b1ae98f6a0e14c1e1ba806a6c18e193b6dae5c 4.0.1 | |
152 | e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2 |
|
152 | e69874dc1f4e142746ff3df91e678a09c6fc208c 4.0.2 | |
153 | a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc |
|
153 | a1dd2c0c479e0550040542e392e87bc91262517e 4.1-rc | |
154 | e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1 |
|
154 | e1526da1e6d84e03146151c9b6e6950fe9a83d7d 4.1 | |
155 | 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1 |
|
155 | 25703b624d27e3917d978af56d6ad59331e0464a 4.1.1 | |
156 | ed5b25874d998ababb181a939dd37a16ea644435 4.1.2 |
|
156 | ed5b25874d998ababb181a939dd37a16ea644435 4.1.2 | |
157 | 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3 |
|
157 | 77eaf9539499a1b8be259ffe7ada787d07857f80 4.1.3 | |
158 | 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc |
|
158 | 616e788321cc4ae9975b7f0c54c849f36d82182b 4.2-rc | |
159 | bb96d4a497432722623ae60d9bc734a1e360179e 4.2 |
|
159 | bb96d4a497432722623ae60d9bc734a1e360179e 4.2 | |
160 | c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1 |
|
160 | c850f0ed54c1d42f9aa079ad528f8127e5775217 4.2.1 | |
161 | 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2 |
|
161 | 26c49ed51a698ec016d2b4c6b44ca3c3f73cc788 4.2.2 | |
162 | 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc |
|
162 | 857876ebaed4e315f63157bd157d6ce553c7ab73 4.3-rc | |
163 | 5544af8622863796a0027566f6b646e10d522c4c 4.3 |
|
163 | 5544af8622863796a0027566f6b646e10d522c4c 4.3 | |
164 | 943c91326b23954e6e1c6960d0239511f9530258 4.2.3 |
|
164 | 943c91326b23954e6e1c6960d0239511f9530258 4.2.3 | |
165 | 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1 |
|
165 | 3fee7f7d2da04226914c2258cc2884dc27384fd7 4.3.1 | |
166 | 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2 |
|
166 | 920977f72c7b70acfdaf56ab35360584d7845827 4.3.2 | |
167 | 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3 |
|
167 | 2f427b57bf9019c6dc3750baa539dc22c1be50f6 4.3.3 | |
168 | 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc |
|
168 | 1e2454b60e5936f5e77498cab2648db469504487 4.4-rc | |
169 | 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4 |
|
169 | 0ccb43d4cf01d013ae05917ec4f305509f851b2d 4.4 | |
170 | cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1 |
|
170 | cabc840ffdee8a72f3689fb77dd74d04fdc2bc04 4.4.1 | |
171 | a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2 |
|
171 | a92b9f8e11ba330614cdfd6af0e03b15c1ff3797 4.4.2 | |
172 | 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc |
|
172 | 27b6df1b5adbdf647cf5c6675b40575e1b197c60 4.5-rc | |
173 | d334afc585e29577f271c5eda03378736a16ca6b 4.5 |
|
173 | d334afc585e29577f271c5eda03378736a16ca6b 4.5 | |
174 | 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1 |
|
174 | 369aadf7a3264b03c8b09efce715bc41e6ab4a9b 4.5.1 | |
175 | 8bba684efde7f45add05f737952093bb2aa07155 4.5.2 |
|
175 | 8bba684efde7f45add05f737952093bb2aa07155 4.5.2 | |
176 | 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3 |
|
176 | 7de7bd407251af2bc98e5b809c8598ee95830daf 4.5.3 | |
177 | ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0 |
|
177 | ed5448edcbfa747b9154099e18630e49024fd47b 4.6rc0 | |
178 | 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1 |
|
178 | 1ec874717d8a93b19e0d50628443e0ee5efab3a9 4.6rc1 | |
179 | 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6 |
|
179 | 6614cac550aea66d19c601e45efd1b7bd08d7c40 4.6 | |
180 | 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1 |
|
180 | 9c5ced5276d6e7d54f7c3dadf5247b7ee98ec79c 4.6.1 | |
181 | 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2 |
|
181 | 0b63a6743010dfdbf8a8154186e119949bdaa1cc 4.6.2 | |
182 | e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0 |
|
182 | e90130af47ce8dd53a3109aed9d15876b3e7dee8 4.7rc0 | |
183 | 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7 |
|
183 | 33ac6a72308a215e6086fbced347ec10aa963b0a 4.7 | |
184 | ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1 |
|
184 | ede3bf31fe63677fdf5bd8db687977d4e3d792ed 4.7.1 | |
185 | 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2 |
|
185 | 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2 | |
186 | 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0 |
|
186 | 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0 | |
187 | a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8 |
|
187 | a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8 | |
188 | 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1 |
|
188 | 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1 | |
189 | 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2 |
|
189 | 197f092b2cd9691e2a55d198f717b231af9be6f9 4.8.2 | |
190 | 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0 |
|
190 | 593718ff5844cad7a27ee3eb5adad89ac8550949 4.9rc0 | |
191 | 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9 |
|
191 | 83377b4b4ae0e9a6b8e579f7b0a693b8cf5c3b10 4.9 | |
192 | 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1 |
|
192 | 4ea21df312ec7159c5b3633096b6ecf68750b0dd 4.9.1 | |
193 | 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0 |
|
193 | 4a8d9ed864754837a185a642170cde24392f9abf 5.0rc0 | |
194 | 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0 |
|
194 | 07e479ef7c9639be0029f00e6a722b96dcc05fee 5.0 | |
195 | c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1 |
|
195 | c3484ddbdb9621256d597ed86b90d229c59c2af9 5.0.1 | |
196 | 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2 |
|
196 | 97ada9b8d51bef24c5cb4cdca4243f0db694ab6e 5.0.2 | |
197 | e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0 |
|
197 | e386b5f4f8360dbb43a576dd9b1368e386fefa5b 5.1rc0 | |
198 | e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1 |
|
198 | e91930d712e8507d1bc1b2dffd96c83edc4cbed3 5.1 | |
199 | a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1 |
|
199 | a4e32fd539ab41489a51b2aa88bda9a73b839562 5.1.1 | |
200 | 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2 |
|
200 | 181e52f2b62f4768aa0d988936c929dc7c4a41a0 5.1.2 | |
201 | 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0 |
|
201 | 59338f9561099de77c684c00f76507f11e46ebe8 5.2rc0 | |
202 | ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2 |
|
202 | ca3dca416f8d5863ca6f5a4a6a6bb835dcd5feeb 5.2 | |
203 | a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1 |
|
203 | a50fecefa691c9b72a99e49aa6fe9dd13943c2bf 5.2.1 | |
204 | b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2 |
|
204 | b4c82b70418022e67cc0e69b1aa3c3aa43aa1d29 5.2.2 | |
205 | 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0 |
|
205 | 84a0102c05c7852c8215ef6cf21d809927586b69 5.3rc0 | |
206 | e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1 |
|
206 | e4344e463c0c888a2f437b78b5982ecdf3f6650a 5.3rc1 | |
207 | 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3 |
|
207 | 7f5410dfc8a64bb587d19637deb95d378fd1eb5c 5.3 | |
208 | 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1 |
|
208 | 6d121acbb82e65fe4dd3c2318a1b61981b958492 5.3.1 | |
209 | 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2 |
|
209 | 8fca7e8449a847e3cf1054f2c07b51237699fad3 5.3.2 | |
210 | 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0 |
|
210 | 26ce8e7515036d3431a03aaeb7bc72dd96cb1112 5.4rc0 | |
211 | cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4 |
|
211 | cf3e07d7648a4371ce584d15dd692e7a6845792f 5.4 | |
212 | 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1 |
|
212 | 065704cbdbdbb05dcd6bb814eb9bbdd982211b28 5.4.1 | |
213 | 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2 |
|
213 | 0ea9c86fac8974cd74dc12ea681c8986eb6da6c4 5.4.2 | |
214 | 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0 |
|
214 | 28163c5de797e5416f9b588940f4608269b4d50a 5.5rc0 | |
215 | 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5 |
|
215 | 7fc3c5fbc65f6fe85d70ea63923b8767dda4f2e0 5.5 | |
216 | f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1 |
|
216 | f62bb5d07848ca598aa860a517394130b61bf2ee 5.5.1 | |
217 | 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2 |
|
217 | 07731064ac41dacdf0ec869ebd05c2e848c14fbf 5.5.2 | |
|
218 | 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0 |
@@ -1,597 +1,597 b'' | |||||
1 | # linux.py - Linux specific automation functionality |
|
1 | # linux.py - Linux specific automation functionality | |
2 | # |
|
2 | # | |
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> |
|
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | # no-check-code because Python 3 native. |
|
8 | # no-check-code because Python 3 native. | |
9 |
|
9 | |||
10 | import os |
|
10 | import os | |
11 | import pathlib |
|
11 | import pathlib | |
12 | import shlex |
|
12 | import shlex | |
13 | import subprocess |
|
13 | import subprocess | |
14 | import tempfile |
|
14 | import tempfile | |
15 |
|
15 | |||
16 | from .ssh import exec_command |
|
16 | from .ssh import exec_command | |
17 |
|
17 | |||
18 |
|
18 | |||
19 | # Linux distributions that are supported. |
|
19 | # Linux distributions that are supported. | |
20 | DISTROS = { |
|
20 | DISTROS = { | |
21 | 'debian9', |
|
21 | 'debian9', | |
22 | 'debian10', |
|
22 | 'debian10', | |
23 | 'ubuntu18.04', |
|
23 | 'ubuntu18.04', | |
24 | 'ubuntu19.04', |
|
24 | 'ubuntu19.04', | |
25 | } |
|
25 | } | |
26 |
|
26 | |||
27 | INSTALL_PYTHONS = r''' |
|
27 | INSTALL_PYTHONS = r''' | |
28 | PYENV2_VERSIONS="2.7.17 pypy2.7-7.2.0" |
|
28 | PYENV2_VERSIONS="2.7.17 pypy2.7-7.2.0" | |
29 | PYENV3_VERSIONS="3.5.10 3.6.12 3.7.9 3.8.6 3.9.0 pypy3.5-7.0.0 pypy3.6-7.3.0" |
|
29 | PYENV3_VERSIONS="3.5.10 3.6.12 3.7.9 3.8.6 3.9.0 pypy3.5-7.0.0 pypy3.6-7.3.0" | |
30 |
|
30 | |||
31 | git clone https://github.com/pyenv/pyenv.git /hgdev/pyenv |
|
31 | git clone https://github.com/pyenv/pyenv.git /hgdev/pyenv | |
32 | pushd /hgdev/pyenv |
|
32 | pushd /hgdev/pyenv | |
33 | git checkout 8ac91b4fd678a8c04356f5ec85cfcd565c265e9a |
|
33 | git checkout 8ac91b4fd678a8c04356f5ec85cfcd565c265e9a | |
34 | popd |
|
34 | popd | |
35 |
|
35 | |||
36 | export PYENV_ROOT="/hgdev/pyenv" |
|
36 | export PYENV_ROOT="/hgdev/pyenv" | |
37 | export PATH="$PYENV_ROOT/bin:$PATH" |
|
37 | export PATH="$PYENV_ROOT/bin:$PATH" | |
38 |
|
38 | |||
39 | # pip 19.2.3. |
|
39 | # pip 19.2.3. | |
40 | PIP_SHA256=57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe |
|
40 | PIP_SHA256=57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe | |
41 | wget -O get-pip.py --progress dot:mega https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py |
|
41 | wget -O get-pip.py --progress dot:mega https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py | |
42 | echo "${PIP_SHA256} get-pip.py" | sha256sum --check - |
|
42 | echo "${PIP_SHA256} get-pip.py" | sha256sum --check - | |
43 |
|
43 | |||
44 | VIRTUALENV_SHA256=f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2 |
|
44 | VIRTUALENV_SHA256=f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2 | |
45 | VIRTUALENV_TARBALL=virtualenv-16.7.5.tar.gz |
|
45 | VIRTUALENV_TARBALL=virtualenv-16.7.5.tar.gz | |
46 | wget -O ${VIRTUALENV_TARBALL} --progress dot:mega https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/${VIRTUALENV_TARBALL} |
|
46 | wget -O ${VIRTUALENV_TARBALL} --progress dot:mega https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/${VIRTUALENV_TARBALL} | |
47 | echo "${VIRTUALENV_SHA256} ${VIRTUALENV_TARBALL}" | sha256sum --check - |
|
47 | echo "${VIRTUALENV_SHA256} ${VIRTUALENV_TARBALL}" | sha256sum --check - | |
48 |
|
48 | |||
49 | for v in ${PYENV2_VERSIONS}; do |
|
49 | for v in ${PYENV2_VERSIONS}; do | |
50 | pyenv install -v ${v} |
|
50 | pyenv install -v ${v} | |
51 | ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py |
|
51 | ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py | |
52 | ${PYENV_ROOT}/versions/${v}/bin/pip install ${VIRTUALENV_TARBALL} |
|
52 | ${PYENV_ROOT}/versions/${v}/bin/pip install ${VIRTUALENV_TARBALL} | |
53 | ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py2.txt |
|
53 | ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py2.txt | |
54 | done |
|
54 | done | |
55 |
|
55 | |||
56 | for v in ${PYENV3_VERSIONS}; do |
|
56 | for v in ${PYENV3_VERSIONS}; do | |
57 | pyenv install -v ${v} |
|
57 | pyenv install -v ${v} | |
58 | ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py |
|
58 | ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py | |
59 | ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py3.txt |
|
59 | ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py3.txt | |
60 | done |
|
60 | done | |
61 |
|
61 | |||
62 | pyenv global ${PYENV2_VERSIONS} ${PYENV3_VERSIONS} system |
|
62 | pyenv global ${PYENV2_VERSIONS} ${PYENV3_VERSIONS} system | |
63 | '''.lstrip().replace( |
|
63 | '''.lstrip().replace( | |
64 | '\r\n', '\n' |
|
64 | '\r\n', '\n' | |
65 | ) |
|
65 | ) | |
66 |
|
66 | |||
67 |
|
67 | |||
68 | INSTALL_RUST = r''' |
|
68 | INSTALL_RUST = r''' | |
69 | RUSTUP_INIT_SHA256=a46fe67199b7bcbbde2dcbc23ae08db6f29883e260e23899a88b9073effc9076 |
|
69 | RUSTUP_INIT_SHA256=a46fe67199b7bcbbde2dcbc23ae08db6f29883e260e23899a88b9073effc9076 | |
70 | wget -O rustup-init --progress dot:mega https://static.rust-lang.org/rustup/archive/1.18.3/x86_64-unknown-linux-gnu/rustup-init |
|
70 | wget -O rustup-init --progress dot:mega https://static.rust-lang.org/rustup/archive/1.18.3/x86_64-unknown-linux-gnu/rustup-init | |
71 | echo "${RUSTUP_INIT_SHA256} rustup-init" | sha256sum --check - |
|
71 | echo "${RUSTUP_INIT_SHA256} rustup-init" | sha256sum --check - | |
72 |
|
72 | |||
73 | chmod +x rustup-init |
|
73 | chmod +x rustup-init | |
74 | sudo -H -u hg -g hg ./rustup-init -y |
|
74 | sudo -H -u hg -g hg ./rustup-init -y | |
75 | sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup install 1.31.1 1.46.0 |
|
75 | sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup install 1.31.1 1.46.0 | |
76 | sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup component add clippy |
|
76 | sudo -H -u hg -g hg /home/hg/.cargo/bin/rustup component add clippy | |
77 |
|
77 | |||
78 |
sudo -H -u hg -g hg /home/hg/.cargo/bin/cargo install -- |
|
78 | sudo -H -u hg -g hg /home/hg/.cargo/bin/cargo install --version 0.9.0 pyoxidizer | |
79 | ''' |
|
79 | ''' | |
80 |
|
80 | |||
81 |
|
81 | |||
82 | BOOTSTRAP_VIRTUALENV = r''' |
|
82 | BOOTSTRAP_VIRTUALENV = r''' | |
83 | /usr/bin/virtualenv /hgdev/venv-bootstrap |
|
83 | /usr/bin/virtualenv /hgdev/venv-bootstrap | |
84 |
|
84 | |||
85 | HG_SHA256=35fc8ba5e0379c1b3affa2757e83fb0509e8ac314cbd9f1fd133cf265d16e49f |
|
85 | HG_SHA256=35fc8ba5e0379c1b3affa2757e83fb0509e8ac314cbd9f1fd133cf265d16e49f | |
86 | HG_TARBALL=mercurial-5.1.1.tar.gz |
|
86 | HG_TARBALL=mercurial-5.1.1.tar.gz | |
87 |
|
87 | |||
88 | wget -O ${HG_TARBALL} --progress dot:mega https://www.mercurial-scm.org/release/${HG_TARBALL} |
|
88 | wget -O ${HG_TARBALL} --progress dot:mega https://www.mercurial-scm.org/release/${HG_TARBALL} | |
89 | echo "${HG_SHA256} ${HG_TARBALL}" | sha256sum --check - |
|
89 | echo "${HG_SHA256} ${HG_TARBALL}" | sha256sum --check - | |
90 |
|
90 | |||
91 | /hgdev/venv-bootstrap/bin/pip install ${HG_TARBALL} |
|
91 | /hgdev/venv-bootstrap/bin/pip install ${HG_TARBALL} | |
92 | '''.lstrip().replace( |
|
92 | '''.lstrip().replace( | |
93 | '\r\n', '\n' |
|
93 | '\r\n', '\n' | |
94 | ) |
|
94 | ) | |
95 |
|
95 | |||
96 |
|
96 | |||
97 | BOOTSTRAP_DEBIAN = ( |
|
97 | BOOTSTRAP_DEBIAN = ( | |
98 | r''' |
|
98 | r''' | |
99 | #!/bin/bash |
|
99 | #!/bin/bash | |
100 |
|
100 | |||
101 | set -ex |
|
101 | set -ex | |
102 |
|
102 | |||
103 | DISTRO=`grep DISTRIB_ID /etc/lsb-release | awk -F= '{{print $2}}'` |
|
103 | DISTRO=`grep DISTRIB_ID /etc/lsb-release | awk -F= '{{print $2}}'` | |
104 | DEBIAN_VERSION=`cat /etc/debian_version` |
|
104 | DEBIAN_VERSION=`cat /etc/debian_version` | |
105 | LSB_RELEASE=`lsb_release -cs` |
|
105 | LSB_RELEASE=`lsb_release -cs` | |
106 |
|
106 | |||
107 | sudo /usr/sbin/groupadd hg |
|
107 | sudo /usr/sbin/groupadd hg | |
108 | sudo /usr/sbin/groupadd docker |
|
108 | sudo /usr/sbin/groupadd docker | |
109 | sudo /usr/sbin/useradd -g hg -G sudo,docker -d /home/hg -m -s /bin/bash hg |
|
109 | sudo /usr/sbin/useradd -g hg -G sudo,docker -d /home/hg -m -s /bin/bash hg | |
110 | sudo mkdir /home/hg/.ssh |
|
110 | sudo mkdir /home/hg/.ssh | |
111 | sudo cp ~/.ssh/authorized_keys /home/hg/.ssh/authorized_keys |
|
111 | sudo cp ~/.ssh/authorized_keys /home/hg/.ssh/authorized_keys | |
112 | sudo chown -R hg:hg /home/hg/.ssh |
|
112 | sudo chown -R hg:hg /home/hg/.ssh | |
113 | sudo chmod 700 /home/hg/.ssh |
|
113 | sudo chmod 700 /home/hg/.ssh | |
114 | sudo chmod 600 /home/hg/.ssh/authorized_keys |
|
114 | sudo chmod 600 /home/hg/.ssh/authorized_keys | |
115 |
|
115 | |||
116 | cat << EOF | sudo tee /etc/sudoers.d/90-hg |
|
116 | cat << EOF | sudo tee /etc/sudoers.d/90-hg | |
117 | hg ALL=(ALL) NOPASSWD:ALL |
|
117 | hg ALL=(ALL) NOPASSWD:ALL | |
118 | EOF |
|
118 | EOF | |
119 |
|
119 | |||
120 | sudo apt-get update |
|
120 | sudo apt-get update | |
121 | sudo DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade |
|
121 | sudo DEBIAN_FRONTEND=noninteractive apt-get -yq dist-upgrade | |
122 |
|
122 | |||
123 | # Install packages necessary to set up Docker Apt repo. |
|
123 | # Install packages necessary to set up Docker Apt repo. | |
124 | sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends \ |
|
124 | sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends \ | |
125 | apt-transport-https \ |
|
125 | apt-transport-https \ | |
126 | gnupg |
|
126 | gnupg | |
127 |
|
127 | |||
128 | cat > docker-apt-key << EOF |
|
128 | cat > docker-apt-key << EOF | |
129 | -----BEGIN PGP PUBLIC KEY BLOCK----- |
|
129 | -----BEGIN PGP PUBLIC KEY BLOCK----- | |
130 |
|
130 | |||
131 | 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 | |
188 | YT90qFF93M3v01BbxP+EIY2/9tiIPbrd |
|
188 | YT90qFF93M3v01BbxP+EIY2/9tiIPbrd | |
189 | =0YYh |
|
189 | =0YYh | |
190 | -----END PGP PUBLIC KEY BLOCK----- |
|
190 | -----END PGP PUBLIC KEY BLOCK----- | |
191 | EOF |
|
191 | EOF | |
192 |
|
192 | |||
193 | sudo apt-key add docker-apt-key |
|
193 | sudo apt-key add docker-apt-key | |
194 |
|
194 | |||
195 | if [ "$LSB_RELEASE" = "stretch" ]; then |
|
195 | if [ "$LSB_RELEASE" = "stretch" ]; then | |
196 | cat << EOF | sudo tee -a /etc/apt/sources.list |
|
196 | cat << EOF | sudo tee -a /etc/apt/sources.list | |
197 | # Need backports for clang-format-6.0 |
|
197 | # Need backports for clang-format-6.0 | |
198 | deb http://deb.debian.org/debian stretch-backports main |
|
198 | deb http://deb.debian.org/debian stretch-backports main | |
199 | EOF |
|
199 | EOF | |
200 | fi |
|
200 | fi | |
201 |
|
201 | |||
202 | if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "buster" ]; then |
|
202 | if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "buster" ]; then | |
203 | cat << EOF | sudo tee -a /etc/apt/sources.list |
|
203 | cat << EOF | sudo tee -a /etc/apt/sources.list | |
204 | # Sources are useful if we want to compile things locally. |
|
204 | # Sources are useful if we want to compile things locally. | |
205 | deb-src http://deb.debian.org/debian $LSB_RELEASE main |
|
205 | deb-src http://deb.debian.org/debian $LSB_RELEASE main | |
206 | deb-src http://security.debian.org/debian-security $LSB_RELEASE/updates main |
|
206 | deb-src http://security.debian.org/debian-security $LSB_RELEASE/updates main | |
207 | deb-src http://deb.debian.org/debian $LSB_RELEASE-updates main |
|
207 | deb-src http://deb.debian.org/debian $LSB_RELEASE-updates main | |
208 | deb-src http://deb.debian.org/debian $LSB_RELEASE-backports main |
|
208 | deb-src http://deb.debian.org/debian $LSB_RELEASE-backports main | |
209 |
|
209 | |||
210 | deb [arch=amd64] https://download.docker.com/linux/debian $LSB_RELEASE stable |
|
210 | deb [arch=amd64] https://download.docker.com/linux/debian $LSB_RELEASE stable | |
211 | EOF |
|
211 | EOF | |
212 |
|
212 | |||
213 | elif [ "$DISTRO" = "Ubuntu" ]; then |
|
213 | elif [ "$DISTRO" = "Ubuntu" ]; then | |
214 | cat << EOF | sudo tee -a /etc/apt/sources.list |
|
214 | cat << EOF | sudo tee -a /etc/apt/sources.list | |
215 | deb [arch=amd64] https://download.docker.com/linux/ubuntu $LSB_RELEASE stable |
|
215 | deb [arch=amd64] https://download.docker.com/linux/ubuntu $LSB_RELEASE stable | |
216 | EOF |
|
216 | EOF | |
217 |
|
217 | |||
218 | fi |
|
218 | fi | |
219 |
|
219 | |||
220 | sudo apt-get update |
|
220 | sudo apt-get update | |
221 |
|
221 | |||
222 | PACKAGES="\ |
|
222 | PACKAGES="\ | |
223 | awscli \ |
|
223 | awscli \ | |
224 | btrfs-progs \ |
|
224 | btrfs-progs \ | |
225 | build-essential \ |
|
225 | build-essential \ | |
226 | bzr \ |
|
226 | bzr \ | |
227 | clang-format-6.0 \ |
|
227 | clang-format-6.0 \ | |
228 | cvs \ |
|
228 | cvs \ | |
229 | darcs \ |
|
229 | darcs \ | |
230 | debhelper \ |
|
230 | debhelper \ | |
231 | devscripts \ |
|
231 | devscripts \ | |
232 | docker-ce \ |
|
232 | docker-ce \ | |
233 | dpkg-dev \ |
|
233 | dpkg-dev \ | |
234 | dstat \ |
|
234 | dstat \ | |
235 | emacs \ |
|
235 | emacs \ | |
236 | gettext \ |
|
236 | gettext \ | |
237 | git \ |
|
237 | git \ | |
238 | htop \ |
|
238 | htop \ | |
239 | iotop \ |
|
239 | iotop \ | |
240 | jfsutils \ |
|
240 | jfsutils \ | |
241 | libbz2-dev \ |
|
241 | libbz2-dev \ | |
242 | libexpat1-dev \ |
|
242 | libexpat1-dev \ | |
243 | libffi-dev \ |
|
243 | libffi-dev \ | |
244 | libgdbm-dev \ |
|
244 | libgdbm-dev \ | |
245 | liblzma-dev \ |
|
245 | liblzma-dev \ | |
246 | libncurses5-dev \ |
|
246 | libncurses5-dev \ | |
247 | libnss3-dev \ |
|
247 | libnss3-dev \ | |
248 | libreadline-dev \ |
|
248 | libreadline-dev \ | |
249 | libsqlite3-dev \ |
|
249 | libsqlite3-dev \ | |
250 | libssl-dev \ |
|
250 | libssl-dev \ | |
251 | netbase \ |
|
251 | netbase \ | |
252 | ntfs-3g \ |
|
252 | ntfs-3g \ | |
253 | nvme-cli \ |
|
253 | nvme-cli \ | |
254 | pyflakes \ |
|
254 | pyflakes \ | |
255 | pyflakes3 \ |
|
255 | pyflakes3 \ | |
256 | pylint \ |
|
256 | pylint \ | |
257 | pylint3 \ |
|
257 | pylint3 \ | |
258 | python-all-dev \ |
|
258 | python-all-dev \ | |
259 | python-dev \ |
|
259 | python-dev \ | |
260 | python-docutils \ |
|
260 | python-docutils \ | |
261 | python-fuzzywuzzy \ |
|
261 | python-fuzzywuzzy \ | |
262 | python-pygments \ |
|
262 | python-pygments \ | |
263 | python-subversion \ |
|
263 | python-subversion \ | |
264 | python-vcr \ |
|
264 | python-vcr \ | |
265 | python3-boto3 \ |
|
265 | python3-boto3 \ | |
266 | python3-dev \ |
|
266 | python3-dev \ | |
267 | python3-docutils \ |
|
267 | python3-docutils \ | |
268 | python3-fuzzywuzzy \ |
|
268 | python3-fuzzywuzzy \ | |
269 | python3-pygments \ |
|
269 | python3-pygments \ | |
270 | python3-vcr \ |
|
270 | python3-vcr \ | |
271 | python3-venv \ |
|
271 | python3-venv \ | |
272 | rsync \ |
|
272 | rsync \ | |
273 | sqlite3 \ |
|
273 | sqlite3 \ | |
274 | subversion \ |
|
274 | subversion \ | |
275 | tcl-dev \ |
|
275 | tcl-dev \ | |
276 | tk-dev \ |
|
276 | tk-dev \ | |
277 | tla \ |
|
277 | tla \ | |
278 | unzip \ |
|
278 | unzip \ | |
279 | uuid-dev \ |
|
279 | uuid-dev \ | |
280 | vim \ |
|
280 | vim \ | |
281 | virtualenv \ |
|
281 | virtualenv \ | |
282 | wget \ |
|
282 | wget \ | |
283 | xfsprogs \ |
|
283 | xfsprogs \ | |
284 | zip \ |
|
284 | zip \ | |
285 | zlib1g-dev" |
|
285 | zlib1g-dev" | |
286 |
|
286 | |||
287 | if [ "LSB_RELEASE" = "stretch" ]; then |
|
287 | if [ "LSB_RELEASE" = "stretch" ]; then | |
288 | PACKAGES="$PACKAGES linux-perf" |
|
288 | PACKAGES="$PACKAGES linux-perf" | |
289 | elif [ "$DISTRO" = "Ubuntu" ]; then |
|
289 | elif [ "$DISTRO" = "Ubuntu" ]; then | |
290 | PACKAGES="$PACKAGES linux-tools-common" |
|
290 | PACKAGES="$PACKAGES linux-tools-common" | |
291 | fi |
|
291 | fi | |
292 |
|
292 | |||
293 | # Monotone only available in older releases. |
|
293 | # Monotone only available in older releases. | |
294 | if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "xenial" ]; then |
|
294 | if [ "$LSB_RELEASE" = "stretch" -o "$LSB_RELEASE" = "xenial" ]; then | |
295 | PACKAGES="$PACKAGES monotone" |
|
295 | PACKAGES="$PACKAGES monotone" | |
296 | fi |
|
296 | fi | |
297 |
|
297 | |||
298 | sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends $PACKAGES |
|
298 | sudo DEBIAN_FRONTEND=noninteractive apt-get -yq install --no-install-recommends $PACKAGES | |
299 |
|
299 | |||
300 | # Create clang-format symlink so test harness finds it. |
|
300 | # Create clang-format symlink so test harness finds it. | |
301 | sudo update-alternatives --install /usr/bin/clang-format clang-format \ |
|
301 | sudo update-alternatives --install /usr/bin/clang-format clang-format \ | |
302 | /usr/bin/clang-format-6.0 1000 |
|
302 | /usr/bin/clang-format-6.0 1000 | |
303 |
|
303 | |||
304 | sudo mkdir /hgdev |
|
304 | sudo mkdir /hgdev | |
305 | # Will be normalized to hg:hg later. |
|
305 | # Will be normalized to hg:hg later. | |
306 | sudo chown `whoami` /hgdev |
|
306 | sudo chown `whoami` /hgdev | |
307 |
|
307 | |||
308 | {install_rust} |
|
308 | {install_rust} | |
309 |
|
309 | |||
310 | cp requirements-py2.txt /hgdev/requirements-py2.txt |
|
310 | cp requirements-py2.txt /hgdev/requirements-py2.txt | |
311 | cp requirements-py3.txt /hgdev/requirements-py3.txt |
|
311 | cp requirements-py3.txt /hgdev/requirements-py3.txt | |
312 |
|
312 | |||
313 | # Disable the pip version check because it uses the network and can |
|
313 | # Disable the pip version check because it uses the network and can | |
314 | # be annoying. |
|
314 | # be annoying. | |
315 | cat << EOF | sudo tee -a /etc/pip.conf |
|
315 | cat << EOF | sudo tee -a /etc/pip.conf | |
316 | [global] |
|
316 | [global] | |
317 | disable-pip-version-check = True |
|
317 | disable-pip-version-check = True | |
318 | EOF |
|
318 | EOF | |
319 |
|
319 | |||
320 | {install_pythons} |
|
320 | {install_pythons} | |
321 | {bootstrap_virtualenv} |
|
321 | {bootstrap_virtualenv} | |
322 |
|
322 | |||
323 | /hgdev/venv-bootstrap/bin/hg clone https://www.mercurial-scm.org/repo/hg /hgdev/src |
|
323 | /hgdev/venv-bootstrap/bin/hg clone https://www.mercurial-scm.org/repo/hg /hgdev/src | |
324 |
|
324 | |||
325 | # Mark the repo as non-publishing. |
|
325 | # Mark the repo as non-publishing. | |
326 | cat >> /hgdev/src/.hg/hgrc << EOF |
|
326 | cat >> /hgdev/src/.hg/hgrc << EOF | |
327 | [phases] |
|
327 | [phases] | |
328 | publish = false |
|
328 | publish = false | |
329 | EOF |
|
329 | EOF | |
330 |
|
330 | |||
331 | sudo chown -R hg:hg /hgdev |
|
331 | sudo chown -R hg:hg /hgdev | |
332 | '''.lstrip() |
|
332 | '''.lstrip() | |
333 | .format( |
|
333 | .format( | |
334 | install_rust=INSTALL_RUST, |
|
334 | install_rust=INSTALL_RUST, | |
335 | install_pythons=INSTALL_PYTHONS, |
|
335 | install_pythons=INSTALL_PYTHONS, | |
336 | bootstrap_virtualenv=BOOTSTRAP_VIRTUALENV, |
|
336 | bootstrap_virtualenv=BOOTSTRAP_VIRTUALENV, | |
337 | ) |
|
337 | ) | |
338 | .replace('\r\n', '\n') |
|
338 | .replace('\r\n', '\n') | |
339 | ) |
|
339 | ) | |
340 |
|
340 | |||
341 |
|
341 | |||
342 | # Prepares /hgdev for operations. |
|
342 | # Prepares /hgdev for operations. | |
343 | PREPARE_HGDEV = ''' |
|
343 | PREPARE_HGDEV = ''' | |
344 | #!/bin/bash |
|
344 | #!/bin/bash | |
345 |
|
345 | |||
346 | set -e |
|
346 | set -e | |
347 |
|
347 | |||
348 | FS=$1 |
|
348 | FS=$1 | |
349 |
|
349 | |||
350 | ensure_device() { |
|
350 | ensure_device() { | |
351 | if [ -z "${DEVICE}" ]; then |
|
351 | if [ -z "${DEVICE}" ]; then | |
352 | echo "could not find block device to format" |
|
352 | echo "could not find block device to format" | |
353 | exit 1 |
|
353 | exit 1 | |
354 | fi |
|
354 | fi | |
355 | } |
|
355 | } | |
356 |
|
356 | |||
357 | # Determine device to partition for extra filesystem. |
|
357 | # Determine device to partition for extra filesystem. | |
358 | # If only 1 volume is present, it will be the root volume and |
|
358 | # If only 1 volume is present, it will be the root volume and | |
359 | # should be /dev/nvme0. If multiple volumes are present, the |
|
359 | # should be /dev/nvme0. If multiple volumes are present, the | |
360 | # root volume could be nvme0 or nvme1. Use whichever one doesn't have |
|
360 | # root volume could be nvme0 or nvme1. Use whichever one doesn't have | |
361 | # a partition. |
|
361 | # a partition. | |
362 | if [ -e /dev/nvme1n1 ]; then |
|
362 | if [ -e /dev/nvme1n1 ]; then | |
363 | if [ -e /dev/nvme0n1p1 ]; then |
|
363 | if [ -e /dev/nvme0n1p1 ]; then | |
364 | DEVICE=/dev/nvme1n1 |
|
364 | DEVICE=/dev/nvme1n1 | |
365 | else |
|
365 | else | |
366 | DEVICE=/dev/nvme0n1 |
|
366 | DEVICE=/dev/nvme0n1 | |
367 | fi |
|
367 | fi | |
368 | else |
|
368 | else | |
369 | DEVICE= |
|
369 | DEVICE= | |
370 | fi |
|
370 | fi | |
371 |
|
371 | |||
372 | sudo mkdir /hgwork |
|
372 | sudo mkdir /hgwork | |
373 |
|
373 | |||
374 | if [ "${FS}" != "default" -a "${FS}" != "tmpfs" ]; then |
|
374 | if [ "${FS}" != "default" -a "${FS}" != "tmpfs" ]; then | |
375 | ensure_device |
|
375 | ensure_device | |
376 | echo "creating ${FS} filesystem on ${DEVICE}" |
|
376 | echo "creating ${FS} filesystem on ${DEVICE}" | |
377 | fi |
|
377 | fi | |
378 |
|
378 | |||
379 | if [ "${FS}" = "default" ]; then |
|
379 | if [ "${FS}" = "default" ]; then | |
380 | : |
|
380 | : | |
381 |
|
381 | |||
382 | elif [ "${FS}" = "btrfs" ]; then |
|
382 | elif [ "${FS}" = "btrfs" ]; then | |
383 | sudo mkfs.btrfs ${DEVICE} |
|
383 | sudo mkfs.btrfs ${DEVICE} | |
384 | sudo mount ${DEVICE} /hgwork |
|
384 | sudo mount ${DEVICE} /hgwork | |
385 |
|
385 | |||
386 | elif [ "${FS}" = "ext3" ]; then |
|
386 | elif [ "${FS}" = "ext3" ]; then | |
387 | # lazy_journal_init speeds up filesystem creation at the expense of |
|
387 | # lazy_journal_init speeds up filesystem creation at the expense of | |
388 | # integrity if things crash. We are an ephemeral instance, so we don't |
|
388 | # integrity if things crash. We are an ephemeral instance, so we don't | |
389 | # care about integrity. |
|
389 | # care about integrity. | |
390 | sudo mkfs.ext3 -E lazy_journal_init=1 ${DEVICE} |
|
390 | sudo mkfs.ext3 -E lazy_journal_init=1 ${DEVICE} | |
391 | sudo mount ${DEVICE} /hgwork |
|
391 | sudo mount ${DEVICE} /hgwork | |
392 |
|
392 | |||
393 | elif [ "${FS}" = "ext4" ]; then |
|
393 | elif [ "${FS}" = "ext4" ]; then | |
394 | sudo mkfs.ext4 -E lazy_journal_init=1 ${DEVICE} |
|
394 | sudo mkfs.ext4 -E lazy_journal_init=1 ${DEVICE} | |
395 | sudo mount ${DEVICE} /hgwork |
|
395 | sudo mount ${DEVICE} /hgwork | |
396 |
|
396 | |||
397 | elif [ "${FS}" = "jfs" ]; then |
|
397 | elif [ "${FS}" = "jfs" ]; then | |
398 | sudo mkfs.jfs ${DEVICE} |
|
398 | sudo mkfs.jfs ${DEVICE} | |
399 | sudo mount ${DEVICE} /hgwork |
|
399 | sudo mount ${DEVICE} /hgwork | |
400 |
|
400 | |||
401 | elif [ "${FS}" = "tmpfs" ]; then |
|
401 | elif [ "${FS}" = "tmpfs" ]; then | |
402 | echo "creating tmpfs volume in /hgwork" |
|
402 | echo "creating tmpfs volume in /hgwork" | |
403 | sudo mount -t tmpfs -o size=1024M tmpfs /hgwork |
|
403 | sudo mount -t tmpfs -o size=1024M tmpfs /hgwork | |
404 |
|
404 | |||
405 | elif [ "${FS}" = "xfs" ]; then |
|
405 | elif [ "${FS}" = "xfs" ]; then | |
406 | sudo mkfs.xfs ${DEVICE} |
|
406 | sudo mkfs.xfs ${DEVICE} | |
407 | sudo mount ${DEVICE} /hgwork |
|
407 | sudo mount ${DEVICE} /hgwork | |
408 |
|
408 | |||
409 | else |
|
409 | else | |
410 | echo "unsupported filesystem: ${FS}" |
|
410 | echo "unsupported filesystem: ${FS}" | |
411 | exit 1 |
|
411 | exit 1 | |
412 | fi |
|
412 | fi | |
413 |
|
413 | |||
414 | echo "/hgwork ready" |
|
414 | echo "/hgwork ready" | |
415 |
|
415 | |||
416 | sudo chown hg:hg /hgwork |
|
416 | sudo chown hg:hg /hgwork | |
417 | mkdir /hgwork/tmp |
|
417 | mkdir /hgwork/tmp | |
418 | chown hg:hg /hgwork/tmp |
|
418 | chown hg:hg /hgwork/tmp | |
419 |
|
419 | |||
420 | rsync -a /hgdev/src /hgwork/ |
|
420 | rsync -a /hgdev/src /hgwork/ | |
421 | '''.lstrip().replace( |
|
421 | '''.lstrip().replace( | |
422 | '\r\n', '\n' |
|
422 | '\r\n', '\n' | |
423 | ) |
|
423 | ) | |
424 |
|
424 | |||
425 |
|
425 | |||
426 | HG_UPDATE_CLEAN = ''' |
|
426 | HG_UPDATE_CLEAN = ''' | |
427 | set -ex |
|
427 | set -ex | |
428 |
|
428 | |||
429 | HG=/hgdev/venv-bootstrap/bin/hg |
|
429 | HG=/hgdev/venv-bootstrap/bin/hg | |
430 |
|
430 | |||
431 | cd /hgwork/src |
|
431 | cd /hgwork/src | |
432 | ${HG} --config extensions.purge= purge --all |
|
432 | ${HG} --config extensions.purge= purge --all | |
433 | ${HG} update -C $1 |
|
433 | ${HG} update -C $1 | |
434 | ${HG} log -r . |
|
434 | ${HG} log -r . | |
435 | '''.lstrip().replace( |
|
435 | '''.lstrip().replace( | |
436 | '\r\n', '\n' |
|
436 | '\r\n', '\n' | |
437 | ) |
|
437 | ) | |
438 |
|
438 | |||
439 |
|
439 | |||
440 | def prepare_exec_environment(ssh_client, filesystem='default'): |
|
440 | def prepare_exec_environment(ssh_client, filesystem='default'): | |
441 | """Prepare an EC2 instance to execute things. |
|
441 | """Prepare an EC2 instance to execute things. | |
442 |
|
442 | |||
443 | The AMI has an ``/hgdev`` bootstrapped with various Python installs |
|
443 | The AMI has an ``/hgdev`` bootstrapped with various Python installs | |
444 | and a clone of the Mercurial repo. |
|
444 | and a clone of the Mercurial repo. | |
445 |
|
445 | |||
446 | In EC2, EBS volumes launched from snapshots have wonky performance behavior. |
|
446 | In EC2, EBS volumes launched from snapshots have wonky performance behavior. | |
447 | Notably, blocks have to be copied on first access, which makes volume |
|
447 | Notably, blocks have to be copied on first access, which makes volume | |
448 | I/O extremely slow on fresh volumes. |
|
448 | I/O extremely slow on fresh volumes. | |
449 |
|
449 | |||
450 | Furthermore, we may want to run operations, tests, etc on alternative |
|
450 | Furthermore, we may want to run operations, tests, etc on alternative | |
451 | filesystems so we examine behavior on different filesystems. |
|
451 | filesystems so we examine behavior on different filesystems. | |
452 |
|
452 | |||
453 | This function is used to facilitate executing operations on alternate |
|
453 | This function is used to facilitate executing operations on alternate | |
454 | volumes. |
|
454 | volumes. | |
455 | """ |
|
455 | """ | |
456 | sftp = ssh_client.open_sftp() |
|
456 | sftp = ssh_client.open_sftp() | |
457 |
|
457 | |||
458 | with sftp.open('/hgdev/prepare-hgdev', 'wb') as fh: |
|
458 | with sftp.open('/hgdev/prepare-hgdev', 'wb') as fh: | |
459 | fh.write(PREPARE_HGDEV) |
|
459 | fh.write(PREPARE_HGDEV) | |
460 | fh.chmod(0o0777) |
|
460 | fh.chmod(0o0777) | |
461 |
|
461 | |||
462 | command = 'sudo /hgdev/prepare-hgdev %s' % filesystem |
|
462 | command = 'sudo /hgdev/prepare-hgdev %s' % filesystem | |
463 | chan, stdin, stdout = exec_command(ssh_client, command) |
|
463 | chan, stdin, stdout = exec_command(ssh_client, command) | |
464 | stdin.close() |
|
464 | stdin.close() | |
465 |
|
465 | |||
466 | for line in stdout: |
|
466 | for line in stdout: | |
467 | print(line, end='') |
|
467 | print(line, end='') | |
468 |
|
468 | |||
469 | res = chan.recv_exit_status() |
|
469 | res = chan.recv_exit_status() | |
470 |
|
470 | |||
471 | if res: |
|
471 | if res: | |
472 | raise Exception('non-0 exit code updating working directory; %d' % res) |
|
472 | raise Exception('non-0 exit code updating working directory; %d' % res) | |
473 |
|
473 | |||
474 |
|
474 | |||
475 | def synchronize_hg( |
|
475 | def synchronize_hg( | |
476 | source_path: pathlib.Path, ec2_instance, revision: str = None |
|
476 | source_path: pathlib.Path, ec2_instance, revision: str = None | |
477 | ): |
|
477 | ): | |
478 | """Synchronize a local Mercurial source path to remote EC2 instance.""" |
|
478 | """Synchronize a local Mercurial source path to remote EC2 instance.""" | |
479 |
|
479 | |||
480 | with tempfile.TemporaryDirectory() as temp_dir: |
|
480 | with tempfile.TemporaryDirectory() as temp_dir: | |
481 | temp_dir = pathlib.Path(temp_dir) |
|
481 | temp_dir = pathlib.Path(temp_dir) | |
482 |
|
482 | |||
483 | ssh_dir = temp_dir / '.ssh' |
|
483 | ssh_dir = temp_dir / '.ssh' | |
484 | ssh_dir.mkdir() |
|
484 | ssh_dir.mkdir() | |
485 | ssh_dir.chmod(0o0700) |
|
485 | ssh_dir.chmod(0o0700) | |
486 |
|
486 | |||
487 | public_ip = ec2_instance.public_ip_address |
|
487 | public_ip = ec2_instance.public_ip_address | |
488 |
|
488 | |||
489 | ssh_config = ssh_dir / 'config' |
|
489 | ssh_config = ssh_dir / 'config' | |
490 |
|
490 | |||
491 | with ssh_config.open('w', encoding='utf-8') as fh: |
|
491 | with ssh_config.open('w', encoding='utf-8') as fh: | |
492 | fh.write('Host %s\n' % public_ip) |
|
492 | fh.write('Host %s\n' % public_ip) | |
493 | fh.write(' User hg\n') |
|
493 | fh.write(' User hg\n') | |
494 | fh.write(' StrictHostKeyChecking no\n') |
|
494 | fh.write(' StrictHostKeyChecking no\n') | |
495 | fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts')) |
|
495 | fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts')) | |
496 | fh.write(' IdentityFile %s\n' % ec2_instance.ssh_private_key_path) |
|
496 | fh.write(' IdentityFile %s\n' % ec2_instance.ssh_private_key_path) | |
497 |
|
497 | |||
498 | if not (source_path / '.hg').is_dir(): |
|
498 | if not (source_path / '.hg').is_dir(): | |
499 | raise Exception( |
|
499 | raise Exception( | |
500 | '%s is not a Mercurial repository; synchronization ' |
|
500 | '%s is not a Mercurial repository; synchronization ' | |
501 | 'not yet supported' % source_path |
|
501 | 'not yet supported' % source_path | |
502 | ) |
|
502 | ) | |
503 |
|
503 | |||
504 | env = dict(os.environ) |
|
504 | env = dict(os.environ) | |
505 | env['HGPLAIN'] = '1' |
|
505 | env['HGPLAIN'] = '1' | |
506 | env['HGENCODING'] = 'utf-8' |
|
506 | env['HGENCODING'] = 'utf-8' | |
507 |
|
507 | |||
508 | hg_bin = source_path / 'hg' |
|
508 | hg_bin = source_path / 'hg' | |
509 |
|
509 | |||
510 | res = subprocess.run( |
|
510 | res = subprocess.run( | |
511 | ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'], |
|
511 | ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'], | |
512 | cwd=str(source_path), |
|
512 | cwd=str(source_path), | |
513 | env=env, |
|
513 | env=env, | |
514 | check=True, |
|
514 | check=True, | |
515 | capture_output=True, |
|
515 | capture_output=True, | |
516 | ) |
|
516 | ) | |
517 |
|
517 | |||
518 | full_revision = res.stdout.decode('ascii') |
|
518 | full_revision = res.stdout.decode('ascii') | |
519 |
|
519 | |||
520 | args = [ |
|
520 | args = [ | |
521 | 'python2.7', |
|
521 | 'python2.7', | |
522 | str(hg_bin), |
|
522 | str(hg_bin), | |
523 | '--config', |
|
523 | '--config', | |
524 | 'ui.ssh=ssh -F %s' % ssh_config, |
|
524 | 'ui.ssh=ssh -F %s' % ssh_config, | |
525 | '--config', |
|
525 | '--config', | |
526 | 'ui.remotecmd=/hgdev/venv-bootstrap/bin/hg', |
|
526 | 'ui.remotecmd=/hgdev/venv-bootstrap/bin/hg', | |
527 | # Also ensure .hgtags changes are present so auto version |
|
527 | # Also ensure .hgtags changes are present so auto version | |
528 | # calculation works. |
|
528 | # calculation works. | |
529 | 'push', |
|
529 | 'push', | |
530 | '-f', |
|
530 | '-f', | |
531 | '-r', |
|
531 | '-r', | |
532 | full_revision, |
|
532 | full_revision, | |
533 | '-r', |
|
533 | '-r', | |
534 | 'file(.hgtags)', |
|
534 | 'file(.hgtags)', | |
535 | 'ssh://%s//hgwork/src' % public_ip, |
|
535 | 'ssh://%s//hgwork/src' % public_ip, | |
536 | ] |
|
536 | ] | |
537 |
|
537 | |||
538 | res = subprocess.run(args, cwd=str(source_path), env=env) |
|
538 | res = subprocess.run(args, cwd=str(source_path), env=env) | |
539 |
|
539 | |||
540 | # Allow 1 (no-op) to not trigger error. |
|
540 | # Allow 1 (no-op) to not trigger error. | |
541 | if res.returncode not in (0, 1): |
|
541 | if res.returncode not in (0, 1): | |
542 | res.check_returncode() |
|
542 | res.check_returncode() | |
543 |
|
543 | |||
544 | # TODO support synchronizing dirty working directory. |
|
544 | # TODO support synchronizing dirty working directory. | |
545 |
|
545 | |||
546 | sftp = ec2_instance.ssh_client.open_sftp() |
|
546 | sftp = ec2_instance.ssh_client.open_sftp() | |
547 |
|
547 | |||
548 | with sftp.open('/hgdev/hgup', 'wb') as fh: |
|
548 | with sftp.open('/hgdev/hgup', 'wb') as fh: | |
549 | fh.write(HG_UPDATE_CLEAN) |
|
549 | fh.write(HG_UPDATE_CLEAN) | |
550 | fh.chmod(0o0700) |
|
550 | fh.chmod(0o0700) | |
551 |
|
551 | |||
552 | chan, stdin, stdout = exec_command( |
|
552 | chan, stdin, stdout = exec_command( | |
553 | ec2_instance.ssh_client, '/hgdev/hgup %s' % full_revision |
|
553 | ec2_instance.ssh_client, '/hgdev/hgup %s' % full_revision | |
554 | ) |
|
554 | ) | |
555 | stdin.close() |
|
555 | stdin.close() | |
556 |
|
556 | |||
557 | for line in stdout: |
|
557 | for line in stdout: | |
558 | print(line, end='') |
|
558 | print(line, end='') | |
559 |
|
559 | |||
560 | res = chan.recv_exit_status() |
|
560 | res = chan.recv_exit_status() | |
561 |
|
561 | |||
562 | if res: |
|
562 | if res: | |
563 | raise Exception( |
|
563 | raise Exception( | |
564 | 'non-0 exit code updating working directory; %d' % res |
|
564 | 'non-0 exit code updating working directory; %d' % res | |
565 | ) |
|
565 | ) | |
566 |
|
566 | |||
567 |
|
567 | |||
568 | def run_tests(ssh_client, python_version, test_flags=None): |
|
568 | def run_tests(ssh_client, python_version, test_flags=None): | |
569 | """Run tests on a remote Linux machine via an SSH client.""" |
|
569 | """Run tests on a remote Linux machine via an SSH client.""" | |
570 | test_flags = test_flags or [] |
|
570 | test_flags = test_flags or [] | |
571 |
|
571 | |||
572 | print('running tests') |
|
572 | print('running tests') | |
573 |
|
573 | |||
574 | if python_version == 'system2': |
|
574 | if python_version == 'system2': | |
575 | python = '/usr/bin/python2' |
|
575 | python = '/usr/bin/python2' | |
576 | elif python_version == 'system3': |
|
576 | elif python_version == 'system3': | |
577 | python = '/usr/bin/python3' |
|
577 | python = '/usr/bin/python3' | |
578 | elif python_version.startswith('pypy'): |
|
578 | elif python_version.startswith('pypy'): | |
579 | python = '/hgdev/pyenv/shims/%s' % python_version |
|
579 | python = '/hgdev/pyenv/shims/%s' % python_version | |
580 | else: |
|
580 | else: | |
581 | python = '/hgdev/pyenv/shims/python%s' % python_version |
|
581 | python = '/hgdev/pyenv/shims/python%s' % python_version | |
582 |
|
582 | |||
583 | test_flags = ' '.join(shlex.quote(a) for a in test_flags) |
|
583 | test_flags = ' '.join(shlex.quote(a) for a in test_flags) | |
584 |
|
584 | |||
585 | command = ( |
|
585 | command = ( | |
586 | '/bin/sh -c "export TMPDIR=/hgwork/tmp; ' |
|
586 | '/bin/sh -c "export TMPDIR=/hgwork/tmp; ' | |
587 | 'cd /hgwork/src/tests && %s run-tests.py %s"' % (python, test_flags) |
|
587 | 'cd /hgwork/src/tests && %s run-tests.py %s"' % (python, test_flags) | |
588 | ) |
|
588 | ) | |
589 |
|
589 | |||
590 | chan, stdin, stdout = exec_command(ssh_client, command) |
|
590 | chan, stdin, stdout = exec_command(ssh_client, command) | |
591 |
|
591 | |||
592 | stdin.close() |
|
592 | stdin.close() | |
593 |
|
593 | |||
594 | for line in stdout: |
|
594 | for line in stdout: | |
595 | print(line, end='') |
|
595 | print(line, end='') | |
596 |
|
596 | |||
597 | return chan.recv_exit_status() |
|
597 | return chan.recv_exit_status() |
@@ -1,663 +1,669 b'' | |||||
1 | # windows.py - Automation specific to Windows |
|
1 | # windows.py - Automation specific to Windows | |
2 | # |
|
2 | # | |
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> |
|
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | # no-check-code because Python 3 native. |
|
8 | # no-check-code because Python 3 native. | |
9 |
|
9 | |||
10 | import datetime |
|
10 | import datetime | |
11 | import os |
|
11 | import os | |
12 | import paramiko |
|
12 | import paramiko | |
13 | import pathlib |
|
13 | import pathlib | |
14 | import re |
|
14 | import re | |
15 | import subprocess |
|
15 | import subprocess | |
16 | import tempfile |
|
16 | import tempfile | |
17 |
|
17 | |||
18 | from .pypi import upload as pypi_upload |
|
18 | from .pypi import upload as pypi_upload | |
19 | from .winrm import run_powershell |
|
19 | from .winrm import run_powershell | |
20 |
|
20 | |||
21 |
|
21 | |||
22 | # PowerShell commands to activate a Visual Studio 2008 environment. |
|
22 | # PowerShell commands to activate a Visual Studio 2008 environment. | |
23 | # This is essentially a port of vcvarsall.bat to PowerShell. |
|
23 | # This is essentially a port of vcvarsall.bat to PowerShell. | |
24 | ACTIVATE_VC9_AMD64 = r''' |
|
24 | ACTIVATE_VC9_AMD64 = r''' | |
25 | Write-Output "activating Visual Studio 2008 environment for AMD64" |
|
25 | Write-Output "activating Visual Studio 2008 environment for AMD64" | |
26 | $root = "$env:LOCALAPPDATA\Programs\Common\Microsoft\Visual C++ for Python\9.0" |
|
26 | $root = "$env:LOCALAPPDATA\Programs\Common\Microsoft\Visual C++ for Python\9.0" | |
27 | $Env:VCINSTALLDIR = "${root}\VC\" |
|
27 | $Env:VCINSTALLDIR = "${root}\VC\" | |
28 | $Env:WindowsSdkDir = "${root}\WinSDK\" |
|
28 | $Env:WindowsSdkDir = "${root}\WinSDK\" | |
29 | $Env:PATH = "${root}\VC\Bin\amd64;${root}\WinSDK\Bin\x64;${root}\WinSDK\Bin;$Env:PATH" |
|
29 | $Env:PATH = "${root}\VC\Bin\amd64;${root}\WinSDK\Bin\x64;${root}\WinSDK\Bin;$Env:PATH" | |
30 | $Env:INCLUDE = "${root}\VC\Include;${root}\WinSDK\Include;$Env:PATH" |
|
30 | $Env:INCLUDE = "${root}\VC\Include;${root}\WinSDK\Include;$Env:PATH" | |
31 | $Env:LIB = "${root}\VC\Lib\amd64;${root}\WinSDK\Lib\x64;$Env:LIB" |
|
31 | $Env:LIB = "${root}\VC\Lib\amd64;${root}\WinSDK\Lib\x64;$Env:LIB" | |
32 | $Env:LIBPATH = "${root}\VC\Lib\amd64;${root}\WinSDK\Lib\x64;$Env:LIBPATH" |
|
32 | $Env:LIBPATH = "${root}\VC\Lib\amd64;${root}\WinSDK\Lib\x64;$Env:LIBPATH" | |
33 | '''.lstrip() |
|
33 | '''.lstrip() | |
34 |
|
34 | |||
35 | ACTIVATE_VC9_X86 = r''' |
|
35 | ACTIVATE_VC9_X86 = r''' | |
36 | Write-Output "activating Visual Studio 2008 environment for x86" |
|
36 | Write-Output "activating Visual Studio 2008 environment for x86" | |
37 | $root = "$env:LOCALAPPDATA\Programs\Common\Microsoft\Visual C++ for Python\9.0" |
|
37 | $root = "$env:LOCALAPPDATA\Programs\Common\Microsoft\Visual C++ for Python\9.0" | |
38 | $Env:VCINSTALLDIR = "${root}\VC\" |
|
38 | $Env:VCINSTALLDIR = "${root}\VC\" | |
39 | $Env:WindowsSdkDir = "${root}\WinSDK\" |
|
39 | $Env:WindowsSdkDir = "${root}\WinSDK\" | |
40 | $Env:PATH = "${root}\VC\Bin;${root}\WinSDK\Bin;$Env:PATH" |
|
40 | $Env:PATH = "${root}\VC\Bin;${root}\WinSDK\Bin;$Env:PATH" | |
41 | $Env:INCLUDE = "${root}\VC\Include;${root}\WinSDK\Include;$Env:INCLUDE" |
|
41 | $Env:INCLUDE = "${root}\VC\Include;${root}\WinSDK\Include;$Env:INCLUDE" | |
42 | $Env:LIB = "${root}\VC\Lib;${root}\WinSDK\Lib;$Env:LIB" |
|
42 | $Env:LIB = "${root}\VC\Lib;${root}\WinSDK\Lib;$Env:LIB" | |
43 | $Env:LIBPATH = "${root}\VC\lib;${root}\WinSDK\Lib;$Env:LIBPATH" |
|
43 | $Env:LIBPATH = "${root}\VC\lib;${root}\WinSDK\Lib;$Env:LIBPATH" | |
44 | '''.lstrip() |
|
44 | '''.lstrip() | |
45 |
|
45 | |||
46 | HG_PURGE = r''' |
|
46 | HG_PURGE = r''' | |
47 | $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" |
|
47 | $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" | |
48 | Set-Location C:\hgdev\src |
|
48 | Set-Location C:\hgdev\src | |
49 | hg.exe --config extensions.purge= purge --all |
|
49 | hg.exe --config extensions.purge= purge --all | |
50 | if ($LASTEXITCODE -ne 0) { |
|
50 | if ($LASTEXITCODE -ne 0) { | |
51 | throw "process exited non-0: $LASTEXITCODE" |
|
51 | throw "process exited non-0: $LASTEXITCODE" | |
52 | } |
|
52 | } | |
53 | Write-Output "purged Mercurial repo" |
|
53 | Write-Output "purged Mercurial repo" | |
54 | ''' |
|
54 | ''' | |
55 |
|
55 | |||
56 | HG_UPDATE_CLEAN = r''' |
|
56 | HG_UPDATE_CLEAN = r''' | |
57 | $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" |
|
57 | $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH" | |
58 | Set-Location C:\hgdev\src |
|
58 | Set-Location C:\hgdev\src | |
59 | hg.exe --config extensions.purge= purge --all |
|
59 | hg.exe --config extensions.purge= purge --all | |
60 | if ($LASTEXITCODE -ne 0) {{ |
|
60 | if ($LASTEXITCODE -ne 0) {{ | |
61 | throw "process exited non-0: $LASTEXITCODE" |
|
61 | throw "process exited non-0: $LASTEXITCODE" | |
62 | }} |
|
62 | }} | |
63 | hg.exe update -C {revision} |
|
63 | hg.exe update -C {revision} | |
64 | if ($LASTEXITCODE -ne 0) {{ |
|
64 | if ($LASTEXITCODE -ne 0) {{ | |
65 | throw "process exited non-0: $LASTEXITCODE" |
|
65 | throw "process exited non-0: $LASTEXITCODE" | |
66 | }} |
|
66 | }} | |
67 | hg.exe log -r . |
|
67 | hg.exe log -r . | |
68 | Write-Output "updated Mercurial working directory to {revision}" |
|
68 | Write-Output "updated Mercurial working directory to {revision}" | |
69 | '''.lstrip() |
|
69 | '''.lstrip() | |
70 |
|
70 | |||
71 | BUILD_INNO_PYTHON3 = r''' |
|
71 | BUILD_INNO_PYTHON3 = r''' | |
72 | $Env:RUSTUP_HOME = "C:\hgdev\rustup" |
|
72 | $Env:RUSTUP_HOME = "C:\hgdev\rustup" | |
73 | $Env:CARGO_HOME = "C:\hgdev\cargo" |
|
73 | $Env:CARGO_HOME = "C:\hgdev\cargo" | |
74 | Set-Location C:\hgdev\src |
|
74 | Set-Location C:\hgdev\src | |
75 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --pyoxidizer-target {pyoxidizer_target} --version {version} |
|
75 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --pyoxidizer-target {pyoxidizer_target} --version {version} | |
76 | if ($LASTEXITCODE -ne 0) {{ |
|
76 | if ($LASTEXITCODE -ne 0) {{ | |
77 | throw "process exited non-0: $LASTEXITCODE" |
|
77 | throw "process exited non-0: $LASTEXITCODE" | |
78 | }} |
|
78 | }} | |
79 | ''' |
|
79 | ''' | |
80 |
|
80 | |||
81 | BUILD_INNO_PYTHON2 = r''' |
|
81 | BUILD_INNO_PYTHON2 = r''' | |
82 | Set-Location C:\hgdev\src |
|
82 | Set-Location C:\hgdev\src | |
83 | $python = "C:\hgdev\python27-{arch}\python.exe" |
|
83 | $python = "C:\hgdev\python27-{arch}\python.exe" | |
84 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --python $python {extra_args} |
|
84 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --python $python {extra_args} | |
85 | if ($LASTEXITCODE -ne 0) {{ |
|
85 | if ($LASTEXITCODE -ne 0) {{ | |
86 | throw "process exited non-0: $LASTEXITCODE" |
|
86 | throw "process exited non-0: $LASTEXITCODE" | |
87 | }} |
|
87 | }} | |
88 | '''.lstrip() |
|
88 | '''.lstrip() | |
89 |
|
89 | |||
90 | BUILD_WHEEL = r''' |
|
90 | BUILD_WHEEL = r''' | |
91 | Set-Location C:\hgdev\src |
|
91 | Set-Location C:\hgdev\src | |
92 | C:\hgdev\python{python_version}-{arch}\python.exe -m pip wheel --wheel-dir dist . |
|
92 | C:\hgdev\python{python_version}-{arch}\python.exe -m pip wheel --wheel-dir dist . | |
93 | if ($LASTEXITCODE -ne 0) {{ |
|
93 | if ($LASTEXITCODE -ne 0) {{ | |
94 | throw "process exited non-0: $LASTEXITCODE" |
|
94 | throw "process exited non-0: $LASTEXITCODE" | |
95 | }} |
|
95 | }} | |
96 | ''' |
|
96 | ''' | |
97 |
|
97 | |||
98 | BUILD_WIX_PYTHON3 = r''' |
|
98 | BUILD_WIX_PYTHON3 = r''' | |
99 | $Env:RUSTUP_HOME = "C:\hgdev\rustup" |
|
99 | $Env:RUSTUP_HOME = "C:\hgdev\rustup" | |
100 | $Env:CARGO_HOME = "C:\hgdev\cargo" |
|
100 | $Env:CARGO_HOME = "C:\hgdev\cargo" | |
101 | Set-Location C:\hgdev\src |
|
101 | Set-Location C:\hgdev\src | |
102 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --pyoxidizer-target {pyoxidizer_target} --version {version} |
|
102 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --pyoxidizer-target {pyoxidizer_target} --version {version} | |
103 | if ($LASTEXITCODE -ne 0) {{ |
|
103 | if ($LASTEXITCODE -ne 0) {{ | |
104 | throw "process exited non-0: $LASTEXITCODE" |
|
104 | throw "process exited non-0: $LASTEXITCODE" | |
105 | }} |
|
105 | }} | |
106 | ''' |
|
106 | ''' | |
107 |
|
107 | |||
108 | BUILD_WIX_PYTHON2 = r''' |
|
108 | BUILD_WIX_PYTHON2 = r''' | |
109 | Set-Location C:\hgdev\src |
|
109 | Set-Location C:\hgdev\src | |
110 | $python = "C:\hgdev\python27-{arch}\python.exe" |
|
110 | $python = "C:\hgdev\python27-{arch}\python.exe" | |
111 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --python $python {extra_args} |
|
111 | C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --python $python {extra_args} | |
112 | if ($LASTEXITCODE -ne 0) {{ |
|
112 | if ($LASTEXITCODE -ne 0) {{ | |
113 | throw "process exited non-0: $LASTEXITCODE" |
|
113 | throw "process exited non-0: $LASTEXITCODE" | |
114 | }} |
|
114 | }} | |
115 | ''' |
|
115 | ''' | |
116 |
|
116 | |||
117 | RUN_TESTS = r''' |
|
117 | RUN_TESTS = r''' | |
118 | C:\hgdev\MinGW\msys\1.0\bin\sh.exe --login -c "cd /c/hgdev/src/tests && /c/hgdev/{python_path}/python.exe run-tests.py {test_flags}" |
|
118 | C:\hgdev\MinGW\msys\1.0\bin\sh.exe --login -c "cd /c/hgdev/src/tests && /c/hgdev/{python_path}/python.exe run-tests.py {test_flags}" | |
119 | if ($LASTEXITCODE -ne 0) {{ |
|
119 | if ($LASTEXITCODE -ne 0) {{ | |
120 | throw "process exited non-0: $LASTEXITCODE" |
|
120 | throw "process exited non-0: $LASTEXITCODE" | |
121 | }} |
|
121 | }} | |
122 | ''' |
|
122 | ''' | |
123 |
|
123 | |||
124 | WHEEL_FILENAME_PYTHON27_X86 = 'mercurial-{version}-cp27-cp27m-win32.whl' |
|
124 | WHEEL_FILENAME_PYTHON27_X86 = 'mercurial-{version}-cp27-cp27m-win32.whl' | |
125 | WHEEL_FILENAME_PYTHON27_X64 = 'mercurial-{version}-cp27-cp27m-win_amd64.whl' |
|
125 | WHEEL_FILENAME_PYTHON27_X64 = 'mercurial-{version}-cp27-cp27m-win_amd64.whl' | |
126 | WHEEL_FILENAME_PYTHON37_X86 = 'mercurial-{version}-cp37-cp37m-win32.whl' |
|
126 | WHEEL_FILENAME_PYTHON37_X86 = 'mercurial-{version}-cp37-cp37m-win32.whl' | |
127 | WHEEL_FILENAME_PYTHON37_X64 = 'mercurial-{version}-cp37-cp37m-win_amd64.whl' |
|
127 | WHEEL_FILENAME_PYTHON37_X64 = 'mercurial-{version}-cp37-cp37m-win_amd64.whl' | |
128 | WHEEL_FILENAME_PYTHON38_X86 = 'mercurial-{version}-cp38-cp38-win32.whl' |
|
128 | WHEEL_FILENAME_PYTHON38_X86 = 'mercurial-{version}-cp38-cp38-win32.whl' | |
129 | WHEEL_FILENAME_PYTHON38_X64 = 'mercurial-{version}-cp38-cp38-win_amd64.whl' |
|
129 | WHEEL_FILENAME_PYTHON38_X64 = 'mercurial-{version}-cp38-cp38-win_amd64.whl' | |
|
130 | WHEEL_FILENAME_PYTHON39_X86 = 'mercurial-{version}-cp39-cp39-win32.whl' | |||
|
131 | WHEEL_FILENAME_PYTHON39_X64 = 'mercurial-{version}-cp39-cp39-win_amd64.whl' | |||
130 |
|
132 | |||
131 | EXE_FILENAME_PYTHON2_X86 = 'Mercurial-{version}-x86-python2.exe' |
|
133 | EXE_FILENAME_PYTHON2_X86 = 'Mercurial-{version}-x86-python2.exe' | |
132 | EXE_FILENAME_PYTHON2_X64 = 'Mercurial-{version}-x64-python2.exe' |
|
134 | EXE_FILENAME_PYTHON2_X64 = 'Mercurial-{version}-x64-python2.exe' | |
133 | EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe' |
|
135 | EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe' | |
134 | EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe' |
|
136 | EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe' | |
135 |
|
137 | |||
136 | MSI_FILENAME_PYTHON2_X86 = 'mercurial-{version}-x86-python2.msi' |
|
138 | MSI_FILENAME_PYTHON2_X86 = 'mercurial-{version}-x86-python2.msi' | |
137 | MSI_FILENAME_PYTHON2_X64 = 'mercurial-{version}-x64-python2.msi' |
|
139 | MSI_FILENAME_PYTHON2_X64 = 'mercurial-{version}-x64-python2.msi' | |
138 | MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi' |
|
140 | MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi' | |
139 | MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi' |
|
141 | MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi' | |
140 |
|
142 | |||
141 | MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows' |
|
143 | MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows' | |
142 |
|
144 | |||
143 | X86_USER_AGENT_PATTERN = '.*Windows.*' |
|
145 | X86_USER_AGENT_PATTERN = '.*Windows.*' | |
144 | X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*' |
|
146 | X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*' | |
145 |
|
147 | |||
146 | EXE_PYTHON2_X86_DESCRIPTION = ( |
|
148 | EXE_PYTHON2_X86_DESCRIPTION = ( | |
147 | 'Mercurial {version} Inno Setup installer - x86 Windows (Python 2) ' |
|
149 | 'Mercurial {version} Inno Setup installer - x86 Windows (Python 2) ' | |
148 | '- does not require admin rights' |
|
150 | '- does not require admin rights' | |
149 | ) |
|
151 | ) | |
150 | EXE_PYTHON2_X64_DESCRIPTION = ( |
|
152 | EXE_PYTHON2_X64_DESCRIPTION = ( | |
151 | 'Mercurial {version} Inno Setup installer - x64 Windows (Python 2) ' |
|
153 | 'Mercurial {version} Inno Setup installer - x64 Windows (Python 2) ' | |
152 | '- does not require admin rights' |
|
154 | '- does not require admin rights' | |
153 | ) |
|
155 | ) | |
154 | # TODO remove Python version once Python 2 is dropped. |
|
156 | # TODO remove Python version once Python 2 is dropped. | |
155 | EXE_PYTHON3_X86_DESCRIPTION = ( |
|
157 | EXE_PYTHON3_X86_DESCRIPTION = ( | |
156 | 'Mercurial {version} Inno Setup installer - x86 Windows (Python 3) ' |
|
158 | 'Mercurial {version} Inno Setup installer - x86 Windows (Python 3) ' | |
157 | '- does not require admin rights' |
|
159 | '- does not require admin rights' | |
158 | ) |
|
160 | ) | |
159 | EXE_PYTHON3_X64_DESCRIPTION = ( |
|
161 | EXE_PYTHON3_X64_DESCRIPTION = ( | |
160 | 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) ' |
|
162 | 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) ' | |
161 | '- does not require admin rights' |
|
163 | '- does not require admin rights' | |
162 | ) |
|
164 | ) | |
163 | MSI_PYTHON2_X86_DESCRIPTION = ( |
|
165 | MSI_PYTHON2_X86_DESCRIPTION = ( | |
164 | 'Mercurial {version} MSI installer - x86 Windows (Python 2) ' |
|
166 | 'Mercurial {version} MSI installer - x86 Windows (Python 2) ' | |
165 | '- requires admin rights' |
|
167 | '- requires admin rights' | |
166 | ) |
|
168 | ) | |
167 | MSI_PYTHON2_X64_DESCRIPTION = ( |
|
169 | MSI_PYTHON2_X64_DESCRIPTION = ( | |
168 | 'Mercurial {version} MSI installer - x64 Windows (Python 2) ' |
|
170 | 'Mercurial {version} MSI installer - x64 Windows (Python 2) ' | |
169 | '- requires admin rights' |
|
171 | '- requires admin rights' | |
170 | ) |
|
172 | ) | |
171 | MSI_PYTHON3_X86_DESCRIPTION = ( |
|
173 | MSI_PYTHON3_X86_DESCRIPTION = ( | |
172 | 'Mercurial {version} MSI installer - x86 Windows (Python 3) ' |
|
174 | 'Mercurial {version} MSI installer - x86 Windows (Python 3) ' | |
173 | '- requires admin rights' |
|
175 | '- requires admin rights' | |
174 | ) |
|
176 | ) | |
175 | MSI_PYTHON3_X64_DESCRIPTION = ( |
|
177 | MSI_PYTHON3_X64_DESCRIPTION = ( | |
176 | 'Mercurial {version} MSI installer - x64 Windows (Python 3) ' |
|
178 | 'Mercurial {version} MSI installer - x64 Windows (Python 3) ' | |
177 | '- requires admin rights' |
|
179 | '- requires admin rights' | |
178 | ) |
|
180 | ) | |
179 |
|
181 | |||
180 |
|
182 | |||
181 | def get_vc_prefix(arch): |
|
183 | def get_vc_prefix(arch): | |
182 | if arch == 'x86': |
|
184 | if arch == 'x86': | |
183 | return ACTIVATE_VC9_X86 |
|
185 | return ACTIVATE_VC9_X86 | |
184 | elif arch == 'x64': |
|
186 | elif arch == 'x64': | |
185 | return ACTIVATE_VC9_AMD64 |
|
187 | return ACTIVATE_VC9_AMD64 | |
186 | else: |
|
188 | else: | |
187 | raise ValueError('illegal arch: %s; must be x86 or x64' % arch) |
|
189 | raise ValueError('illegal arch: %s; must be x86 or x64' % arch) | |
188 |
|
190 | |||
189 |
|
191 | |||
190 | def fix_authorized_keys_permissions(winrm_client, path): |
|
192 | def fix_authorized_keys_permissions(winrm_client, path): | |
191 | commands = [ |
|
193 | commands = [ | |
192 | '$ErrorActionPreference = "Stop"', |
|
194 | '$ErrorActionPreference = "Stop"', | |
193 | 'Repair-AuthorizedKeyPermission -FilePath %s -Confirm:$false' % path, |
|
195 | 'Repair-AuthorizedKeyPermission -FilePath %s -Confirm:$false' % path, | |
194 | r'icacls %s /remove:g "NT Service\sshd"' % path, |
|
196 | r'icacls %s /remove:g "NT Service\sshd"' % path, | |
195 | ] |
|
197 | ] | |
196 |
|
198 | |||
197 | run_powershell(winrm_client, '\n'.join(commands)) |
|
199 | run_powershell(winrm_client, '\n'.join(commands)) | |
198 |
|
200 | |||
199 |
|
201 | |||
200 | def synchronize_hg(hg_repo: pathlib.Path, revision: str, ec2_instance): |
|
202 | def synchronize_hg(hg_repo: pathlib.Path, revision: str, ec2_instance): | |
201 | """Synchronize local Mercurial repo to remote EC2 instance.""" |
|
203 | """Synchronize local Mercurial repo to remote EC2 instance.""" | |
202 |
|
204 | |||
203 | winrm_client = ec2_instance.winrm_client |
|
205 | winrm_client = ec2_instance.winrm_client | |
204 |
|
206 | |||
205 | with tempfile.TemporaryDirectory() as temp_dir: |
|
207 | with tempfile.TemporaryDirectory() as temp_dir: | |
206 | temp_dir = pathlib.Path(temp_dir) |
|
208 | temp_dir = pathlib.Path(temp_dir) | |
207 |
|
209 | |||
208 | ssh_dir = temp_dir / '.ssh' |
|
210 | ssh_dir = temp_dir / '.ssh' | |
209 | ssh_dir.mkdir() |
|
211 | ssh_dir.mkdir() | |
210 | ssh_dir.chmod(0o0700) |
|
212 | ssh_dir.chmod(0o0700) | |
211 |
|
213 | |||
212 | # Generate SSH key to use for communication. |
|
214 | # Generate SSH key to use for communication. | |
213 | subprocess.run( |
|
215 | subprocess.run( | |
214 | [ |
|
216 | [ | |
215 | 'ssh-keygen', |
|
217 | 'ssh-keygen', | |
216 | '-t', |
|
218 | '-t', | |
217 | 'rsa', |
|
219 | 'rsa', | |
218 | '-b', |
|
220 | '-b', | |
219 | '4096', |
|
221 | '4096', | |
220 | '-N', |
|
222 | '-N', | |
221 | '', |
|
223 | '', | |
222 | '-f', |
|
224 | '-f', | |
223 | str(ssh_dir / 'id_rsa'), |
|
225 | str(ssh_dir / 'id_rsa'), | |
224 | ], |
|
226 | ], | |
225 | check=True, |
|
227 | check=True, | |
226 | capture_output=True, |
|
228 | capture_output=True, | |
227 | ) |
|
229 | ) | |
228 |
|
230 | |||
229 | # Add it to ~/.ssh/authorized_keys on remote. |
|
231 | # Add it to ~/.ssh/authorized_keys on remote. | |
230 | # This assumes the file doesn't already exist. |
|
232 | # This assumes the file doesn't already exist. | |
231 | authorized_keys = r'c:\Users\Administrator\.ssh\authorized_keys' |
|
233 | authorized_keys = r'c:\Users\Administrator\.ssh\authorized_keys' | |
232 | winrm_client.execute_cmd(r'mkdir c:\Users\Administrator\.ssh') |
|
234 | winrm_client.execute_cmd(r'mkdir c:\Users\Administrator\.ssh') | |
233 | winrm_client.copy(str(ssh_dir / 'id_rsa.pub'), authorized_keys) |
|
235 | winrm_client.copy(str(ssh_dir / 'id_rsa.pub'), authorized_keys) | |
234 | fix_authorized_keys_permissions(winrm_client, authorized_keys) |
|
236 | fix_authorized_keys_permissions(winrm_client, authorized_keys) | |
235 |
|
237 | |||
236 | public_ip = ec2_instance.public_ip_address |
|
238 | public_ip = ec2_instance.public_ip_address | |
237 |
|
239 | |||
238 | ssh_config = temp_dir / '.ssh' / 'config' |
|
240 | ssh_config = temp_dir / '.ssh' / 'config' | |
239 |
|
241 | |||
240 | with open(ssh_config, 'w', encoding='utf-8') as fh: |
|
242 | with open(ssh_config, 'w', encoding='utf-8') as fh: | |
241 | fh.write('Host %s\n' % public_ip) |
|
243 | fh.write('Host %s\n' % public_ip) | |
242 | fh.write(' User Administrator\n') |
|
244 | fh.write(' User Administrator\n') | |
243 | fh.write(' StrictHostKeyChecking no\n') |
|
245 | fh.write(' StrictHostKeyChecking no\n') | |
244 | fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts')) |
|
246 | fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts')) | |
245 | fh.write(' IdentityFile %s\n' % (ssh_dir / 'id_rsa')) |
|
247 | fh.write(' IdentityFile %s\n' % (ssh_dir / 'id_rsa')) | |
246 |
|
248 | |||
247 | if not (hg_repo / '.hg').is_dir(): |
|
249 | if not (hg_repo / '.hg').is_dir(): | |
248 | raise Exception( |
|
250 | raise Exception( | |
249 | '%s is not a Mercurial repository; ' |
|
251 | '%s is not a Mercurial repository; ' | |
250 | 'synchronization not yet supported' % hg_repo |
|
252 | 'synchronization not yet supported' % hg_repo | |
251 | ) |
|
253 | ) | |
252 |
|
254 | |||
253 | env = dict(os.environ) |
|
255 | env = dict(os.environ) | |
254 | env['HGPLAIN'] = '1' |
|
256 | env['HGPLAIN'] = '1' | |
255 | env['HGENCODING'] = 'utf-8' |
|
257 | env['HGENCODING'] = 'utf-8' | |
256 |
|
258 | |||
257 | hg_bin = hg_repo / 'hg' |
|
259 | hg_bin = hg_repo / 'hg' | |
258 |
|
260 | |||
259 | res = subprocess.run( |
|
261 | res = subprocess.run( | |
260 | ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'], |
|
262 | ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'], | |
261 | cwd=str(hg_repo), |
|
263 | cwd=str(hg_repo), | |
262 | env=env, |
|
264 | env=env, | |
263 | check=True, |
|
265 | check=True, | |
264 | capture_output=True, |
|
266 | capture_output=True, | |
265 | ) |
|
267 | ) | |
266 |
|
268 | |||
267 | full_revision = res.stdout.decode('ascii') |
|
269 | full_revision = res.stdout.decode('ascii') | |
268 |
|
270 | |||
269 | args = [ |
|
271 | args = [ | |
270 | 'python2.7', |
|
272 | 'python2.7', | |
271 | hg_bin, |
|
273 | hg_bin, | |
272 | '--config', |
|
274 | '--config', | |
273 | 'ui.ssh=ssh -F %s' % ssh_config, |
|
275 | 'ui.ssh=ssh -F %s' % ssh_config, | |
274 | '--config', |
|
276 | '--config', | |
275 | 'ui.remotecmd=c:/hgdev/venv-bootstrap/Scripts/hg.exe', |
|
277 | 'ui.remotecmd=c:/hgdev/venv-bootstrap/Scripts/hg.exe', | |
276 | # Also ensure .hgtags changes are present so auto version |
|
278 | # Also ensure .hgtags changes are present so auto version | |
277 | # calculation works. |
|
279 | # calculation works. | |
278 | 'push', |
|
280 | 'push', | |
279 | '-f', |
|
281 | '-f', | |
280 | '-r', |
|
282 | '-r', | |
281 | full_revision, |
|
283 | full_revision, | |
282 | '-r', |
|
284 | '-r', | |
283 | 'file(.hgtags)', |
|
285 | 'file(.hgtags)', | |
284 | 'ssh://%s/c:/hgdev/src' % public_ip, |
|
286 | 'ssh://%s/c:/hgdev/src' % public_ip, | |
285 | ] |
|
287 | ] | |
286 |
|
288 | |||
287 | res = subprocess.run(args, cwd=str(hg_repo), env=env) |
|
289 | res = subprocess.run(args, cwd=str(hg_repo), env=env) | |
288 |
|
290 | |||
289 | # Allow 1 (no-op) to not trigger error. |
|
291 | # Allow 1 (no-op) to not trigger error. | |
290 | if res.returncode not in (0, 1): |
|
292 | if res.returncode not in (0, 1): | |
291 | res.check_returncode() |
|
293 | res.check_returncode() | |
292 |
|
294 | |||
293 | run_powershell( |
|
295 | run_powershell( | |
294 | winrm_client, HG_UPDATE_CLEAN.format(revision=full_revision) |
|
296 | winrm_client, HG_UPDATE_CLEAN.format(revision=full_revision) | |
295 | ) |
|
297 | ) | |
296 |
|
298 | |||
297 | # TODO detect dirty local working directory and synchronize accordingly. |
|
299 | # TODO detect dirty local working directory and synchronize accordingly. | |
298 |
|
300 | |||
299 |
|
301 | |||
300 | def purge_hg(winrm_client): |
|
302 | def purge_hg(winrm_client): | |
301 | """Purge the Mercurial source repository on an EC2 instance.""" |
|
303 | """Purge the Mercurial source repository on an EC2 instance.""" | |
302 | run_powershell(winrm_client, HG_PURGE) |
|
304 | run_powershell(winrm_client, HG_PURGE) | |
303 |
|
305 | |||
304 |
|
306 | |||
305 | def find_latest_dist(winrm_client, pattern): |
|
307 | def find_latest_dist(winrm_client, pattern): | |
306 | """Find path to newest file in dist/ directory matching a pattern.""" |
|
308 | """Find path to newest file in dist/ directory matching a pattern.""" | |
307 |
|
309 | |||
308 | res = winrm_client.execute_ps( |
|
310 | res = winrm_client.execute_ps( | |
309 | r'$v = Get-ChildItem -Path C:\hgdev\src\dist -Filter "%s" ' |
|
311 | r'$v = Get-ChildItem -Path C:\hgdev\src\dist -Filter "%s" ' | |
310 | '| Sort-Object LastWriteTime -Descending ' |
|
312 | '| Sort-Object LastWriteTime -Descending ' | |
311 | '| Select-Object -First 1\n' |
|
313 | '| Select-Object -First 1\n' | |
312 | '$v.name' % pattern |
|
314 | '$v.name' % pattern | |
313 | ) |
|
315 | ) | |
314 | return res[0] |
|
316 | return res[0] | |
315 |
|
317 | |||
316 |
|
318 | |||
317 | def copy_latest_dist(winrm_client, pattern, dest_path): |
|
319 | def copy_latest_dist(winrm_client, pattern, dest_path): | |
318 | """Copy latest file matching pattern in dist/ directory. |
|
320 | """Copy latest file matching pattern in dist/ directory. | |
319 |
|
321 | |||
320 | Given a WinRM client and a file pattern, find the latest file on the remote |
|
322 | Given a WinRM client and a file pattern, find the latest file on the remote | |
321 | matching that pattern and copy it to the ``dest_path`` directory on the |
|
323 | matching that pattern and copy it to the ``dest_path`` directory on the | |
322 | local machine. |
|
324 | local machine. | |
323 | """ |
|
325 | """ | |
324 | latest = find_latest_dist(winrm_client, pattern) |
|
326 | latest = find_latest_dist(winrm_client, pattern) | |
325 | source = r'C:\hgdev\src\dist\%s' % latest |
|
327 | source = r'C:\hgdev\src\dist\%s' % latest | |
326 | dest = dest_path / latest |
|
328 | dest = dest_path / latest | |
327 | print('copying %s to %s' % (source, dest)) |
|
329 | print('copying %s to %s' % (source, dest)) | |
328 | winrm_client.fetch(source, str(dest)) |
|
330 | winrm_client.fetch(source, str(dest)) | |
329 |
|
331 | |||
330 |
|
332 | |||
331 | def build_inno_installer( |
|
333 | def build_inno_installer( | |
332 | winrm_client, |
|
334 | winrm_client, | |
333 | python_version: int, |
|
335 | python_version: int, | |
334 | arch: str, |
|
336 | arch: str, | |
335 | dest_path: pathlib.Path, |
|
337 | dest_path: pathlib.Path, | |
336 | version=None, |
|
338 | version=None, | |
337 | ): |
|
339 | ): | |
338 | """Build the Inno Setup installer on a remote machine. |
|
340 | """Build the Inno Setup installer on a remote machine. | |
339 |
|
341 | |||
340 | Using a WinRM client, remote commands are executed to build |
|
342 | Using a WinRM client, remote commands are executed to build | |
341 | a Mercurial Inno Setup installer. |
|
343 | a Mercurial Inno Setup installer. | |
342 | """ |
|
344 | """ | |
343 | print( |
|
345 | print( | |
344 | 'building Inno Setup installer for Python %d %s' |
|
346 | 'building Inno Setup installer for Python %d %s' | |
345 | % (python_version, arch) |
|
347 | % (python_version, arch) | |
346 | ) |
|
348 | ) | |
347 |
|
349 | |||
348 | if python_version == 3: |
|
350 | if python_version == 3: | |
349 | # TODO fix this limitation in packaging code |
|
351 | # TODO fix this limitation in packaging code | |
350 | if not version: |
|
352 | if not version: | |
351 | raise Exception( |
|
353 | raise Exception( | |
352 | "version string is required when building for Python 3" |
|
354 | "version string is required when building for Python 3" | |
353 | ) |
|
355 | ) | |
354 |
|
356 | |||
355 | if arch == "x86": |
|
357 | if arch == "x86": | |
356 | target_triple = "i686-pc-windows-msvc" |
|
358 | target_triple = "i686-pc-windows-msvc" | |
357 | elif arch == "x64": |
|
359 | elif arch == "x64": | |
358 | target_triple = "x86_64-pc-windows-msvc" |
|
360 | target_triple = "x86_64-pc-windows-msvc" | |
359 | else: |
|
361 | else: | |
360 | raise Exception("unhandled arch: %s" % arch) |
|
362 | raise Exception("unhandled arch: %s" % arch) | |
361 |
|
363 | |||
362 | ps = BUILD_INNO_PYTHON3.format( |
|
364 | ps = BUILD_INNO_PYTHON3.format( | |
363 | pyoxidizer_target=target_triple, version=version, |
|
365 | pyoxidizer_target=target_triple, version=version, | |
364 | ) |
|
366 | ) | |
365 | else: |
|
367 | else: | |
366 | extra_args = [] |
|
368 | extra_args = [] | |
367 | if version: |
|
369 | if version: | |
368 | extra_args.extend(['--version', version]) |
|
370 | extra_args.extend(['--version', version]) | |
369 |
|
371 | |||
370 | ps = get_vc_prefix(arch) + BUILD_INNO_PYTHON2.format( |
|
372 | ps = get_vc_prefix(arch) + BUILD_INNO_PYTHON2.format( | |
371 | arch=arch, extra_args=' '.join(extra_args) |
|
373 | arch=arch, extra_args=' '.join(extra_args) | |
372 | ) |
|
374 | ) | |
373 |
|
375 | |||
374 | run_powershell(winrm_client, ps) |
|
376 | run_powershell(winrm_client, ps) | |
375 | copy_latest_dist(winrm_client, '*.exe', dest_path) |
|
377 | copy_latest_dist(winrm_client, '*.exe', dest_path) | |
376 |
|
378 | |||
377 |
|
379 | |||
378 | def build_wheel( |
|
380 | def build_wheel( | |
379 | winrm_client, python_version: str, arch: str, dest_path: pathlib.Path |
|
381 | winrm_client, python_version: str, arch: str, dest_path: pathlib.Path | |
380 | ): |
|
382 | ): | |
381 | """Build Python wheels on a remote machine. |
|
383 | """Build Python wheels on a remote machine. | |
382 |
|
384 | |||
383 | Using a WinRM client, remote commands are executed to build a Python wheel |
|
385 | Using a WinRM client, remote commands are executed to build a Python wheel | |
384 | for Mercurial. |
|
386 | for Mercurial. | |
385 | """ |
|
387 | """ | |
386 | print('Building Windows wheel for Python %s %s' % (python_version, arch)) |
|
388 | print('Building Windows wheel for Python %s %s' % (python_version, arch)) | |
387 |
|
389 | |||
388 | ps = BUILD_WHEEL.format( |
|
390 | ps = BUILD_WHEEL.format( | |
389 | python_version=python_version.replace(".", ""), arch=arch |
|
391 | python_version=python_version.replace(".", ""), arch=arch | |
390 | ) |
|
392 | ) | |
391 |
|
393 | |||
392 | # Python 2.7 requires an activated environment. |
|
394 | # Python 2.7 requires an activated environment. | |
393 | if python_version == "2.7": |
|
395 | if python_version == "2.7": | |
394 | ps = get_vc_prefix(arch) + ps |
|
396 | ps = get_vc_prefix(arch) + ps | |
395 |
|
397 | |||
396 | run_powershell(winrm_client, ps) |
|
398 | run_powershell(winrm_client, ps) | |
397 | copy_latest_dist(winrm_client, '*.whl', dest_path) |
|
399 | copy_latest_dist(winrm_client, '*.whl', dest_path) | |
398 |
|
400 | |||
399 |
|
401 | |||
400 | def build_wix_installer( |
|
402 | def build_wix_installer( | |
401 | winrm_client, |
|
403 | winrm_client, | |
402 | python_version: int, |
|
404 | python_version: int, | |
403 | arch: str, |
|
405 | arch: str, | |
404 | dest_path: pathlib.Path, |
|
406 | dest_path: pathlib.Path, | |
405 | version=None, |
|
407 | version=None, | |
406 | ): |
|
408 | ): | |
407 | """Build the WiX installer on a remote machine. |
|
409 | """Build the WiX installer on a remote machine. | |
408 |
|
410 | |||
409 | Using a WinRM client, remote commands are executed to build a WiX installer. |
|
411 | Using a WinRM client, remote commands are executed to build a WiX installer. | |
410 | """ |
|
412 | """ | |
411 | print('Building WiX installer for Python %d %s' % (python_version, arch)) |
|
413 | print('Building WiX installer for Python %d %s' % (python_version, arch)) | |
412 |
|
414 | |||
413 | if python_version == 3: |
|
415 | if python_version == 3: | |
414 | # TODO fix this limitation in packaging code |
|
416 | # TODO fix this limitation in packaging code | |
415 | if not version: |
|
417 | if not version: | |
416 | raise Exception( |
|
418 | raise Exception( | |
417 | "version string is required when building for Python 3" |
|
419 | "version string is required when building for Python 3" | |
418 | ) |
|
420 | ) | |
419 |
|
421 | |||
420 | if arch == "x86": |
|
422 | if arch == "x86": | |
421 | target_triple = "i686-pc-windows-msvc" |
|
423 | target_triple = "i686-pc-windows-msvc" | |
422 | elif arch == "x64": |
|
424 | elif arch == "x64": | |
423 | target_triple = "x86_64-pc-windows-msvc" |
|
425 | target_triple = "x86_64-pc-windows-msvc" | |
424 | else: |
|
426 | else: | |
425 | raise Exception("unhandled arch: %s" % arch) |
|
427 | raise Exception("unhandled arch: %s" % arch) | |
426 |
|
428 | |||
427 | ps = BUILD_WIX_PYTHON3.format( |
|
429 | ps = BUILD_WIX_PYTHON3.format( | |
428 | pyoxidizer_target=target_triple, version=version, |
|
430 | pyoxidizer_target=target_triple, version=version, | |
429 | ) |
|
431 | ) | |
430 | else: |
|
432 | else: | |
431 | extra_args = [] |
|
433 | extra_args = [] | |
432 | if version: |
|
434 | if version: | |
433 | extra_args.extend(['--version', version]) |
|
435 | extra_args.extend(['--version', version]) | |
434 |
|
436 | |||
435 | ps = get_vc_prefix(arch) + BUILD_WIX_PYTHON2.format( |
|
437 | ps = get_vc_prefix(arch) + BUILD_WIX_PYTHON2.format( | |
436 | arch=arch, extra_args=' '.join(extra_args) |
|
438 | arch=arch, extra_args=' '.join(extra_args) | |
437 | ) |
|
439 | ) | |
438 |
|
440 | |||
439 | run_powershell(winrm_client, ps) |
|
441 | run_powershell(winrm_client, ps) | |
440 | copy_latest_dist(winrm_client, '*.msi', dest_path) |
|
442 | copy_latest_dist(winrm_client, '*.msi', dest_path) | |
441 |
|
443 | |||
442 |
|
444 | |||
443 | def run_tests(winrm_client, python_version, arch, test_flags=''): |
|
445 | def run_tests(winrm_client, python_version, arch, test_flags=''): | |
444 | """Run tests on a remote Windows machine. |
|
446 | """Run tests on a remote Windows machine. | |
445 |
|
447 | |||
446 | ``python_version`` is a ``X.Y`` string like ``2.7`` or ``3.7``. |
|
448 | ``python_version`` is a ``X.Y`` string like ``2.7`` or ``3.7``. | |
447 | ``arch`` is ``x86`` or ``x64``. |
|
449 | ``arch`` is ``x86`` or ``x64``. | |
448 | ``test_flags`` is a str representing extra arguments to pass to |
|
450 | ``test_flags`` is a str representing extra arguments to pass to | |
449 | ``run-tests.py``. |
|
451 | ``run-tests.py``. | |
450 | """ |
|
452 | """ | |
451 | if not re.match(r'\d\.\d', python_version): |
|
453 | if not re.match(r'\d\.\d', python_version): | |
452 | raise ValueError( |
|
454 | raise ValueError( | |
453 | r'python_version must be \d.\d; got %s' % python_version |
|
455 | r'python_version must be \d.\d; got %s' % python_version | |
454 | ) |
|
456 | ) | |
455 |
|
457 | |||
456 | if arch not in ('x86', 'x64'): |
|
458 | if arch not in ('x86', 'x64'): | |
457 | raise ValueError('arch must be x86 or x64; got %s' % arch) |
|
459 | raise ValueError('arch must be x86 or x64; got %s' % arch) | |
458 |
|
460 | |||
459 | python_path = 'python%s-%s' % (python_version.replace('.', ''), arch) |
|
461 | python_path = 'python%s-%s' % (python_version.replace('.', ''), arch) | |
460 |
|
462 | |||
461 | ps = RUN_TESTS.format(python_path=python_path, test_flags=test_flags or '',) |
|
463 | ps = RUN_TESTS.format(python_path=python_path, test_flags=test_flags or '',) | |
462 |
|
464 | |||
463 | run_powershell(winrm_client, ps) |
|
465 | run_powershell(winrm_client, ps) | |
464 |
|
466 | |||
465 |
|
467 | |||
466 | def resolve_wheel_artifacts(dist_path: pathlib.Path, version: str): |
|
468 | def resolve_wheel_artifacts(dist_path: pathlib.Path, version: str): | |
467 | return ( |
|
469 | return ( | |
468 | dist_path / WHEEL_FILENAME_PYTHON27_X86.format(version=version), |
|
470 | dist_path / WHEEL_FILENAME_PYTHON27_X86.format(version=version), | |
469 | dist_path / WHEEL_FILENAME_PYTHON27_X64.format(version=version), |
|
471 | dist_path / WHEEL_FILENAME_PYTHON27_X64.format(version=version), | |
470 | dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version), |
|
472 | dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version), | |
471 | dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version), |
|
473 | dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version), | |
472 | dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version), |
|
474 | dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version), | |
473 | dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), |
|
475 | dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), | |
|
476 | dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version), | |||
|
477 | dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version), | |||
474 | ) |
|
478 | ) | |
475 |
|
479 | |||
476 |
|
480 | |||
477 | def resolve_all_artifacts(dist_path: pathlib.Path, version: str): |
|
481 | def resolve_all_artifacts(dist_path: pathlib.Path, version: str): | |
478 | return ( |
|
482 | return ( | |
479 | dist_path / WHEEL_FILENAME_PYTHON27_X86.format(version=version), |
|
483 | dist_path / WHEEL_FILENAME_PYTHON27_X86.format(version=version), | |
480 | dist_path / WHEEL_FILENAME_PYTHON27_X64.format(version=version), |
|
484 | dist_path / WHEEL_FILENAME_PYTHON27_X64.format(version=version), | |
481 | dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version), |
|
485 | dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version), | |
482 | dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version), |
|
486 | dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version), | |
483 | dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version), |
|
487 | dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version), | |
484 | dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), |
|
488 | dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version), | |
|
489 | dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version), | |||
|
490 | dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version), | |||
485 | dist_path / EXE_FILENAME_PYTHON2_X86.format(version=version), |
|
491 | dist_path / EXE_FILENAME_PYTHON2_X86.format(version=version), | |
486 | dist_path / EXE_FILENAME_PYTHON2_X64.format(version=version), |
|
492 | dist_path / EXE_FILENAME_PYTHON2_X64.format(version=version), | |
487 | dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version), |
|
493 | dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version), | |
488 | dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version), |
|
494 | dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version), | |
489 | dist_path / MSI_FILENAME_PYTHON2_X86.format(version=version), |
|
495 | dist_path / MSI_FILENAME_PYTHON2_X86.format(version=version), | |
490 | dist_path / MSI_FILENAME_PYTHON2_X64.format(version=version), |
|
496 | dist_path / MSI_FILENAME_PYTHON2_X64.format(version=version), | |
491 | dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version), |
|
497 | dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version), | |
492 | dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version), |
|
498 | dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version), | |
493 | ) |
|
499 | ) | |
494 |
|
500 | |||
495 |
|
501 | |||
496 | def generate_latest_dat(version: str): |
|
502 | def generate_latest_dat(version: str): | |
497 | python2_x86_exe_filename = EXE_FILENAME_PYTHON2_X86.format(version=version) |
|
503 | python2_x86_exe_filename = EXE_FILENAME_PYTHON2_X86.format(version=version) | |
498 | python2_x64_exe_filename = EXE_FILENAME_PYTHON2_X64.format(version=version) |
|
504 | python2_x64_exe_filename = EXE_FILENAME_PYTHON2_X64.format(version=version) | |
499 | python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version) |
|
505 | python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version) | |
500 | python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version) |
|
506 | python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version) | |
501 | python2_x86_msi_filename = MSI_FILENAME_PYTHON2_X86.format(version=version) |
|
507 | python2_x86_msi_filename = MSI_FILENAME_PYTHON2_X86.format(version=version) | |
502 | python2_x64_msi_filename = MSI_FILENAME_PYTHON2_X64.format(version=version) |
|
508 | python2_x64_msi_filename = MSI_FILENAME_PYTHON2_X64.format(version=version) | |
503 | python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version) |
|
509 | python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version) | |
504 | python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version) |
|
510 | python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version) | |
505 |
|
511 | |||
506 | entries = ( |
|
512 | entries = ( | |
507 | ( |
|
513 | ( | |
508 | '10', |
|
514 | '10', | |
509 | version, |
|
515 | version, | |
510 | X86_USER_AGENT_PATTERN, |
|
516 | X86_USER_AGENT_PATTERN, | |
511 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_exe_filename), |
|
517 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_exe_filename), | |
512 | EXE_PYTHON3_X86_DESCRIPTION.format(version=version), |
|
518 | EXE_PYTHON3_X86_DESCRIPTION.format(version=version), | |
513 | ), |
|
519 | ), | |
514 | ( |
|
520 | ( | |
515 | '10', |
|
521 | '10', | |
516 | version, |
|
522 | version, | |
517 | X64_USER_AGENT_PATTERN, |
|
523 | X64_USER_AGENT_PATTERN, | |
518 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_exe_filename), |
|
524 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_exe_filename), | |
519 | EXE_PYTHON3_X64_DESCRIPTION.format(version=version), |
|
525 | EXE_PYTHON3_X64_DESCRIPTION.format(version=version), | |
520 | ), |
|
526 | ), | |
521 | ( |
|
527 | ( | |
522 | '9', |
|
528 | '9', | |
523 | version, |
|
529 | version, | |
524 | X86_USER_AGENT_PATTERN, |
|
530 | X86_USER_AGENT_PATTERN, | |
525 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_exe_filename), |
|
531 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_exe_filename), | |
526 | EXE_PYTHON2_X86_DESCRIPTION.format(version=version), |
|
532 | EXE_PYTHON2_X86_DESCRIPTION.format(version=version), | |
527 | ), |
|
533 | ), | |
528 | ( |
|
534 | ( | |
529 | '9', |
|
535 | '9', | |
530 | version, |
|
536 | version, | |
531 | X64_USER_AGENT_PATTERN, |
|
537 | X64_USER_AGENT_PATTERN, | |
532 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_exe_filename), |
|
538 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_exe_filename), | |
533 | EXE_PYTHON2_X64_DESCRIPTION.format(version=version), |
|
539 | EXE_PYTHON2_X64_DESCRIPTION.format(version=version), | |
534 | ), |
|
540 | ), | |
535 | ( |
|
541 | ( | |
536 | '10', |
|
542 | '10', | |
537 | version, |
|
543 | version, | |
538 | X86_USER_AGENT_PATTERN, |
|
544 | X86_USER_AGENT_PATTERN, | |
539 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_msi_filename), |
|
545 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_msi_filename), | |
540 | MSI_PYTHON3_X86_DESCRIPTION.format(version=version), |
|
546 | MSI_PYTHON3_X86_DESCRIPTION.format(version=version), | |
541 | ), |
|
547 | ), | |
542 | ( |
|
548 | ( | |
543 | '10', |
|
549 | '10', | |
544 | version, |
|
550 | version, | |
545 | X64_USER_AGENT_PATTERN, |
|
551 | X64_USER_AGENT_PATTERN, | |
546 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename), |
|
552 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename), | |
547 | MSI_PYTHON3_X64_DESCRIPTION.format(version=version), |
|
553 | MSI_PYTHON3_X64_DESCRIPTION.format(version=version), | |
548 | ), |
|
554 | ), | |
549 | ( |
|
555 | ( | |
550 | '9', |
|
556 | '9', | |
551 | version, |
|
557 | version, | |
552 | X86_USER_AGENT_PATTERN, |
|
558 | X86_USER_AGENT_PATTERN, | |
553 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_msi_filename), |
|
559 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_msi_filename), | |
554 | MSI_PYTHON2_X86_DESCRIPTION.format(version=version), |
|
560 | MSI_PYTHON2_X86_DESCRIPTION.format(version=version), | |
555 | ), |
|
561 | ), | |
556 | ( |
|
562 | ( | |
557 | '9', |
|
563 | '9', | |
558 | version, |
|
564 | version, | |
559 | X64_USER_AGENT_PATTERN, |
|
565 | X64_USER_AGENT_PATTERN, | |
560 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_msi_filename), |
|
566 | '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_msi_filename), | |
561 | MSI_PYTHON2_X64_DESCRIPTION.format(version=version), |
|
567 | MSI_PYTHON2_X64_DESCRIPTION.format(version=version), | |
562 | ), |
|
568 | ), | |
563 | ) |
|
569 | ) | |
564 |
|
570 | |||
565 | lines = ['\t'.join(e) for e in entries] |
|
571 | lines = ['\t'.join(e) for e in entries] | |
566 |
|
572 | |||
567 | return '\n'.join(lines) + '\n' |
|
573 | return '\n'.join(lines) + '\n' | |
568 |
|
574 | |||
569 |
|
575 | |||
570 | def publish_artifacts_pypi(dist_path: pathlib.Path, version: str): |
|
576 | def publish_artifacts_pypi(dist_path: pathlib.Path, version: str): | |
571 | """Publish Windows release artifacts to PyPI.""" |
|
577 | """Publish Windows release artifacts to PyPI.""" | |
572 |
|
578 | |||
573 | wheel_paths = resolve_wheel_artifacts(dist_path, version) |
|
579 | wheel_paths = resolve_wheel_artifacts(dist_path, version) | |
574 |
|
580 | |||
575 | for p in wheel_paths: |
|
581 | for p in wheel_paths: | |
576 | if not p.exists(): |
|
582 | if not p.exists(): | |
577 | raise Exception('%s not found' % p) |
|
583 | raise Exception('%s not found' % p) | |
578 |
|
584 | |||
579 | print('uploading wheels to PyPI (you may be prompted for credentials)') |
|
585 | print('uploading wheels to PyPI (you may be prompted for credentials)') | |
580 | pypi_upload(wheel_paths) |
|
586 | pypi_upload(wheel_paths) | |
581 |
|
587 | |||
582 |
|
588 | |||
583 | def publish_artifacts_mercurial_scm_org( |
|
589 | def publish_artifacts_mercurial_scm_org( | |
584 | dist_path: pathlib.Path, version: str, ssh_username=None |
|
590 | dist_path: pathlib.Path, version: str, ssh_username=None | |
585 | ): |
|
591 | ): | |
586 | """Publish Windows release artifacts to mercurial-scm.org.""" |
|
592 | """Publish Windows release artifacts to mercurial-scm.org.""" | |
587 | all_paths = resolve_all_artifacts(dist_path, version) |
|
593 | all_paths = resolve_all_artifacts(dist_path, version) | |
588 |
|
594 | |||
589 | for p in all_paths: |
|
595 | for p in all_paths: | |
590 | if not p.exists(): |
|
596 | if not p.exists(): | |
591 | raise Exception('%s not found' % p) |
|
597 | raise Exception('%s not found' % p) | |
592 |
|
598 | |||
593 | client = paramiko.SSHClient() |
|
599 | client = paramiko.SSHClient() | |
594 | client.load_system_host_keys() |
|
600 | client.load_system_host_keys() | |
595 | # We assume the system SSH configuration knows how to connect. |
|
601 | # We assume the system SSH configuration knows how to connect. | |
596 | print('connecting to mercurial-scm.org via ssh...') |
|
602 | print('connecting to mercurial-scm.org via ssh...') | |
597 | try: |
|
603 | try: | |
598 | client.connect('mercurial-scm.org', username=ssh_username) |
|
604 | client.connect('mercurial-scm.org', username=ssh_username) | |
599 | except paramiko.AuthenticationException: |
|
605 | except paramiko.AuthenticationException: | |
600 | print('error authenticating; is an SSH key available in an SSH agent?') |
|
606 | print('error authenticating; is an SSH key available in an SSH agent?') | |
601 | raise |
|
607 | raise | |
602 |
|
608 | |||
603 | print('SSH connection established') |
|
609 | print('SSH connection established') | |
604 |
|
610 | |||
605 | print('opening SFTP client...') |
|
611 | print('opening SFTP client...') | |
606 | sftp = client.open_sftp() |
|
612 | sftp = client.open_sftp() | |
607 | print('SFTP client obtained') |
|
613 | print('SFTP client obtained') | |
608 |
|
614 | |||
609 | for p in all_paths: |
|
615 | for p in all_paths: | |
610 | dest_path = '/var/www/release/windows/%s' % p.name |
|
616 | dest_path = '/var/www/release/windows/%s' % p.name | |
611 | print('uploading %s to %s' % (p, dest_path)) |
|
617 | print('uploading %s to %s' % (p, dest_path)) | |
612 |
|
618 | |||
613 | with p.open('rb') as fh: |
|
619 | with p.open('rb') as fh: | |
614 | data = fh.read() |
|
620 | data = fh.read() | |
615 |
|
621 | |||
616 | with sftp.open(dest_path, 'wb') as fh: |
|
622 | with sftp.open(dest_path, 'wb') as fh: | |
617 | fh.write(data) |
|
623 | fh.write(data) | |
618 | fh.chmod(0o0664) |
|
624 | fh.chmod(0o0664) | |
619 |
|
625 | |||
620 | latest_dat_path = '/var/www/release/windows/latest.dat' |
|
626 | latest_dat_path = '/var/www/release/windows/latest.dat' | |
621 |
|
627 | |||
622 | now = datetime.datetime.utcnow() |
|
628 | now = datetime.datetime.utcnow() | |
623 | backup_path = dist_path / ( |
|
629 | backup_path = dist_path / ( | |
624 | 'latest-windows-%s.dat' % now.strftime('%Y%m%dT%H%M%S') |
|
630 | 'latest-windows-%s.dat' % now.strftime('%Y%m%dT%H%M%S') | |
625 | ) |
|
631 | ) | |
626 | print('backing up %s to %s' % (latest_dat_path, backup_path)) |
|
632 | print('backing up %s to %s' % (latest_dat_path, backup_path)) | |
627 |
|
633 | |||
628 | with sftp.open(latest_dat_path, 'rb') as fh: |
|
634 | with sftp.open(latest_dat_path, 'rb') as fh: | |
629 | latest_dat_old = fh.read() |
|
635 | latest_dat_old = fh.read() | |
630 |
|
636 | |||
631 | with backup_path.open('wb') as fh: |
|
637 | with backup_path.open('wb') as fh: | |
632 | fh.write(latest_dat_old) |
|
638 | fh.write(latest_dat_old) | |
633 |
|
639 | |||
634 | print('writing %s with content:' % latest_dat_path) |
|
640 | print('writing %s with content:' % latest_dat_path) | |
635 | latest_dat_content = generate_latest_dat(version) |
|
641 | latest_dat_content = generate_latest_dat(version) | |
636 | print(latest_dat_content) |
|
642 | print(latest_dat_content) | |
637 |
|
643 | |||
638 | with sftp.open(latest_dat_path, 'wb') as fh: |
|
644 | with sftp.open(latest_dat_path, 'wb') as fh: | |
639 | fh.write(latest_dat_content.encode('ascii')) |
|
645 | fh.write(latest_dat_content.encode('ascii')) | |
640 |
|
646 | |||
641 |
|
647 | |||
642 | def publish_artifacts( |
|
648 | def publish_artifacts( | |
643 | dist_path: pathlib.Path, |
|
649 | dist_path: pathlib.Path, | |
644 | version: str, |
|
650 | version: str, | |
645 | pypi=True, |
|
651 | pypi=True, | |
646 | mercurial_scm_org=True, |
|
652 | mercurial_scm_org=True, | |
647 | ssh_username=None, |
|
653 | ssh_username=None, | |
648 | ): |
|
654 | ): | |
649 | """Publish Windows release artifacts. |
|
655 | """Publish Windows release artifacts. | |
650 |
|
656 | |||
651 | Files are found in `dist_path`. We will look for files with version string |
|
657 | Files are found in `dist_path`. We will look for files with version string | |
652 | `version`. |
|
658 | `version`. | |
653 |
|
659 | |||
654 | `pypi` controls whether we upload to PyPI. |
|
660 | `pypi` controls whether we upload to PyPI. | |
655 | `mercurial_scm_org` controls whether we upload to mercurial-scm.org. |
|
661 | `mercurial_scm_org` controls whether we upload to mercurial-scm.org. | |
656 | """ |
|
662 | """ | |
657 | if pypi: |
|
663 | if pypi: | |
658 | publish_artifacts_pypi(dist_path, version) |
|
664 | publish_artifacts_pypi(dist_path, version) | |
659 |
|
665 | |||
660 | if mercurial_scm_org: |
|
666 | if mercurial_scm_org: | |
661 | publish_artifacts_mercurial_scm_org( |
|
667 | publish_artifacts_mercurial_scm_org( | |
662 | dist_path, version, ssh_username=ssh_username |
|
668 | dist_path, version, ssh_username=ssh_username | |
663 | ) |
|
669 | ) |
@@ -1,211 +1,211 b'' | |||||
1 | # install-dependencies.ps1 - Install Windows dependencies for building Mercurial |
|
1 | # install-dependencies.ps1 - Install Windows dependencies for building Mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> |
|
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | # This script can be used to bootstrap a Mercurial build environment on |
|
8 | # This script can be used to bootstrap a Mercurial build environment on | |
9 | # Windows. |
|
9 | # Windows. | |
10 | # |
|
10 | # | |
11 | # The script makes a lot of assumptions about how things should work. |
|
11 | # The script makes a lot of assumptions about how things should work. | |
12 | # For example, the install location of Python is hardcoded to c:\hgdev\*. |
|
12 | # For example, the install location of Python is hardcoded to c:\hgdev\*. | |
13 | # |
|
13 | # | |
14 | # The script should be executed from a PowerShell with elevated privileges |
|
14 | # The script should be executed from a PowerShell with elevated privileges | |
15 | # if you don't want to see a UAC prompt for various installers. |
|
15 | # if you don't want to see a UAC prompt for various installers. | |
16 | # |
|
16 | # | |
17 | # The script is tested on Windows 10 and Windows Server 2019 (in EC2). |
|
17 | # The script is tested on Windows 10 and Windows Server 2019 (in EC2). | |
18 |
|
18 | |||
19 | $VS_BUILD_TOOLS_URL = "https://download.visualstudio.microsoft.com/download/pr/a1603c02-8a66-4b83-b821-811e3610a7c4/aa2db8bb39e0cbd23e9940d8951e0bc3/vs_buildtools.exe" |
|
19 | $VS_BUILD_TOOLS_URL = "https://download.visualstudio.microsoft.com/download/pr/a1603c02-8a66-4b83-b821-811e3610a7c4/aa2db8bb39e0cbd23e9940d8951e0bc3/vs_buildtools.exe" | |
20 | $VS_BUILD_TOOLS_SHA256 = "911E292B8E6E5F46CBC17003BDCD2D27A70E616E8D5E6E69D5D489A605CAA139" |
|
20 | $VS_BUILD_TOOLS_SHA256 = "911E292B8E6E5F46CBC17003BDCD2D27A70E616E8D5E6E69D5D489A605CAA139" | |
21 |
|
21 | |||
22 | $VC9_PYTHON_URL = "https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi" |
|
22 | $VC9_PYTHON_URL = "https://download.microsoft.com/download/7/9/6/796EF2E4-801B-4FC4-AB28-B59FBF6D907B/VCForPython27.msi" | |
23 | $VC9_PYTHON_SHA256 = "070474db76a2e625513a5835df4595df9324d820f9cc97eab2a596dcbc2f5cbf" |
|
23 | $VC9_PYTHON_SHA256 = "070474db76a2e625513a5835df4595df9324d820f9cc97eab2a596dcbc2f5cbf" | |
24 |
|
24 | |||
25 | $PYTHON27_x64_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi" |
|
25 | $PYTHON27_x64_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.amd64.msi" | |
26 | $PYTHON27_x64_SHA256 = "b74a3afa1e0bf2a6fc566a7b70d15c9bfabba3756fb077797d16fffa27800c05" |
|
26 | $PYTHON27_x64_SHA256 = "b74a3afa1e0bf2a6fc566a7b70d15c9bfabba3756fb077797d16fffa27800c05" | |
27 | $PYTHON27_X86_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.msi" |
|
27 | $PYTHON27_X86_URL = "https://www.python.org/ftp/python/2.7.18/python-2.7.18.msi" | |
28 | $PYTHON27_X86_SHA256 = "d901802e90026e9bad76b8a81f8dd7e43c7d7e8269d9281c9e9df7a9c40480a9" |
|
28 | $PYTHON27_X86_SHA256 = "d901802e90026e9bad76b8a81f8dd7e43c7d7e8269d9281c9e9df7a9c40480a9" | |
29 |
|
29 | |||
30 | $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe" |
|
30 | $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe" | |
31 | $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220" |
|
31 | $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220" | |
32 | $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe" |
|
32 | $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe" | |
33 | $PYTHON37_x64_SHA256 = "e69ed52afb5a722e5c56f6c21d594e85c17cb29f12f18bb69751cf1714e0f987" |
|
33 | $PYTHON37_x64_SHA256 = "e69ed52afb5a722e5c56f6c21d594e85c17cb29f12f18bb69751cf1714e0f987" | |
34 |
|
34 | |||
35 | $PYTHON38_x86_URL = "https://www.python.org/ftp/python/3.8.6/python-3.8.6.exe" |
|
35 | $PYTHON38_x86_URL = "https://www.python.org/ftp/python/3.8.6/python-3.8.6.exe" | |
36 | $PYTHON38_x86_SHA256 = "287d5df01ff22ff09e6a487ae018603ee19eade71d462ec703850c96f1d5e8a0" |
|
36 | $PYTHON38_x86_SHA256 = "287d5df01ff22ff09e6a487ae018603ee19eade71d462ec703850c96f1d5e8a0" | |
37 | $PYTHON38_x64_URL = "https://www.python.org/ftp/python/3.8.6/python-3.8.6-amd64.exe" |
|
37 | $PYTHON38_x64_URL = "https://www.python.org/ftp/python/3.8.6/python-3.8.6-amd64.exe" | |
38 | $PYTHON38_x64_SHA256 = "328a257f189cb500606bb26ab0fbdd298ed0e05d8c36540a322a1744f489a0a0" |
|
38 | $PYTHON38_x64_SHA256 = "328a257f189cb500606bb26ab0fbdd298ed0e05d8c36540a322a1744f489a0a0" | |
39 |
|
39 | |||
40 | $PYTHON39_x86_URL = "https://www.python.org/ftp/python/3.9.0/python-3.9.0.exe" |
|
40 | $PYTHON39_x86_URL = "https://www.python.org/ftp/python/3.9.0/python-3.9.0.exe" | |
41 | $PYTHON39_x86_SHA256 = "a4c65917f4225d1543959342f0615c813a4e9e7ff1137c4394ff6a5290ac1913" |
|
41 | $PYTHON39_x86_SHA256 = "a4c65917f4225d1543959342f0615c813a4e9e7ff1137c4394ff6a5290ac1913" | |
42 | $PYTHON39_x64_URL = "https://www.python.org/ftp/python/3.9.0/python-3.9.0-amd64.exe" |
|
42 | $PYTHON39_x64_URL = "https://www.python.org/ftp/python/3.9.0/python-3.9.0-amd64.exe" | |
43 | $PYTHON39_x64_SHA256 = "fd2e2c6612d43bb6b213b72fc53f07d73d99059fa72c96e44bde12e7815073ae" |
|
43 | $PYTHON39_x64_SHA256 = "fd2e2c6612d43bb6b213b72fc53f07d73d99059fa72c96e44bde12e7815073ae" | |
44 |
|
44 | |||
45 | # PIP 19.2.3. |
|
45 | # PIP 19.2.3. | |
46 | $PIP_URL = "https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py" |
|
46 | $PIP_URL = "https://github.com/pypa/get-pip/raw/309a56c5fd94bd1134053a541cb4657a4e47e09d/get-pip.py" | |
47 | $PIP_SHA256 = "57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe" |
|
47 | $PIP_SHA256 = "57e3643ff19f018f8a00dfaa6b7e4620e3c1a7a2171fd218425366ec006b3bfe" | |
48 |
|
48 | |||
49 | $VIRTUALENV_URL = "https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/virtualenv-16.7.5.tar.gz" |
|
49 | $VIRTUALENV_URL = "https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/virtualenv-16.7.5.tar.gz" | |
50 | $VIRTUALENV_SHA256 = "f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2" |
|
50 | $VIRTUALENV_SHA256 = "f78d81b62d3147396ac33fc9d77579ddc42cc2a98dd9ea38886f616b33bc7fb2" | |
51 |
|
51 | |||
52 | $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe" |
|
52 | $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe" | |
53 | $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538" |
|
53 | $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538" | |
54 |
|
54 | |||
55 | $MINGW_BIN_URL = "https://osdn.net/frs/redir.php?m=constant&f=mingw%2F68260%2Fmingw-get-0.6.3-mingw32-pre-20170905-1-bin.zip" |
|
55 | $MINGW_BIN_URL = "https://osdn.net/frs/redir.php?m=constant&f=mingw%2F68260%2Fmingw-get-0.6.3-mingw32-pre-20170905-1-bin.zip" | |
56 | $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF" |
|
56 | $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF" | |
57 |
|
57 | |||
58 | $MERCURIAL_WHEEL_FILENAME = "mercurial-5.1.2-cp27-cp27m-win_amd64.whl" |
|
58 | $MERCURIAL_WHEEL_FILENAME = "mercurial-5.1.2-cp27-cp27m-win_amd64.whl" | |
59 | $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/6d/47/e031e47f7fe9b16e4e3383da47e2b0a7eae6e603996bc67a03ec4fa1b3f4/$MERCURIAL_WHEEL_FILENAME" |
|
59 | $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/6d/47/e031e47f7fe9b16e4e3383da47e2b0a7eae6e603996bc67a03ec4fa1b3f4/$MERCURIAL_WHEEL_FILENAME" | |
60 | $MERCURIAL_WHEEL_SHA256 = "1d18c7f6ca1456f0f62ee65c9a50c14cbba48ce6e924930cdb10537f5c9eaf5f" |
|
60 | $MERCURIAL_WHEEL_SHA256 = "1d18c7f6ca1456f0f62ee65c9a50c14cbba48ce6e924930cdb10537f5c9eaf5f" | |
61 |
|
61 | |||
62 | $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe" |
|
62 | $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe" | |
63 | $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72" |
|
63 | $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72" | |
64 |
|
64 | |||
65 | # Writing progress slows down downloads substantially. So disable it. |
|
65 | # Writing progress slows down downloads substantially. So disable it. | |
66 | $progressPreference = 'silentlyContinue' |
|
66 | $progressPreference = 'silentlyContinue' | |
67 |
|
67 | |||
68 | function Secure-Download($url, $path, $sha256) { |
|
68 | function Secure-Download($url, $path, $sha256) { | |
69 | if (Test-Path -Path $path) { |
|
69 | if (Test-Path -Path $path) { | |
70 | Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash |
|
70 | Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash | |
71 |
|
71 | |||
72 | if ($hash.Hash -eq $sha256) { |
|
72 | if ($hash.Hash -eq $sha256) { | |
73 | Write-Output "SHA256 of $path verified as $sha256" |
|
73 | Write-Output "SHA256 of $path verified as $sha256" | |
74 | return |
|
74 | return | |
75 | } |
|
75 | } | |
76 |
|
76 | |||
77 | Write-Output "hash mismatch on $path; downloading again" |
|
77 | Write-Output "hash mismatch on $path; downloading again" | |
78 | } |
|
78 | } | |
79 |
|
79 | |||
80 | Write-Output "downloading $url to $path" |
|
80 | Write-Output "downloading $url to $path" | |
81 | Invoke-WebRequest -Uri $url -OutFile $path |
|
81 | Invoke-WebRequest -Uri $url -OutFile $path | |
82 | Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash |
|
82 | Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash | |
83 |
|
83 | |||
84 | if ($hash.Hash -ne $sha256) { |
|
84 | if ($hash.Hash -ne $sha256) { | |
85 | Remove-Item -Path $path |
|
85 | Remove-Item -Path $path | |
86 | throw "hash mismatch when downloading $url; got $($hash.Hash), expected $sha256" |
|
86 | throw "hash mismatch when downloading $url; got $($hash.Hash), expected $sha256" | |
87 | } |
|
87 | } | |
88 | } |
|
88 | } | |
89 |
|
89 | |||
90 | function Invoke-Process($path, $arguments) { |
|
90 | function Invoke-Process($path, $arguments) { | |
91 | $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden |
|
91 | $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden | |
92 |
|
92 | |||
93 | if ($p.ExitCode -ne 0) { |
|
93 | if ($p.ExitCode -ne 0) { | |
94 | throw "process exited non-0: $($p.ExitCode)" |
|
94 | throw "process exited non-0: $($p.ExitCode)" | |
95 | } |
|
95 | } | |
96 | } |
|
96 | } | |
97 |
|
97 | |||
98 | function Install-Python3($name, $installer, $dest, $pip) { |
|
98 | function Install-Python3($name, $installer, $dest, $pip) { | |
99 | Write-Output "installing $name" |
|
99 | Write-Output "installing $name" | |
100 |
|
100 | |||
101 | # We hit this when running the script as part of Simple Systems Manager in |
|
101 | # We hit this when running the script as part of Simple Systems Manager in | |
102 | # EC2. The Python 3 installer doesn't seem to like per-user installs |
|
102 | # EC2. The Python 3 installer doesn't seem to like per-user installs | |
103 | # when running as the SYSTEM user. So enable global installs if executed in |
|
103 | # when running as the SYSTEM user. So enable global installs if executed in | |
104 | # this mode. |
|
104 | # this mode. | |
105 | if ($env:USERPROFILE -eq "C:\Windows\system32\config\systemprofile") { |
|
105 | if ($env:USERPROFILE -eq "C:\Windows\system32\config\systemprofile") { | |
106 | Write-Output "running with SYSTEM account; installing for all users" |
|
106 | Write-Output "running with SYSTEM account; installing for all users" | |
107 | $allusers = "1" |
|
107 | $allusers = "1" | |
108 | } |
|
108 | } | |
109 | else { |
|
109 | else { | |
110 | $allusers = "0" |
|
110 | $allusers = "0" | |
111 | } |
|
111 | } | |
112 |
|
112 | |||
113 | Invoke-Process $installer "/quiet TargetDir=${dest} InstallAllUsers=${allusers} AssociateFiles=0 CompileAll=0 PrependPath=0 Include_doc=0 Include_launcher=0 InstallLauncherAllUsers=0 Include_pip=0 Include_test=0" |
|
113 | Invoke-Process $installer "/quiet TargetDir=${dest} InstallAllUsers=${allusers} AssociateFiles=0 CompileAll=0 PrependPath=0 Include_doc=0 Include_launcher=0 InstallLauncherAllUsers=0 Include_pip=0 Include_test=0" | |
114 | Invoke-Process ${dest}\python.exe $pip |
|
114 | Invoke-Process ${dest}\python.exe $pip | |
115 | } |
|
115 | } | |
116 |
|
116 | |||
117 | function Install-Rust($prefix) { |
|
117 | function Install-Rust($prefix) { | |
118 | Write-Output "installing Rust" |
|
118 | Write-Output "installing Rust" | |
119 | $Env:RUSTUP_HOME = "${prefix}\rustup" |
|
119 | $Env:RUSTUP_HOME = "${prefix}\rustup" | |
120 | $Env:CARGO_HOME = "${prefix}\cargo" |
|
120 | $Env:CARGO_HOME = "${prefix}\cargo" | |
121 |
|
121 | |||
122 | Invoke-Process "${prefix}\assets\rustup-init.exe" "-y --default-host x86_64-pc-windows-msvc" |
|
122 | Invoke-Process "${prefix}\assets\rustup-init.exe" "-y --default-host x86_64-pc-windows-msvc" | |
123 | Invoke-Process "${prefix}\cargo\bin\rustup.exe" "target add i686-pc-windows-msvc" |
|
123 | Invoke-Process "${prefix}\cargo\bin\rustup.exe" "target add i686-pc-windows-msvc" | |
124 | Invoke-Process "${prefix}\cargo\bin\rustup.exe" "install 1.46.0" |
|
124 | Invoke-Process "${prefix}\cargo\bin\rustup.exe" "install 1.46.0" | |
125 | Invoke-Process "${prefix}\cargo\bin\rustup.exe" "component add clippy" |
|
125 | Invoke-Process "${prefix}\cargo\bin\rustup.exe" "component add clippy" | |
126 |
|
126 | |||
127 | # Install PyOxidizer for packaging. |
|
127 | # Install PyOxidizer for packaging. | |
128 |
Invoke-Process "${prefix}\cargo\bin\cargo.exe" "install -- |
|
128 | Invoke-Process "${prefix}\cargo\bin\cargo.exe" "install --version 0.9.0 pyoxidizer" | |
129 | } |
|
129 | } | |
130 |
|
130 | |||
131 | function Install-Dependencies($prefix) { |
|
131 | function Install-Dependencies($prefix) { | |
132 | if (!(Test-Path -Path $prefix\assets)) { |
|
132 | if (!(Test-Path -Path $prefix\assets)) { | |
133 | New-Item -Path $prefix\assets -ItemType Directory |
|
133 | New-Item -Path $prefix\assets -ItemType Directory | |
134 | } |
|
134 | } | |
135 |
|
135 | |||
136 | $pip = "${prefix}\assets\get-pip.py" |
|
136 | $pip = "${prefix}\assets\get-pip.py" | |
137 |
|
137 | |||
138 | Secure-Download $VC9_PYTHON_URL ${prefix}\assets\VCForPython27.msi $VC9_PYTHON_SHA256 |
|
138 | Secure-Download $VC9_PYTHON_URL ${prefix}\assets\VCForPython27.msi $VC9_PYTHON_SHA256 | |
139 | Secure-Download $PYTHON27_x86_URL ${prefix}\assets\python27-x86.msi $PYTHON27_x86_SHA256 |
|
139 | Secure-Download $PYTHON27_x86_URL ${prefix}\assets\python27-x86.msi $PYTHON27_x86_SHA256 | |
140 | Secure-Download $PYTHON27_x64_URL ${prefix}\assets\python27-x64.msi $PYTHON27_x64_SHA256 |
|
140 | Secure-Download $PYTHON27_x64_URL ${prefix}\assets\python27-x64.msi $PYTHON27_x64_SHA256 | |
141 | Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256 |
|
141 | Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256 | |
142 | Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256 |
|
142 | Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256 | |
143 | Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256 |
|
143 | Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256 | |
144 | Secure-Download $PYTHON38_x64_URL ${prefix}\assets\python38-x64.exe $PYTHON38_x64_SHA256 |
|
144 | Secure-Download $PYTHON38_x64_URL ${prefix}\assets\python38-x64.exe $PYTHON38_x64_SHA256 | |
145 | Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256 |
|
145 | Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256 | |
146 | Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256 |
|
146 | Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256 | |
147 | Secure-Download $PIP_URL ${pip} $PIP_SHA256 |
|
147 | Secure-Download $PIP_URL ${pip} $PIP_SHA256 | |
148 | Secure-Download $VIRTUALENV_URL ${prefix}\assets\virtualenv.tar.gz $VIRTUALENV_SHA256 |
|
148 | Secure-Download $VIRTUALENV_URL ${prefix}\assets\virtualenv.tar.gz $VIRTUALENV_SHA256 | |
149 | Secure-Download $VS_BUILD_TOOLS_URL ${prefix}\assets\vs_buildtools.exe $VS_BUILD_TOOLS_SHA256 |
|
149 | Secure-Download $VS_BUILD_TOOLS_URL ${prefix}\assets\vs_buildtools.exe $VS_BUILD_TOOLS_SHA256 | |
150 | Secure-Download $INNO_SETUP_URL ${prefix}\assets\InnoSetup.exe $INNO_SETUP_SHA256 |
|
150 | Secure-Download $INNO_SETUP_URL ${prefix}\assets\InnoSetup.exe $INNO_SETUP_SHA256 | |
151 | Secure-Download $MINGW_BIN_URL ${prefix}\assets\mingw-get-bin.zip $MINGW_BIN_SHA256 |
|
151 | Secure-Download $MINGW_BIN_URL ${prefix}\assets\mingw-get-bin.zip $MINGW_BIN_SHA256 | |
152 | Secure-Download $MERCURIAL_WHEEL_URL ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME} $MERCURIAL_WHEEL_SHA256 |
|
152 | Secure-Download $MERCURIAL_WHEEL_URL ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME} $MERCURIAL_WHEEL_SHA256 | |
153 | Secure-Download $RUSTUP_INIT_URL ${prefix}\assets\rustup-init.exe $RUSTUP_INIT_SHA256 |
|
153 | Secure-Download $RUSTUP_INIT_URL ${prefix}\assets\rustup-init.exe $RUSTUP_INIT_SHA256 | |
154 |
|
154 | |||
155 | Write-Output "installing Python 2.7 32-bit" |
|
155 | Write-Output "installing Python 2.7 32-bit" | |
156 | Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x86.msi /l* ${prefix}\assets\python27-x86.log /q TARGETDIR=${prefix}\python27-x86 ALLUSERS=" |
|
156 | Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x86.msi /l* ${prefix}\assets\python27-x86.log /q TARGETDIR=${prefix}\python27-x86 ALLUSERS=" | |
157 | Invoke-Process ${prefix}\python27-x86\python.exe ${prefix}\assets\get-pip.py |
|
157 | Invoke-Process ${prefix}\python27-x86\python.exe ${prefix}\assets\get-pip.py | |
158 | Invoke-Process ${prefix}\python27-x86\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz" |
|
158 | Invoke-Process ${prefix}\python27-x86\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz" | |
159 |
|
159 | |||
160 | Write-Output "installing Python 2.7 64-bit" |
|
160 | Write-Output "installing Python 2.7 64-bit" | |
161 | Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x64.msi /l* ${prefix}\assets\python27-x64.log /q TARGETDIR=${prefix}\python27-x64 ALLUSERS=" |
|
161 | Invoke-Process msiexec.exe "/i ${prefix}\assets\python27-x64.msi /l* ${prefix}\assets\python27-x64.log /q TARGETDIR=${prefix}\python27-x64 ALLUSERS=" | |
162 | Invoke-Process ${prefix}\python27-x64\python.exe ${prefix}\assets\get-pip.py |
|
162 | Invoke-Process ${prefix}\python27-x64\python.exe ${prefix}\assets\get-pip.py | |
163 | Invoke-Process ${prefix}\python27-x64\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz" |
|
163 | Invoke-Process ${prefix}\python27-x64\Scripts\pip.exe "install ${prefix}\assets\virtualenv.tar.gz" | |
164 |
|
164 | |||
165 | Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip} |
|
165 | Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip} | |
166 | Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip} |
|
166 | Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip} | |
167 | Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip} |
|
167 | Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip} | |
168 | Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip} |
|
168 | Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip} | |
169 | Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip} |
|
169 | Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip} | |
170 | Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip} |
|
170 | Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip} | |
171 |
|
171 | |||
172 | Write-Output "installing Visual Studio 2017 Build Tools and SDKs" |
|
172 | Write-Output "installing Visual Studio 2017 Build Tools and SDKs" | |
173 | Invoke-Process ${prefix}\assets\vs_buildtools.exe "--quiet --wait --norestart --nocache --channelUri https://aka.ms/vs/15/release/channel --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.Windows10SDK.17763 --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.Windows10SDK --add Microsoft.VisualStudio.Component.VC.140" |
|
173 | Invoke-Process ${prefix}\assets\vs_buildtools.exe "--quiet --wait --norestart --nocache --channelUri https://aka.ms/vs/15/release/channel --add Microsoft.VisualStudio.Workload.MSBuildTools --add Microsoft.VisualStudio.Component.Windows10SDK.17763 --add Microsoft.VisualStudio.Workload.VCTools --add Microsoft.VisualStudio.Component.Windows10SDK --add Microsoft.VisualStudio.Component.VC.140" | |
174 |
|
174 | |||
175 | Install-Rust ${prefix} |
|
175 | Install-Rust ${prefix} | |
176 |
|
176 | |||
177 | Write-Output "installing Visual C++ 9.0 for Python 2.7" |
|
177 | Write-Output "installing Visual C++ 9.0 for Python 2.7" | |
178 | Invoke-Process msiexec.exe "/i ${prefix}\assets\VCForPython27.msi /l* ${prefix}\assets\VCForPython27.log /q" |
|
178 | Invoke-Process msiexec.exe "/i ${prefix}\assets\VCForPython27.msi /l* ${prefix}\assets\VCForPython27.log /q" | |
179 |
|
179 | |||
180 | Write-Output "installing Inno Setup" |
|
180 | Write-Output "installing Inno Setup" | |
181 | Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES" |
|
181 | Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES" | |
182 |
|
182 | |||
183 | Write-Output "extracting MinGW base archive" |
|
183 | Write-Output "extracting MinGW base archive" | |
184 | Expand-Archive -Path ${prefix}\assets\mingw-get-bin.zip -DestinationPath "${prefix}\MinGW" -Force |
|
184 | Expand-Archive -Path ${prefix}\assets\mingw-get-bin.zip -DestinationPath "${prefix}\MinGW" -Force | |
185 |
|
185 | |||
186 | Write-Output "updating MinGW package catalogs" |
|
186 | Write-Output "updating MinGW package catalogs" | |
187 | Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "update" |
|
187 | Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "update" | |
188 |
|
188 | |||
189 | Write-Output "installing MinGW packages" |
|
189 | Write-Output "installing MinGW packages" | |
190 | Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "install msys-base msys-coreutils msys-diffutils msys-unzip" |
|
190 | Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "install msys-base msys-coreutils msys-diffutils msys-unzip" | |
191 |
|
191 | |||
192 | # Construct a virtualenv useful for bootstrapping. It conveniently contains a |
|
192 | # Construct a virtualenv useful for bootstrapping. It conveniently contains a | |
193 | # Mercurial install. |
|
193 | # Mercurial install. | |
194 | Write-Output "creating bootstrap virtualenv with Mercurial" |
|
194 | Write-Output "creating bootstrap virtualenv with Mercurial" | |
195 | Invoke-Process "$prefix\python27-x64\Scripts\virtualenv.exe" "${prefix}\venv-bootstrap" |
|
195 | Invoke-Process "$prefix\python27-x64\Scripts\virtualenv.exe" "${prefix}\venv-bootstrap" | |
196 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}" |
|
196 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}" | |
197 | } |
|
197 | } | |
198 |
|
198 | |||
199 | function Clone-Mercurial-Repo($prefix, $repo_url, $dest) { |
|
199 | function Clone-Mercurial-Repo($prefix, $repo_url, $dest) { | |
200 | Write-Output "cloning $repo_url to $dest" |
|
200 | Write-Output "cloning $repo_url to $dest" | |
201 | # TODO Figure out why CA verification isn't working in EC2 and remove |
|
201 | # TODO Figure out why CA verification isn't working in EC2 and remove | |
202 | # --insecure. |
|
202 | # --insecure. | |
203 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\hg.exe" "clone --insecure $repo_url $dest" |
|
203 | Invoke-Process "${prefix}\venv-bootstrap\Scripts\hg.exe" "clone --insecure $repo_url $dest" | |
204 |
|
204 | |||
205 | # Mark repo as non-publishing by default for convenience. |
|
205 | # Mark repo as non-publishing by default for convenience. | |
206 | Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false" |
|
206 | Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false" | |
207 | } |
|
207 | } | |
208 |
|
208 | |||
209 | $prefix = "c:\hgdev" |
|
209 | $prefix = "c:\hgdev" | |
210 | Install-Dependencies $prefix |
|
210 | Install-Dependencies $prefix | |
211 | Clone-Mercurial-Repo $prefix "https://www.mercurial-scm.org/repo/hg" $prefix\src |
|
211 | Clone-Mercurial-Repo $prefix "https://www.mercurial-scm.org/repo/hg" $prefix\src |
@@ -1,232 +1,232 b'' | |||||
1 | # inno.py - Inno Setup functionality. |
|
1 | # inno.py - Inno Setup functionality. | |
2 | # |
|
2 | # | |
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> |
|
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | # no-check-code because Python 3 native. |
|
8 | # no-check-code because Python 3 native. | |
9 |
|
9 | |||
10 | import os |
|
10 | import os | |
11 | import pathlib |
|
11 | import pathlib | |
12 | import shutil |
|
12 | import shutil | |
13 | import subprocess |
|
13 | import subprocess | |
14 |
|
14 | |||
15 | import jinja2 |
|
15 | import jinja2 | |
16 |
|
16 | |||
17 | from .py2exe import ( |
|
17 | from .py2exe import ( | |
18 | build_py2exe, |
|
18 | build_py2exe, | |
19 | stage_install, |
|
19 | stage_install, | |
20 | ) |
|
20 | ) | |
21 | from .pyoxidizer import run_pyoxidizer |
|
21 | from .pyoxidizer import run_pyoxidizer | |
22 | from .util import ( |
|
22 | from .util import ( | |
23 | find_legacy_vc_runtime_files, |
|
23 | find_legacy_vc_runtime_files, | |
24 | normalize_windows_version, |
|
24 | normalize_windows_version, | |
25 | process_install_rules, |
|
25 | process_install_rules, | |
26 | read_version_py, |
|
26 | read_version_py, | |
27 | ) |
|
27 | ) | |
28 |
|
28 | |||
29 | EXTRA_PACKAGES = { |
|
29 | EXTRA_PACKAGES = { | |
30 | 'dulwich', |
|
30 | 'dulwich', | |
31 | 'keyring', |
|
31 | 'keyring', | |
32 | 'pygments', |
|
32 | 'pygments', | |
33 | 'win32ctypes', |
|
33 | 'win32ctypes', | |
34 | } |
|
34 | } | |
35 |
|
35 | |||
36 | EXTRA_INSTALL_RULES = [ |
|
36 | EXTRA_INSTALL_RULES = [ | |
37 | ('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'), |
|
37 | ('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'), | |
38 | ] |
|
38 | ] | |
39 |
|
39 | |||
40 | PACKAGE_FILES_METADATA = { |
|
40 | PACKAGE_FILES_METADATA = { | |
41 | 'ReadMe.html': 'Flags: isreadme', |
|
41 | 'ReadMe.html': 'Flags: isreadme', | |
42 | } |
|
42 | } | |
43 |
|
43 | |||
44 |
|
44 | |||
45 | def build_with_py2exe( |
|
45 | def build_with_py2exe( | |
46 | source_dir: pathlib.Path, |
|
46 | source_dir: pathlib.Path, | |
47 | build_dir: pathlib.Path, |
|
47 | build_dir: pathlib.Path, | |
48 | python_exe: pathlib.Path, |
|
48 | python_exe: pathlib.Path, | |
49 | iscc_exe: pathlib.Path, |
|
49 | iscc_exe: pathlib.Path, | |
50 | version=None, |
|
50 | version=None, | |
51 | ): |
|
51 | ): | |
52 | """Build the Inno installer using py2exe. |
|
52 | """Build the Inno installer using py2exe. | |
53 |
|
53 | |||
54 | Build files will be placed in ``build_dir``. |
|
54 | Build files will be placed in ``build_dir``. | |
55 |
|
55 | |||
56 | py2exe's setup.py doesn't use setuptools. It doesn't have modern logic |
|
56 | py2exe's setup.py doesn't use setuptools. It doesn't have modern logic | |
57 | for finding the Python 2.7 toolchain. So, we require the environment |
|
57 | for finding the Python 2.7 toolchain. So, we require the environment | |
58 | to already be configured with an active toolchain. |
|
58 | to already be configured with an active toolchain. | |
59 | """ |
|
59 | """ | |
60 | if not iscc_exe.exists(): |
|
60 | if not iscc_exe.exists(): | |
61 | raise Exception('%s does not exist' % iscc_exe) |
|
61 | raise Exception('%s does not exist' % iscc_exe) | |
62 |
|
62 | |||
63 | vc_x64 = r'\x64' in os.environ.get('LIB', '') |
|
63 | vc_x64 = r'\x64' in os.environ.get('LIB', '') | |
64 | arch = 'x64' if vc_x64 else 'x86' |
|
64 | arch = 'x64' if vc_x64 else 'x86' | |
65 | inno_build_dir = build_dir / ('inno-py2exe-%s' % arch) |
|
65 | inno_build_dir = build_dir / ('inno-py2exe-%s' % arch) | |
66 | staging_dir = inno_build_dir / 'stage' |
|
66 | staging_dir = inno_build_dir / 'stage' | |
67 |
|
67 | |||
68 | requirements_txt = ( |
|
68 | requirements_txt = ( | |
69 |
source_dir / 'contrib' / 'packaging' / 'requirements |
|
69 | source_dir / 'contrib' / 'packaging' / 'requirements-windows-py2.txt' | |
70 | ) |
|
70 | ) | |
71 |
|
71 | |||
72 | inno_build_dir.mkdir(parents=True, exist_ok=True) |
|
72 | inno_build_dir.mkdir(parents=True, exist_ok=True) | |
73 |
|
73 | |||
74 | build_py2exe( |
|
74 | build_py2exe( | |
75 | source_dir, |
|
75 | source_dir, | |
76 | build_dir, |
|
76 | build_dir, | |
77 | python_exe, |
|
77 | python_exe, | |
78 | 'inno', |
|
78 | 'inno', | |
79 | requirements_txt, |
|
79 | requirements_txt, | |
80 | extra_packages=EXTRA_PACKAGES, |
|
80 | extra_packages=EXTRA_PACKAGES, | |
81 | ) |
|
81 | ) | |
82 |
|
82 | |||
83 | # Purge the staging directory for every build so packaging is |
|
83 | # Purge the staging directory for every build so packaging is | |
84 | # pristine. |
|
84 | # pristine. | |
85 | if staging_dir.exists(): |
|
85 | if staging_dir.exists(): | |
86 | print('purging %s' % staging_dir) |
|
86 | print('purging %s' % staging_dir) | |
87 | shutil.rmtree(staging_dir) |
|
87 | shutil.rmtree(staging_dir) | |
88 |
|
88 | |||
89 | # Now assemble all the packaged files into the staging directory. |
|
89 | # Now assemble all the packaged files into the staging directory. | |
90 | stage_install(source_dir, staging_dir) |
|
90 | stage_install(source_dir, staging_dir) | |
91 |
|
91 | |||
92 | # We also install some extra files. |
|
92 | # We also install some extra files. | |
93 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) |
|
93 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) | |
94 |
|
94 | |||
95 | # hg.exe depends on VC9 runtime DLLs. Copy those into place. |
|
95 | # hg.exe depends on VC9 runtime DLLs. Copy those into place. | |
96 | for f in find_legacy_vc_runtime_files(vc_x64): |
|
96 | for f in find_legacy_vc_runtime_files(vc_x64): | |
97 | if f.name.endswith('.manifest'): |
|
97 | if f.name.endswith('.manifest'): | |
98 | basename = 'Microsoft.VC90.CRT.manifest' |
|
98 | basename = 'Microsoft.VC90.CRT.manifest' | |
99 | else: |
|
99 | else: | |
100 | basename = f.name |
|
100 | basename = f.name | |
101 |
|
101 | |||
102 | dest_path = staging_dir / basename |
|
102 | dest_path = staging_dir / basename | |
103 |
|
103 | |||
104 | print('copying %s to %s' % (f, dest_path)) |
|
104 | print('copying %s to %s' % (f, dest_path)) | |
105 | shutil.copyfile(f, dest_path) |
|
105 | shutil.copyfile(f, dest_path) | |
106 |
|
106 | |||
107 | build_installer( |
|
107 | build_installer( | |
108 | source_dir, |
|
108 | source_dir, | |
109 | inno_build_dir, |
|
109 | inno_build_dir, | |
110 | staging_dir, |
|
110 | staging_dir, | |
111 | iscc_exe, |
|
111 | iscc_exe, | |
112 | version, |
|
112 | version, | |
113 | arch="x64" if vc_x64 else None, |
|
113 | arch="x64" if vc_x64 else None, | |
114 | suffix="-python2", |
|
114 | suffix="-python2", | |
115 | ) |
|
115 | ) | |
116 |
|
116 | |||
117 |
|
117 | |||
118 | def build_with_pyoxidizer( |
|
118 | def build_with_pyoxidizer( | |
119 | source_dir: pathlib.Path, |
|
119 | source_dir: pathlib.Path, | |
120 | build_dir: pathlib.Path, |
|
120 | build_dir: pathlib.Path, | |
121 | target_triple: str, |
|
121 | target_triple: str, | |
122 | iscc_exe: pathlib.Path, |
|
122 | iscc_exe: pathlib.Path, | |
123 | version=None, |
|
123 | version=None, | |
124 | ): |
|
124 | ): | |
125 | """Build the Inno installer using PyOxidizer.""" |
|
125 | """Build the Inno installer using PyOxidizer.""" | |
126 | if not iscc_exe.exists(): |
|
126 | if not iscc_exe.exists(): | |
127 | raise Exception("%s does not exist" % iscc_exe) |
|
127 | raise Exception("%s does not exist" % iscc_exe) | |
128 |
|
128 | |||
129 | inno_build_dir = build_dir / ("inno-pyoxidizer-%s" % target_triple) |
|
129 | inno_build_dir = build_dir / ("inno-pyoxidizer-%s" % target_triple) | |
130 | staging_dir = inno_build_dir / "stage" |
|
130 | staging_dir = inno_build_dir / "stage" | |
131 |
|
131 | |||
132 | inno_build_dir.mkdir(parents=True, exist_ok=True) |
|
132 | inno_build_dir.mkdir(parents=True, exist_ok=True) | |
133 | run_pyoxidizer(source_dir, inno_build_dir, staging_dir, target_triple) |
|
133 | run_pyoxidizer(source_dir, inno_build_dir, staging_dir, target_triple) | |
134 |
|
134 | |||
135 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) |
|
135 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) | |
136 |
|
136 | |||
137 | build_installer( |
|
137 | build_installer( | |
138 | source_dir, |
|
138 | source_dir, | |
139 | inno_build_dir, |
|
139 | inno_build_dir, | |
140 | staging_dir, |
|
140 | staging_dir, | |
141 | iscc_exe, |
|
141 | iscc_exe, | |
142 | version, |
|
142 | version, | |
143 | arch="x64" if "x86_64" in target_triple else None, |
|
143 | arch="x64" if "x86_64" in target_triple else None, | |
144 | ) |
|
144 | ) | |
145 |
|
145 | |||
146 |
|
146 | |||
147 | def build_installer( |
|
147 | def build_installer( | |
148 | source_dir: pathlib.Path, |
|
148 | source_dir: pathlib.Path, | |
149 | inno_build_dir: pathlib.Path, |
|
149 | inno_build_dir: pathlib.Path, | |
150 | staging_dir: pathlib.Path, |
|
150 | staging_dir: pathlib.Path, | |
151 | iscc_exe: pathlib.Path, |
|
151 | iscc_exe: pathlib.Path, | |
152 | version, |
|
152 | version, | |
153 | arch=None, |
|
153 | arch=None, | |
154 | suffix="", |
|
154 | suffix="", | |
155 | ): |
|
155 | ): | |
156 | """Build an Inno installer from staged Mercurial files. |
|
156 | """Build an Inno installer from staged Mercurial files. | |
157 |
|
157 | |||
158 | This function is agnostic about how to build Mercurial. It just |
|
158 | This function is agnostic about how to build Mercurial. It just | |
159 | cares that Mercurial files are in ``staging_dir``. |
|
159 | cares that Mercurial files are in ``staging_dir``. | |
160 | """ |
|
160 | """ | |
161 | inno_source_dir = source_dir / "contrib" / "packaging" / "inno" |
|
161 | inno_source_dir = source_dir / "contrib" / "packaging" / "inno" | |
162 |
|
162 | |||
163 | # The final package layout is simply a mirror of the staging directory. |
|
163 | # The final package layout is simply a mirror of the staging directory. | |
164 | package_files = [] |
|
164 | package_files = [] | |
165 | for root, dirs, files in os.walk(staging_dir): |
|
165 | for root, dirs, files in os.walk(staging_dir): | |
166 | dirs.sort() |
|
166 | dirs.sort() | |
167 |
|
167 | |||
168 | root = pathlib.Path(root) |
|
168 | root = pathlib.Path(root) | |
169 |
|
169 | |||
170 | for f in sorted(files): |
|
170 | for f in sorted(files): | |
171 | full = root / f |
|
171 | full = root / f | |
172 | rel = full.relative_to(staging_dir) |
|
172 | rel = full.relative_to(staging_dir) | |
173 | if str(rel.parent) == '.': |
|
173 | if str(rel.parent) == '.': | |
174 | dest_dir = '{app}' |
|
174 | dest_dir = '{app}' | |
175 | else: |
|
175 | else: | |
176 | dest_dir = '{app}\\%s' % rel.parent |
|
176 | dest_dir = '{app}\\%s' % rel.parent | |
177 |
|
177 | |||
178 | package_files.append( |
|
178 | package_files.append( | |
179 | { |
|
179 | { | |
180 | 'source': rel, |
|
180 | 'source': rel, | |
181 | 'dest_dir': dest_dir, |
|
181 | 'dest_dir': dest_dir, | |
182 | 'metadata': PACKAGE_FILES_METADATA.get(str(rel), None), |
|
182 | 'metadata': PACKAGE_FILES_METADATA.get(str(rel), None), | |
183 | } |
|
183 | } | |
184 | ) |
|
184 | ) | |
185 |
|
185 | |||
186 | print('creating installer') |
|
186 | print('creating installer') | |
187 |
|
187 | |||
188 | # Install Inno files by rendering a template. |
|
188 | # Install Inno files by rendering a template. | |
189 | jinja_env = jinja2.Environment( |
|
189 | jinja_env = jinja2.Environment( | |
190 | loader=jinja2.FileSystemLoader(str(inno_source_dir)), |
|
190 | loader=jinja2.FileSystemLoader(str(inno_source_dir)), | |
191 | # Need to change these to prevent conflict with Inno Setup. |
|
191 | # Need to change these to prevent conflict with Inno Setup. | |
192 | comment_start_string='{##', |
|
192 | comment_start_string='{##', | |
193 | comment_end_string='##}', |
|
193 | comment_end_string='##}', | |
194 | ) |
|
194 | ) | |
195 |
|
195 | |||
196 | try: |
|
196 | try: | |
197 | template = jinja_env.get_template('mercurial.iss') |
|
197 | template = jinja_env.get_template('mercurial.iss') | |
198 | except jinja2.TemplateSyntaxError as e: |
|
198 | except jinja2.TemplateSyntaxError as e: | |
199 | raise Exception( |
|
199 | raise Exception( | |
200 | 'template syntax error at %s:%d: %s' |
|
200 | 'template syntax error at %s:%d: %s' | |
201 | % (e.name, e.lineno, e.message,) |
|
201 | % (e.name, e.lineno, e.message,) | |
202 | ) |
|
202 | ) | |
203 |
|
203 | |||
204 | content = template.render(package_files=package_files) |
|
204 | content = template.render(package_files=package_files) | |
205 |
|
205 | |||
206 | with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh: |
|
206 | with (inno_build_dir / 'mercurial.iss').open('w', encoding='utf-8') as fh: | |
207 | fh.write(content) |
|
207 | fh.write(content) | |
208 |
|
208 | |||
209 | # Copy additional files used by Inno. |
|
209 | # Copy additional files used by Inno. | |
210 | for p in ('mercurial.ico', 'postinstall.txt'): |
|
210 | for p in ('mercurial.ico', 'postinstall.txt'): | |
211 | shutil.copyfile( |
|
211 | shutil.copyfile( | |
212 | source_dir / 'contrib' / 'win32' / p, inno_build_dir / p |
|
212 | source_dir / 'contrib' / 'win32' / p, inno_build_dir / p | |
213 | ) |
|
213 | ) | |
214 |
|
214 | |||
215 | args = [str(iscc_exe)] |
|
215 | args = [str(iscc_exe)] | |
216 |
|
216 | |||
217 | if arch: |
|
217 | if arch: | |
218 | args.append('/dARCH=%s' % arch) |
|
218 | args.append('/dARCH=%s' % arch) | |
219 | args.append('/dSUFFIX=-%s%s' % (arch, suffix)) |
|
219 | args.append('/dSUFFIX=-%s%s' % (arch, suffix)) | |
220 | else: |
|
220 | else: | |
221 | args.append('/dSUFFIX=-x86%s' % suffix) |
|
221 | args.append('/dSUFFIX=-x86%s' % suffix) | |
222 |
|
222 | |||
223 | if not version: |
|
223 | if not version: | |
224 | version = read_version_py(source_dir) |
|
224 | version = read_version_py(source_dir) | |
225 |
|
225 | |||
226 | args.append('/dVERSION=%s' % version) |
|
226 | args.append('/dVERSION=%s' % version) | |
227 | args.append('/dQUAD_VERSION=%s' % normalize_windows_version(version)) |
|
227 | args.append('/dQUAD_VERSION=%s' % normalize_windows_version(version)) | |
228 |
|
228 | |||
229 | args.append('/Odist') |
|
229 | args.append('/Odist') | |
230 | args.append(str(inno_build_dir / 'mercurial.iss')) |
|
230 | args.append(str(inno_build_dir / 'mercurial.iss')) | |
231 |
|
231 | |||
232 | subprocess.run(args, cwd=str(source_dir), check=True) |
|
232 | subprocess.run(args, cwd=str(source_dir), check=True) |
@@ -1,539 +1,539 b'' | |||||
1 | # wix.py - WiX installer functionality |
|
1 | # wix.py - WiX installer functionality | |
2 | # |
|
2 | # | |
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> |
|
3 | # Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | # no-check-code because Python 3 native. |
|
8 | # no-check-code because Python 3 native. | |
9 |
|
9 | |||
10 | import collections |
|
10 | import collections | |
11 | import os |
|
11 | import os | |
12 | import pathlib |
|
12 | import pathlib | |
13 | import re |
|
13 | import re | |
14 | import shutil |
|
14 | import shutil | |
15 | import subprocess |
|
15 | import subprocess | |
16 | import typing |
|
16 | import typing | |
17 | import uuid |
|
17 | import uuid | |
18 | import xml.dom.minidom |
|
18 | import xml.dom.minidom | |
19 |
|
19 | |||
20 | from .downloads import download_entry |
|
20 | from .downloads import download_entry | |
21 | from .py2exe import ( |
|
21 | from .py2exe import ( | |
22 | build_py2exe, |
|
22 | build_py2exe, | |
23 | stage_install, |
|
23 | stage_install, | |
24 | ) |
|
24 | ) | |
25 | from .pyoxidizer import run_pyoxidizer |
|
25 | from .pyoxidizer import run_pyoxidizer | |
26 | from .util import ( |
|
26 | from .util import ( | |
27 | extract_zip_to_directory, |
|
27 | extract_zip_to_directory, | |
28 | normalize_windows_version, |
|
28 | normalize_windows_version, | |
29 | process_install_rules, |
|
29 | process_install_rules, | |
30 | sign_with_signtool, |
|
30 | sign_with_signtool, | |
31 | ) |
|
31 | ) | |
32 |
|
32 | |||
33 |
|
33 | |||
34 | EXTRA_PACKAGES = { |
|
34 | EXTRA_PACKAGES = { | |
35 | 'dulwich', |
|
35 | 'dulwich', | |
36 | 'distutils', |
|
36 | 'distutils', | |
37 | 'keyring', |
|
37 | 'keyring', | |
38 | 'pygments', |
|
38 | 'pygments', | |
39 | 'win32ctypes', |
|
39 | 'win32ctypes', | |
40 | } |
|
40 | } | |
41 |
|
41 | |||
42 |
|
42 | |||
43 | EXTRA_INSTALL_RULES = [ |
|
43 | EXTRA_INSTALL_RULES = [ | |
44 | ('contrib/packaging/wix/COPYING.rtf', 'COPYING.rtf'), |
|
44 | ('contrib/packaging/wix/COPYING.rtf', 'COPYING.rtf'), | |
45 | ('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'), |
|
45 | ('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'), | |
46 | ] |
|
46 | ] | |
47 |
|
47 | |||
48 | STAGING_REMOVE_FILES = [ |
|
48 | STAGING_REMOVE_FILES = [ | |
49 | # We use the RTF variant. |
|
49 | # We use the RTF variant. | |
50 | 'copying.txt', |
|
50 | 'copying.txt', | |
51 | ] |
|
51 | ] | |
52 |
|
52 | |||
53 | SHORTCUTS = { |
|
53 | SHORTCUTS = { | |
54 | # hg.1.html' |
|
54 | # hg.1.html' | |
55 | 'hg.file.5d3e441c_28d9_5542_afd0_cdd4234f12d5': { |
|
55 | 'hg.file.5d3e441c_28d9_5542_afd0_cdd4234f12d5': { | |
56 | 'Name': 'Mercurial Command Reference', |
|
56 | 'Name': 'Mercurial Command Reference', | |
57 | }, |
|
57 | }, | |
58 | # hgignore.5.html |
|
58 | # hgignore.5.html | |
59 | 'hg.file.5757d8e0_f207_5e10_a2ec_3ba0a062f431': { |
|
59 | 'hg.file.5757d8e0_f207_5e10_a2ec_3ba0a062f431': { | |
60 | 'Name': 'Mercurial Ignore Files', |
|
60 | 'Name': 'Mercurial Ignore Files', | |
61 | }, |
|
61 | }, | |
62 | # hgrc.5.html |
|
62 | # hgrc.5.html | |
63 | 'hg.file.92e605fd_1d1a_5dc6_9fc0_5d2998eb8f5e': { |
|
63 | 'hg.file.92e605fd_1d1a_5dc6_9fc0_5d2998eb8f5e': { | |
64 | 'Name': 'Mercurial Configuration Files', |
|
64 | 'Name': 'Mercurial Configuration Files', | |
65 | }, |
|
65 | }, | |
66 | } |
|
66 | } | |
67 |
|
67 | |||
68 |
|
68 | |||
69 | def find_version(source_dir: pathlib.Path): |
|
69 | def find_version(source_dir: pathlib.Path): | |
70 | version_py = source_dir / 'mercurial' / '__version__.py' |
|
70 | version_py = source_dir / 'mercurial' / '__version__.py' | |
71 |
|
71 | |||
72 | with version_py.open('r', encoding='utf-8') as fh: |
|
72 | with version_py.open('r', encoding='utf-8') as fh: | |
73 | source = fh.read().strip() |
|
73 | source = fh.read().strip() | |
74 |
|
74 | |||
75 | m = re.search('version = b"(.*)"', source) |
|
75 | m = re.search('version = b"(.*)"', source) | |
76 | return m.group(1) |
|
76 | return m.group(1) | |
77 |
|
77 | |||
78 |
|
78 | |||
79 | def ensure_vc90_merge_modules(build_dir): |
|
79 | def ensure_vc90_merge_modules(build_dir): | |
80 | x86 = ( |
|
80 | x86 = ( | |
81 | download_entry( |
|
81 | download_entry( | |
82 | 'vc9-crt-x86-msm', |
|
82 | 'vc9-crt-x86-msm', | |
83 | build_dir, |
|
83 | build_dir, | |
84 | local_name='microsoft.vcxx.crt.x86_msm.msm', |
|
84 | local_name='microsoft.vcxx.crt.x86_msm.msm', | |
85 | )[0], |
|
85 | )[0], | |
86 | download_entry( |
|
86 | download_entry( | |
87 | 'vc9-crt-x86-msm-policy', |
|
87 | 'vc9-crt-x86-msm-policy', | |
88 | build_dir, |
|
88 | build_dir, | |
89 | local_name='policy.x.xx.microsoft.vcxx.crt.x86_msm.msm', |
|
89 | local_name='policy.x.xx.microsoft.vcxx.crt.x86_msm.msm', | |
90 | )[0], |
|
90 | )[0], | |
91 | ) |
|
91 | ) | |
92 |
|
92 | |||
93 | x64 = ( |
|
93 | x64 = ( | |
94 | download_entry( |
|
94 | download_entry( | |
95 | 'vc9-crt-x64-msm', |
|
95 | 'vc9-crt-x64-msm', | |
96 | build_dir, |
|
96 | build_dir, | |
97 | local_name='microsoft.vcxx.crt.x64_msm.msm', |
|
97 | local_name='microsoft.vcxx.crt.x64_msm.msm', | |
98 | )[0], |
|
98 | )[0], | |
99 | download_entry( |
|
99 | download_entry( | |
100 | 'vc9-crt-x64-msm-policy', |
|
100 | 'vc9-crt-x64-msm-policy', | |
101 | build_dir, |
|
101 | build_dir, | |
102 | local_name='policy.x.xx.microsoft.vcxx.crt.x64_msm.msm', |
|
102 | local_name='policy.x.xx.microsoft.vcxx.crt.x64_msm.msm', | |
103 | )[0], |
|
103 | )[0], | |
104 | ) |
|
104 | ) | |
105 | return { |
|
105 | return { | |
106 | 'x86': x86, |
|
106 | 'x86': x86, | |
107 | 'x64': x64, |
|
107 | 'x64': x64, | |
108 | } |
|
108 | } | |
109 |
|
109 | |||
110 |
|
110 | |||
111 | def run_candle(wix, cwd, wxs, source_dir, defines=None): |
|
111 | def run_candle(wix, cwd, wxs, source_dir, defines=None): | |
112 | args = [ |
|
112 | args = [ | |
113 | str(wix / 'candle.exe'), |
|
113 | str(wix / 'candle.exe'), | |
114 | '-nologo', |
|
114 | '-nologo', | |
115 | str(wxs), |
|
115 | str(wxs), | |
116 | '-dSourceDir=%s' % source_dir, |
|
116 | '-dSourceDir=%s' % source_dir, | |
117 | ] |
|
117 | ] | |
118 |
|
118 | |||
119 | if defines: |
|
119 | if defines: | |
120 | args.extend('-d%s=%s' % define for define in sorted(defines.items())) |
|
120 | args.extend('-d%s=%s' % define for define in sorted(defines.items())) | |
121 |
|
121 | |||
122 | subprocess.run(args, cwd=str(cwd), check=True) |
|
122 | subprocess.run(args, cwd=str(cwd), check=True) | |
123 |
|
123 | |||
124 |
|
124 | |||
125 | def make_files_xml(staging_dir: pathlib.Path, is_x64) -> str: |
|
125 | def make_files_xml(staging_dir: pathlib.Path, is_x64) -> str: | |
126 | """Create XML string listing every file to be installed.""" |
|
126 | """Create XML string listing every file to be installed.""" | |
127 |
|
127 | |||
128 | # We derive GUIDs from a deterministic file path identifier. |
|
128 | # We derive GUIDs from a deterministic file path identifier. | |
129 | # We shoehorn the name into something that looks like a URL because |
|
129 | # We shoehorn the name into something that looks like a URL because | |
130 | # the UUID namespaces are supposed to work that way (even though |
|
130 | # the UUID namespaces are supposed to work that way (even though | |
131 | # the input data probably is never validated). |
|
131 | # the input data probably is never validated). | |
132 |
|
132 | |||
133 | doc = xml.dom.minidom.parseString( |
|
133 | doc = xml.dom.minidom.parseString( | |
134 | '<?xml version="1.0" encoding="utf-8"?>' |
|
134 | '<?xml version="1.0" encoding="utf-8"?>' | |
135 | '<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">' |
|
135 | '<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">' | |
136 | '</Wix>' |
|
136 | '</Wix>' | |
137 | ) |
|
137 | ) | |
138 |
|
138 | |||
139 | # Assemble the install layout by directory. This makes it easier to |
|
139 | # Assemble the install layout by directory. This makes it easier to | |
140 | # emit XML, since each directory has separate entities. |
|
140 | # emit XML, since each directory has separate entities. | |
141 | manifest = collections.defaultdict(dict) |
|
141 | manifest = collections.defaultdict(dict) | |
142 |
|
142 | |||
143 | for root, dirs, files in os.walk(staging_dir): |
|
143 | for root, dirs, files in os.walk(staging_dir): | |
144 | dirs.sort() |
|
144 | dirs.sort() | |
145 |
|
145 | |||
146 | root = pathlib.Path(root) |
|
146 | root = pathlib.Path(root) | |
147 | rel_dir = root.relative_to(staging_dir) |
|
147 | rel_dir = root.relative_to(staging_dir) | |
148 |
|
148 | |||
149 | for i in range(len(rel_dir.parts)): |
|
149 | for i in range(len(rel_dir.parts)): | |
150 | parent = '/'.join(rel_dir.parts[0 : i + 1]) |
|
150 | parent = '/'.join(rel_dir.parts[0 : i + 1]) | |
151 | manifest.setdefault(parent, {}) |
|
151 | manifest.setdefault(parent, {}) | |
152 |
|
152 | |||
153 | for f in sorted(files): |
|
153 | for f in sorted(files): | |
154 | full = root / f |
|
154 | full = root / f | |
155 | manifest[str(rel_dir).replace('\\', '/')][full.name] = full |
|
155 | manifest[str(rel_dir).replace('\\', '/')][full.name] = full | |
156 |
|
156 | |||
157 | component_groups = collections.defaultdict(list) |
|
157 | component_groups = collections.defaultdict(list) | |
158 |
|
158 | |||
159 | # Now emit a <Fragment> for each directory. |
|
159 | # Now emit a <Fragment> for each directory. | |
160 | # Each directory is composed of a <DirectoryRef> pointing to its parent |
|
160 | # Each directory is composed of a <DirectoryRef> pointing to its parent | |
161 | # and defines child <Directory>'s and a <Component> with all the files. |
|
161 | # and defines child <Directory>'s and a <Component> with all the files. | |
162 | for dir_name, entries in sorted(manifest.items()): |
|
162 | for dir_name, entries in sorted(manifest.items()): | |
163 | # The directory id is derived from the path. But the root directory |
|
163 | # The directory id is derived from the path. But the root directory | |
164 | # is special. |
|
164 | # is special. | |
165 | if dir_name == '.': |
|
165 | if dir_name == '.': | |
166 | parent_directory_id = 'INSTALLDIR' |
|
166 | parent_directory_id = 'INSTALLDIR' | |
167 | else: |
|
167 | else: | |
168 | parent_directory_id = 'hg.dir.%s' % dir_name.replace( |
|
168 | parent_directory_id = 'hg.dir.%s' % dir_name.replace( | |
169 | '/', '.' |
|
169 | '/', '.' | |
170 | ).replace('-', '_') |
|
170 | ).replace('-', '_') | |
171 |
|
171 | |||
172 | fragment = doc.createElement('Fragment') |
|
172 | fragment = doc.createElement('Fragment') | |
173 | directory_ref = doc.createElement('DirectoryRef') |
|
173 | directory_ref = doc.createElement('DirectoryRef') | |
174 | directory_ref.setAttribute('Id', parent_directory_id) |
|
174 | directory_ref.setAttribute('Id', parent_directory_id) | |
175 |
|
175 | |||
176 | # Add <Directory> entries for immediate children directories. |
|
176 | # Add <Directory> entries for immediate children directories. | |
177 | for possible_child in sorted(manifest.keys()): |
|
177 | for possible_child in sorted(manifest.keys()): | |
178 | if ( |
|
178 | if ( | |
179 | dir_name == '.' |
|
179 | dir_name == '.' | |
180 | and '/' not in possible_child |
|
180 | and '/' not in possible_child | |
181 | and possible_child != '.' |
|
181 | and possible_child != '.' | |
182 | ): |
|
182 | ): | |
183 | child_directory_id = ('hg.dir.%s' % possible_child).replace( |
|
183 | child_directory_id = ('hg.dir.%s' % possible_child).replace( | |
184 | '-', '_' |
|
184 | '-', '_' | |
185 | ) |
|
185 | ) | |
186 | name = possible_child |
|
186 | name = possible_child | |
187 | else: |
|
187 | else: | |
188 | if not possible_child.startswith('%s/' % dir_name): |
|
188 | if not possible_child.startswith('%s/' % dir_name): | |
189 | continue |
|
189 | continue | |
190 | name = possible_child[len(dir_name) + 1 :] |
|
190 | name = possible_child[len(dir_name) + 1 :] | |
191 | if '/' in name: |
|
191 | if '/' in name: | |
192 | continue |
|
192 | continue | |
193 |
|
193 | |||
194 | child_directory_id = 'hg.dir.%s' % possible_child.replace( |
|
194 | child_directory_id = 'hg.dir.%s' % possible_child.replace( | |
195 | '/', '.' |
|
195 | '/', '.' | |
196 | ).replace('-', '_') |
|
196 | ).replace('-', '_') | |
197 |
|
197 | |||
198 | directory = doc.createElement('Directory') |
|
198 | directory = doc.createElement('Directory') | |
199 | directory.setAttribute('Id', child_directory_id) |
|
199 | directory.setAttribute('Id', child_directory_id) | |
200 | directory.setAttribute('Name', name) |
|
200 | directory.setAttribute('Name', name) | |
201 | directory_ref.appendChild(directory) |
|
201 | directory_ref.appendChild(directory) | |
202 |
|
202 | |||
203 | # Add <Component>s for files in this directory. |
|
203 | # Add <Component>s for files in this directory. | |
204 | for rel, source_path in sorted(entries.items()): |
|
204 | for rel, source_path in sorted(entries.items()): | |
205 | if dir_name == '.': |
|
205 | if dir_name == '.': | |
206 | full_rel = rel |
|
206 | full_rel = rel | |
207 | else: |
|
207 | else: | |
208 | full_rel = '%s/%s' % (dir_name, rel) |
|
208 | full_rel = '%s/%s' % (dir_name, rel) | |
209 |
|
209 | |||
210 | component_unique_id = ( |
|
210 | component_unique_id = ( | |
211 | 'https://www.mercurial-scm.org/wix-installer/0/component/%s' |
|
211 | 'https://www.mercurial-scm.org/wix-installer/0/component/%s' | |
212 | % full_rel |
|
212 | % full_rel | |
213 | ) |
|
213 | ) | |
214 | component_guid = uuid.uuid5(uuid.NAMESPACE_URL, component_unique_id) |
|
214 | component_guid = uuid.uuid5(uuid.NAMESPACE_URL, component_unique_id) | |
215 | component_id = 'hg.component.%s' % str(component_guid).replace( |
|
215 | component_id = 'hg.component.%s' % str(component_guid).replace( | |
216 | '-', '_' |
|
216 | '-', '_' | |
217 | ) |
|
217 | ) | |
218 |
|
218 | |||
219 | component = doc.createElement('Component') |
|
219 | component = doc.createElement('Component') | |
220 |
|
220 | |||
221 | component.setAttribute('Id', component_id) |
|
221 | component.setAttribute('Id', component_id) | |
222 | component.setAttribute('Guid', str(component_guid).upper()) |
|
222 | component.setAttribute('Guid', str(component_guid).upper()) | |
223 | component.setAttribute('Win64', 'yes' if is_x64 else 'no') |
|
223 | component.setAttribute('Win64', 'yes' if is_x64 else 'no') | |
224 |
|
224 | |||
225 | # Assign this component to a top-level group. |
|
225 | # Assign this component to a top-level group. | |
226 | if dir_name == '.': |
|
226 | if dir_name == '.': | |
227 | component_groups['ROOT'].append(component_id) |
|
227 | component_groups['ROOT'].append(component_id) | |
228 | elif '/' in dir_name: |
|
228 | elif '/' in dir_name: | |
229 | component_groups[dir_name[0 : dir_name.index('/')]].append( |
|
229 | component_groups[dir_name[0 : dir_name.index('/')]].append( | |
230 | component_id |
|
230 | component_id | |
231 | ) |
|
231 | ) | |
232 | else: |
|
232 | else: | |
233 | component_groups[dir_name].append(component_id) |
|
233 | component_groups[dir_name].append(component_id) | |
234 |
|
234 | |||
235 | unique_id = ( |
|
235 | unique_id = ( | |
236 | 'https://www.mercurial-scm.org/wix-installer/0/%s' % full_rel |
|
236 | 'https://www.mercurial-scm.org/wix-installer/0/%s' % full_rel | |
237 | ) |
|
237 | ) | |
238 | file_guid = uuid.uuid5(uuid.NAMESPACE_URL, unique_id) |
|
238 | file_guid = uuid.uuid5(uuid.NAMESPACE_URL, unique_id) | |
239 |
|
239 | |||
240 | # IDs have length limits. So use GUID to derive them. |
|
240 | # IDs have length limits. So use GUID to derive them. | |
241 | file_guid_normalized = str(file_guid).replace('-', '_') |
|
241 | file_guid_normalized = str(file_guid).replace('-', '_') | |
242 | file_id = 'hg.file.%s' % file_guid_normalized |
|
242 | file_id = 'hg.file.%s' % file_guid_normalized | |
243 |
|
243 | |||
244 | file_element = doc.createElement('File') |
|
244 | file_element = doc.createElement('File') | |
245 | file_element.setAttribute('Id', file_id) |
|
245 | file_element.setAttribute('Id', file_id) | |
246 | file_element.setAttribute('Source', str(source_path)) |
|
246 | file_element.setAttribute('Source', str(source_path)) | |
247 | file_element.setAttribute('KeyPath', 'yes') |
|
247 | file_element.setAttribute('KeyPath', 'yes') | |
248 | file_element.setAttribute('ReadOnly', 'yes') |
|
248 | file_element.setAttribute('ReadOnly', 'yes') | |
249 |
|
249 | |||
250 | component.appendChild(file_element) |
|
250 | component.appendChild(file_element) | |
251 | directory_ref.appendChild(component) |
|
251 | directory_ref.appendChild(component) | |
252 |
|
252 | |||
253 | fragment.appendChild(directory_ref) |
|
253 | fragment.appendChild(directory_ref) | |
254 | doc.documentElement.appendChild(fragment) |
|
254 | doc.documentElement.appendChild(fragment) | |
255 |
|
255 | |||
256 | for group, component_ids in sorted(component_groups.items()): |
|
256 | for group, component_ids in sorted(component_groups.items()): | |
257 | fragment = doc.createElement('Fragment') |
|
257 | fragment = doc.createElement('Fragment') | |
258 | component_group = doc.createElement('ComponentGroup') |
|
258 | component_group = doc.createElement('ComponentGroup') | |
259 | component_group.setAttribute('Id', 'hg.group.%s' % group) |
|
259 | component_group.setAttribute('Id', 'hg.group.%s' % group) | |
260 |
|
260 | |||
261 | for component_id in component_ids: |
|
261 | for component_id in component_ids: | |
262 | component_ref = doc.createElement('ComponentRef') |
|
262 | component_ref = doc.createElement('ComponentRef') | |
263 | component_ref.setAttribute('Id', component_id) |
|
263 | component_ref.setAttribute('Id', component_id) | |
264 | component_group.appendChild(component_ref) |
|
264 | component_group.appendChild(component_ref) | |
265 |
|
265 | |||
266 | fragment.appendChild(component_group) |
|
266 | fragment.appendChild(component_group) | |
267 | doc.documentElement.appendChild(fragment) |
|
267 | doc.documentElement.appendChild(fragment) | |
268 |
|
268 | |||
269 | # Add <Shortcut> to files that have it defined. |
|
269 | # Add <Shortcut> to files that have it defined. | |
270 | for file_id, metadata in sorted(SHORTCUTS.items()): |
|
270 | for file_id, metadata in sorted(SHORTCUTS.items()): | |
271 | els = doc.getElementsByTagName('File') |
|
271 | els = doc.getElementsByTagName('File') | |
272 | els = [el for el in els if el.getAttribute('Id') == file_id] |
|
272 | els = [el for el in els if el.getAttribute('Id') == file_id] | |
273 |
|
273 | |||
274 | if not els: |
|
274 | if not els: | |
275 | raise Exception('could not find File[Id=%s]' % file_id) |
|
275 | raise Exception('could not find File[Id=%s]' % file_id) | |
276 |
|
276 | |||
277 | for el in els: |
|
277 | for el in els: | |
278 | shortcut = doc.createElement('Shortcut') |
|
278 | shortcut = doc.createElement('Shortcut') | |
279 | shortcut.setAttribute('Id', 'hg.shortcut.%s' % file_id) |
|
279 | shortcut.setAttribute('Id', 'hg.shortcut.%s' % file_id) | |
280 | shortcut.setAttribute('Directory', 'ProgramMenuDir') |
|
280 | shortcut.setAttribute('Directory', 'ProgramMenuDir') | |
281 | shortcut.setAttribute('Icon', 'hgIcon.ico') |
|
281 | shortcut.setAttribute('Icon', 'hgIcon.ico') | |
282 | shortcut.setAttribute('IconIndex', '0') |
|
282 | shortcut.setAttribute('IconIndex', '0') | |
283 | shortcut.setAttribute('Advertise', 'yes') |
|
283 | shortcut.setAttribute('Advertise', 'yes') | |
284 | for k, v in sorted(metadata.items()): |
|
284 | for k, v in sorted(metadata.items()): | |
285 | shortcut.setAttribute(k, v) |
|
285 | shortcut.setAttribute(k, v) | |
286 |
|
286 | |||
287 | el.appendChild(shortcut) |
|
287 | el.appendChild(shortcut) | |
288 |
|
288 | |||
289 | return doc.toprettyxml() |
|
289 | return doc.toprettyxml() | |
290 |
|
290 | |||
291 |
|
291 | |||
292 | def build_installer_py2exe( |
|
292 | def build_installer_py2exe( | |
293 | source_dir: pathlib.Path, |
|
293 | source_dir: pathlib.Path, | |
294 | python_exe: pathlib.Path, |
|
294 | python_exe: pathlib.Path, | |
295 | msi_name='mercurial', |
|
295 | msi_name='mercurial', | |
296 | version=None, |
|
296 | version=None, | |
297 | extra_packages_script=None, |
|
297 | extra_packages_script=None, | |
298 | extra_wxs: typing.Optional[typing.Dict[str, str]] = None, |
|
298 | extra_wxs: typing.Optional[typing.Dict[str, str]] = None, | |
299 | extra_features: typing.Optional[typing.List[str]] = None, |
|
299 | extra_features: typing.Optional[typing.List[str]] = None, | |
300 | signing_info: typing.Optional[typing.Dict[str, str]] = None, |
|
300 | signing_info: typing.Optional[typing.Dict[str, str]] = None, | |
301 | ): |
|
301 | ): | |
302 | """Build a WiX MSI installer using py2exe. |
|
302 | """Build a WiX MSI installer using py2exe. | |
303 |
|
303 | |||
304 | ``source_dir`` is the path to the Mercurial source tree to use. |
|
304 | ``source_dir`` is the path to the Mercurial source tree to use. | |
305 | ``arch`` is the target architecture. either ``x86`` or ``x64``. |
|
305 | ``arch`` is the target architecture. either ``x86`` or ``x64``. | |
306 | ``python_exe`` is the path to the Python executable to use/bundle. |
|
306 | ``python_exe`` is the path to the Python executable to use/bundle. | |
307 | ``version`` is the Mercurial version string. If not defined, |
|
307 | ``version`` is the Mercurial version string. If not defined, | |
308 | ``mercurial/__version__.py`` will be consulted. |
|
308 | ``mercurial/__version__.py`` will be consulted. | |
309 | ``extra_packages_script`` is a command to be run to inject extra packages |
|
309 | ``extra_packages_script`` is a command to be run to inject extra packages | |
310 | into the py2exe binary. It should stage packages into the virtualenv and |
|
310 | into the py2exe binary. It should stage packages into the virtualenv and | |
311 | print a null byte followed by a newline-separated list of packages that |
|
311 | print a null byte followed by a newline-separated list of packages that | |
312 | should be included in the exe. |
|
312 | should be included in the exe. | |
313 | ``extra_wxs`` is a dict of {wxs_name: working_dir_for_wxs_build}. |
|
313 | ``extra_wxs`` is a dict of {wxs_name: working_dir_for_wxs_build}. | |
314 | ``extra_features`` is a list of additional named Features to include in |
|
314 | ``extra_features`` is a list of additional named Features to include in | |
315 | the build. These must match Feature names in one of the wxs scripts. |
|
315 | the build. These must match Feature names in one of the wxs scripts. | |
316 | """ |
|
316 | """ | |
317 | arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86' |
|
317 | arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86' | |
318 |
|
318 | |||
319 | hg_build_dir = source_dir / 'build' |
|
319 | hg_build_dir = source_dir / 'build' | |
320 |
|
320 | |||
321 | requirements_txt = ( |
|
321 | requirements_txt = ( | |
322 |
source_dir / 'contrib' / 'packaging' / 'requirements |
|
322 | source_dir / 'contrib' / 'packaging' / 'requirements-windows-py2.txt' | |
323 | ) |
|
323 | ) | |
324 |
|
324 | |||
325 | build_py2exe( |
|
325 | build_py2exe( | |
326 | source_dir, |
|
326 | source_dir, | |
327 | hg_build_dir, |
|
327 | hg_build_dir, | |
328 | python_exe, |
|
328 | python_exe, | |
329 | 'wix', |
|
329 | 'wix', | |
330 | requirements_txt, |
|
330 | requirements_txt, | |
331 | extra_packages=EXTRA_PACKAGES, |
|
331 | extra_packages=EXTRA_PACKAGES, | |
332 | extra_packages_script=extra_packages_script, |
|
332 | extra_packages_script=extra_packages_script, | |
333 | ) |
|
333 | ) | |
334 |
|
334 | |||
335 | build_dir = hg_build_dir / ('wix-%s' % arch) |
|
335 | build_dir = hg_build_dir / ('wix-%s' % arch) | |
336 | staging_dir = build_dir / 'stage' |
|
336 | staging_dir = build_dir / 'stage' | |
337 |
|
337 | |||
338 | build_dir.mkdir(exist_ok=True) |
|
338 | build_dir.mkdir(exist_ok=True) | |
339 |
|
339 | |||
340 | # Purge the staging directory for every build so packaging is pristine. |
|
340 | # Purge the staging directory for every build so packaging is pristine. | |
341 | if staging_dir.exists(): |
|
341 | if staging_dir.exists(): | |
342 | print('purging %s' % staging_dir) |
|
342 | print('purging %s' % staging_dir) | |
343 | shutil.rmtree(staging_dir) |
|
343 | shutil.rmtree(staging_dir) | |
344 |
|
344 | |||
345 | stage_install(source_dir, staging_dir, lower_case=True) |
|
345 | stage_install(source_dir, staging_dir, lower_case=True) | |
346 |
|
346 | |||
347 | # We also install some extra files. |
|
347 | # We also install some extra files. | |
348 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) |
|
348 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) | |
349 |
|
349 | |||
350 | # And remove some files we don't want. |
|
350 | # And remove some files we don't want. | |
351 | for f in STAGING_REMOVE_FILES: |
|
351 | for f in STAGING_REMOVE_FILES: | |
352 | p = staging_dir / f |
|
352 | p = staging_dir / f | |
353 | if p.exists(): |
|
353 | if p.exists(): | |
354 | print('removing %s' % p) |
|
354 | print('removing %s' % p) | |
355 | p.unlink() |
|
355 | p.unlink() | |
356 |
|
356 | |||
357 | return run_wix_packaging( |
|
357 | return run_wix_packaging( | |
358 | source_dir, |
|
358 | source_dir, | |
359 | build_dir, |
|
359 | build_dir, | |
360 | staging_dir, |
|
360 | staging_dir, | |
361 | arch, |
|
361 | arch, | |
362 | version=version, |
|
362 | version=version, | |
363 | python2=True, |
|
363 | python2=True, | |
364 | msi_name=msi_name, |
|
364 | msi_name=msi_name, | |
365 | suffix="-python2", |
|
365 | suffix="-python2", | |
366 | extra_wxs=extra_wxs, |
|
366 | extra_wxs=extra_wxs, | |
367 | extra_features=extra_features, |
|
367 | extra_features=extra_features, | |
368 | signing_info=signing_info, |
|
368 | signing_info=signing_info, | |
369 | ) |
|
369 | ) | |
370 |
|
370 | |||
371 |
|
371 | |||
372 | def build_installer_pyoxidizer( |
|
372 | def build_installer_pyoxidizer( | |
373 | source_dir: pathlib.Path, |
|
373 | source_dir: pathlib.Path, | |
374 | target_triple: str, |
|
374 | target_triple: str, | |
375 | msi_name='mercurial', |
|
375 | msi_name='mercurial', | |
376 | version=None, |
|
376 | version=None, | |
377 | extra_wxs: typing.Optional[typing.Dict[str, str]] = None, |
|
377 | extra_wxs: typing.Optional[typing.Dict[str, str]] = None, | |
378 | extra_features: typing.Optional[typing.List[str]] = None, |
|
378 | extra_features: typing.Optional[typing.List[str]] = None, | |
379 | signing_info: typing.Optional[typing.Dict[str, str]] = None, |
|
379 | signing_info: typing.Optional[typing.Dict[str, str]] = None, | |
380 | ): |
|
380 | ): | |
381 | """Build a WiX MSI installer using PyOxidizer.""" |
|
381 | """Build a WiX MSI installer using PyOxidizer.""" | |
382 | hg_build_dir = source_dir / "build" |
|
382 | hg_build_dir = source_dir / "build" | |
383 | build_dir = hg_build_dir / ("wix-%s" % target_triple) |
|
383 | build_dir = hg_build_dir / ("wix-%s" % target_triple) | |
384 | staging_dir = build_dir / "stage" |
|
384 | staging_dir = build_dir / "stage" | |
385 |
|
385 | |||
386 | arch = "x64" if "x86_64" in target_triple else "x86" |
|
386 | arch = "x64" if "x86_64" in target_triple else "x86" | |
387 |
|
387 | |||
388 | build_dir.mkdir(parents=True, exist_ok=True) |
|
388 | build_dir.mkdir(parents=True, exist_ok=True) | |
389 | run_pyoxidizer(source_dir, build_dir, staging_dir, target_triple) |
|
389 | run_pyoxidizer(source_dir, build_dir, staging_dir, target_triple) | |
390 |
|
390 | |||
391 | # We also install some extra files. |
|
391 | # We also install some extra files. | |
392 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) |
|
392 | process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir) | |
393 |
|
393 | |||
394 | # And remove some files we don't want. |
|
394 | # And remove some files we don't want. | |
395 | for f in STAGING_REMOVE_FILES: |
|
395 | for f in STAGING_REMOVE_FILES: | |
396 | p = staging_dir / f |
|
396 | p = staging_dir / f | |
397 | if p.exists(): |
|
397 | if p.exists(): | |
398 | print('removing %s' % p) |
|
398 | print('removing %s' % p) | |
399 | p.unlink() |
|
399 | p.unlink() | |
400 |
|
400 | |||
401 | return run_wix_packaging( |
|
401 | return run_wix_packaging( | |
402 | source_dir, |
|
402 | source_dir, | |
403 | build_dir, |
|
403 | build_dir, | |
404 | staging_dir, |
|
404 | staging_dir, | |
405 | arch, |
|
405 | arch, | |
406 | version, |
|
406 | version, | |
407 | python2=False, |
|
407 | python2=False, | |
408 | msi_name=msi_name, |
|
408 | msi_name=msi_name, | |
409 | extra_wxs=extra_wxs, |
|
409 | extra_wxs=extra_wxs, | |
410 | extra_features=extra_features, |
|
410 | extra_features=extra_features, | |
411 | signing_info=signing_info, |
|
411 | signing_info=signing_info, | |
412 | ) |
|
412 | ) | |
413 |
|
413 | |||
414 |
|
414 | |||
415 | def run_wix_packaging( |
|
415 | def run_wix_packaging( | |
416 | source_dir: pathlib.Path, |
|
416 | source_dir: pathlib.Path, | |
417 | build_dir: pathlib.Path, |
|
417 | build_dir: pathlib.Path, | |
418 | staging_dir: pathlib.Path, |
|
418 | staging_dir: pathlib.Path, | |
419 | arch: str, |
|
419 | arch: str, | |
420 | version: str, |
|
420 | version: str, | |
421 | python2: bool, |
|
421 | python2: bool, | |
422 | msi_name: typing.Optional[str] = "mercurial", |
|
422 | msi_name: typing.Optional[str] = "mercurial", | |
423 | suffix: str = "", |
|
423 | suffix: str = "", | |
424 | extra_wxs: typing.Optional[typing.Dict[str, str]] = None, |
|
424 | extra_wxs: typing.Optional[typing.Dict[str, str]] = None, | |
425 | extra_features: typing.Optional[typing.List[str]] = None, |
|
425 | extra_features: typing.Optional[typing.List[str]] = None, | |
426 | signing_info: typing.Optional[typing.Dict[str, str]] = None, |
|
426 | signing_info: typing.Optional[typing.Dict[str, str]] = None, | |
427 | ): |
|
427 | ): | |
428 | """Invokes WiX to package up a built Mercurial. |
|
428 | """Invokes WiX to package up a built Mercurial. | |
429 |
|
429 | |||
430 | ``signing_info`` is a dict defining properties to facilitate signing the |
|
430 | ``signing_info`` is a dict defining properties to facilitate signing the | |
431 | installer. Recognized keys include ``name``, ``subject_name``, |
|
431 | installer. Recognized keys include ``name``, ``subject_name``, | |
432 | ``cert_path``, ``cert_password``, and ``timestamp_url``. If populated, |
|
432 | ``cert_path``, ``cert_password``, and ``timestamp_url``. If populated, | |
433 | we will sign both the hg.exe and the .msi using the signing credentials |
|
433 | we will sign both the hg.exe and the .msi using the signing credentials | |
434 | specified. |
|
434 | specified. | |
435 | """ |
|
435 | """ | |
436 |
|
436 | |||
437 | orig_version = version or find_version(source_dir) |
|
437 | orig_version = version or find_version(source_dir) | |
438 | version = normalize_windows_version(orig_version) |
|
438 | version = normalize_windows_version(orig_version) | |
439 | print('using version string: %s' % version) |
|
439 | print('using version string: %s' % version) | |
440 | if version != orig_version: |
|
440 | if version != orig_version: | |
441 | print('(normalized from: %s)' % orig_version) |
|
441 | print('(normalized from: %s)' % orig_version) | |
442 |
|
442 | |||
443 | if signing_info: |
|
443 | if signing_info: | |
444 | sign_with_signtool( |
|
444 | sign_with_signtool( | |
445 | staging_dir / "hg.exe", |
|
445 | staging_dir / "hg.exe", | |
446 | "%s %s" % (signing_info["name"], version), |
|
446 | "%s %s" % (signing_info["name"], version), | |
447 | subject_name=signing_info["subject_name"], |
|
447 | subject_name=signing_info["subject_name"], | |
448 | cert_path=signing_info["cert_path"], |
|
448 | cert_path=signing_info["cert_path"], | |
449 | cert_password=signing_info["cert_password"], |
|
449 | cert_password=signing_info["cert_password"], | |
450 | timestamp_url=signing_info["timestamp_url"], |
|
450 | timestamp_url=signing_info["timestamp_url"], | |
451 | ) |
|
451 | ) | |
452 |
|
452 | |||
453 | wix_dir = source_dir / 'contrib' / 'packaging' / 'wix' |
|
453 | wix_dir = source_dir / 'contrib' / 'packaging' / 'wix' | |
454 |
|
454 | |||
455 | wix_pkg, wix_entry = download_entry('wix', build_dir) |
|
455 | wix_pkg, wix_entry = download_entry('wix', build_dir) | |
456 | wix_path = build_dir / ('wix-%s' % wix_entry['version']) |
|
456 | wix_path = build_dir / ('wix-%s' % wix_entry['version']) | |
457 |
|
457 | |||
458 | if not wix_path.exists(): |
|
458 | if not wix_path.exists(): | |
459 | extract_zip_to_directory(wix_pkg, wix_path) |
|
459 | extract_zip_to_directory(wix_pkg, wix_path) | |
460 |
|
460 | |||
461 | if python2: |
|
461 | if python2: | |
462 | ensure_vc90_merge_modules(build_dir) |
|
462 | ensure_vc90_merge_modules(build_dir) | |
463 |
|
463 | |||
464 | source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir)) |
|
464 | source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir)) | |
465 |
|
465 | |||
466 | defines = {'Platform': arch} |
|
466 | defines = {'Platform': arch} | |
467 |
|
467 | |||
468 | # Derive a .wxs file with the staged files. |
|
468 | # Derive a .wxs file with the staged files. | |
469 | manifest_wxs = build_dir / 'stage.wxs' |
|
469 | manifest_wxs = build_dir / 'stage.wxs' | |
470 | with manifest_wxs.open('w', encoding='utf-8') as fh: |
|
470 | with manifest_wxs.open('w', encoding='utf-8') as fh: | |
471 | fh.write(make_files_xml(staging_dir, is_x64=arch == 'x64')) |
|
471 | fh.write(make_files_xml(staging_dir, is_x64=arch == 'x64')) | |
472 |
|
472 | |||
473 | run_candle(wix_path, build_dir, manifest_wxs, staging_dir, defines=defines) |
|
473 | run_candle(wix_path, build_dir, manifest_wxs, staging_dir, defines=defines) | |
474 |
|
474 | |||
475 | for source, rel_path in sorted((extra_wxs or {}).items()): |
|
475 | for source, rel_path in sorted((extra_wxs or {}).items()): | |
476 | run_candle(wix_path, build_dir, source, rel_path, defines=defines) |
|
476 | run_candle(wix_path, build_dir, source, rel_path, defines=defines) | |
477 |
|
477 | |||
478 | source = wix_dir / 'mercurial.wxs' |
|
478 | source = wix_dir / 'mercurial.wxs' | |
479 | defines['Version'] = version |
|
479 | defines['Version'] = version | |
480 | defines['Comments'] = 'Installs Mercurial version %s' % version |
|
480 | defines['Comments'] = 'Installs Mercurial version %s' % version | |
481 |
|
481 | |||
482 | if python2: |
|
482 | if python2: | |
483 | defines["PythonVersion"] = "2" |
|
483 | defines["PythonVersion"] = "2" | |
484 | defines['VCRedistSrcDir'] = str(build_dir) |
|
484 | defines['VCRedistSrcDir'] = str(build_dir) | |
485 | else: |
|
485 | else: | |
486 | defines["PythonVersion"] = "3" |
|
486 | defines["PythonVersion"] = "3" | |
487 |
|
487 | |||
488 | if (staging_dir / "lib").exists(): |
|
488 | if (staging_dir / "lib").exists(): | |
489 | defines["MercurialHasLib"] = "1" |
|
489 | defines["MercurialHasLib"] = "1" | |
490 |
|
490 | |||
491 | if extra_features: |
|
491 | if extra_features: | |
492 | assert all(';' not in f for f in extra_features) |
|
492 | assert all(';' not in f for f in extra_features) | |
493 | defines['MercurialExtraFeatures'] = ';'.join(extra_features) |
|
493 | defines['MercurialExtraFeatures'] = ';'.join(extra_features) | |
494 |
|
494 | |||
495 | run_candle(wix_path, build_dir, source, source_build_rel, defines=defines) |
|
495 | run_candle(wix_path, build_dir, source, source_build_rel, defines=defines) | |
496 |
|
496 | |||
497 | msi_path = ( |
|
497 | msi_path = ( | |
498 | source_dir |
|
498 | source_dir | |
499 | / 'dist' |
|
499 | / 'dist' | |
500 | / ('%s-%s-%s%s.msi' % (msi_name, orig_version, arch, suffix)) |
|
500 | / ('%s-%s-%s%s.msi' % (msi_name, orig_version, arch, suffix)) | |
501 | ) |
|
501 | ) | |
502 |
|
502 | |||
503 | args = [ |
|
503 | args = [ | |
504 | str(wix_path / 'light.exe'), |
|
504 | str(wix_path / 'light.exe'), | |
505 | '-nologo', |
|
505 | '-nologo', | |
506 | '-ext', |
|
506 | '-ext', | |
507 | 'WixUIExtension', |
|
507 | 'WixUIExtension', | |
508 | '-sw1076', |
|
508 | '-sw1076', | |
509 | '-spdb', |
|
509 | '-spdb', | |
510 | '-o', |
|
510 | '-o', | |
511 | str(msi_path), |
|
511 | str(msi_path), | |
512 | ] |
|
512 | ] | |
513 |
|
513 | |||
514 | for source, rel_path in sorted((extra_wxs or {}).items()): |
|
514 | for source, rel_path in sorted((extra_wxs or {}).items()): | |
515 | assert source.endswith('.wxs') |
|
515 | assert source.endswith('.wxs') | |
516 | source = os.path.basename(source) |
|
516 | source = os.path.basename(source) | |
517 | args.append(str(build_dir / ('%s.wixobj' % source[:-4]))) |
|
517 | args.append(str(build_dir / ('%s.wixobj' % source[:-4]))) | |
518 |
|
518 | |||
519 | args.extend( |
|
519 | args.extend( | |
520 | [str(build_dir / 'stage.wixobj'), str(build_dir / 'mercurial.wixobj'),] |
|
520 | [str(build_dir / 'stage.wixobj'), str(build_dir / 'mercurial.wixobj'),] | |
521 | ) |
|
521 | ) | |
522 |
|
522 | |||
523 | subprocess.run(args, cwd=str(source_dir), check=True) |
|
523 | subprocess.run(args, cwd=str(source_dir), check=True) | |
524 |
|
524 | |||
525 | print('%s created' % msi_path) |
|
525 | print('%s created' % msi_path) | |
526 |
|
526 | |||
527 | if signing_info: |
|
527 | if signing_info: | |
528 | sign_with_signtool( |
|
528 | sign_with_signtool( | |
529 | msi_path, |
|
529 | msi_path, | |
530 | "%s %s" % (signing_info["name"], version), |
|
530 | "%s %s" % (signing_info["name"], version), | |
531 | subject_name=signing_info["subject_name"], |
|
531 | subject_name=signing_info["subject_name"], | |
532 | cert_path=signing_info["cert_path"], |
|
532 | cert_path=signing_info["cert_path"], | |
533 | cert_password=signing_info["cert_password"], |
|
533 | cert_password=signing_info["cert_password"], | |
534 | timestamp_url=signing_info["timestamp_url"], |
|
534 | timestamp_url=signing_info["timestamp_url"], | |
535 | ) |
|
535 | ) | |
536 |
|
536 | |||
537 | return { |
|
537 | return { | |
538 | 'msi_path': msi_path, |
|
538 | 'msi_path': msi_path, | |
539 | } |
|
539 | } |
@@ -1,117 +1,129 b'' | |||||
1 | # |
|
1 | # | |
2 | # This file is autogenerated by pip-compile |
|
2 | # This file is autogenerated by pip-compile | |
3 | # To update, run: |
|
3 | # To update, run: | |
4 | # |
|
4 | # | |
5 |
# pip-compile --generate-hashes --output-file=contrib/packaging/requirements |
|
5 | # pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py2.txt contrib/packaging/requirements-windows.txt.in | |
6 | # |
|
6 | # | |
7 | certifi==2020.6.20 \ |
|
7 | certifi==2020.6.20 \ | |
8 | --hash=sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3 \ |
|
8 | --hash=sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3 \ | |
9 | --hash=sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41 \ |
|
9 | --hash=sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41 \ | |
10 | # via dulwich |
|
10 | # via dulwich | |
11 | cffi==1.14.3 \ |
|
11 | cffi==1.14.3 \ | |
12 | --hash=sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d \ |
|
12 | --hash=sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d \ | |
13 | --hash=sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b \ |
|
13 | --hash=sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b \ | |
14 | --hash=sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4 \ |
|
14 | --hash=sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4 \ | |
15 | --hash=sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f \ |
|
15 | --hash=sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f \ | |
16 | --hash=sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3 \ |
|
16 | --hash=sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3 \ | |
17 | --hash=sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579 \ |
|
17 | --hash=sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579 \ | |
18 | --hash=sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537 \ |
|
18 | --hash=sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537 \ | |
19 | --hash=sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e \ |
|
19 | --hash=sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e \ | |
20 | --hash=sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05 \ |
|
20 | --hash=sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05 \ | |
21 | --hash=sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171 \ |
|
21 | --hash=sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171 \ | |
22 | --hash=sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca \ |
|
22 | --hash=sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca \ | |
23 | --hash=sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522 \ |
|
23 | --hash=sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522 \ | |
24 | --hash=sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c \ |
|
24 | --hash=sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c \ | |
25 | --hash=sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc \ |
|
25 | --hash=sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc \ | |
26 | --hash=sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d \ |
|
26 | --hash=sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d \ | |
27 | --hash=sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808 \ |
|
27 | --hash=sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808 \ | |
28 | --hash=sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828 \ |
|
28 | --hash=sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828 \ | |
29 | --hash=sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869 \ |
|
29 | --hash=sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869 \ | |
30 | --hash=sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d \ |
|
30 | --hash=sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d \ | |
31 | --hash=sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9 \ |
|
31 | --hash=sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9 \ | |
32 | --hash=sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0 \ |
|
32 | --hash=sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0 \ | |
33 | --hash=sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc \ |
|
33 | --hash=sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc \ | |
34 | --hash=sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15 \ |
|
34 | --hash=sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15 \ | |
35 | --hash=sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c \ |
|
35 | --hash=sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c \ | |
36 | --hash=sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a \ |
|
36 | --hash=sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a \ | |
37 | --hash=sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3 \ |
|
37 | --hash=sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3 \ | |
38 | --hash=sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1 \ |
|
38 | --hash=sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1 \ | |
39 | --hash=sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768 \ |
|
39 | --hash=sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768 \ | |
40 | --hash=sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d \ |
|
40 | --hash=sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d \ | |
41 | --hash=sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b \ |
|
41 | --hash=sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b \ | |
42 | --hash=sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e \ |
|
42 | --hash=sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e \ | |
43 | --hash=sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d \ |
|
43 | --hash=sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d \ | |
44 | --hash=sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730 \ |
|
44 | --hash=sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730 \ | |
45 | --hash=sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394 \ |
|
45 | --hash=sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394 \ | |
46 | --hash=sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1 \ |
|
46 | --hash=sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1 \ | |
47 | --hash=sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591 \ |
|
47 | --hash=sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591 \ | |
48 | # via cryptography |
|
48 | # via cryptography | |
|
49 | configparser==4.0.2 \ | |||
|
50 | --hash=sha256:254c1d9c79f60c45dfde850850883d5aaa7f19a23f13561243a050d5a7c3fe4c \ | |||
|
51 | --hash=sha256:c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df \ | |||
|
52 | # via entrypoints | |||
49 | cryptography==3.1.1 \ |
|
53 | cryptography==3.1.1 \ | |
50 | --hash=sha256:21b47c59fcb1c36f1113f3709d37935368e34815ea1d7073862e92f810dc7499 \ |
|
54 | --hash=sha256:21b47c59fcb1c36f1113f3709d37935368e34815ea1d7073862e92f810dc7499 \ | |
51 | --hash=sha256:451cdf60be4dafb6a3b78802006a020e6cd709c22d240f94f7a0696240a17154 \ |
|
55 | --hash=sha256:451cdf60be4dafb6a3b78802006a020e6cd709c22d240f94f7a0696240a17154 \ | |
52 | --hash=sha256:4549b137d8cbe3c2eadfa56c0c858b78acbeff956bd461e40000b2164d9167c6 \ |
|
56 | --hash=sha256:4549b137d8cbe3c2eadfa56c0c858b78acbeff956bd461e40000b2164d9167c6 \ | |
53 | --hash=sha256:48ee615a779ffa749d7d50c291761dc921d93d7cf203dca2db663b4f193f0e49 \ |
|
57 | --hash=sha256:48ee615a779ffa749d7d50c291761dc921d93d7cf203dca2db663b4f193f0e49 \ | |
54 | --hash=sha256:559d622aef2a2dff98a892eef321433ba5bc55b2485220a8ca289c1ecc2bd54f \ |
|
58 | --hash=sha256:559d622aef2a2dff98a892eef321433ba5bc55b2485220a8ca289c1ecc2bd54f \ | |
55 | --hash=sha256:5d52c72449bb02dd45a773a203196e6d4fae34e158769c896012401f33064396 \ |
|
59 | --hash=sha256:5d52c72449bb02dd45a773a203196e6d4fae34e158769c896012401f33064396 \ | |
56 | --hash=sha256:65beb15e7f9c16e15934569d29fb4def74ea1469d8781f6b3507ab896d6d8719 \ |
|
60 | --hash=sha256:65beb15e7f9c16e15934569d29fb4def74ea1469d8781f6b3507ab896d6d8719 \ | |
57 | --hash=sha256:680da076cad81cdf5ffcac50c477b6790be81768d30f9da9e01960c4b18a66db \ |
|
61 | --hash=sha256:680da076cad81cdf5ffcac50c477b6790be81768d30f9da9e01960c4b18a66db \ | |
58 | --hash=sha256:762bc5a0df03c51ee3f09c621e1cee64e3a079a2b5020de82f1613873d79ee70 \ |
|
62 | --hash=sha256:762bc5a0df03c51ee3f09c621e1cee64e3a079a2b5020de82f1613873d79ee70 \ | |
59 | --hash=sha256:89aceb31cd5f9fc2449fe8cf3810797ca52b65f1489002d58fe190bfb265c536 \ |
|
63 | --hash=sha256:89aceb31cd5f9fc2449fe8cf3810797ca52b65f1489002d58fe190bfb265c536 \ | |
60 | --hash=sha256:983c0c3de4cb9fcba68fd3f45ed846eb86a2a8b8d8bc5bb18364c4d00b3c61fe \ |
|
64 | --hash=sha256:983c0c3de4cb9fcba68fd3f45ed846eb86a2a8b8d8bc5bb18364c4d00b3c61fe \ | |
61 | --hash=sha256:99d4984aabd4c7182050bca76176ce2dbc9fa9748afe583a7865c12954d714ba \ |
|
65 | --hash=sha256:99d4984aabd4c7182050bca76176ce2dbc9fa9748afe583a7865c12954d714ba \ | |
62 | --hash=sha256:9d9fc6a16357965d282dd4ab6531013935425d0dc4950df2e0cf2a1b1ac1017d \ |
|
66 | --hash=sha256:9d9fc6a16357965d282dd4ab6531013935425d0dc4950df2e0cf2a1b1ac1017d \ | |
63 | --hash=sha256:a7597ffc67987b37b12e09c029bd1dc43965f75d328076ae85721b84046e9ca7 \ |
|
67 | --hash=sha256:a7597ffc67987b37b12e09c029bd1dc43965f75d328076ae85721b84046e9ca7 \ | |
64 | --hash=sha256:ab010e461bb6b444eaf7f8c813bb716be2d78ab786103f9608ffd37a4bd7d490 \ |
|
68 | --hash=sha256:ab010e461bb6b444eaf7f8c813bb716be2d78ab786103f9608ffd37a4bd7d490 \ | |
65 | --hash=sha256:b12e715c10a13ca1bd27fbceed9adc8c5ff640f8e1f7ea76416352de703523c8 \ |
|
69 | --hash=sha256:b12e715c10a13ca1bd27fbceed9adc8c5ff640f8e1f7ea76416352de703523c8 \ | |
66 | --hash=sha256:b2bded09c578d19e08bd2c5bb8fed7f103e089752c9cf7ca7ca7de522326e921 \ |
|
70 | --hash=sha256:b2bded09c578d19e08bd2c5bb8fed7f103e089752c9cf7ca7ca7de522326e921 \ | |
67 | --hash=sha256:b372026ebf32fe2523159f27d9f0e9f485092e43b00a5adacf732192a70ba118 \ |
|
71 | --hash=sha256:b372026ebf32fe2523159f27d9f0e9f485092e43b00a5adacf732192a70ba118 \ | |
68 | --hash=sha256:cb179acdd4ae1e4a5a160d80b87841b3d0e0be84af46c7bb2cd7ece57a39c4ba \ |
|
72 | --hash=sha256:cb179acdd4ae1e4a5a160d80b87841b3d0e0be84af46c7bb2cd7ece57a39c4ba \ | |
69 | --hash=sha256:e97a3b627e3cb63c415a16245d6cef2139cca18bb1183d1b9375a1c14e83f3b3 \ |
|
73 | --hash=sha256:e97a3b627e3cb63c415a16245d6cef2139cca18bb1183d1b9375a1c14e83f3b3 \ | |
70 | --hash=sha256:f0e099fc4cc697450c3dd4031791559692dd941a95254cb9aeded66a7aa8b9bc \ |
|
74 | --hash=sha256:f0e099fc4cc697450c3dd4031791559692dd941a95254cb9aeded66a7aa8b9bc \ | |
71 | --hash=sha256:f99317a0fa2e49917689b8cf977510addcfaaab769b3f899b9c481bbd76730c2 \ |
|
75 | --hash=sha256:f99317a0fa2e49917689b8cf977510addcfaaab769b3f899b9c481bbd76730c2 \ | |
72 | # via secretstorage |
|
76 | # via secretstorage | |
73 | docutils==0.16 \ |
|
77 | docutils==0.16 \ | |
74 | --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ |
|
78 | --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ | |
75 | --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \ |
|
79 | --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \ | |
76 |
# via -r contrib/packaging/requirements |
|
80 | # via -r contrib/packaging/requirements-windows.txt.in | |
77 | dulwich==0.19.16 \ |
|
81 | dulwich==0.19.16 ; python_version <= "2.7" \ | |
78 | --hash=sha256:10699277c6268d0c16febe141a5b1c1a6e9744f3144c2d2de1706f4b1adafe63 \ |
|
82 | --hash=sha256:10699277c6268d0c16febe141a5b1c1a6e9744f3144c2d2de1706f4b1adafe63 \ | |
79 | --hash=sha256:267160904e9a1cb6c248c5efc53597a35d038ecc6f60bdc4546b3053bed11982 \ |
|
83 | --hash=sha256:267160904e9a1cb6c248c5efc53597a35d038ecc6f60bdc4546b3053bed11982 \ | |
80 | --hash=sha256:4e3aba5e4844e7c700721c1fc696987ea820ee3528a03604dc4e74eff4196826 \ |
|
84 | --hash=sha256:4e3aba5e4844e7c700721c1fc696987ea820ee3528a03604dc4e74eff4196826 \ | |
81 | --hash=sha256:60bb2c2c92f5025c1b53a556304008f0f624c98ae36f22d870e056b2d4236c11 \ |
|
85 | --hash=sha256:60bb2c2c92f5025c1b53a556304008f0f624c98ae36f22d870e056b2d4236c11 \ | |
82 | --hash=sha256:dddae02d372fc3b5cfb0046d0f62246ef281fa0c088df7601ab5916607add94b \ |
|
86 | --hash=sha256:dddae02d372fc3b5cfb0046d0f62246ef281fa0c088df7601ab5916607add94b \ | |
83 | --hash=sha256:f00d132082b8fcc2eb0d722abc773d4aeb5558c1475d7edd1f0f571146c29db9 \ |
|
87 | --hash=sha256:f00d132082b8fcc2eb0d722abc773d4aeb5558c1475d7edd1f0f571146c29db9 \ | |
84 | --hash=sha256:f74561c448bfb6f04c07de731c1181ae4280017f759b0bb04fa5770aa84ca850 \ |
|
88 | --hash=sha256:f74561c448bfb6f04c07de731c1181ae4280017f759b0bb04fa5770aa84ca850 \ | |
85 |
# via -r contrib/packaging/requirements |
|
89 | # via -r contrib/packaging/requirements-windows.txt.in | |
86 | jeepney==0.4.3 \ |
|
90 | entrypoints==0.3 \ | |
87 | --hash=sha256:3479b861cc2b6407de5188695fa1a8d57e5072d7059322469b62628869b8e36e \ |
|
91 | --hash=sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19 \ | |
88 | --hash=sha256:d6c6b49683446d2407d2fe3acb7a368a77ff063f9182fe427da15d622adc24cf \ |
|
92 | --hash=sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451 \ | |
89 |
# via keyring |
|
93 | # via keyring | |
90 |
|
|
94 | enum34==1.1.10 \ | |
91 | --hash=sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d \ |
|
95 | --hash=sha256:a98a201d6de3f2ab3db284e70a33b0f896fbf35f8086594e8c9e74b909058d53 \ | |
92 | --hash=sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466 \ |
|
96 | --hash=sha256:c3858660960c984d6ab0ebad691265180da2b43f07e061c0f8dca9ef3cffd328 \ | |
93 | # via -r contrib/packaging/requirements_win32.txt.in |
|
97 | --hash=sha256:cce6a7477ed816bd2542d03d53db9f0db935dd013b70f336a95c73979289f248 \ | |
|
98 | # via cryptography | |||
|
99 | ipaddress==1.0.23 \ | |||
|
100 | --hash=sha256:6e0f4a39e66cb5bb9a137b00276a2eff74f93b71dcbdad6f10ff7df9d3557fcc \ | |||
|
101 | --hash=sha256:b7f8e0369580bb4a24d5ba1d7cc29660a4a6987763faf1d8a8046830e020e7e2 \ | |||
|
102 | # via cryptography | |||
|
103 | keyring==18.0.1 \ | |||
|
104 | --hash=sha256:67d6cc0132bd77922725fae9f18366bb314fd8f95ff4d323a4df41890a96a838 \ | |||
|
105 | --hash=sha256:7b29ebfcf8678c4da531b2478a912eea01e80007e5ddca9ee0c7038cb3489ec6 \ | |||
|
106 | # via -r contrib/packaging/requirements-windows.txt.in | |||
94 | pycparser==2.20 \ |
|
107 | pycparser==2.20 \ | |
95 | --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ |
|
108 | --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ | |
96 | --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 \ |
|
109 | --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 \ | |
97 | # via cffi |
|
110 | # via cffi | |
98 |
pygments==2. |
|
111 | pygments==2.5.2 \ | |
99 | --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \ |
|
112 | --hash=sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b \ | |
100 | --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7 \ |
|
113 | --hash=sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe \ | |
101 |
# via -r contrib/packaging/requirements |
|
114 | # via -r contrib/packaging/requirements-windows.txt.in | |
102 | pywin32-ctypes==0.2.0 \ |
|
115 | pywin32-ctypes==0.2.0 \ | |
103 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ |
|
116 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ | |
104 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \ |
|
117 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \ | |
105 |
# via -r contrib/packaging/requirements |
|
118 | # via -r contrib/packaging/requirements-windows.txt.in | |
106 |
secretstorage==3.1 |
|
119 | secretstorage==2.3.1 \ | |
107 | --hash=sha256:15da8a989b65498e29be338b3b279965f1b8f09b9668bd8010da183024c8bff6 \ |
|
120 | --hash=sha256:3af65c87765323e6f64c83575b05393f9e003431959c9395d1791d51497f29b6 \ | |
108 | --hash=sha256:b5ec909dde94d4ae2fa26af7c089036997030f0cf0a5cb372b4cccabd81c143b \ |
|
|||
109 | # via keyring |
|
121 | # via keyring | |
110 | six==1.15.0 \ |
|
122 | six==1.15.0 \ | |
111 | --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \ |
|
123 | --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \ | |
112 | --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ |
|
124 | --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ | |
113 | # via cryptography |
|
125 | # via cryptography | |
114 |
urllib3==1.25.1 |
|
126 | urllib3==1.25.11 \ | |
115 | --hash=sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a \ |
|
127 | --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \ | |
116 | --hash=sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461 \ |
|
128 | --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e \ | |
117 | # via dulwich |
|
129 | # via dulwich |
@@ -1,117 +1,123 b'' | |||||
1 | # |
|
1 | # | |
2 | # This file is autogenerated by pip-compile |
|
2 | # This file is autogenerated by pip-compile | |
3 | # To update, run: |
|
3 | # To update, run: | |
4 | # |
|
4 | # | |
5 |
# pip-compile --generate-hashes --output-file=contrib/packaging/requirements |
|
5 | # pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py3.txt contrib/packaging/requirements-windows.txt.in | |
6 | # |
|
6 | # | |
7 | certifi==2020.6.20 \ |
|
7 | certifi==2020.6.20 \ | |
8 | --hash=sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3 \ |
|
8 | --hash=sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3 \ | |
9 | --hash=sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41 \ |
|
9 | --hash=sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41 \ | |
10 | # via dulwich |
|
10 | # via dulwich | |
11 | cffi==1.14.3 \ |
|
11 | cffi==1.14.3 \ | |
12 | --hash=sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d \ |
|
12 | --hash=sha256:005f2bfe11b6745d726dbb07ace4d53f057de66e336ff92d61b8c7e9c8f4777d \ | |
13 | --hash=sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b \ |
|
13 | --hash=sha256:09e96138280241bd355cd585148dec04dbbedb4f46128f340d696eaafc82dd7b \ | |
14 | --hash=sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4 \ |
|
14 | --hash=sha256:0b1ad452cc824665ddc682400b62c9e4f5b64736a2ba99110712fdee5f2505c4 \ | |
15 | --hash=sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f \ |
|
15 | --hash=sha256:0ef488305fdce2580c8b2708f22d7785ae222d9825d3094ab073e22e93dfe51f \ | |
16 | --hash=sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3 \ |
|
16 | --hash=sha256:15f351bed09897fbda218e4db5a3d5c06328862f6198d4fb385f3e14e19decb3 \ | |
17 | --hash=sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579 \ |
|
17 | --hash=sha256:22399ff4870fb4c7ef19fff6eeb20a8bbf15571913c181c78cb361024d574579 \ | |
18 | --hash=sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537 \ |
|
18 | --hash=sha256:23e5d2040367322824605bc29ae8ee9175200b92cb5483ac7d466927a9b3d537 \ | |
19 | --hash=sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e \ |
|
19 | --hash=sha256:2791f68edc5749024b4722500e86303a10d342527e1e3bcac47f35fbd25b764e \ | |
20 | --hash=sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05 \ |
|
20 | --hash=sha256:2f9674623ca39c9ebe38afa3da402e9326c245f0f5ceff0623dccdac15023e05 \ | |
21 | --hash=sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171 \ |
|
21 | --hash=sha256:3363e77a6176afb8823b6e06db78c46dbc4c7813b00a41300a4873b6ba63b171 \ | |
22 | --hash=sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca \ |
|
22 | --hash=sha256:33c6cdc071ba5cd6d96769c8969a0531be2d08c2628a0143a10a7dcffa9719ca \ | |
23 | --hash=sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522 \ |
|
23 | --hash=sha256:3b8eaf915ddc0709779889c472e553f0d3e8b7bdf62dab764c8921b09bf94522 \ | |
24 | --hash=sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c \ |
|
24 | --hash=sha256:3cb3e1b9ec43256c4e0f8d2837267a70b0e1ca8c4f456685508ae6106b1f504c \ | |
25 | --hash=sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc \ |
|
25 | --hash=sha256:3eeeb0405fd145e714f7633a5173318bd88d8bbfc3dd0a5751f8c4f70ae629bc \ | |
26 | --hash=sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d \ |
|
26 | --hash=sha256:44f60519595eaca110f248e5017363d751b12782a6f2bd6a7041cba275215f5d \ | |
27 | --hash=sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808 \ |
|
27 | --hash=sha256:4d7c26bfc1ea9f92084a1d75e11999e97b62d63128bcc90c3624d07813c52808 \ | |
28 | --hash=sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828 \ |
|
28 | --hash=sha256:529c4ed2e10437c205f38f3691a68be66c39197d01062618c55f74294a4a4828 \ | |
29 | --hash=sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869 \ |
|
29 | --hash=sha256:6642f15ad963b5092d65aed022d033c77763515fdc07095208f15d3563003869 \ | |
30 | --hash=sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d \ |
|
30 | --hash=sha256:85ba797e1de5b48aa5a8427b6ba62cf69607c18c5d4eb747604b7302f1ec382d \ | |
31 | --hash=sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9 \ |
|
31 | --hash=sha256:8f0f1e499e4000c4c347a124fa6a27d37608ced4fe9f7d45070563b7c4c370c9 \ | |
32 | --hash=sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0 \ |
|
32 | --hash=sha256:a624fae282e81ad2e4871bdb767e2c914d0539708c0f078b5b355258293c98b0 \ | |
33 | --hash=sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc \ |
|
33 | --hash=sha256:b0358e6fefc74a16f745afa366acc89f979040e0cbc4eec55ab26ad1f6a9bfbc \ | |
34 | --hash=sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15 \ |
|
34 | --hash=sha256:bbd2f4dfee1079f76943767fce837ade3087b578aeb9f69aec7857d5bf25db15 \ | |
35 | --hash=sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c \ |
|
35 | --hash=sha256:bf39a9e19ce7298f1bd6a9758fa99707e9e5b1ebe5e90f2c3913a47bc548747c \ | |
36 | --hash=sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a \ |
|
36 | --hash=sha256:c11579638288e53fc94ad60022ff1b67865363e730ee41ad5e6f0a17188b327a \ | |
37 | --hash=sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3 \ |
|
37 | --hash=sha256:c150eaa3dadbb2b5339675b88d4573c1be3cb6f2c33a6c83387e10cc0bf05bd3 \ | |
38 | --hash=sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1 \ |
|
38 | --hash=sha256:c53af463f4a40de78c58b8b2710ade243c81cbca641e34debf3396a9640d6ec1 \ | |
39 | --hash=sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768 \ |
|
39 | --hash=sha256:cb763ceceae04803adcc4e2d80d611ef201c73da32d8f2722e9d0ab0c7f10768 \ | |
40 | --hash=sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d \ |
|
40 | --hash=sha256:cc75f58cdaf043fe6a7a6c04b3b5a0e694c6a9e24050967747251fb80d7bce0d \ | |
41 | --hash=sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b \ |
|
41 | --hash=sha256:d80998ed59176e8cba74028762fbd9b9153b9afc71ea118e63bbf5d4d0f9552b \ | |
42 | --hash=sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e \ |
|
42 | --hash=sha256:de31b5164d44ef4943db155b3e8e17929707cac1e5bd2f363e67a56e3af4af6e \ | |
43 | --hash=sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d \ |
|
43 | --hash=sha256:e66399cf0fc07de4dce4f588fc25bfe84a6d1285cc544e67987d22663393926d \ | |
44 | --hash=sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730 \ |
|
44 | --hash=sha256:f0620511387790860b249b9241c2f13c3a80e21a73e0b861a2df24e9d6f56730 \ | |
45 | --hash=sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394 \ |
|
45 | --hash=sha256:f4eae045e6ab2bb54ca279733fe4eb85f1effda392666308250714e01907f394 \ | |
46 | --hash=sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1 \ |
|
46 | --hash=sha256:f92cdecb618e5fa4658aeb97d5eb3d2f47aa94ac6477c6daf0f306c5a3b9e6b1 \ | |
47 | --hash=sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591 \ |
|
47 | --hash=sha256:f92f789e4f9241cd262ad7a555ca2c648a98178a953af117ef7fad46aa1d5591 \ | |
48 | # via cryptography |
|
48 | # via cryptography | |
49 | cryptography==3.1.1 \ |
|
49 | cryptography==3.1.1 \ | |
50 | --hash=sha256:21b47c59fcb1c36f1113f3709d37935368e34815ea1d7073862e92f810dc7499 \ |
|
50 | --hash=sha256:21b47c59fcb1c36f1113f3709d37935368e34815ea1d7073862e92f810dc7499 \ | |
51 | --hash=sha256:451cdf60be4dafb6a3b78802006a020e6cd709c22d240f94f7a0696240a17154 \ |
|
51 | --hash=sha256:451cdf60be4dafb6a3b78802006a020e6cd709c22d240f94f7a0696240a17154 \ | |
52 | --hash=sha256:4549b137d8cbe3c2eadfa56c0c858b78acbeff956bd461e40000b2164d9167c6 \ |
|
52 | --hash=sha256:4549b137d8cbe3c2eadfa56c0c858b78acbeff956bd461e40000b2164d9167c6 \ | |
53 | --hash=sha256:48ee615a779ffa749d7d50c291761dc921d93d7cf203dca2db663b4f193f0e49 \ |
|
53 | --hash=sha256:48ee615a779ffa749d7d50c291761dc921d93d7cf203dca2db663b4f193f0e49 \ | |
54 | --hash=sha256:559d622aef2a2dff98a892eef321433ba5bc55b2485220a8ca289c1ecc2bd54f \ |
|
54 | --hash=sha256:559d622aef2a2dff98a892eef321433ba5bc55b2485220a8ca289c1ecc2bd54f \ | |
55 | --hash=sha256:5d52c72449bb02dd45a773a203196e6d4fae34e158769c896012401f33064396 \ |
|
55 | --hash=sha256:5d52c72449bb02dd45a773a203196e6d4fae34e158769c896012401f33064396 \ | |
56 | --hash=sha256:65beb15e7f9c16e15934569d29fb4def74ea1469d8781f6b3507ab896d6d8719 \ |
|
56 | --hash=sha256:65beb15e7f9c16e15934569d29fb4def74ea1469d8781f6b3507ab896d6d8719 \ | |
57 | --hash=sha256:680da076cad81cdf5ffcac50c477b6790be81768d30f9da9e01960c4b18a66db \ |
|
57 | --hash=sha256:680da076cad81cdf5ffcac50c477b6790be81768d30f9da9e01960c4b18a66db \ | |
58 | --hash=sha256:762bc5a0df03c51ee3f09c621e1cee64e3a079a2b5020de82f1613873d79ee70 \ |
|
58 | --hash=sha256:762bc5a0df03c51ee3f09c621e1cee64e3a079a2b5020de82f1613873d79ee70 \ | |
59 | --hash=sha256:89aceb31cd5f9fc2449fe8cf3810797ca52b65f1489002d58fe190bfb265c536 \ |
|
59 | --hash=sha256:89aceb31cd5f9fc2449fe8cf3810797ca52b65f1489002d58fe190bfb265c536 \ | |
60 | --hash=sha256:983c0c3de4cb9fcba68fd3f45ed846eb86a2a8b8d8bc5bb18364c4d00b3c61fe \ |
|
60 | --hash=sha256:983c0c3de4cb9fcba68fd3f45ed846eb86a2a8b8d8bc5bb18364c4d00b3c61fe \ | |
61 | --hash=sha256:99d4984aabd4c7182050bca76176ce2dbc9fa9748afe583a7865c12954d714ba \ |
|
61 | --hash=sha256:99d4984aabd4c7182050bca76176ce2dbc9fa9748afe583a7865c12954d714ba \ | |
62 | --hash=sha256:9d9fc6a16357965d282dd4ab6531013935425d0dc4950df2e0cf2a1b1ac1017d \ |
|
62 | --hash=sha256:9d9fc6a16357965d282dd4ab6531013935425d0dc4950df2e0cf2a1b1ac1017d \ | |
63 | --hash=sha256:a7597ffc67987b37b12e09c029bd1dc43965f75d328076ae85721b84046e9ca7 \ |
|
63 | --hash=sha256:a7597ffc67987b37b12e09c029bd1dc43965f75d328076ae85721b84046e9ca7 \ | |
64 | --hash=sha256:ab010e461bb6b444eaf7f8c813bb716be2d78ab786103f9608ffd37a4bd7d490 \ |
|
64 | --hash=sha256:ab010e461bb6b444eaf7f8c813bb716be2d78ab786103f9608ffd37a4bd7d490 \ | |
65 | --hash=sha256:b12e715c10a13ca1bd27fbceed9adc8c5ff640f8e1f7ea76416352de703523c8 \ |
|
65 | --hash=sha256:b12e715c10a13ca1bd27fbceed9adc8c5ff640f8e1f7ea76416352de703523c8 \ | |
66 | --hash=sha256:b2bded09c578d19e08bd2c5bb8fed7f103e089752c9cf7ca7ca7de522326e921 \ |
|
66 | --hash=sha256:b2bded09c578d19e08bd2c5bb8fed7f103e089752c9cf7ca7ca7de522326e921 \ | |
67 | --hash=sha256:b372026ebf32fe2523159f27d9f0e9f485092e43b00a5adacf732192a70ba118 \ |
|
67 | --hash=sha256:b372026ebf32fe2523159f27d9f0e9f485092e43b00a5adacf732192a70ba118 \ | |
68 | --hash=sha256:cb179acdd4ae1e4a5a160d80b87841b3d0e0be84af46c7bb2cd7ece57a39c4ba \ |
|
68 | --hash=sha256:cb179acdd4ae1e4a5a160d80b87841b3d0e0be84af46c7bb2cd7ece57a39c4ba \ | |
69 | --hash=sha256:e97a3b627e3cb63c415a16245d6cef2139cca18bb1183d1b9375a1c14e83f3b3 \ |
|
69 | --hash=sha256:e97a3b627e3cb63c415a16245d6cef2139cca18bb1183d1b9375a1c14e83f3b3 \ | |
70 | --hash=sha256:f0e099fc4cc697450c3dd4031791559692dd941a95254cb9aeded66a7aa8b9bc \ |
|
70 | --hash=sha256:f0e099fc4cc697450c3dd4031791559692dd941a95254cb9aeded66a7aa8b9bc \ | |
71 | --hash=sha256:f99317a0fa2e49917689b8cf977510addcfaaab769b3f899b9c481bbd76730c2 \ |
|
71 | --hash=sha256:f99317a0fa2e49917689b8cf977510addcfaaab769b3f899b9c481bbd76730c2 \ | |
72 | # via secretstorage |
|
72 | # via secretstorage | |
73 | docutils==0.16 \ |
|
73 | docutils==0.16 \ | |
74 | --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ |
|
74 | --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \ | |
75 | --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \ |
|
75 | --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \ | |
76 |
# via -r contrib/packaging/requirements |
|
76 | # via -r contrib/packaging/requirements-windows.txt.in | |
77 | dulwich==0.19.16 \ |
|
77 | dulwich==0.20.6 ; python_version >= "3" \ | |
78 | --hash=sha256:10699277c6268d0c16febe141a5b1c1a6e9744f3144c2d2de1706f4b1adafe63 \ |
|
78 | --hash=sha256:1ccd55e38fa9f169290f93e027ab4508202f5bdd6ef534facac4edd3f6903f0d \ | |
79 | --hash=sha256:267160904e9a1cb6c248c5efc53597a35d038ecc6f60bdc4546b3053bed11982 \ |
|
79 | --hash=sha256:2452a0379cc7bbbd7ab893ec104d18039f1ea98b0d6be6bca5646e5cf29e0ae9 \ | |
80 | --hash=sha256:4e3aba5e4844e7c700721c1fc696987ea820ee3528a03604dc4e74eff4196826 \ |
|
80 | --hash=sha256:2f4aebc54ed2d37dcee737024421452375570a422eb682232e676aa7ebc9cb4b \ | |
81 | --hash=sha256:60bb2c2c92f5025c1b53a556304008f0f624c98ae36f22d870e056b2d4236c11 \ |
|
81 | --hash=sha256:304f52b10c49c3a6ddfbd73e2e93d8e979350225cfba9688e51110e74fa2f718 \ | |
82 | --hash=sha256:dddae02d372fc3b5cfb0046d0f62246ef281fa0c088df7601ab5916607add94b \ |
|
82 | --hash=sha256:49e747c72d9099e873bf6196260346d5996c3f28af788294d47a8accdc524de7 \ | |
83 | --hash=sha256:f00d132082b8fcc2eb0d722abc773d4aeb5558c1475d7edd1f0f571146c29db9 \ |
|
83 | --hash=sha256:4fee359928c59b53af153a582a7ed7595259a5a825df400301a29e17fd78dfd3 \ | |
84 | --hash=sha256:f74561c448bfb6f04c07de731c1181ae4280017f759b0bb04fa5770aa84ca850 \ |
|
84 | --hash=sha256:50ef300a9fa4efd9f85009c2bd8b515266ec1529400f8834f85c04fa9f09b2c0 \ | |
85 | # via -r contrib/packaging/requirements_win32.txt.in |
|
85 | --hash=sha256:5348310f21b2a23847342ce464461499b6652483fa42de03714d0f6421a99698 \ | |
|
86 | --hash=sha256:7e7b5dea5178b6493fdb83adccbe81de9ddff55f79880185ed594c0e3a97209b \ | |||
|
87 | --hash=sha256:8f7a7f973be2beedfb10dd8d3eb6bdf9ec466c72ad555704897cbd6357fe5021 \ | |||
|
88 | --hash=sha256:bea6e6caffc6c73bfd1647714c5715ab96ac49deb8beb8b67511529afa25685a \ | |||
|
89 | --hash=sha256:e5871b86a079e9e290f52ab14559cea1b694a0b8ed2b9ebb898f6ced7f14a406 \ | |||
|
90 | --hash=sha256:e593f514b8ac740b4ceeb047745b4719bfc9f334904245c6edcb3a9d002f577b \ | |||
|
91 | # via -r contrib/packaging/requirements-windows.txt.in | |||
86 | jeepney==0.4.3 \ |
|
92 | jeepney==0.4.3 \ | |
87 | --hash=sha256:3479b861cc2b6407de5188695fa1a8d57e5072d7059322469b62628869b8e36e \ |
|
93 | --hash=sha256:3479b861cc2b6407de5188695fa1a8d57e5072d7059322469b62628869b8e36e \ | |
88 | --hash=sha256:d6c6b49683446d2407d2fe3acb7a368a77ff063f9182fe427da15d622adc24cf \ |
|
94 | --hash=sha256:d6c6b49683446d2407d2fe3acb7a368a77ff063f9182fe427da15d622adc24cf \ | |
89 | # via keyring, secretstorage |
|
95 | # via keyring, secretstorage | |
90 | keyring==21.4.0 \ |
|
96 | keyring==21.4.0 \ | |
91 | --hash=sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d \ |
|
97 | --hash=sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d \ | |
92 | --hash=sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466 \ |
|
98 | --hash=sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466 \ | |
93 |
# via -r contrib/packaging/requirements |
|
99 | # via -r contrib/packaging/requirements-windows.txt.in | |
94 | pycparser==2.20 \ |
|
100 | pycparser==2.20 \ | |
95 | --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ |
|
101 | --hash=sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0 \ | |
96 | --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 \ |
|
102 | --hash=sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705 \ | |
97 | # via cffi |
|
103 | # via cffi | |
98 | pygments==2.7.1 \ |
|
104 | pygments==2.7.1 \ | |
99 | --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \ |
|
105 | --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \ | |
100 | --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7 \ |
|
106 | --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7 \ | |
101 |
# via -r contrib/packaging/requirements |
|
107 | # via -r contrib/packaging/requirements-windows.txt.in | |
102 | pywin32-ctypes==0.2.0 \ |
|
108 | pywin32-ctypes==0.2.0 \ | |
103 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ |
|
109 | --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \ | |
104 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \ |
|
110 | --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \ | |
105 |
# via -r contrib/packaging/requirements |
|
111 | # via -r contrib/packaging/requirements-windows.txt.in | |
106 | secretstorage==3.1.2 \ |
|
112 | secretstorage==3.1.2 \ | |
107 | --hash=sha256:15da8a989b65498e29be338b3b279965f1b8f09b9668bd8010da183024c8bff6 \ |
|
113 | --hash=sha256:15da8a989b65498e29be338b3b279965f1b8f09b9668bd8010da183024c8bff6 \ | |
108 | --hash=sha256:b5ec909dde94d4ae2fa26af7c089036997030f0cf0a5cb372b4cccabd81c143b \ |
|
114 | --hash=sha256:b5ec909dde94d4ae2fa26af7c089036997030f0cf0a5cb372b4cccabd81c143b \ | |
109 | # via keyring |
|
115 | # via keyring | |
110 | six==1.15.0 \ |
|
116 | six==1.15.0 \ | |
111 | --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \ |
|
117 | --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \ | |
112 | --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ |
|
118 | --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \ | |
113 | # via cryptography |
|
119 | # via cryptography | |
114 |
urllib3==1.25.1 |
|
120 | urllib3==1.25.11 \ | |
115 | --hash=sha256:91056c15fa70756691db97756772bb1eb9678fa585d9184f24534b100dc60f4a \ |
|
121 | --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \ | |
116 | --hash=sha256:e7983572181f5e1522d9c98453462384ee92a0be7fac5f1413a1e35c56cc0461 \ |
|
122 | --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e \ | |
117 | # via dulwich |
|
123 | # via dulwich |
@@ -1,8 +1,9 b'' | |||||
1 | docutils |
|
1 | docutils | |
2 | # Pinned to an old version because 0.20 drops Python 3 compatibility. |
|
2 | # Pinned to an old version because 0.20 drops Python 3 compatibility. | |
3 | dulwich < 0.20 |
|
3 | dulwich < 0.20 ; python_version <= '2.7' | |
|
4 | dulwich ; python_version >= '3' | |||
4 | keyring |
|
5 | keyring | |
5 | pygments |
|
6 | pygments | |
6 | # Need to list explicitly so dependency gets pulled in when |
|
7 | # Need to list explicitly so dependency gets pulled in when | |
7 | # not running on Windows. |
|
8 | # not running on Windows. | |
8 | pywin32-ctypes |
|
9 | pywin32-ctypes |
@@ -1,184 +1,184 b'' | |||||
1 | # demandimportpy3 - global demand-loading of modules for Mercurial |
|
1 | # demandimportpy3 - global demand-loading of modules for Mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2017 Facebook Inc. |
|
3 | # Copyright 2017 Facebook Inc. | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | """Lazy loading for Python 3.6 and above. |
|
8 | """Lazy loading for Python 3.6 and above. | |
9 |
|
9 | |||
10 | This uses the new importlib finder/loader functionality available in Python 3.5 |
|
10 | This uses the new importlib finder/loader functionality available in Python 3.5 | |
11 | and up. The code reuses most of the mechanics implemented inside importlib.util, |
|
11 | and up. The code reuses most of the mechanics implemented inside importlib.util, | |
12 | but with a few additions: |
|
12 | but with a few additions: | |
13 |
|
13 | |||
14 | * Allow excluding certain modules from lazy imports. |
|
14 | * Allow excluding certain modules from lazy imports. | |
15 | * Expose an interface that's substantially the same as demandimport for |
|
15 | * Expose an interface that's substantially the same as demandimport for | |
16 | Python 2. |
|
16 | Python 2. | |
17 |
|
17 | |||
18 | This also has some limitations compared to the Python 2 implementation: |
|
18 | This also has some limitations compared to the Python 2 implementation: | |
19 |
|
19 | |||
20 | * Much of the logic is per-package, not per-module, so any packages loaded |
|
20 | * Much of the logic is per-package, not per-module, so any packages loaded | |
21 | before demandimport is enabled will not be lazily imported in the future. In |
|
21 | before demandimport is enabled will not be lazily imported in the future. In | |
22 | practice, we only expect builtins to be loaded before demandimport is |
|
22 | practice, we only expect builtins to be loaded before demandimport is | |
23 | enabled. |
|
23 | enabled. | |
24 | """ |
|
24 | """ | |
25 |
|
25 | |||
26 | # This line is unnecessary, but it satisfies test-check-py3-compat.t. |
|
26 | # This line is unnecessary, but it satisfies test-check-py3-compat.t. | |
27 | from __future__ import absolute_import |
|
27 | from __future__ import absolute_import | |
28 |
|
28 | |||
29 | import contextlib |
|
29 | import contextlib | |
30 | import importlib.util |
|
30 | import importlib.util | |
31 | import sys |
|
31 | import sys | |
32 |
|
32 | |||
33 | from . import tracing |
|
33 | from . import tracing | |
34 |
|
34 | |||
35 | _deactivated = False |
|
35 | _deactivated = False | |
36 |
|
36 | |||
37 | # Python 3.5's LazyLoader doesn't work for some reason. |
|
37 | # Python 3.5's LazyLoader doesn't work for some reason. | |
38 | # https://bugs.python.org/issue26186 is a known issue with extension |
|
38 | # https://bugs.python.org/issue26186 is a known issue with extension | |
39 | # importing. But it appears to not have a meaningful effect with |
|
39 | # importing. But it appears to not have a meaningful effect with | |
40 | # Mercurial. |
|
40 | # Mercurial. | |
41 | _supported = sys.version_info[0:2] >= (3, 6) |
|
41 | _supported = sys.version_info[0:2] >= (3, 6) | |
42 |
|
42 | |||
43 |
|
43 | |||
44 | class _lazyloaderex(importlib.util.LazyLoader): |
|
44 | class _lazyloaderex(importlib.util.LazyLoader): | |
45 | """This is a LazyLoader except it also follows the _deactivated global and |
|
45 | """This is a LazyLoader except it also follows the _deactivated global and | |
46 | the ignore list. |
|
46 | the ignore list. | |
47 | """ |
|
47 | """ | |
48 |
|
48 | |||
49 | def exec_module(self, module): |
|
49 | def exec_module(self, module): | |
50 | """Make the module load lazily.""" |
|
50 | """Make the module load lazily.""" | |
51 | with tracing.log('demandimport %s', module): |
|
51 | with tracing.log('demandimport %s', module): | |
52 | if _deactivated or module.__name__ in ignores: |
|
52 | if _deactivated or module.__name__ in ignores: | |
53 | self.loader.exec_module(module) |
|
53 | self.loader.exec_module(module) | |
54 | else: |
|
54 | else: | |
55 | super().exec_module(module) |
|
55 | super().exec_module(module) | |
56 |
|
56 | |||
57 |
|
57 | |||
58 | class LazyFinder(object): |
|
58 | class LazyFinder(object): | |
59 | """A wrapper around a ``MetaPathFinder`` that makes loaders lazy. |
|
59 | """A wrapper around a ``MetaPathFinder`` that makes loaders lazy. | |
60 |
|
60 | |||
61 | ``sys.meta_path`` finders have their ``find_spec()`` called to locate a |
|
61 | ``sys.meta_path`` finders have their ``find_spec()`` called to locate a | |
62 | module. This returns a ``ModuleSpec`` if found or ``None``. The |
|
62 | module. This returns a ``ModuleSpec`` if found or ``None``. The | |
63 | ``ModuleSpec`` has a ``loader`` attribute, which is called to actually |
|
63 | ``ModuleSpec`` has a ``loader`` attribute, which is called to actually | |
64 | load a module. |
|
64 | load a module. | |
65 |
|
65 | |||
66 | Our class wraps an existing finder and overloads its ``find_spec()`` to |
|
66 | Our class wraps an existing finder and overloads its ``find_spec()`` to | |
67 | replace the ``loader`` with our lazy loader proxy. |
|
67 | replace the ``loader`` with our lazy loader proxy. | |
68 |
|
68 | |||
69 | We have to use __getattribute__ to proxy the instance because some meta |
|
69 | We have to use __getattribute__ to proxy the instance because some meta | |
70 | path finders don't support monkeypatching. |
|
70 | path finders don't support monkeypatching. | |
71 | """ |
|
71 | """ | |
72 |
|
72 | |||
73 | __slots__ = ("_finder",) |
|
73 | __slots__ = ("_finder",) | |
74 |
|
74 | |||
75 | def __init__(self, finder): |
|
75 | def __init__(self, finder): | |
76 | object.__setattr__(self, "_finder", finder) |
|
76 | object.__setattr__(self, "_finder", finder) | |
77 |
|
77 | |||
78 | def __repr__(self): |
|
78 | def __repr__(self): | |
79 | return "<LazyFinder for %r>" % object.__getattribute__(self, "_finder") |
|
79 | return "<LazyFinder for %r>" % object.__getattribute__(self, "_finder") | |
80 |
|
80 | |||
81 | # __bool__ is canonical Python 3. But check-code insists on __nonzero__ being |
|
81 | # __bool__ is canonical Python 3. But check-code insists on __nonzero__ being | |
82 | # defined via `def`. |
|
82 | # defined via `def`. | |
83 | def __nonzero__(self): |
|
83 | def __nonzero__(self): | |
84 | return bool(object.__getattribute__(self, "_finder")) |
|
84 | return bool(object.__getattribute__(self, "_finder")) | |
85 |
|
85 | |||
86 | __bool__ = __nonzero__ |
|
86 | __bool__ = __nonzero__ | |
87 |
|
87 | |||
88 | def __getattribute__(self, name): |
|
88 | def __getattribute__(self, name): | |
89 | if name in ("_finder", "find_spec"): |
|
89 | if name in ("_finder", "find_spec"): | |
90 | return object.__getattribute__(self, name) |
|
90 | return object.__getattribute__(self, name) | |
91 |
|
91 | |||
92 | return getattr(object.__getattribute__(self, "_finder"), name) |
|
92 | return getattr(object.__getattribute__(self, "_finder"), name) | |
93 |
|
93 | |||
94 | def __delattr__(self, name): |
|
94 | def __delattr__(self, name): | |
95 | return delattr(object.__getattribute__(self, "_finder")) |
|
95 | return delattr(object.__getattribute__(self, "_finder")) | |
96 |
|
96 | |||
97 | def __setattr__(self, name, value): |
|
97 | def __setattr__(self, name, value): | |
98 | return setattr(object.__getattribute__(self, "_finder"), name, value) |
|
98 | return setattr(object.__getattribute__(self, "_finder"), name, value) | |
99 |
|
99 | |||
100 | def find_spec(self, fullname, path, target=None): |
|
100 | def find_spec(self, fullname, path, target=None): | |
101 | finder = object.__getattribute__(self, "_finder") |
|
101 | finder = object.__getattribute__(self, "_finder") | |
102 | try: |
|
102 | try: | |
103 | find_spec = finder.find_spec |
|
103 | find_spec = finder.find_spec | |
104 | except AttributeError: |
|
104 | except AttributeError: | |
105 | loader = finder.find_module(fullname, path) |
|
105 | loader = finder.find_module(fullname, path) | |
106 | if loader is None: |
|
106 | if loader is None: | |
107 | spec = None |
|
107 | spec = None | |
108 | else: |
|
108 | else: | |
109 | spec = importlib.util.spec_from_loader(fullname, loader) |
|
109 | spec = importlib.util.spec_from_loader(fullname, loader) | |
110 | else: |
|
110 | else: | |
111 | spec = find_spec(fullname, path, target) |
|
111 | spec = find_spec(fullname, path, target) | |
112 |
|
112 | |||
113 | # Lazy loader requires exec_module(). |
|
113 | # Lazy loader requires exec_module(). | |
114 | if ( |
|
114 | if ( | |
115 | spec is not None |
|
115 | spec is not None | |
116 | and spec.loader is not None |
|
116 | and spec.loader is not None | |
117 | and getattr(spec.loader, "exec_module") |
|
117 | and getattr(spec.loader, "exec_module", None) | |
118 | ): |
|
118 | ): | |
119 | spec.loader = _lazyloaderex(spec.loader) |
|
119 | spec.loader = _lazyloaderex(spec.loader) | |
120 |
|
120 | |||
121 | return spec |
|
121 | return spec | |
122 |
|
122 | |||
123 |
|
123 | |||
124 | ignores = set() |
|
124 | ignores = set() | |
125 |
|
125 | |||
126 |
|
126 | |||
127 | def init(ignoreset): |
|
127 | def init(ignoreset): | |
128 | global ignores |
|
128 | global ignores | |
129 | ignores = ignoreset |
|
129 | ignores = ignoreset | |
130 |
|
130 | |||
131 |
|
131 | |||
132 | def isenabled(): |
|
132 | def isenabled(): | |
133 | return not _deactivated and any( |
|
133 | return not _deactivated and any( | |
134 | isinstance(finder, LazyFinder) for finder in sys.meta_path |
|
134 | isinstance(finder, LazyFinder) for finder in sys.meta_path | |
135 | ) |
|
135 | ) | |
136 |
|
136 | |||
137 |
|
137 | |||
138 | def disable(): |
|
138 | def disable(): | |
139 | new_finders = [] |
|
139 | new_finders = [] | |
140 | for finder in sys.meta_path: |
|
140 | for finder in sys.meta_path: | |
141 | new_finders.append( |
|
141 | new_finders.append( | |
142 | finder._finder if isinstance(finder, LazyFinder) else finder |
|
142 | finder._finder if isinstance(finder, LazyFinder) else finder | |
143 | ) |
|
143 | ) | |
144 | sys.meta_path[:] = new_finders |
|
144 | sys.meta_path[:] = new_finders | |
145 |
|
145 | |||
146 |
|
146 | |||
147 | def enable(): |
|
147 | def enable(): | |
148 | if not _supported: |
|
148 | if not _supported: | |
149 | return |
|
149 | return | |
150 |
|
150 | |||
151 | new_finders = [] |
|
151 | new_finders = [] | |
152 | for finder in sys.meta_path: |
|
152 | for finder in sys.meta_path: | |
153 | new_finders.append( |
|
153 | new_finders.append( | |
154 | LazyFinder(finder) if not isinstance(finder, LazyFinder) else finder |
|
154 | LazyFinder(finder) if not isinstance(finder, LazyFinder) else finder | |
155 | ) |
|
155 | ) | |
156 | sys.meta_path[:] = new_finders |
|
156 | sys.meta_path[:] = new_finders | |
157 |
|
157 | |||
158 |
|
158 | |||
159 | @contextlib.contextmanager |
|
159 | @contextlib.contextmanager | |
160 | def deactivated(): |
|
160 | def deactivated(): | |
161 | # This implementation is a bit different from Python 2's. Python 3 |
|
161 | # This implementation is a bit different from Python 2's. Python 3 | |
162 | # maintains a per-package finder cache in sys.path_importer_cache (see |
|
162 | # maintains a per-package finder cache in sys.path_importer_cache (see | |
163 | # PEP 302). This means that we can't just call disable + enable. |
|
163 | # PEP 302). This means that we can't just call disable + enable. | |
164 | # If we do that, in situations like: |
|
164 | # If we do that, in situations like: | |
165 | # |
|
165 | # | |
166 | # demandimport.enable() |
|
166 | # demandimport.enable() | |
167 | # ... |
|
167 | # ... | |
168 | # from foo.bar import mod1 |
|
168 | # from foo.bar import mod1 | |
169 | # with demandimport.deactivated(): |
|
169 | # with demandimport.deactivated(): | |
170 | # from foo.bar import mod2 |
|
170 | # from foo.bar import mod2 | |
171 | # |
|
171 | # | |
172 | # mod2 will be imported lazily. (The converse also holds -- whatever finder |
|
172 | # mod2 will be imported lazily. (The converse also holds -- whatever finder | |
173 | # first gets cached will be used.) |
|
173 | # first gets cached will be used.) | |
174 | # |
|
174 | # | |
175 | # Instead, have a global flag the LazyLoader can use. |
|
175 | # Instead, have a global flag the LazyLoader can use. | |
176 | global _deactivated |
|
176 | global _deactivated | |
177 | demandenabled = isenabled() |
|
177 | demandenabled = isenabled() | |
178 | if demandenabled: |
|
178 | if demandenabled: | |
179 | _deactivated = True |
|
179 | _deactivated = True | |
180 | try: |
|
180 | try: | |
181 | yield |
|
181 | yield | |
182 | finally: |
|
182 | finally: | |
183 | if demandenabled: |
|
183 | if demandenabled: | |
184 | _deactivated = False |
|
184 | _deactivated = False |
@@ -1,2793 +1,2796 b'' | |||||
1 | # revset.py - revision set queries for mercurial |
|
1 | # revset.py - revision set queries for mercurial | |
2 | # |
|
2 | # | |
3 | # Copyright 2010 Matt Mackall <mpm@selenic.com> |
|
3 | # Copyright 2010 Matt Mackall <mpm@selenic.com> | |
4 | # |
|
4 | # | |
5 | # This software may be used and distributed according to the terms of the |
|
5 | # This software may be used and distributed according to the terms of the | |
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | from __future__ import absolute_import |
|
8 | from __future__ import absolute_import | |
9 |
|
9 | |||
10 | import re |
|
10 | import re | |
11 |
|
11 | |||
12 | from .i18n import _ |
|
12 | from .i18n import _ | |
13 | from .pycompat import getattr |
|
13 | from .pycompat import getattr | |
14 | from . import ( |
|
14 | from . import ( | |
15 | dagop, |
|
15 | dagop, | |
16 | destutil, |
|
16 | destutil, | |
17 | diffutil, |
|
17 | diffutil, | |
18 | encoding, |
|
18 | encoding, | |
19 | error, |
|
19 | error, | |
20 | grep as grepmod, |
|
20 | grep as grepmod, | |
21 | hbisect, |
|
21 | hbisect, | |
22 | match as matchmod, |
|
22 | match as matchmod, | |
23 | node, |
|
23 | node, | |
24 | obsolete as obsmod, |
|
24 | obsolete as obsmod, | |
25 | obsutil, |
|
25 | obsutil, | |
26 | pathutil, |
|
26 | pathutil, | |
27 | phases, |
|
27 | phases, | |
28 | pycompat, |
|
28 | pycompat, | |
29 | registrar, |
|
29 | registrar, | |
30 | repoview, |
|
30 | repoview, | |
31 | revsetlang, |
|
31 | revsetlang, | |
32 | scmutil, |
|
32 | scmutil, | |
33 | smartset, |
|
33 | smartset, | |
34 | stack as stackmod, |
|
34 | stack as stackmod, | |
35 | util, |
|
35 | util, | |
36 | ) |
|
36 | ) | |
37 | from .utils import ( |
|
37 | from .utils import ( | |
38 | dateutil, |
|
38 | dateutil, | |
39 | stringutil, |
|
39 | stringutil, | |
40 | ) |
|
40 | ) | |
41 |
|
41 | |||
42 | # helpers for processing parsed tree |
|
42 | # helpers for processing parsed tree | |
43 | getsymbol = revsetlang.getsymbol |
|
43 | getsymbol = revsetlang.getsymbol | |
44 | getstring = revsetlang.getstring |
|
44 | getstring = revsetlang.getstring | |
45 | getinteger = revsetlang.getinteger |
|
45 | getinteger = revsetlang.getinteger | |
46 | getboolean = revsetlang.getboolean |
|
46 | getboolean = revsetlang.getboolean | |
47 | getlist = revsetlang.getlist |
|
47 | getlist = revsetlang.getlist | |
48 | getintrange = revsetlang.getintrange |
|
48 | getintrange = revsetlang.getintrange | |
49 | getargs = revsetlang.getargs |
|
49 | getargs = revsetlang.getargs | |
50 | getargsdict = revsetlang.getargsdict |
|
50 | getargsdict = revsetlang.getargsdict | |
51 |
|
51 | |||
52 | baseset = smartset.baseset |
|
52 | baseset = smartset.baseset | |
53 | generatorset = smartset.generatorset |
|
53 | generatorset = smartset.generatorset | |
54 | spanset = smartset.spanset |
|
54 | spanset = smartset.spanset | |
55 | fullreposet = smartset.fullreposet |
|
55 | fullreposet = smartset.fullreposet | |
56 |
|
56 | |||
57 | # revisions not included in all(), but populated if specified |
|
57 | # revisions not included in all(), but populated if specified | |
58 | _virtualrevs = (node.nullrev, node.wdirrev) |
|
58 | _virtualrevs = (node.nullrev, node.wdirrev) | |
59 |
|
59 | |||
60 | # Constants for ordering requirement, used in getset(): |
|
60 | # Constants for ordering requirement, used in getset(): | |
61 | # |
|
61 | # | |
62 | # If 'define', any nested functions and operations MAY change the ordering of |
|
62 | # If 'define', any nested functions and operations MAY change the ordering of | |
63 | # the entries in the set (but if changes the ordering, it MUST ALWAYS change |
|
63 | # the entries in the set (but if changes the ordering, it MUST ALWAYS change | |
64 | # it). If 'follow', any nested functions and operations MUST take the ordering |
|
64 | # it). If 'follow', any nested functions and operations MUST take the ordering | |
65 | # specified by the first operand to the '&' operator. |
|
65 | # specified by the first operand to the '&' operator. | |
66 | # |
|
66 | # | |
67 | # For instance, |
|
67 | # For instance, | |
68 | # |
|
68 | # | |
69 | # X & (Y | Z) |
|
69 | # X & (Y | Z) | |
70 | # ^ ^^^^^^^ |
|
70 | # ^ ^^^^^^^ | |
71 | # | follow |
|
71 | # | follow | |
72 | # define |
|
72 | # define | |
73 | # |
|
73 | # | |
74 | # will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order |
|
74 | # will be evaluated as 'or(y(x()), z(x()))', where 'x()' can change the order | |
75 | # of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't. |
|
75 | # of the entries in the set, but 'y()', 'z()' and 'or()' shouldn't. | |
76 | # |
|
76 | # | |
77 | # 'any' means the order doesn't matter. For instance, |
|
77 | # 'any' means the order doesn't matter. For instance, | |
78 | # |
|
78 | # | |
79 | # (X & !Y) | ancestors(Z) |
|
79 | # (X & !Y) | ancestors(Z) | |
80 | # ^ ^ |
|
80 | # ^ ^ | |
81 | # any any |
|
81 | # any any | |
82 | # |
|
82 | # | |
83 | # For 'X & !Y', 'X' decides the order and 'Y' is subtracted from 'X', so the |
|
83 | # For 'X & !Y', 'X' decides the order and 'Y' is subtracted from 'X', so the | |
84 | # order of 'Y' does not matter. For 'ancestors(Z)', Z's order does not matter |
|
84 | # order of 'Y' does not matter. For 'ancestors(Z)', Z's order does not matter | |
85 | # since 'ancestors' does not care about the order of its argument. |
|
85 | # since 'ancestors' does not care about the order of its argument. | |
86 | # |
|
86 | # | |
87 | # Currently, most revsets do not care about the order, so 'define' is |
|
87 | # Currently, most revsets do not care about the order, so 'define' is | |
88 | # equivalent to 'follow' for them, and the resulting order is based on the |
|
88 | # equivalent to 'follow' for them, and the resulting order is based on the | |
89 | # 'subset' parameter passed down to them: |
|
89 | # 'subset' parameter passed down to them: | |
90 | # |
|
90 | # | |
91 | # m = revset.match(...) |
|
91 | # m = revset.match(...) | |
92 | # m(repo, subset, order=defineorder) |
|
92 | # m(repo, subset, order=defineorder) | |
93 | # ^^^^^^ |
|
93 | # ^^^^^^ | |
94 | # For most revsets, 'define' means using the order this subset provides |
|
94 | # For most revsets, 'define' means using the order this subset provides | |
95 | # |
|
95 | # | |
96 | # There are a few revsets that always redefine the order if 'define' is |
|
96 | # There are a few revsets that always redefine the order if 'define' is | |
97 | # specified: 'sort(X)', 'reverse(X)', 'x:y'. |
|
97 | # specified: 'sort(X)', 'reverse(X)', 'x:y'. | |
98 | anyorder = b'any' # don't care the order, could be even random-shuffled |
|
98 | anyorder = b'any' # don't care the order, could be even random-shuffled | |
99 | defineorder = b'define' # ALWAYS redefine, or ALWAYS follow the current order |
|
99 | defineorder = b'define' # ALWAYS redefine, or ALWAYS follow the current order | |
100 | followorder = b'follow' # MUST follow the current order |
|
100 | followorder = b'follow' # MUST follow the current order | |
101 |
|
101 | |||
102 | # helpers |
|
102 | # helpers | |
103 |
|
103 | |||
104 |
|
104 | |||
105 | def getset(repo, subset, x, order=defineorder): |
|
105 | def getset(repo, subset, x, order=defineorder): | |
106 | if not x: |
|
106 | if not x: | |
107 | raise error.ParseError(_(b"missing argument")) |
|
107 | raise error.ParseError(_(b"missing argument")) | |
108 | return methods[x[0]](repo, subset, *x[1:], order=order) |
|
108 | return methods[x[0]](repo, subset, *x[1:], order=order) | |
109 |
|
109 | |||
110 |
|
110 | |||
111 | def _getrevsource(repo, r): |
|
111 | def _getrevsource(repo, r): | |
112 | extra = repo[r].extra() |
|
112 | extra = repo[r].extra() | |
113 | for label in (b'source', b'transplant_source', b'rebase_source'): |
|
113 | for label in (b'source', b'transplant_source', b'rebase_source'): | |
114 | if label in extra: |
|
114 | if label in extra: | |
115 | try: |
|
115 | try: | |
116 | return repo[extra[label]].rev() |
|
116 | return repo[extra[label]].rev() | |
117 | except error.RepoLookupError: |
|
117 | except error.RepoLookupError: | |
118 | pass |
|
118 | pass | |
119 | return None |
|
119 | return None | |
120 |
|
120 | |||
121 |
|
121 | |||
122 | def _sortedb(xs): |
|
122 | def _sortedb(xs): | |
123 | return sorted(pycompat.rapply(pycompat.maybebytestr, xs)) |
|
123 | return sorted(pycompat.rapply(pycompat.maybebytestr, xs)) | |
124 |
|
124 | |||
125 |
|
125 | |||
126 | # operator methods |
|
126 | # operator methods | |
127 |
|
127 | |||
128 |
|
128 | |||
129 | def stringset(repo, subset, x, order): |
|
129 | def stringset(repo, subset, x, order): | |
130 | if not x: |
|
130 | if not x: | |
131 | raise error.ParseError(_(b"empty string is not a valid revision")) |
|
131 | raise error.ParseError(_(b"empty string is not a valid revision")) | |
132 | x = scmutil.intrev(scmutil.revsymbol(repo, x)) |
|
132 | x = scmutil.intrev(scmutil.revsymbol(repo, x)) | |
133 | if x in subset or x in _virtualrevs and isinstance(subset, fullreposet): |
|
133 | if x in subset or x in _virtualrevs and isinstance(subset, fullreposet): | |
134 | return baseset([x]) |
|
134 | return baseset([x]) | |
135 | return baseset() |
|
135 | return baseset() | |
136 |
|
136 | |||
137 |
|
137 | |||
138 | def rawsmartset(repo, subset, x, order): |
|
138 | def rawsmartset(repo, subset, x, order): | |
139 | """argument is already a smartset, use that directly""" |
|
139 | """argument is already a smartset, use that directly""" | |
140 | if order == followorder: |
|
140 | if order == followorder: | |
141 | return subset & x |
|
141 | return subset & x | |
142 | else: |
|
142 | else: | |
143 | return x & subset |
|
143 | return x & subset | |
144 |
|
144 | |||
145 |
|
145 | |||
146 | def rangeset(repo, subset, x, y, order): |
|
146 | def rangeset(repo, subset, x, y, order): | |
147 | m = getset(repo, fullreposet(repo), x) |
|
147 | m = getset(repo, fullreposet(repo), x) | |
148 | n = getset(repo, fullreposet(repo), y) |
|
148 | n = getset(repo, fullreposet(repo), y) | |
149 |
|
149 | |||
150 | if not m or not n: |
|
150 | if not m or not n: | |
151 | return baseset() |
|
151 | return baseset() | |
152 | return _makerangeset(repo, subset, m.first(), n.last(), order) |
|
152 | return _makerangeset(repo, subset, m.first(), n.last(), order) | |
153 |
|
153 | |||
154 |
|
154 | |||
155 | def rangeall(repo, subset, x, order): |
|
155 | def rangeall(repo, subset, x, order): | |
156 | assert x is None |
|
156 | assert x is None | |
157 | return _makerangeset(repo, subset, 0, repo.changelog.tiprev(), order) |
|
157 | return _makerangeset(repo, subset, 0, repo.changelog.tiprev(), order) | |
158 |
|
158 | |||
159 |
|
159 | |||
160 | def rangepre(repo, subset, y, order): |
|
160 | def rangepre(repo, subset, y, order): | |
161 | # ':y' can't be rewritten to '0:y' since '0' may be hidden |
|
161 | # ':y' can't be rewritten to '0:y' since '0' may be hidden | |
162 | n = getset(repo, fullreposet(repo), y) |
|
162 | n = getset(repo, fullreposet(repo), y) | |
163 | if not n: |
|
163 | if not n: | |
164 | return baseset() |
|
164 | return baseset() | |
165 | return _makerangeset(repo, subset, 0, n.last(), order) |
|
165 | return _makerangeset(repo, subset, 0, n.last(), order) | |
166 |
|
166 | |||
167 |
|
167 | |||
168 | def rangepost(repo, subset, x, order): |
|
168 | def rangepost(repo, subset, x, order): | |
169 | m = getset(repo, fullreposet(repo), x) |
|
169 | m = getset(repo, fullreposet(repo), x) | |
170 | if not m: |
|
170 | if not m: | |
171 | return baseset() |
|
171 | return baseset() | |
172 | return _makerangeset( |
|
172 | return _makerangeset( | |
173 | repo, subset, m.first(), repo.changelog.tiprev(), order |
|
173 | repo, subset, m.first(), repo.changelog.tiprev(), order | |
174 | ) |
|
174 | ) | |
175 |
|
175 | |||
176 |
|
176 | |||
177 | def _makerangeset(repo, subset, m, n, order): |
|
177 | def _makerangeset(repo, subset, m, n, order): | |
178 | if m == n: |
|
178 | if m == n: | |
179 | r = baseset([m]) |
|
179 | r = baseset([m]) | |
180 | elif n == node.wdirrev: |
|
180 | elif n == node.wdirrev: | |
181 | r = spanset(repo, m, len(repo)) + baseset([n]) |
|
181 | r = spanset(repo, m, len(repo)) + baseset([n]) | |
182 | elif m == node.wdirrev: |
|
182 | elif m == node.wdirrev: | |
183 | r = baseset([m]) + spanset(repo, repo.changelog.tiprev(), n - 1) |
|
183 | r = baseset([m]) + spanset(repo, repo.changelog.tiprev(), n - 1) | |
184 | elif m < n: |
|
184 | elif m < n: | |
185 | r = spanset(repo, m, n + 1) |
|
185 | r = spanset(repo, m, n + 1) | |
186 | else: |
|
186 | else: | |
187 | r = spanset(repo, m, n - 1) |
|
187 | r = spanset(repo, m, n - 1) | |
188 |
|
188 | |||
189 | if order == defineorder: |
|
189 | if order == defineorder: | |
190 | return r & subset |
|
190 | return r & subset | |
191 | else: |
|
191 | else: | |
192 | # carrying the sorting over when possible would be more efficient |
|
192 | # carrying the sorting over when possible would be more efficient | |
193 | return subset & r |
|
193 | return subset & r | |
194 |
|
194 | |||
195 |
|
195 | |||
196 | def dagrange(repo, subset, x, y, order): |
|
196 | def dagrange(repo, subset, x, y, order): | |
197 | r = fullreposet(repo) |
|
197 | r = fullreposet(repo) | |
198 | xs = dagop.reachableroots( |
|
198 | xs = dagop.reachableroots( | |
199 | repo, getset(repo, r, x), getset(repo, r, y), includepath=True |
|
199 | repo, getset(repo, r, x), getset(repo, r, y), includepath=True | |
200 | ) |
|
200 | ) | |
201 | return subset & xs |
|
201 | return subset & xs | |
202 |
|
202 | |||
203 |
|
203 | |||
204 | def andset(repo, subset, x, y, order): |
|
204 | def andset(repo, subset, x, y, order): | |
205 | if order == anyorder: |
|
205 | if order == anyorder: | |
206 | yorder = anyorder |
|
206 | yorder = anyorder | |
207 | else: |
|
207 | else: | |
208 | yorder = followorder |
|
208 | yorder = followorder | |
209 | return getset(repo, getset(repo, subset, x, order), y, yorder) |
|
209 | return getset(repo, getset(repo, subset, x, order), y, yorder) | |
210 |
|
210 | |||
211 |
|
211 | |||
212 | def andsmallyset(repo, subset, x, y, order): |
|
212 | def andsmallyset(repo, subset, x, y, order): | |
213 | # 'andsmally(x, y)' is equivalent to 'and(x, y)', but faster when y is small |
|
213 | # 'andsmally(x, y)' is equivalent to 'and(x, y)', but faster when y is small | |
214 | if order == anyorder: |
|
214 | if order == anyorder: | |
215 | yorder = anyorder |
|
215 | yorder = anyorder | |
216 | else: |
|
216 | else: | |
217 | yorder = followorder |
|
217 | yorder = followorder | |
218 | return getset(repo, getset(repo, subset, y, yorder), x, order) |
|
218 | return getset(repo, getset(repo, subset, y, yorder), x, order) | |
219 |
|
219 | |||
220 |
|
220 | |||
221 | def differenceset(repo, subset, x, y, order): |
|
221 | def differenceset(repo, subset, x, y, order): | |
222 | return getset(repo, subset, x, order) - getset(repo, subset, y, anyorder) |
|
222 | return getset(repo, subset, x, order) - getset(repo, subset, y, anyorder) | |
223 |
|
223 | |||
224 |
|
224 | |||
225 | def _orsetlist(repo, subset, xs, order): |
|
225 | def _orsetlist(repo, subset, xs, order): | |
226 | assert xs |
|
226 | assert xs | |
227 | if len(xs) == 1: |
|
227 | if len(xs) == 1: | |
228 | return getset(repo, subset, xs[0], order) |
|
228 | return getset(repo, subset, xs[0], order) | |
229 | p = len(xs) // 2 |
|
229 | p = len(xs) // 2 | |
230 | a = _orsetlist(repo, subset, xs[:p], order) |
|
230 | a = _orsetlist(repo, subset, xs[:p], order) | |
231 | b = _orsetlist(repo, subset, xs[p:], order) |
|
231 | b = _orsetlist(repo, subset, xs[p:], order) | |
232 | return a + b |
|
232 | return a + b | |
233 |
|
233 | |||
234 |
|
234 | |||
235 | def orset(repo, subset, x, order): |
|
235 | def orset(repo, subset, x, order): | |
236 | xs = getlist(x) |
|
236 | xs = getlist(x) | |
237 | if not xs: |
|
237 | if not xs: | |
238 | return baseset() |
|
238 | return baseset() | |
239 | if order == followorder: |
|
239 | if order == followorder: | |
240 | # slow path to take the subset order |
|
240 | # slow path to take the subset order | |
241 | return subset & _orsetlist(repo, fullreposet(repo), xs, anyorder) |
|
241 | return subset & _orsetlist(repo, fullreposet(repo), xs, anyorder) | |
242 | else: |
|
242 | else: | |
243 | return _orsetlist(repo, subset, xs, order) |
|
243 | return _orsetlist(repo, subset, xs, order) | |
244 |
|
244 | |||
245 |
|
245 | |||
246 | def notset(repo, subset, x, order): |
|
246 | def notset(repo, subset, x, order): | |
247 | return subset - getset(repo, subset, x, anyorder) |
|
247 | return subset - getset(repo, subset, x, anyorder) | |
248 |
|
248 | |||
249 |
|
249 | |||
250 | def relationset(repo, subset, x, y, order): |
|
250 | def relationset(repo, subset, x, y, order): | |
251 | # this is pretty basic implementation of 'x#y' operator, still |
|
251 | # this is pretty basic implementation of 'x#y' operator, still | |
252 | # experimental so undocumented. see the wiki for further ideas. |
|
252 | # experimental so undocumented. see the wiki for further ideas. | |
253 | # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan |
|
253 | # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan | |
254 | rel = getsymbol(y) |
|
254 | rel = getsymbol(y) | |
255 | if rel in relations: |
|
255 | if rel in relations: | |
256 | return relations[rel](repo, subset, x, rel, order) |
|
256 | return relations[rel](repo, subset, x, rel, order) | |
257 |
|
257 | |||
258 | relnames = [r for r in relations.keys() if len(r) > 1] |
|
258 | relnames = [r for r in relations.keys() if len(r) > 1] | |
259 | raise error.UnknownIdentifier(rel, relnames) |
|
259 | raise error.UnknownIdentifier(rel, relnames) | |
260 |
|
260 | |||
261 |
|
261 | |||
262 | def _splitrange(a, b): |
|
262 | def _splitrange(a, b): | |
263 | """Split range with bounds a and b into two ranges at 0 and return two |
|
263 | """Split range with bounds a and b into two ranges at 0 and return two | |
264 | tuples of numbers for use as startdepth and stopdepth arguments of |
|
264 | tuples of numbers for use as startdepth and stopdepth arguments of | |
265 | revancestors and revdescendants. |
|
265 | revancestors and revdescendants. | |
266 |
|
266 | |||
267 | >>> _splitrange(-10, -5) # [-10:-5] |
|
267 | >>> _splitrange(-10, -5) # [-10:-5] | |
268 | ((5, 11), (None, None)) |
|
268 | ((5, 11), (None, None)) | |
269 | >>> _splitrange(5, 10) # [5:10] |
|
269 | >>> _splitrange(5, 10) # [5:10] | |
270 | ((None, None), (5, 11)) |
|
270 | ((None, None), (5, 11)) | |
271 | >>> _splitrange(-10, 10) # [-10:10] |
|
271 | >>> _splitrange(-10, 10) # [-10:10] | |
272 | ((0, 11), (0, 11)) |
|
272 | ((0, 11), (0, 11)) | |
273 | >>> _splitrange(-10, 0) # [-10:0] |
|
273 | >>> _splitrange(-10, 0) # [-10:0] | |
274 | ((0, 11), (None, None)) |
|
274 | ((0, 11), (None, None)) | |
275 | >>> _splitrange(0, 10) # [0:10] |
|
275 | >>> _splitrange(0, 10) # [0:10] | |
276 | ((None, None), (0, 11)) |
|
276 | ((None, None), (0, 11)) | |
277 | >>> _splitrange(0, 0) # [0:0] |
|
277 | >>> _splitrange(0, 0) # [0:0] | |
278 | ((0, 1), (None, None)) |
|
278 | ((0, 1), (None, None)) | |
279 | >>> _splitrange(1, -1) # [1:-1] |
|
279 | >>> _splitrange(1, -1) # [1:-1] | |
280 | ((None, None), (None, None)) |
|
280 | ((None, None), (None, None)) | |
281 | """ |
|
281 | """ | |
282 | ancdepths = (None, None) |
|
282 | ancdepths = (None, None) | |
283 | descdepths = (None, None) |
|
283 | descdepths = (None, None) | |
284 | if a == b == 0: |
|
284 | if a == b == 0: | |
285 | ancdepths = (0, 1) |
|
285 | ancdepths = (0, 1) | |
286 | if a < 0: |
|
286 | if a < 0: | |
287 | ancdepths = (-min(b, 0), -a + 1) |
|
287 | ancdepths = (-min(b, 0), -a + 1) | |
288 | if b > 0: |
|
288 | if b > 0: | |
289 | descdepths = (max(a, 0), b + 1) |
|
289 | descdepths = (max(a, 0), b + 1) | |
290 | return ancdepths, descdepths |
|
290 | return ancdepths, descdepths | |
291 |
|
291 | |||
292 |
|
292 | |||
293 | def generationsrel(repo, subset, x, rel, order): |
|
293 | def generationsrel(repo, subset, x, rel, order): | |
294 | z = (b'rangeall', None) |
|
294 | z = (b'rangeall', None) | |
295 | return generationssubrel(repo, subset, x, rel, z, order) |
|
295 | return generationssubrel(repo, subset, x, rel, z, order) | |
296 |
|
296 | |||
297 |
|
297 | |||
298 | def generationssubrel(repo, subset, x, rel, z, order): |
|
298 | def generationssubrel(repo, subset, x, rel, z, order): | |
299 | # TODO: rewrite tests, and drop startdepth argument from ancestors() and |
|
299 | # TODO: rewrite tests, and drop startdepth argument from ancestors() and | |
300 | # descendants() predicates |
|
300 | # descendants() predicates | |
301 | a, b = getintrange( |
|
301 | a, b = getintrange( | |
302 | z, |
|
302 | z, | |
303 | _(b'relation subscript must be an integer or a range'), |
|
303 | _(b'relation subscript must be an integer or a range'), | |
304 | _(b'relation subscript bounds must be integers'), |
|
304 | _(b'relation subscript bounds must be integers'), | |
305 | deffirst=-(dagop.maxlogdepth - 1), |
|
305 | deffirst=-(dagop.maxlogdepth - 1), | |
306 | deflast=+(dagop.maxlogdepth - 1), |
|
306 | deflast=+(dagop.maxlogdepth - 1), | |
307 | ) |
|
307 | ) | |
308 | (ancstart, ancstop), (descstart, descstop) = _splitrange(a, b) |
|
308 | (ancstart, ancstop), (descstart, descstop) = _splitrange(a, b) | |
309 |
|
309 | |||
310 | if ancstart is None and descstart is None: |
|
310 | if ancstart is None and descstart is None: | |
311 | return baseset() |
|
311 | return baseset() | |
312 |
|
312 | |||
313 | revs = getset(repo, fullreposet(repo), x) |
|
313 | revs = getset(repo, fullreposet(repo), x) | |
314 | if not revs: |
|
314 | if not revs: | |
315 | return baseset() |
|
315 | return baseset() | |
316 |
|
316 | |||
317 | if ancstart is not None and descstart is not None: |
|
317 | if ancstart is not None and descstart is not None: | |
318 | s = dagop.revancestors(repo, revs, False, ancstart, ancstop) |
|
318 | s = dagop.revancestors(repo, revs, False, ancstart, ancstop) | |
319 | s += dagop.revdescendants(repo, revs, False, descstart, descstop) |
|
319 | s += dagop.revdescendants(repo, revs, False, descstart, descstop) | |
320 | elif ancstart is not None: |
|
320 | elif ancstart is not None: | |
321 | s = dagop.revancestors(repo, revs, False, ancstart, ancstop) |
|
321 | s = dagop.revancestors(repo, revs, False, ancstart, ancstop) | |
322 | elif descstart is not None: |
|
322 | elif descstart is not None: | |
323 | s = dagop.revdescendants(repo, revs, False, descstart, descstop) |
|
323 | s = dagop.revdescendants(repo, revs, False, descstart, descstop) | |
324 |
|
324 | |||
325 | return subset & s |
|
325 | return subset & s | |
326 |
|
326 | |||
327 |
|
327 | |||
328 | def relsubscriptset(repo, subset, x, y, z, order): |
|
328 | def relsubscriptset(repo, subset, x, y, z, order): | |
329 | # this is pretty basic implementation of 'x#y[z]' operator, still |
|
329 | # this is pretty basic implementation of 'x#y[z]' operator, still | |
330 | # experimental so undocumented. see the wiki for further ideas. |
|
330 | # experimental so undocumented. see the wiki for further ideas. | |
331 | # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan |
|
331 | # https://www.mercurial-scm.org/wiki/RevsetOperatorPlan | |
332 | rel = getsymbol(y) |
|
332 | rel = getsymbol(y) | |
333 | if rel in subscriptrelations: |
|
333 | if rel in subscriptrelations: | |
334 | return subscriptrelations[rel](repo, subset, x, rel, z, order) |
|
334 | return subscriptrelations[rel](repo, subset, x, rel, z, order) | |
335 |
|
335 | |||
336 | relnames = [r for r in subscriptrelations.keys() if len(r) > 1] |
|
336 | relnames = [r for r in subscriptrelations.keys() if len(r) > 1] | |
337 | raise error.UnknownIdentifier(rel, relnames) |
|
337 | raise error.UnknownIdentifier(rel, relnames) | |
338 |
|
338 | |||
339 |
|
339 | |||
340 | def subscriptset(repo, subset, x, y, order): |
|
340 | def subscriptset(repo, subset, x, y, order): | |
341 | raise error.ParseError(_(b"can't use a subscript in this context")) |
|
341 | raise error.ParseError(_(b"can't use a subscript in this context")) | |
342 |
|
342 | |||
343 |
|
343 | |||
344 | def listset(repo, subset, *xs, **opts): |
|
344 | def listset(repo, subset, *xs, **opts): | |
345 | raise error.ParseError( |
|
345 | raise error.ParseError( | |
346 | _(b"can't use a list in this context"), |
|
346 | _(b"can't use a list in this context"), | |
347 | hint=_(b'see \'hg help "revsets.x or y"\''), |
|
347 | hint=_(b'see \'hg help "revsets.x or y"\''), | |
348 | ) |
|
348 | ) | |
349 |
|
349 | |||
350 |
|
350 | |||
351 | def keyvaluepair(repo, subset, k, v, order): |
|
351 | def keyvaluepair(repo, subset, k, v, order): | |
352 | raise error.ParseError(_(b"can't use a key-value pair in this context")) |
|
352 | raise error.ParseError(_(b"can't use a key-value pair in this context")) | |
353 |
|
353 | |||
354 |
|
354 | |||
355 | def func(repo, subset, a, b, order): |
|
355 | def func(repo, subset, a, b, order): | |
356 | f = getsymbol(a) |
|
356 | f = getsymbol(a) | |
357 | if f in symbols: |
|
357 | if f in symbols: | |
358 | func = symbols[f] |
|
358 | func = symbols[f] | |
359 | if getattr(func, '_takeorder', False): |
|
359 | if getattr(func, '_takeorder', False): | |
360 | return func(repo, subset, b, order) |
|
360 | return func(repo, subset, b, order) | |
361 | return func(repo, subset, b) |
|
361 | return func(repo, subset, b) | |
362 |
|
362 | |||
363 | keep = lambda fn: getattr(fn, '__doc__', None) is not None |
|
363 | keep = lambda fn: getattr(fn, '__doc__', None) is not None | |
364 |
|
364 | |||
365 | syms = [s for (s, fn) in symbols.items() if keep(fn)] |
|
365 | syms = [s for (s, fn) in symbols.items() if keep(fn)] | |
366 | raise error.UnknownIdentifier(f, syms) |
|
366 | raise error.UnknownIdentifier(f, syms) | |
367 |
|
367 | |||
368 |
|
368 | |||
369 | # functions |
|
369 | # functions | |
370 |
|
370 | |||
371 | # symbols are callables like: |
|
371 | # symbols are callables like: | |
372 | # fn(repo, subset, x) |
|
372 | # fn(repo, subset, x) | |
373 | # with: |
|
373 | # with: | |
374 | # repo - current repository instance |
|
374 | # repo - current repository instance | |
375 | # subset - of revisions to be examined |
|
375 | # subset - of revisions to be examined | |
376 | # x - argument in tree form |
|
376 | # x - argument in tree form | |
377 | symbols = revsetlang.symbols |
|
377 | symbols = revsetlang.symbols | |
378 |
|
378 | |||
379 | # symbols which can't be used for a DoS attack for any given input |
|
379 | # symbols which can't be used for a DoS attack for any given input | |
380 | # (e.g. those which accept regexes as plain strings shouldn't be included) |
|
380 | # (e.g. those which accept regexes as plain strings shouldn't be included) | |
381 | # functions that just return a lot of changesets (like all) don't count here |
|
381 | # functions that just return a lot of changesets (like all) don't count here | |
382 | safesymbols = set() |
|
382 | safesymbols = set() | |
383 |
|
383 | |||
384 | predicate = registrar.revsetpredicate() |
|
384 | predicate = registrar.revsetpredicate() | |
385 |
|
385 | |||
386 |
|
386 | |||
387 | @predicate(b'_destupdate') |
|
387 | @predicate(b'_destupdate') | |
388 | def _destupdate(repo, subset, x): |
|
388 | def _destupdate(repo, subset, x): | |
389 | # experimental revset for update destination |
|
389 | # experimental revset for update destination | |
390 | args = getargsdict(x, b'limit', b'clean') |
|
390 | args = getargsdict(x, b'limit', b'clean') | |
391 | return subset & baseset( |
|
391 | return subset & baseset( | |
392 | [destutil.destupdate(repo, **pycompat.strkwargs(args))[0]] |
|
392 | [destutil.destupdate(repo, **pycompat.strkwargs(args))[0]] | |
393 | ) |
|
393 | ) | |
394 |
|
394 | |||
395 |
|
395 | |||
396 | @predicate(b'_destmerge') |
|
396 | @predicate(b'_destmerge') | |
397 | def _destmerge(repo, subset, x): |
|
397 | def _destmerge(repo, subset, x): | |
398 | # experimental revset for merge destination |
|
398 | # experimental revset for merge destination | |
399 | sourceset = None |
|
399 | sourceset = None | |
400 | if x is not None: |
|
400 | if x is not None: | |
401 | sourceset = getset(repo, fullreposet(repo), x) |
|
401 | sourceset = getset(repo, fullreposet(repo), x) | |
402 | return subset & baseset([destutil.destmerge(repo, sourceset=sourceset)]) |
|
402 | return subset & baseset([destutil.destmerge(repo, sourceset=sourceset)]) | |
403 |
|
403 | |||
404 |
|
404 | |||
405 | @predicate(b'adds(pattern)', safe=True, weight=30) |
|
405 | @predicate(b'adds(pattern)', safe=True, weight=30) | |
406 | def adds(repo, subset, x): |
|
406 | def adds(repo, subset, x): | |
407 | """Changesets that add a file matching pattern. |
|
407 | """Changesets that add a file matching pattern. | |
408 |
|
408 | |||
409 | The pattern without explicit kind like ``glob:`` is expected to be |
|
409 | The pattern without explicit kind like ``glob:`` is expected to be | |
410 | relative to the current directory and match against a file or a |
|
410 | relative to the current directory and match against a file or a | |
411 | directory. |
|
411 | directory. | |
412 | """ |
|
412 | """ | |
413 | # i18n: "adds" is a keyword |
|
413 | # i18n: "adds" is a keyword | |
414 | pat = getstring(x, _(b"adds requires a pattern")) |
|
414 | pat = getstring(x, _(b"adds requires a pattern")) | |
415 | return checkstatus(repo, subset, pat, 'added') |
|
415 | return checkstatus(repo, subset, pat, 'added') | |
416 |
|
416 | |||
417 |
|
417 | |||
418 | @predicate(b'ancestor(*changeset)', safe=True, weight=0.5) |
|
418 | @predicate(b'ancestor(*changeset)', safe=True, weight=0.5) | |
419 | def ancestor(repo, subset, x): |
|
419 | def ancestor(repo, subset, x): | |
420 | """A greatest common ancestor of the changesets. |
|
420 | """A greatest common ancestor of the changesets. | |
421 |
|
421 | |||
422 | Accepts 0 or more changesets. |
|
422 | Accepts 0 or more changesets. | |
423 | Will return empty list when passed no args. |
|
423 | Will return empty list when passed no args. | |
424 | Greatest common ancestor of a single changeset is that changeset. |
|
424 | Greatest common ancestor of a single changeset is that changeset. | |
425 | """ |
|
425 | """ | |
426 | reviter = iter(orset(repo, fullreposet(repo), x, order=anyorder)) |
|
426 | reviter = iter(orset(repo, fullreposet(repo), x, order=anyorder)) | |
427 | try: |
|
427 | try: | |
428 | anc = repo[next(reviter)] |
|
428 | anc = repo[next(reviter)] | |
429 | except StopIteration: |
|
429 | except StopIteration: | |
430 | return baseset() |
|
430 | return baseset() | |
431 | for r in reviter: |
|
431 | for r in reviter: | |
432 | anc = anc.ancestor(repo[r]) |
|
432 | anc = anc.ancestor(repo[r]) | |
433 |
|
433 | |||
434 | r = scmutil.intrev(anc) |
|
434 | r = scmutil.intrev(anc) | |
435 | if r in subset: |
|
435 | if r in subset: | |
436 | return baseset([r]) |
|
436 | return baseset([r]) | |
437 | return baseset() |
|
437 | return baseset() | |
438 |
|
438 | |||
439 |
|
439 | |||
440 | def _ancestors( |
|
440 | def _ancestors( | |
441 | repo, subset, x, followfirst=False, startdepth=None, stopdepth=None |
|
441 | repo, subset, x, followfirst=False, startdepth=None, stopdepth=None | |
442 | ): |
|
442 | ): | |
443 | heads = getset(repo, fullreposet(repo), x) |
|
443 | heads = getset(repo, fullreposet(repo), x) | |
444 | if not heads: |
|
444 | if not heads: | |
445 | return baseset() |
|
445 | return baseset() | |
446 | s = dagop.revancestors(repo, heads, followfirst, startdepth, stopdepth) |
|
446 | s = dagop.revancestors(repo, heads, followfirst, startdepth, stopdepth) | |
447 | return subset & s |
|
447 | return subset & s | |
448 |
|
448 | |||
449 |
|
449 | |||
450 | @predicate(b'ancestors(set[, depth])', safe=True) |
|
450 | @predicate(b'ancestors(set[, depth])', safe=True) | |
451 | def ancestors(repo, subset, x): |
|
451 | def ancestors(repo, subset, x): | |
452 | """Changesets that are ancestors of changesets in set, including the |
|
452 | """Changesets that are ancestors of changesets in set, including the | |
453 | given changesets themselves. |
|
453 | given changesets themselves. | |
454 |
|
454 | |||
455 | If depth is specified, the result only includes changesets up to |
|
455 | If depth is specified, the result only includes changesets up to | |
456 | the specified generation. |
|
456 | the specified generation. | |
457 | """ |
|
457 | """ | |
458 | # startdepth is for internal use only until we can decide the UI |
|
458 | # startdepth is for internal use only until we can decide the UI | |
459 | args = getargsdict(x, b'ancestors', b'set depth startdepth') |
|
459 | args = getargsdict(x, b'ancestors', b'set depth startdepth') | |
460 | if b'set' not in args: |
|
460 | if b'set' not in args: | |
461 | # i18n: "ancestors" is a keyword |
|
461 | # i18n: "ancestors" is a keyword | |
462 | raise error.ParseError(_(b'ancestors takes at least 1 argument')) |
|
462 | raise error.ParseError(_(b'ancestors takes at least 1 argument')) | |
463 | startdepth = stopdepth = None |
|
463 | startdepth = stopdepth = None | |
464 | if b'startdepth' in args: |
|
464 | if b'startdepth' in args: | |
465 | n = getinteger( |
|
465 | n = getinteger( | |
466 | args[b'startdepth'], b"ancestors expects an integer startdepth" |
|
466 | args[b'startdepth'], b"ancestors expects an integer startdepth" | |
467 | ) |
|
467 | ) | |
468 | if n < 0: |
|
468 | if n < 0: | |
469 | raise error.ParseError(b"negative startdepth") |
|
469 | raise error.ParseError(b"negative startdepth") | |
470 | startdepth = n |
|
470 | startdepth = n | |
471 | if b'depth' in args: |
|
471 | if b'depth' in args: | |
472 | # i18n: "ancestors" is a keyword |
|
472 | # i18n: "ancestors" is a keyword | |
473 | n = getinteger(args[b'depth'], _(b"ancestors expects an integer depth")) |
|
473 | n = getinteger(args[b'depth'], _(b"ancestors expects an integer depth")) | |
474 | if n < 0: |
|
474 | if n < 0: | |
475 | raise error.ParseError(_(b"negative depth")) |
|
475 | raise error.ParseError(_(b"negative depth")) | |
476 | stopdepth = n + 1 |
|
476 | stopdepth = n + 1 | |
477 | return _ancestors( |
|
477 | return _ancestors( | |
478 | repo, subset, args[b'set'], startdepth=startdepth, stopdepth=stopdepth |
|
478 | repo, subset, args[b'set'], startdepth=startdepth, stopdepth=stopdepth | |
479 | ) |
|
479 | ) | |
480 |
|
480 | |||
481 |
|
481 | |||
482 | @predicate(b'_firstancestors', safe=True) |
|
482 | @predicate(b'_firstancestors', safe=True) | |
483 | def _firstancestors(repo, subset, x): |
|
483 | def _firstancestors(repo, subset, x): | |
484 | # ``_firstancestors(set)`` |
|
484 | # ``_firstancestors(set)`` | |
485 | # Like ``ancestors(set)`` but follows only the first parents. |
|
485 | # Like ``ancestors(set)`` but follows only the first parents. | |
486 | return _ancestors(repo, subset, x, followfirst=True) |
|
486 | return _ancestors(repo, subset, x, followfirst=True) | |
487 |
|
487 | |||
488 |
|
488 | |||
489 | def _childrenspec(repo, subset, x, n, order): |
|
489 | def _childrenspec(repo, subset, x, n, order): | |
490 | """Changesets that are the Nth child of a changeset |
|
490 | """Changesets that are the Nth child of a changeset | |
491 | in set. |
|
491 | in set. | |
492 | """ |
|
492 | """ | |
493 | cs = set() |
|
493 | cs = set() | |
494 | for r in getset(repo, fullreposet(repo), x): |
|
494 | for r in getset(repo, fullreposet(repo), x): | |
495 | for i in range(n): |
|
495 | for i in range(n): | |
496 | c = repo[r].children() |
|
496 | c = repo[r].children() | |
497 | if len(c) == 0: |
|
497 | if len(c) == 0: | |
498 | break |
|
498 | break | |
499 | if len(c) > 1: |
|
499 | if len(c) > 1: | |
500 | raise error.RepoLookupError( |
|
500 | raise error.RepoLookupError( | |
501 | _(b"revision in set has more than one child") |
|
501 | _(b"revision in set has more than one child") | |
502 | ) |
|
502 | ) | |
503 | r = c[0].rev() |
|
503 | r = c[0].rev() | |
504 | else: |
|
504 | else: | |
505 | cs.add(r) |
|
505 | cs.add(r) | |
506 | return subset & cs |
|
506 | return subset & cs | |
507 |
|
507 | |||
508 |
|
508 | |||
509 | def ancestorspec(repo, subset, x, n, order): |
|
509 | def ancestorspec(repo, subset, x, n, order): | |
510 | """``set~n`` |
|
510 | """``set~n`` | |
511 | Changesets that are the Nth ancestor (first parents only) of a changeset |
|
511 | Changesets that are the Nth ancestor (first parents only) of a changeset | |
512 | in set. |
|
512 | in set. | |
513 | """ |
|
513 | """ | |
514 | n = getinteger(n, _(b"~ expects a number")) |
|
514 | n = getinteger(n, _(b"~ expects a number")) | |
515 | if n < 0: |
|
515 | if n < 0: | |
516 | # children lookup |
|
516 | # children lookup | |
517 | return _childrenspec(repo, subset, x, -n, order) |
|
517 | return _childrenspec(repo, subset, x, -n, order) | |
518 | ps = set() |
|
518 | ps = set() | |
519 | cl = repo.changelog |
|
519 | cl = repo.changelog | |
520 | for r in getset(repo, fullreposet(repo), x): |
|
520 | for r in getset(repo, fullreposet(repo), x): | |
521 | for i in range(n): |
|
521 | for i in range(n): | |
522 | try: |
|
522 | try: | |
523 | r = cl.parentrevs(r)[0] |
|
523 | r = cl.parentrevs(r)[0] | |
524 | except error.WdirUnsupported: |
|
524 | except error.WdirUnsupported: | |
525 | r = repo[r].p1().rev() |
|
525 | r = repo[r].p1().rev() | |
526 | ps.add(r) |
|
526 | ps.add(r) | |
527 | return subset & ps |
|
527 | return subset & ps | |
528 |
|
528 | |||
529 |
|
529 | |||
530 | @predicate(b'author(string)', safe=True, weight=10) |
|
530 | @predicate(b'author(string)', safe=True, weight=10) | |
531 | def author(repo, subset, x): |
|
531 | def author(repo, subset, x): | |
532 | """Alias for ``user(string)``. |
|
532 | """Alias for ``user(string)``. | |
533 | """ |
|
533 | """ | |
534 | # i18n: "author" is a keyword |
|
534 | # i18n: "author" is a keyword | |
535 | n = getstring(x, _(b"author requires a string")) |
|
535 | n = getstring(x, _(b"author requires a string")) | |
536 | kind, pattern, matcher = _substringmatcher(n, casesensitive=False) |
|
536 | kind, pattern, matcher = _substringmatcher(n, casesensitive=False) | |
537 | return subset.filter( |
|
537 | return subset.filter( | |
538 | lambda x: matcher(repo[x].user()), condrepr=(b'<user %r>', n) |
|
538 | lambda x: matcher(repo[x].user()), condrepr=(b'<user %r>', n) | |
539 | ) |
|
539 | ) | |
540 |
|
540 | |||
541 |
|
541 | |||
542 | @predicate(b'bisect(string)', safe=True) |
|
542 | @predicate(b'bisect(string)', safe=True) | |
543 | def bisect(repo, subset, x): |
|
543 | def bisect(repo, subset, x): | |
544 | """Changesets marked in the specified bisect status: |
|
544 | """Changesets marked in the specified bisect status: | |
545 |
|
545 | |||
546 | - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip |
|
546 | - ``good``, ``bad``, ``skip``: csets explicitly marked as good/bad/skip | |
547 | - ``goods``, ``bads`` : csets topologically good/bad |
|
547 | - ``goods``, ``bads`` : csets topologically good/bad | |
548 | - ``range`` : csets taking part in the bisection |
|
548 | - ``range`` : csets taking part in the bisection | |
549 | - ``pruned`` : csets that are goods, bads or skipped |
|
549 | - ``pruned`` : csets that are goods, bads or skipped | |
550 | - ``untested`` : csets whose fate is yet unknown |
|
550 | - ``untested`` : csets whose fate is yet unknown | |
551 | - ``ignored`` : csets ignored due to DAG topology |
|
551 | - ``ignored`` : csets ignored due to DAG topology | |
552 | - ``current`` : the cset currently being bisected |
|
552 | - ``current`` : the cset currently being bisected | |
553 | """ |
|
553 | """ | |
554 | # i18n: "bisect" is a keyword |
|
554 | # i18n: "bisect" is a keyword | |
555 | status = getstring(x, _(b"bisect requires a string")).lower() |
|
555 | status = getstring(x, _(b"bisect requires a string")).lower() | |
556 | state = set(hbisect.get(repo, status)) |
|
556 | state = set(hbisect.get(repo, status)) | |
557 | return subset & state |
|
557 | return subset & state | |
558 |
|
558 | |||
559 |
|
559 | |||
560 | # Backward-compatibility |
|
560 | # Backward-compatibility | |
561 | # - no help entry so that we do not advertise it any more |
|
561 | # - no help entry so that we do not advertise it any more | |
562 | @predicate(b'bisected', safe=True) |
|
562 | @predicate(b'bisected', safe=True) | |
563 | def bisected(repo, subset, x): |
|
563 | def bisected(repo, subset, x): | |
564 | return bisect(repo, subset, x) |
|
564 | return bisect(repo, subset, x) | |
565 |
|
565 | |||
566 |
|
566 | |||
567 | @predicate(b'bookmark([name])', safe=True) |
|
567 | @predicate(b'bookmark([name])', safe=True) | |
568 | def bookmark(repo, subset, x): |
|
568 | def bookmark(repo, subset, x): | |
569 | """The named bookmark or all bookmarks. |
|
569 | """The named bookmark or all bookmarks. | |
570 |
|
570 | |||
571 | Pattern matching is supported for `name`. See :hg:`help revisions.patterns`. |
|
571 | Pattern matching is supported for `name`. See :hg:`help revisions.patterns`. | |
572 | """ |
|
572 | """ | |
573 | # i18n: "bookmark" is a keyword |
|
573 | # i18n: "bookmark" is a keyword | |
574 | args = getargs(x, 0, 1, _(b'bookmark takes one or no arguments')) |
|
574 | args = getargs(x, 0, 1, _(b'bookmark takes one or no arguments')) | |
575 | if args: |
|
575 | if args: | |
576 | bm = getstring( |
|
576 | bm = getstring( | |
577 | args[0], |
|
577 | args[0], | |
578 | # i18n: "bookmark" is a keyword |
|
578 | # i18n: "bookmark" is a keyword | |
579 | _(b'the argument to bookmark must be a string'), |
|
579 | _(b'the argument to bookmark must be a string'), | |
580 | ) |
|
580 | ) | |
581 | kind, pattern, matcher = stringutil.stringmatcher(bm) |
|
581 | kind, pattern, matcher = stringutil.stringmatcher(bm) | |
582 | bms = set() |
|
582 | bms = set() | |
583 | if kind == b'literal': |
|
583 | if kind == b'literal': | |
584 | if bm == pattern: |
|
584 | if bm == pattern: | |
585 | pattern = repo._bookmarks.expandname(pattern) |
|
585 | pattern = repo._bookmarks.expandname(pattern) | |
586 | bmrev = repo._bookmarks.get(pattern, None) |
|
586 | bmrev = repo._bookmarks.get(pattern, None) | |
587 | if not bmrev: |
|
587 | if not bmrev: | |
588 | raise error.RepoLookupError( |
|
588 | raise error.RepoLookupError( | |
589 | _(b"bookmark '%s' does not exist") % pattern |
|
589 | _(b"bookmark '%s' does not exist") % pattern | |
590 | ) |
|
590 | ) | |
591 | bms.add(repo[bmrev].rev()) |
|
591 | bms.add(repo[bmrev].rev()) | |
592 | else: |
|
592 | else: | |
593 | matchrevs = set() |
|
593 | matchrevs = set() | |
594 | for name, bmrev in pycompat.iteritems(repo._bookmarks): |
|
594 | for name, bmrev in pycompat.iteritems(repo._bookmarks): | |
595 | if matcher(name): |
|
595 | if matcher(name): | |
596 | matchrevs.add(bmrev) |
|
596 | matchrevs.add(bmrev) | |
597 | for bmrev in matchrevs: |
|
597 | for bmrev in matchrevs: | |
598 | bms.add(repo[bmrev].rev()) |
|
598 | bms.add(repo[bmrev].rev()) | |
599 | else: |
|
599 | else: | |
600 | bms = {repo[r].rev() for r in repo._bookmarks.values()} |
|
600 | bms = {repo[r].rev() for r in repo._bookmarks.values()} | |
601 | bms -= {node.nullrev} |
|
601 | bms -= {node.nullrev} | |
602 | return subset & bms |
|
602 | return subset & bms | |
603 |
|
603 | |||
604 |
|
604 | |||
605 | @predicate(b'branch(string or set)', safe=True, weight=10) |
|
605 | @predicate(b'branch(string or set)', safe=True, weight=10) | |
606 | def branch(repo, subset, x): |
|
606 | def branch(repo, subset, x): | |
607 | """ |
|
607 | """ | |
608 | All changesets belonging to the given branch or the branches of the given |
|
608 | All changesets belonging to the given branch or the branches of the given | |
609 | changesets. |
|
609 | changesets. | |
610 |
|
610 | |||
611 | Pattern matching is supported for `string`. See |
|
611 | Pattern matching is supported for `string`. See | |
612 | :hg:`help revisions.patterns`. |
|
612 | :hg:`help revisions.patterns`. | |
613 | """ |
|
613 | """ | |
614 | getbi = repo.revbranchcache().branchinfo |
|
614 | getbi = repo.revbranchcache().branchinfo | |
615 |
|
615 | |||
616 | def getbranch(r): |
|
616 | def getbranch(r): | |
617 | try: |
|
617 | try: | |
618 | return getbi(r)[0] |
|
618 | return getbi(r)[0] | |
619 | except error.WdirUnsupported: |
|
619 | except error.WdirUnsupported: | |
620 | return repo[r].branch() |
|
620 | return repo[r].branch() | |
621 |
|
621 | |||
622 | try: |
|
622 | try: | |
623 | b = getstring(x, b'') |
|
623 | b = getstring(x, b'') | |
624 | except error.ParseError: |
|
624 | except error.ParseError: | |
625 | # not a string, but another revspec, e.g. tip() |
|
625 | # not a string, but another revspec, e.g. tip() | |
626 | pass |
|
626 | pass | |
627 | else: |
|
627 | else: | |
628 | kind, pattern, matcher = stringutil.stringmatcher(b) |
|
628 | kind, pattern, matcher = stringutil.stringmatcher(b) | |
629 | if kind == b'literal': |
|
629 | if kind == b'literal': | |
630 | # note: falls through to the revspec case if no branch with |
|
630 | # note: falls through to the revspec case if no branch with | |
631 | # this name exists and pattern kind is not specified explicitly |
|
631 | # this name exists and pattern kind is not specified explicitly | |
632 | if repo.branchmap().hasbranch(pattern): |
|
632 | if repo.branchmap().hasbranch(pattern): | |
633 | return subset.filter( |
|
633 | return subset.filter( | |
634 | lambda r: matcher(getbranch(r)), |
|
634 | lambda r: matcher(getbranch(r)), | |
635 | condrepr=(b'<branch %r>', b), |
|
635 | condrepr=(b'<branch %r>', b), | |
636 | ) |
|
636 | ) | |
637 | if b.startswith(b'literal:'): |
|
637 | if b.startswith(b'literal:'): | |
638 | raise error.RepoLookupError( |
|
638 | raise error.RepoLookupError( | |
639 | _(b"branch '%s' does not exist") % pattern |
|
639 | _(b"branch '%s' does not exist") % pattern | |
640 | ) |
|
640 | ) | |
641 | else: |
|
641 | else: | |
642 | return subset.filter( |
|
642 | return subset.filter( | |
643 | lambda r: matcher(getbranch(r)), condrepr=(b'<branch %r>', b) |
|
643 | lambda r: matcher(getbranch(r)), condrepr=(b'<branch %r>', b) | |
644 | ) |
|
644 | ) | |
645 |
|
645 | |||
646 | s = getset(repo, fullreposet(repo), x) |
|
646 | s = getset(repo, fullreposet(repo), x) | |
647 | b = set() |
|
647 | b = set() | |
648 | for r in s: |
|
648 | for r in s: | |
649 | b.add(getbranch(r)) |
|
649 | b.add(getbranch(r)) | |
650 | c = s.__contains__ |
|
650 | c = s.__contains__ | |
651 | return subset.filter( |
|
651 | return subset.filter( | |
652 | lambda r: c(r) or getbranch(r) in b, |
|
652 | lambda r: c(r) or getbranch(r) in b, | |
653 | condrepr=lambda: b'<branch %r>' % _sortedb(b), |
|
653 | condrepr=lambda: b'<branch %r>' % _sortedb(b), | |
654 | ) |
|
654 | ) | |
655 |
|
655 | |||
656 |
|
656 | |||
657 | @predicate(b'phasedivergent()', safe=True) |
|
657 | @predicate(b'phasedivergent()', safe=True) | |
658 | def phasedivergent(repo, subset, x): |
|
658 | def phasedivergent(repo, subset, x): | |
659 | """Mutable changesets marked as successors of public changesets. |
|
659 | """Mutable changesets marked as successors of public changesets. | |
660 |
|
660 | |||
661 | Only non-public and non-obsolete changesets can be `phasedivergent`. |
|
661 | Only non-public and non-obsolete changesets can be `phasedivergent`. | |
662 | (EXPERIMENTAL) |
|
662 | (EXPERIMENTAL) | |
663 | """ |
|
663 | """ | |
664 | # i18n: "phasedivergent" is a keyword |
|
664 | # i18n: "phasedivergent" is a keyword | |
665 | getargs(x, 0, 0, _(b"phasedivergent takes no arguments")) |
|
665 | getargs(x, 0, 0, _(b"phasedivergent takes no arguments")) | |
666 | phasedivergent = obsmod.getrevs(repo, b'phasedivergent') |
|
666 | phasedivergent = obsmod.getrevs(repo, b'phasedivergent') | |
667 | return subset & phasedivergent |
|
667 | return subset & phasedivergent | |
668 |
|
668 | |||
669 |
|
669 | |||
670 | @predicate(b'bundle()', safe=True) |
|
670 | @predicate(b'bundle()', safe=True) | |
671 | def bundle(repo, subset, x): |
|
671 | def bundle(repo, subset, x): | |
672 | """Changesets in the bundle. |
|
672 | """Changesets in the bundle. | |
673 |
|
673 | |||
674 | Bundle must be specified by the -R option.""" |
|
674 | Bundle must be specified by the -R option.""" | |
675 |
|
675 | |||
676 | try: |
|
676 | try: | |
677 | bundlerevs = repo.changelog.bundlerevs |
|
677 | bundlerevs = repo.changelog.bundlerevs | |
678 | except AttributeError: |
|
678 | except AttributeError: | |
679 | raise error.Abort(_(b"no bundle provided - specify with -R")) |
|
679 | raise error.Abort(_(b"no bundle provided - specify with -R")) | |
680 | return subset & bundlerevs |
|
680 | return subset & bundlerevs | |
681 |
|
681 | |||
682 |
|
682 | |||
683 | def checkstatus(repo, subset, pat, field): |
|
683 | def checkstatus(repo, subset, pat, field): | |
684 | """Helper for status-related revsets (adds, removes, modifies). |
|
684 | """Helper for status-related revsets (adds, removes, modifies). | |
685 | The field parameter says which kind is desired. |
|
685 | The field parameter says which kind is desired. | |
686 | """ |
|
686 | """ | |
687 | hasset = matchmod.patkind(pat) == b'set' |
|
687 | hasset = matchmod.patkind(pat) == b'set' | |
688 |
|
688 | |||
689 | mcache = [None] |
|
689 | mcache = [None] | |
690 |
|
690 | |||
691 | def matches(x): |
|
691 | def matches(x): | |
692 | c = repo[x] |
|
692 | c = repo[x] | |
693 | if not mcache[0] or hasset: |
|
693 | if not mcache[0] or hasset: | |
694 | mcache[0] = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c) |
|
694 | mcache[0] = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c) | |
695 | m = mcache[0] |
|
695 | m = mcache[0] | |
696 | fname = None |
|
696 | fname = None | |
697 |
|
697 | |||
698 | assert m is not None # help pytype |
|
698 | assert m is not None # help pytype | |
699 | if not m.anypats() and len(m.files()) == 1: |
|
699 | if not m.anypats() and len(m.files()) == 1: | |
700 | fname = m.files()[0] |
|
700 | fname = m.files()[0] | |
701 | if fname is not None: |
|
701 | if fname is not None: | |
702 | if fname not in c.files(): |
|
702 | if fname not in c.files(): | |
703 | return False |
|
703 | return False | |
704 | else: |
|
704 | else: | |
705 | if not any(m(f) for f in c.files()): |
|
705 | if not any(m(f) for f in c.files()): | |
706 | return False |
|
706 | return False | |
707 | files = getattr(repo.status(c.p1().node(), c.node()), field) |
|
707 | files = getattr(repo.status(c.p1().node(), c.node()), field) | |
708 | if fname is not None: |
|
708 | if fname is not None: | |
709 | if fname in files: |
|
709 | if fname in files: | |
710 | return True |
|
710 | return True | |
711 | else: |
|
711 | else: | |
712 | if any(m(f) for f in files): |
|
712 | if any(m(f) for f in files): | |
713 | return True |
|
713 | return True | |
714 |
|
714 | |||
715 | return subset.filter( |
|
715 | return subset.filter( | |
716 | matches, condrepr=(b'<status.%s %r>', pycompat.sysbytes(field), pat) |
|
716 | matches, condrepr=(b'<status.%s %r>', pycompat.sysbytes(field), pat) | |
717 | ) |
|
717 | ) | |
718 |
|
718 | |||
719 |
|
719 | |||
720 | def _children(repo, subset, parentset): |
|
720 | def _children(repo, subset, parentset): | |
721 | if not parentset: |
|
721 | if not parentset: | |
722 | return baseset() |
|
722 | return baseset() | |
723 | cs = set() |
|
723 | cs = set() | |
724 | pr = repo.changelog.parentrevs |
|
724 | pr = repo.changelog.parentrevs | |
725 | minrev = parentset.min() |
|
725 | minrev = parentset.min() | |
726 | nullrev = node.nullrev |
|
726 | nullrev = node.nullrev | |
727 | for r in subset: |
|
727 | for r in subset: | |
728 | if r <= minrev: |
|
728 | if r <= minrev: | |
729 | continue |
|
729 | continue | |
730 | p1, p2 = pr(r) |
|
730 | p1, p2 = pr(r) | |
731 | if p1 in parentset: |
|
731 | if p1 in parentset: | |
732 | cs.add(r) |
|
732 | cs.add(r) | |
733 | if p2 != nullrev and p2 in parentset: |
|
733 | if p2 != nullrev and p2 in parentset: | |
734 | cs.add(r) |
|
734 | cs.add(r) | |
735 | return baseset(cs) |
|
735 | return baseset(cs) | |
736 |
|
736 | |||
737 |
|
737 | |||
738 | @predicate(b'children(set)', safe=True) |
|
738 | @predicate(b'children(set)', safe=True) | |
739 | def children(repo, subset, x): |
|
739 | def children(repo, subset, x): | |
740 | """Child changesets of changesets in set. |
|
740 | """Child changesets of changesets in set. | |
741 | """ |
|
741 | """ | |
742 | s = getset(repo, fullreposet(repo), x) |
|
742 | s = getset(repo, fullreposet(repo), x) | |
743 | cs = _children(repo, subset, s) |
|
743 | cs = _children(repo, subset, s) | |
744 | return subset & cs |
|
744 | return subset & cs | |
745 |
|
745 | |||
746 |
|
746 | |||
747 | @predicate(b'closed()', safe=True, weight=10) |
|
747 | @predicate(b'closed()', safe=True, weight=10) | |
748 | def closed(repo, subset, x): |
|
748 | def closed(repo, subset, x): | |
749 | """Changeset is closed. |
|
749 | """Changeset is closed. | |
750 | """ |
|
750 | """ | |
751 | # i18n: "closed" is a keyword |
|
751 | # i18n: "closed" is a keyword | |
752 | getargs(x, 0, 0, _(b"closed takes no arguments")) |
|
752 | getargs(x, 0, 0, _(b"closed takes no arguments")) | |
753 | return subset.filter( |
|
753 | return subset.filter( | |
754 | lambda r: repo[r].closesbranch(), condrepr=b'<branch closed>' |
|
754 | lambda r: repo[r].closesbranch(), condrepr=b'<branch closed>' | |
755 | ) |
|
755 | ) | |
756 |
|
756 | |||
757 |
|
757 | |||
758 | # for internal use |
|
758 | # for internal use | |
759 | @predicate(b'_commonancestorheads(set)', safe=True) |
|
759 | @predicate(b'_commonancestorheads(set)', safe=True) | |
760 | def _commonancestorheads(repo, subset, x): |
|
760 | def _commonancestorheads(repo, subset, x): | |
761 | # This is an internal method is for quickly calculating "heads(::x and |
|
761 | # This is an internal method is for quickly calculating "heads(::x and | |
762 | # ::y)" |
|
762 | # ::y)" | |
763 |
|
763 | |||
764 | # These greatest common ancestors are the same ones that the consensus bid |
|
764 | # These greatest common ancestors are the same ones that the consensus bid | |
765 | # merge will find. |
|
765 | # merge will find. | |
766 | startrevs = getset(repo, fullreposet(repo), x, order=anyorder) |
|
766 | startrevs = getset(repo, fullreposet(repo), x, order=anyorder) | |
767 |
|
767 | |||
768 | ancs = repo.changelog._commonancestorsheads(*list(startrevs)) |
|
768 | ancs = repo.changelog._commonancestorsheads(*list(startrevs)) | |
769 | return subset & baseset(ancs) |
|
769 | return subset & baseset(ancs) | |
770 |
|
770 | |||
771 |
|
771 | |||
772 | @predicate(b'commonancestors(set)', safe=True) |
|
772 | @predicate(b'commonancestors(set)', safe=True) | |
773 | def commonancestors(repo, subset, x): |
|
773 | def commonancestors(repo, subset, x): | |
774 | """Changesets that are ancestors of every changeset in set. |
|
774 | """Changesets that are ancestors of every changeset in set. | |
775 | """ |
|
775 | """ | |
776 | startrevs = getset(repo, fullreposet(repo), x, order=anyorder) |
|
776 | startrevs = getset(repo, fullreposet(repo), x, order=anyorder) | |
777 | if not startrevs: |
|
777 | if not startrevs: | |
778 | return baseset() |
|
778 | return baseset() | |
779 | for r in startrevs: |
|
779 | for r in startrevs: | |
780 | subset &= dagop.revancestors(repo, baseset([r])) |
|
780 | subset &= dagop.revancestors(repo, baseset([r])) | |
781 | return subset |
|
781 | return subset | |
782 |
|
782 | |||
783 |
|
783 | |||
784 | @predicate(b'conflictlocal()', safe=True) |
|
784 | @predicate(b'conflictlocal()', safe=True) | |
785 | def conflictlocal(repo, subset, x): |
|
785 | def conflictlocal(repo, subset, x): | |
786 | """The local side of the merge, if currently in an unresolved merge. |
|
786 | """The local side of the merge, if currently in an unresolved merge. | |
787 |
|
787 | |||
788 | "merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'. |
|
788 | "merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'. | |
789 | """ |
|
789 | """ | |
790 | getargs(x, 0, 0, _(b"conflictlocal takes no arguments")) |
|
790 | getargs(x, 0, 0, _(b"conflictlocal takes no arguments")) | |
791 | from . import mergestate as mergestatemod |
|
791 | from . import mergestate as mergestatemod | |
792 |
|
792 | |||
793 | mergestate = mergestatemod.mergestate.read(repo) |
|
793 | mergestate = mergestatemod.mergestate.read(repo) | |
794 | if mergestate.active() and repo.changelog.hasnode(mergestate.local): |
|
794 | if mergestate.active() and repo.changelog.hasnode(mergestate.local): | |
795 | return subset & {repo.changelog.rev(mergestate.local)} |
|
795 | return subset & {repo.changelog.rev(mergestate.local)} | |
796 |
|
796 | |||
797 | return baseset() |
|
797 | return baseset() | |
798 |
|
798 | |||
799 |
|
799 | |||
800 | @predicate(b'conflictother()', safe=True) |
|
800 | @predicate(b'conflictother()', safe=True) | |
801 | def conflictother(repo, subset, x): |
|
801 | def conflictother(repo, subset, x): | |
802 | """The other side of the merge, if currently in an unresolved merge. |
|
802 | """The other side of the merge, if currently in an unresolved merge. | |
803 |
|
803 | |||
804 | "merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'. |
|
804 | "merge" here includes merge conflicts from e.g. 'hg rebase' or 'hg graft'. | |
805 | """ |
|
805 | """ | |
806 | getargs(x, 0, 0, _(b"conflictother takes no arguments")) |
|
806 | getargs(x, 0, 0, _(b"conflictother takes no arguments")) | |
807 | from . import mergestate as mergestatemod |
|
807 | from . import mergestate as mergestatemod | |
808 |
|
808 | |||
809 | mergestate = mergestatemod.mergestate.read(repo) |
|
809 | mergestate = mergestatemod.mergestate.read(repo) | |
810 | if mergestate.active() and repo.changelog.hasnode(mergestate.other): |
|
810 | if mergestate.active() and repo.changelog.hasnode(mergestate.other): | |
811 | return subset & {repo.changelog.rev(mergestate.other)} |
|
811 | return subset & {repo.changelog.rev(mergestate.other)} | |
812 |
|
812 | |||
813 | return baseset() |
|
813 | return baseset() | |
814 |
|
814 | |||
815 |
|
815 | |||
816 | @predicate(b'contains(pattern)', weight=100) |
|
816 | @predicate(b'contains(pattern)', weight=100) | |
817 | def contains(repo, subset, x): |
|
817 | def contains(repo, subset, x): | |
818 | """The revision's manifest contains a file matching pattern (but might not |
|
818 | """The revision's manifest contains a file matching pattern (but might not | |
819 | modify it). See :hg:`help patterns` for information about file patterns. |
|
819 | modify it). See :hg:`help patterns` for information about file patterns. | |
820 |
|
820 | |||
821 | The pattern without explicit kind like ``glob:`` is expected to be |
|
821 | The pattern without explicit kind like ``glob:`` is expected to be | |
822 | relative to the current directory and match against a file exactly |
|
822 | relative to the current directory and match against a file exactly | |
823 | for efficiency. |
|
823 | for efficiency. | |
824 | """ |
|
824 | """ | |
825 | # i18n: "contains" is a keyword |
|
825 | # i18n: "contains" is a keyword | |
826 | pat = getstring(x, _(b"contains requires a pattern")) |
|
826 | pat = getstring(x, _(b"contains requires a pattern")) | |
827 |
|
827 | |||
828 | def matches(x): |
|
828 | def matches(x): | |
829 | if not matchmod.patkind(pat): |
|
829 | if not matchmod.patkind(pat): | |
830 | pats = pathutil.canonpath(repo.root, repo.getcwd(), pat) |
|
830 | pats = pathutil.canonpath(repo.root, repo.getcwd(), pat) | |
831 | if pats in repo[x]: |
|
831 | if pats in repo[x]: | |
832 | return True |
|
832 | return True | |
833 | else: |
|
833 | else: | |
834 | c = repo[x] |
|
834 | c = repo[x] | |
835 | m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c) |
|
835 | m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c) | |
836 | for f in c.manifest(): |
|
836 | for f in c.manifest(): | |
837 | if m(f): |
|
837 | if m(f): | |
838 | return True |
|
838 | return True | |
839 | return False |
|
839 | return False | |
840 |
|
840 | |||
841 | return subset.filter(matches, condrepr=(b'<contains %r>', pat)) |
|
841 | return subset.filter(matches, condrepr=(b'<contains %r>', pat)) | |
842 |
|
842 | |||
843 |
|
843 | |||
844 | @predicate(b'converted([id])', safe=True) |
|
844 | @predicate(b'converted([id])', safe=True) | |
845 | def converted(repo, subset, x): |
|
845 | def converted(repo, subset, x): | |
846 | """Changesets converted from the given identifier in the old repository if |
|
846 | """Changesets converted from the given identifier in the old repository if | |
847 | present, or all converted changesets if no identifier is specified. |
|
847 | present, or all converted changesets if no identifier is specified. | |
848 | """ |
|
848 | """ | |
849 |
|
849 | |||
850 | # There is exactly no chance of resolving the revision, so do a simple |
|
850 | # There is exactly no chance of resolving the revision, so do a simple | |
851 | # string compare and hope for the best |
|
851 | # string compare and hope for the best | |
852 |
|
852 | |||
853 | rev = None |
|
853 | rev = None | |
854 | # i18n: "converted" is a keyword |
|
854 | # i18n: "converted" is a keyword | |
855 | l = getargs(x, 0, 1, _(b'converted takes one or no arguments')) |
|
855 | l = getargs(x, 0, 1, _(b'converted takes one or no arguments')) | |
856 | if l: |
|
856 | if l: | |
857 | # i18n: "converted" is a keyword |
|
857 | # i18n: "converted" is a keyword | |
858 | rev = getstring(l[0], _(b'converted requires a revision')) |
|
858 | rev = getstring(l[0], _(b'converted requires a revision')) | |
859 |
|
859 | |||
860 | def _matchvalue(r): |
|
860 | def _matchvalue(r): | |
861 | source = repo[r].extra().get(b'convert_revision', None) |
|
861 | source = repo[r].extra().get(b'convert_revision', None) | |
862 | return source is not None and (rev is None or source.startswith(rev)) |
|
862 | return source is not None and (rev is None or source.startswith(rev)) | |
863 |
|
863 | |||
864 | return subset.filter( |
|
864 | return subset.filter( | |
865 | lambda r: _matchvalue(r), condrepr=(b'<converted %r>', rev) |
|
865 | lambda r: _matchvalue(r), condrepr=(b'<converted %r>', rev) | |
866 | ) |
|
866 | ) | |
867 |
|
867 | |||
868 |
|
868 | |||
869 | @predicate(b'date(interval)', safe=True, weight=10) |
|
869 | @predicate(b'date(interval)', safe=True, weight=10) | |
870 | def date(repo, subset, x): |
|
870 | def date(repo, subset, x): | |
871 | """Changesets within the interval, see :hg:`help dates`. |
|
871 | """Changesets within the interval, see :hg:`help dates`. | |
872 | """ |
|
872 | """ | |
873 | # i18n: "date" is a keyword |
|
873 | # i18n: "date" is a keyword | |
874 | ds = getstring(x, _(b"date requires a string")) |
|
874 | ds = getstring(x, _(b"date requires a string")) | |
875 | dm = dateutil.matchdate(ds) |
|
875 | dm = dateutil.matchdate(ds) | |
876 | return subset.filter( |
|
876 | return subset.filter( | |
877 | lambda x: dm(repo[x].date()[0]), condrepr=(b'<date %r>', ds) |
|
877 | lambda x: dm(repo[x].date()[0]), condrepr=(b'<date %r>', ds) | |
878 | ) |
|
878 | ) | |
879 |
|
879 | |||
880 |
|
880 | |||
881 | @predicate(b'desc(string)', safe=True, weight=10) |
|
881 | @predicate(b'desc(string)', safe=True, weight=10) | |
882 | def desc(repo, subset, x): |
|
882 | def desc(repo, subset, x): | |
883 | """Search commit message for string. The match is case-insensitive. |
|
883 | """Search commit message for string. The match is case-insensitive. | |
884 |
|
884 | |||
885 | Pattern matching is supported for `string`. See |
|
885 | Pattern matching is supported for `string`. See | |
886 | :hg:`help revisions.patterns`. |
|
886 | :hg:`help revisions.patterns`. | |
887 | """ |
|
887 | """ | |
888 | # i18n: "desc" is a keyword |
|
888 | # i18n: "desc" is a keyword | |
889 | ds = getstring(x, _(b"desc requires a string")) |
|
889 | ds = getstring(x, _(b"desc requires a string")) | |
890 |
|
890 | |||
891 | kind, pattern, matcher = _substringmatcher(ds, casesensitive=False) |
|
891 | kind, pattern, matcher = _substringmatcher(ds, casesensitive=False) | |
892 |
|
892 | |||
893 | return subset.filter( |
|
893 | return subset.filter( | |
894 | lambda r: matcher(repo[r].description()), condrepr=(b'<desc %r>', ds) |
|
894 | lambda r: matcher(repo[r].description()), condrepr=(b'<desc %r>', ds) | |
895 | ) |
|
895 | ) | |
896 |
|
896 | |||
897 |
|
897 | |||
898 | def _descendants( |
|
898 | def _descendants( | |
899 | repo, subset, x, followfirst=False, startdepth=None, stopdepth=None |
|
899 | repo, subset, x, followfirst=False, startdepth=None, stopdepth=None | |
900 | ): |
|
900 | ): | |
901 | roots = getset(repo, fullreposet(repo), x) |
|
901 | roots = getset(repo, fullreposet(repo), x) | |
902 | if not roots: |
|
902 | if not roots: | |
903 | return baseset() |
|
903 | return baseset() | |
904 | s = dagop.revdescendants(repo, roots, followfirst, startdepth, stopdepth) |
|
904 | s = dagop.revdescendants(repo, roots, followfirst, startdepth, stopdepth) | |
905 | return subset & s |
|
905 | return subset & s | |
906 |
|
906 | |||
907 |
|
907 | |||
908 | @predicate(b'descendants(set[, depth])', safe=True) |
|
908 | @predicate(b'descendants(set[, depth])', safe=True) | |
909 | def descendants(repo, subset, x): |
|
909 | def descendants(repo, subset, x): | |
910 | """Changesets which are descendants of changesets in set, including the |
|
910 | """Changesets which are descendants of changesets in set, including the | |
911 | given changesets themselves. |
|
911 | given changesets themselves. | |
912 |
|
912 | |||
913 | If depth is specified, the result only includes changesets up to |
|
913 | If depth is specified, the result only includes changesets up to | |
914 | the specified generation. |
|
914 | the specified generation. | |
915 | """ |
|
915 | """ | |
916 | # startdepth is for internal use only until we can decide the UI |
|
916 | # startdepth is for internal use only until we can decide the UI | |
917 | args = getargsdict(x, b'descendants', b'set depth startdepth') |
|
917 | args = getargsdict(x, b'descendants', b'set depth startdepth') | |
918 | if b'set' not in args: |
|
918 | if b'set' not in args: | |
919 | # i18n: "descendants" is a keyword |
|
919 | # i18n: "descendants" is a keyword | |
920 | raise error.ParseError(_(b'descendants takes at least 1 argument')) |
|
920 | raise error.ParseError(_(b'descendants takes at least 1 argument')) | |
921 | startdepth = stopdepth = None |
|
921 | startdepth = stopdepth = None | |
922 | if b'startdepth' in args: |
|
922 | if b'startdepth' in args: | |
923 | n = getinteger( |
|
923 | n = getinteger( | |
924 | args[b'startdepth'], b"descendants expects an integer startdepth" |
|
924 | args[b'startdepth'], b"descendants expects an integer startdepth" | |
925 | ) |
|
925 | ) | |
926 | if n < 0: |
|
926 | if n < 0: | |
927 | raise error.ParseError(b"negative startdepth") |
|
927 | raise error.ParseError(b"negative startdepth") | |
928 | startdepth = n |
|
928 | startdepth = n | |
929 | if b'depth' in args: |
|
929 | if b'depth' in args: | |
930 | # i18n: "descendants" is a keyword |
|
930 | # i18n: "descendants" is a keyword | |
931 | n = getinteger( |
|
931 | n = getinteger( | |
932 | args[b'depth'], _(b"descendants expects an integer depth") |
|
932 | args[b'depth'], _(b"descendants expects an integer depth") | |
933 | ) |
|
933 | ) | |
934 | if n < 0: |
|
934 | if n < 0: | |
935 | raise error.ParseError(_(b"negative depth")) |
|
935 | raise error.ParseError(_(b"negative depth")) | |
936 | stopdepth = n + 1 |
|
936 | stopdepth = n + 1 | |
937 | return _descendants( |
|
937 | return _descendants( | |
938 | repo, subset, args[b'set'], startdepth=startdepth, stopdepth=stopdepth |
|
938 | repo, subset, args[b'set'], startdepth=startdepth, stopdepth=stopdepth | |
939 | ) |
|
939 | ) | |
940 |
|
940 | |||
941 |
|
941 | |||
942 | @predicate(b'_firstdescendants', safe=True) |
|
942 | @predicate(b'_firstdescendants', safe=True) | |
943 | def _firstdescendants(repo, subset, x): |
|
943 | def _firstdescendants(repo, subset, x): | |
944 | # ``_firstdescendants(set)`` |
|
944 | # ``_firstdescendants(set)`` | |
945 | # Like ``descendants(set)`` but follows only the first parents. |
|
945 | # Like ``descendants(set)`` but follows only the first parents. | |
946 | return _descendants(repo, subset, x, followfirst=True) |
|
946 | return _descendants(repo, subset, x, followfirst=True) | |
947 |
|
947 | |||
948 |
|
948 | |||
949 | @predicate(b'destination([set])', safe=True, weight=10) |
|
949 | @predicate(b'destination([set])', safe=True, weight=10) | |
950 | def destination(repo, subset, x): |
|
950 | def destination(repo, subset, x): | |
951 | """Changesets that were created by a graft, transplant or rebase operation, |
|
951 | """Changesets that were created by a graft, transplant or rebase operation, | |
952 | with the given revisions specified as the source. Omitting the optional set |
|
952 | with the given revisions specified as the source. Omitting the optional set | |
953 | is the same as passing all(). |
|
953 | is the same as passing all(). | |
954 | """ |
|
954 | """ | |
955 | if x is not None: |
|
955 | if x is not None: | |
956 | sources = getset(repo, fullreposet(repo), x) |
|
956 | sources = getset(repo, fullreposet(repo), x) | |
957 | else: |
|
957 | else: | |
958 | sources = fullreposet(repo) |
|
958 | sources = fullreposet(repo) | |
959 |
|
959 | |||
960 | dests = set() |
|
960 | dests = set() | |
961 |
|
961 | |||
962 | # subset contains all of the possible destinations that can be returned, so |
|
962 | # subset contains all of the possible destinations that can be returned, so | |
963 | # iterate over them and see if their source(s) were provided in the arg set. |
|
963 | # iterate over them and see if their source(s) were provided in the arg set. | |
964 | # Even if the immediate src of r is not in the arg set, src's source (or |
|
964 | # Even if the immediate src of r is not in the arg set, src's source (or | |
965 | # further back) may be. Scanning back further than the immediate src allows |
|
965 | # further back) may be. Scanning back further than the immediate src allows | |
966 | # transitive transplants and rebases to yield the same results as transitive |
|
966 | # transitive transplants and rebases to yield the same results as transitive | |
967 | # grafts. |
|
967 | # grafts. | |
968 | for r in subset: |
|
968 | for r in subset: | |
969 | src = _getrevsource(repo, r) |
|
969 | src = _getrevsource(repo, r) | |
970 | lineage = None |
|
970 | lineage = None | |
971 |
|
971 | |||
972 | while src is not None: |
|
972 | while src is not None: | |
973 | if lineage is None: |
|
973 | if lineage is None: | |
974 | lineage = list() |
|
974 | lineage = list() | |
975 |
|
975 | |||
976 | lineage.append(r) |
|
976 | lineage.append(r) | |
977 |
|
977 | |||
978 | # The visited lineage is a match if the current source is in the arg |
|
978 | # The visited lineage is a match if the current source is in the arg | |
979 | # set. Since every candidate dest is visited by way of iterating |
|
979 | # set. Since every candidate dest is visited by way of iterating | |
980 | # subset, any dests further back in the lineage will be tested by a |
|
980 | # subset, any dests further back in the lineage will be tested by a | |
981 | # different iteration over subset. Likewise, if the src was already |
|
981 | # different iteration over subset. Likewise, if the src was already | |
982 | # selected, the current lineage can be selected without going back |
|
982 | # selected, the current lineage can be selected without going back | |
983 | # further. |
|
983 | # further. | |
984 | if src in sources or src in dests: |
|
984 | if src in sources or src in dests: | |
985 | dests.update(lineage) |
|
985 | dests.update(lineage) | |
986 | break |
|
986 | break | |
987 |
|
987 | |||
988 | r = src |
|
988 | r = src | |
989 | src = _getrevsource(repo, r) |
|
989 | src = _getrevsource(repo, r) | |
990 |
|
990 | |||
991 | return subset.filter( |
|
991 | return subset.filter( | |
992 | dests.__contains__, |
|
992 | dests.__contains__, | |
993 | condrepr=lambda: b'<destination %r>' % _sortedb(dests), |
|
993 | condrepr=lambda: b'<destination %r>' % _sortedb(dests), | |
994 | ) |
|
994 | ) | |
995 |
|
995 | |||
996 |
|
996 | |||
997 | @predicate(b'diff(pattern)', weight=110) |
|
997 | @predicate(b'diffcontains(pattern)', weight=110) | |
998 | def diff(repo, subset, x): |
|
998 | def diffcontains(repo, subset, x): | |
999 | """Search revision differences for when the pattern was added or removed. |
|
999 | """Search revision differences for when the pattern was added or removed. | |
1000 |
|
1000 | |||
1001 | The pattern may be a substring literal or a regular expression. See |
|
1001 | The pattern may be a substring literal or a regular expression. See | |
1002 | :hg:`help revisions.patterns`. |
|
1002 | :hg:`help revisions.patterns`. | |
1003 | """ |
|
1003 | """ | |
1004 | args = getargsdict(x, b'diff', b'pattern') |
|
1004 | args = getargsdict(x, b'diffcontains', b'pattern') | |
1005 | if b'pattern' not in args: |
|
1005 | if b'pattern' not in args: | |
1006 | # i18n: "diff" is a keyword |
|
1006 | # i18n: "diffcontains" is a keyword | |
1007 | raise error.ParseError(_(b'diff takes at least 1 argument')) |
|
1007 | raise error.ParseError(_(b'diffcontains takes at least 1 argument')) | |
1008 |
|
1008 | |||
1009 | pattern = getstring(args[b'pattern'], _(b'diff requires a string pattern')) |
|
1009 | pattern = getstring( | |
|
1010 | args[b'pattern'], _(b'diffcontains requires a string pattern') | |||
|
1011 | ) | |||
1010 | regexp = stringutil.substringregexp(pattern, re.M) |
|
1012 | regexp = stringutil.substringregexp(pattern, re.M) | |
1011 |
|
1013 | |||
1012 | # TODO: add support for file pattern and --follow. For example, |
|
1014 | # TODO: add support for file pattern and --follow. For example, | |
1013 |
# diff(pattern[, set]) where set may be file(pattern) or |
|
1015 | # diffcontains(pattern[, set]) where set may be file(pattern) or | |
1014 |
# and we'll eventually add a support for narrowing |
|
1016 | # follow(pattern), and we'll eventually add a support for narrowing | |
|
1017 | # files by revset? | |||
1015 | fmatch = matchmod.always() |
|
1018 | fmatch = matchmod.always() | |
1016 |
|
1019 | |||
1017 | def makefilematcher(ctx): |
|
1020 | def makefilematcher(ctx): | |
1018 | return fmatch |
|
1021 | return fmatch | |
1019 |
|
1022 | |||
1020 | # TODO: search in a windowed way |
|
1023 | # TODO: search in a windowed way | |
1021 | searcher = grepmod.grepsearcher(repo.ui, repo, regexp, diff=True) |
|
1024 | searcher = grepmod.grepsearcher(repo.ui, repo, regexp, diff=True) | |
1022 |
|
1025 | |||
1023 | def testdiff(rev): |
|
1026 | def testdiff(rev): | |
1024 | # consume the generator to discard revfiles/matches cache |
|
1027 | # consume the generator to discard revfiles/matches cache | |
1025 | found = False |
|
1028 | found = False | |
1026 | for fn, ctx, pstates, states in searcher.searchfiles( |
|
1029 | for fn, ctx, pstates, states in searcher.searchfiles( | |
1027 | baseset([rev]), makefilematcher |
|
1030 | baseset([rev]), makefilematcher | |
1028 | ): |
|
1031 | ): | |
1029 | if next(grepmod.difflinestates(pstates, states), None): |
|
1032 | if next(grepmod.difflinestates(pstates, states), None): | |
1030 | found = True |
|
1033 | found = True | |
1031 | return found |
|
1034 | return found | |
1032 |
|
1035 | |||
1033 | return subset.filter(testdiff, condrepr=(b'<diff %r>', pattern)) |
|
1036 | return subset.filter(testdiff, condrepr=(b'<diffcontains %r>', pattern)) | |
1034 |
|
1037 | |||
1035 |
|
1038 | |||
1036 | @predicate(b'contentdivergent()', safe=True) |
|
1039 | @predicate(b'contentdivergent()', safe=True) | |
1037 | def contentdivergent(repo, subset, x): |
|
1040 | def contentdivergent(repo, subset, x): | |
1038 | """ |
|
1041 | """ | |
1039 | Final successors of changesets with an alternative set of final |
|
1042 | Final successors of changesets with an alternative set of final | |
1040 | successors. (EXPERIMENTAL) |
|
1043 | successors. (EXPERIMENTAL) | |
1041 | """ |
|
1044 | """ | |
1042 | # i18n: "contentdivergent" is a keyword |
|
1045 | # i18n: "contentdivergent" is a keyword | |
1043 | getargs(x, 0, 0, _(b"contentdivergent takes no arguments")) |
|
1046 | getargs(x, 0, 0, _(b"contentdivergent takes no arguments")) | |
1044 | contentdivergent = obsmod.getrevs(repo, b'contentdivergent') |
|
1047 | contentdivergent = obsmod.getrevs(repo, b'contentdivergent') | |
1045 | return subset & contentdivergent |
|
1048 | return subset & contentdivergent | |
1046 |
|
1049 | |||
1047 |
|
1050 | |||
1048 | @predicate(b'expectsize(set[, size])', safe=True, takeorder=True) |
|
1051 | @predicate(b'expectsize(set[, size])', safe=True, takeorder=True) | |
1049 | def expectsize(repo, subset, x, order): |
|
1052 | def expectsize(repo, subset, x, order): | |
1050 | """Return the given revset if size matches the revset size. |
|
1053 | """Return the given revset if size matches the revset size. | |
1051 | Abort if the revset doesn't expect given size. |
|
1054 | Abort if the revset doesn't expect given size. | |
1052 | size can either be an integer range or an integer. |
|
1055 | size can either be an integer range or an integer. | |
1053 |
|
1056 | |||
1054 | For example, ``expectsize(0:1, 3:5)`` will abort as revset size is 2 and |
|
1057 | For example, ``expectsize(0:1, 3:5)`` will abort as revset size is 2 and | |
1055 | 2 is not between 3 and 5 inclusive.""" |
|
1058 | 2 is not between 3 and 5 inclusive.""" | |
1056 |
|
1059 | |||
1057 | args = getargsdict(x, b'expectsize', b'set size') |
|
1060 | args = getargsdict(x, b'expectsize', b'set size') | |
1058 | minsize = 0 |
|
1061 | minsize = 0 | |
1059 | maxsize = len(repo) + 1 |
|
1062 | maxsize = len(repo) + 1 | |
1060 | err = b'' |
|
1063 | err = b'' | |
1061 | if b'size' not in args or b'set' not in args: |
|
1064 | if b'size' not in args or b'set' not in args: | |
1062 | raise error.ParseError(_(b'invalid set of arguments')) |
|
1065 | raise error.ParseError(_(b'invalid set of arguments')) | |
1063 | minsize, maxsize = getintrange( |
|
1066 | minsize, maxsize = getintrange( | |
1064 | args[b'size'], |
|
1067 | args[b'size'], | |
1065 | _(b'expectsize requires a size range or a positive integer'), |
|
1068 | _(b'expectsize requires a size range or a positive integer'), | |
1066 | _(b'size range bounds must be integers'), |
|
1069 | _(b'size range bounds must be integers'), | |
1067 | minsize, |
|
1070 | minsize, | |
1068 | maxsize, |
|
1071 | maxsize, | |
1069 | ) |
|
1072 | ) | |
1070 | if minsize < 0 or maxsize < 0: |
|
1073 | if minsize < 0 or maxsize < 0: | |
1071 | raise error.ParseError(_(b'negative size')) |
|
1074 | raise error.ParseError(_(b'negative size')) | |
1072 | rev = getset(repo, fullreposet(repo), args[b'set'], order=order) |
|
1075 | rev = getset(repo, fullreposet(repo), args[b'set'], order=order) | |
1073 | if minsize != maxsize and (len(rev) < minsize or len(rev) > maxsize): |
|
1076 | if minsize != maxsize and (len(rev) < minsize or len(rev) > maxsize): | |
1074 | err = _(b'revset size mismatch. expected between %d and %d, got %d') % ( |
|
1077 | err = _(b'revset size mismatch. expected between %d and %d, got %d') % ( | |
1075 | minsize, |
|
1078 | minsize, | |
1076 | maxsize, |
|
1079 | maxsize, | |
1077 | len(rev), |
|
1080 | len(rev), | |
1078 | ) |
|
1081 | ) | |
1079 | elif minsize == maxsize and len(rev) != minsize: |
|
1082 | elif minsize == maxsize and len(rev) != minsize: | |
1080 | err = _(b'revset size mismatch. expected %d, got %d') % ( |
|
1083 | err = _(b'revset size mismatch. expected %d, got %d') % ( | |
1081 | minsize, |
|
1084 | minsize, | |
1082 | len(rev), |
|
1085 | len(rev), | |
1083 | ) |
|
1086 | ) | |
1084 | if err: |
|
1087 | if err: | |
1085 | raise error.RepoLookupError(err) |
|
1088 | raise error.RepoLookupError(err) | |
1086 | if order == followorder: |
|
1089 | if order == followorder: | |
1087 | return subset & rev |
|
1090 | return subset & rev | |
1088 | else: |
|
1091 | else: | |
1089 | return rev & subset |
|
1092 | return rev & subset | |
1090 |
|
1093 | |||
1091 |
|
1094 | |||
1092 | @predicate(b'extdata(source)', safe=False, weight=100) |
|
1095 | @predicate(b'extdata(source)', safe=False, weight=100) | |
1093 | def extdata(repo, subset, x): |
|
1096 | def extdata(repo, subset, x): | |
1094 | """Changesets in the specified extdata source. (EXPERIMENTAL)""" |
|
1097 | """Changesets in the specified extdata source. (EXPERIMENTAL)""" | |
1095 | # i18n: "extdata" is a keyword |
|
1098 | # i18n: "extdata" is a keyword | |
1096 | args = getargsdict(x, b'extdata', b'source') |
|
1099 | args = getargsdict(x, b'extdata', b'source') | |
1097 | source = getstring( |
|
1100 | source = getstring( | |
1098 | args.get(b'source'), |
|
1101 | args.get(b'source'), | |
1099 | # i18n: "extdata" is a keyword |
|
1102 | # i18n: "extdata" is a keyword | |
1100 | _(b'extdata takes at least 1 string argument'), |
|
1103 | _(b'extdata takes at least 1 string argument'), | |
1101 | ) |
|
1104 | ) | |
1102 | data = scmutil.extdatasource(repo, source) |
|
1105 | data = scmutil.extdatasource(repo, source) | |
1103 | return subset & baseset(data) |
|
1106 | return subset & baseset(data) | |
1104 |
|
1107 | |||
1105 |
|
1108 | |||
1106 | @predicate(b'extinct()', safe=True) |
|
1109 | @predicate(b'extinct()', safe=True) | |
1107 | def extinct(repo, subset, x): |
|
1110 | def extinct(repo, subset, x): | |
1108 | """Obsolete changesets with obsolete descendants only. (EXPERIMENTAL) |
|
1111 | """Obsolete changesets with obsolete descendants only. (EXPERIMENTAL) | |
1109 | """ |
|
1112 | """ | |
1110 | # i18n: "extinct" is a keyword |
|
1113 | # i18n: "extinct" is a keyword | |
1111 | getargs(x, 0, 0, _(b"extinct takes no arguments")) |
|
1114 | getargs(x, 0, 0, _(b"extinct takes no arguments")) | |
1112 | extincts = obsmod.getrevs(repo, b'extinct') |
|
1115 | extincts = obsmod.getrevs(repo, b'extinct') | |
1113 | return subset & extincts |
|
1116 | return subset & extincts | |
1114 |
|
1117 | |||
1115 |
|
1118 | |||
1116 | @predicate(b'extra(label, [value])', safe=True) |
|
1119 | @predicate(b'extra(label, [value])', safe=True) | |
1117 | def extra(repo, subset, x): |
|
1120 | def extra(repo, subset, x): | |
1118 | """Changesets with the given label in the extra metadata, with the given |
|
1121 | """Changesets with the given label in the extra metadata, with the given | |
1119 | optional value. |
|
1122 | optional value. | |
1120 |
|
1123 | |||
1121 | Pattern matching is supported for `value`. See |
|
1124 | Pattern matching is supported for `value`. See | |
1122 | :hg:`help revisions.patterns`. |
|
1125 | :hg:`help revisions.patterns`. | |
1123 | """ |
|
1126 | """ | |
1124 | args = getargsdict(x, b'extra', b'label value') |
|
1127 | args = getargsdict(x, b'extra', b'label value') | |
1125 | if b'label' not in args: |
|
1128 | if b'label' not in args: | |
1126 | # i18n: "extra" is a keyword |
|
1129 | # i18n: "extra" is a keyword | |
1127 | raise error.ParseError(_(b'extra takes at least 1 argument')) |
|
1130 | raise error.ParseError(_(b'extra takes at least 1 argument')) | |
1128 | # i18n: "extra" is a keyword |
|
1131 | # i18n: "extra" is a keyword | |
1129 | label = getstring( |
|
1132 | label = getstring( | |
1130 | args[b'label'], _(b'first argument to extra must be a string') |
|
1133 | args[b'label'], _(b'first argument to extra must be a string') | |
1131 | ) |
|
1134 | ) | |
1132 | value = None |
|
1135 | value = None | |
1133 |
|
1136 | |||
1134 | if b'value' in args: |
|
1137 | if b'value' in args: | |
1135 | # i18n: "extra" is a keyword |
|
1138 | # i18n: "extra" is a keyword | |
1136 | value = getstring( |
|
1139 | value = getstring( | |
1137 | args[b'value'], _(b'second argument to extra must be a string') |
|
1140 | args[b'value'], _(b'second argument to extra must be a string') | |
1138 | ) |
|
1141 | ) | |
1139 | kind, value, matcher = stringutil.stringmatcher(value) |
|
1142 | kind, value, matcher = stringutil.stringmatcher(value) | |
1140 |
|
1143 | |||
1141 | def _matchvalue(r): |
|
1144 | def _matchvalue(r): | |
1142 | extra = repo[r].extra() |
|
1145 | extra = repo[r].extra() | |
1143 | return label in extra and (value is None or matcher(extra[label])) |
|
1146 | return label in extra and (value is None or matcher(extra[label])) | |
1144 |
|
1147 | |||
1145 | return subset.filter( |
|
1148 | return subset.filter( | |
1146 | lambda r: _matchvalue(r), condrepr=(b'<extra[%r] %r>', label, value) |
|
1149 | lambda r: _matchvalue(r), condrepr=(b'<extra[%r] %r>', label, value) | |
1147 | ) |
|
1150 | ) | |
1148 |
|
1151 | |||
1149 |
|
1152 | |||
1150 | @predicate(b'filelog(pattern)', safe=True) |
|
1153 | @predicate(b'filelog(pattern)', safe=True) | |
1151 | def filelog(repo, subset, x): |
|
1154 | def filelog(repo, subset, x): | |
1152 | """Changesets connected to the specified filelog. |
|
1155 | """Changesets connected to the specified filelog. | |
1153 |
|
1156 | |||
1154 | For performance reasons, visits only revisions mentioned in the file-level |
|
1157 | For performance reasons, visits only revisions mentioned in the file-level | |
1155 | filelog, rather than filtering through all changesets (much faster, but |
|
1158 | filelog, rather than filtering through all changesets (much faster, but | |
1156 | doesn't include deletes or duplicate changes). For a slower, more accurate |
|
1159 | doesn't include deletes or duplicate changes). For a slower, more accurate | |
1157 | result, use ``file()``. |
|
1160 | result, use ``file()``. | |
1158 |
|
1161 | |||
1159 | The pattern without explicit kind like ``glob:`` is expected to be |
|
1162 | The pattern without explicit kind like ``glob:`` is expected to be | |
1160 | relative to the current directory and match against a file exactly |
|
1163 | relative to the current directory and match against a file exactly | |
1161 | for efficiency. |
|
1164 | for efficiency. | |
1162 | """ |
|
1165 | """ | |
1163 |
|
1166 | |||
1164 | # i18n: "filelog" is a keyword |
|
1167 | # i18n: "filelog" is a keyword | |
1165 | pat = getstring(x, _(b"filelog requires a pattern")) |
|
1168 | pat = getstring(x, _(b"filelog requires a pattern")) | |
1166 | s = set() |
|
1169 | s = set() | |
1167 | cl = repo.changelog |
|
1170 | cl = repo.changelog | |
1168 |
|
1171 | |||
1169 | if not matchmod.patkind(pat): |
|
1172 | if not matchmod.patkind(pat): | |
1170 | f = pathutil.canonpath(repo.root, repo.getcwd(), pat) |
|
1173 | f = pathutil.canonpath(repo.root, repo.getcwd(), pat) | |
1171 | files = [f] |
|
1174 | files = [f] | |
1172 | else: |
|
1175 | else: | |
1173 | m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None]) |
|
1176 | m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[None]) | |
1174 | files = (f for f in repo[None] if m(f)) |
|
1177 | files = (f for f in repo[None] if m(f)) | |
1175 |
|
1178 | |||
1176 | for f in files: |
|
1179 | for f in files: | |
1177 | fl = repo.file(f) |
|
1180 | fl = repo.file(f) | |
1178 | known = {} |
|
1181 | known = {} | |
1179 | scanpos = 0 |
|
1182 | scanpos = 0 | |
1180 | for fr in list(fl): |
|
1183 | for fr in list(fl): | |
1181 | fn = fl.node(fr) |
|
1184 | fn = fl.node(fr) | |
1182 | if fn in known: |
|
1185 | if fn in known: | |
1183 | s.add(known[fn]) |
|
1186 | s.add(known[fn]) | |
1184 | continue |
|
1187 | continue | |
1185 |
|
1188 | |||
1186 | lr = fl.linkrev(fr) |
|
1189 | lr = fl.linkrev(fr) | |
1187 | if lr in cl: |
|
1190 | if lr in cl: | |
1188 | s.add(lr) |
|
1191 | s.add(lr) | |
1189 | elif scanpos is not None: |
|
1192 | elif scanpos is not None: | |
1190 | # lowest matching changeset is filtered, scan further |
|
1193 | # lowest matching changeset is filtered, scan further | |
1191 | # ahead in changelog |
|
1194 | # ahead in changelog | |
1192 | start = max(lr, scanpos) + 1 |
|
1195 | start = max(lr, scanpos) + 1 | |
1193 | scanpos = None |
|
1196 | scanpos = None | |
1194 | for r in cl.revs(start): |
|
1197 | for r in cl.revs(start): | |
1195 | # minimize parsing of non-matching entries |
|
1198 | # minimize parsing of non-matching entries | |
1196 | if f in cl.revision(r) and f in cl.readfiles(r): |
|
1199 | if f in cl.revision(r) and f in cl.readfiles(r): | |
1197 | try: |
|
1200 | try: | |
1198 | # try to use manifest delta fastpath |
|
1201 | # try to use manifest delta fastpath | |
1199 | n = repo[r].filenode(f) |
|
1202 | n = repo[r].filenode(f) | |
1200 | if n not in known: |
|
1203 | if n not in known: | |
1201 | if n == fn: |
|
1204 | if n == fn: | |
1202 | s.add(r) |
|
1205 | s.add(r) | |
1203 | scanpos = r |
|
1206 | scanpos = r | |
1204 | break |
|
1207 | break | |
1205 | else: |
|
1208 | else: | |
1206 | known[n] = r |
|
1209 | known[n] = r | |
1207 | except error.ManifestLookupError: |
|
1210 | except error.ManifestLookupError: | |
1208 | # deletion in changelog |
|
1211 | # deletion in changelog | |
1209 | continue |
|
1212 | continue | |
1210 |
|
1213 | |||
1211 | return subset & s |
|
1214 | return subset & s | |
1212 |
|
1215 | |||
1213 |
|
1216 | |||
1214 | @predicate(b'first(set, [n])', safe=True, takeorder=True, weight=0) |
|
1217 | @predicate(b'first(set, [n])', safe=True, takeorder=True, weight=0) | |
1215 | def first(repo, subset, x, order): |
|
1218 | def first(repo, subset, x, order): | |
1216 | """An alias for limit(). |
|
1219 | """An alias for limit(). | |
1217 | """ |
|
1220 | """ | |
1218 | return limit(repo, subset, x, order) |
|
1221 | return limit(repo, subset, x, order) | |
1219 |
|
1222 | |||
1220 |
|
1223 | |||
1221 | def _follow(repo, subset, x, name, followfirst=False): |
|
1224 | def _follow(repo, subset, x, name, followfirst=False): | |
1222 | args = getargsdict(x, name, b'file startrev') |
|
1225 | args = getargsdict(x, name, b'file startrev') | |
1223 | revs = None |
|
1226 | revs = None | |
1224 | if b'startrev' in args: |
|
1227 | if b'startrev' in args: | |
1225 | revs = getset(repo, fullreposet(repo), args[b'startrev']) |
|
1228 | revs = getset(repo, fullreposet(repo), args[b'startrev']) | |
1226 | if b'file' in args: |
|
1229 | if b'file' in args: | |
1227 | x = getstring(args[b'file'], _(b"%s expected a pattern") % name) |
|
1230 | x = getstring(args[b'file'], _(b"%s expected a pattern") % name) | |
1228 | if revs is None: |
|
1231 | if revs is None: | |
1229 | revs = [None] |
|
1232 | revs = [None] | |
1230 | fctxs = [] |
|
1233 | fctxs = [] | |
1231 | for r in revs: |
|
1234 | for r in revs: | |
1232 | ctx = mctx = repo[r] |
|
1235 | ctx = mctx = repo[r] | |
1233 | if r is None: |
|
1236 | if r is None: | |
1234 | ctx = repo[b'.'] |
|
1237 | ctx = repo[b'.'] | |
1235 | m = matchmod.match( |
|
1238 | m = matchmod.match( | |
1236 | repo.root, repo.getcwd(), [x], ctx=mctx, default=b'path' |
|
1239 | repo.root, repo.getcwd(), [x], ctx=mctx, default=b'path' | |
1237 | ) |
|
1240 | ) | |
1238 | fctxs.extend(ctx[f].introfilectx() for f in ctx.manifest().walk(m)) |
|
1241 | fctxs.extend(ctx[f].introfilectx() for f in ctx.manifest().walk(m)) | |
1239 | s = dagop.filerevancestors(fctxs, followfirst) |
|
1242 | s = dagop.filerevancestors(fctxs, followfirst) | |
1240 | else: |
|
1243 | else: | |
1241 | if revs is None: |
|
1244 | if revs is None: | |
1242 | revs = baseset([repo[b'.'].rev()]) |
|
1245 | revs = baseset([repo[b'.'].rev()]) | |
1243 | s = dagop.revancestors(repo, revs, followfirst) |
|
1246 | s = dagop.revancestors(repo, revs, followfirst) | |
1244 |
|
1247 | |||
1245 | return subset & s |
|
1248 | return subset & s | |
1246 |
|
1249 | |||
1247 |
|
1250 | |||
1248 | @predicate(b'follow([file[, startrev]])', safe=True) |
|
1251 | @predicate(b'follow([file[, startrev]])', safe=True) | |
1249 | def follow(repo, subset, x): |
|
1252 | def follow(repo, subset, x): | |
1250 | """ |
|
1253 | """ | |
1251 | An alias for ``::.`` (ancestors of the working directory's first parent). |
|
1254 | An alias for ``::.`` (ancestors of the working directory's first parent). | |
1252 | If file pattern is specified, the histories of files matching given |
|
1255 | If file pattern is specified, the histories of files matching given | |
1253 | pattern in the revision given by startrev are followed, including copies. |
|
1256 | pattern in the revision given by startrev are followed, including copies. | |
1254 | """ |
|
1257 | """ | |
1255 | return _follow(repo, subset, x, b'follow') |
|
1258 | return _follow(repo, subset, x, b'follow') | |
1256 |
|
1259 | |||
1257 |
|
1260 | |||
1258 | @predicate(b'_followfirst', safe=True) |
|
1261 | @predicate(b'_followfirst', safe=True) | |
1259 | def _followfirst(repo, subset, x): |
|
1262 | def _followfirst(repo, subset, x): | |
1260 | # ``followfirst([file[, startrev]])`` |
|
1263 | # ``followfirst([file[, startrev]])`` | |
1261 | # Like ``follow([file[, startrev]])`` but follows only the first parent |
|
1264 | # Like ``follow([file[, startrev]])`` but follows only the first parent | |
1262 | # of every revisions or files revisions. |
|
1265 | # of every revisions or files revisions. | |
1263 | return _follow(repo, subset, x, b'_followfirst', followfirst=True) |
|
1266 | return _follow(repo, subset, x, b'_followfirst', followfirst=True) | |
1264 |
|
1267 | |||
1265 |
|
1268 | |||
1266 | @predicate( |
|
1269 | @predicate( | |
1267 | b'followlines(file, fromline:toline[, startrev=., descend=False])', |
|
1270 | b'followlines(file, fromline:toline[, startrev=., descend=False])', | |
1268 | safe=True, |
|
1271 | safe=True, | |
1269 | ) |
|
1272 | ) | |
1270 | def followlines(repo, subset, x): |
|
1273 | def followlines(repo, subset, x): | |
1271 | """Changesets modifying `file` in line range ('fromline', 'toline'). |
|
1274 | """Changesets modifying `file` in line range ('fromline', 'toline'). | |
1272 |
|
1275 | |||
1273 | Line range corresponds to 'file' content at 'startrev' and should hence be |
|
1276 | Line range corresponds to 'file' content at 'startrev' and should hence be | |
1274 | consistent with file size. If startrev is not specified, working directory's |
|
1277 | consistent with file size. If startrev is not specified, working directory's | |
1275 | parent is used. |
|
1278 | parent is used. | |
1276 |
|
1279 | |||
1277 | By default, ancestors of 'startrev' are returned. If 'descend' is True, |
|
1280 | By default, ancestors of 'startrev' are returned. If 'descend' is True, | |
1278 | descendants of 'startrev' are returned though renames are (currently) not |
|
1281 | descendants of 'startrev' are returned though renames are (currently) not | |
1279 | followed in this direction. |
|
1282 | followed in this direction. | |
1280 | """ |
|
1283 | """ | |
1281 | args = getargsdict(x, b'followlines', b'file *lines startrev descend') |
|
1284 | args = getargsdict(x, b'followlines', b'file *lines startrev descend') | |
1282 | if len(args[b'lines']) != 1: |
|
1285 | if len(args[b'lines']) != 1: | |
1283 | raise error.ParseError(_(b"followlines requires a line range")) |
|
1286 | raise error.ParseError(_(b"followlines requires a line range")) | |
1284 |
|
1287 | |||
1285 | rev = b'.' |
|
1288 | rev = b'.' | |
1286 | if b'startrev' in args: |
|
1289 | if b'startrev' in args: | |
1287 | revs = getset(repo, fullreposet(repo), args[b'startrev']) |
|
1290 | revs = getset(repo, fullreposet(repo), args[b'startrev']) | |
1288 | if len(revs) != 1: |
|
1291 | if len(revs) != 1: | |
1289 | raise error.ParseError( |
|
1292 | raise error.ParseError( | |
1290 | # i18n: "followlines" is a keyword |
|
1293 | # i18n: "followlines" is a keyword | |
1291 | _(b"followlines expects exactly one revision") |
|
1294 | _(b"followlines expects exactly one revision") | |
1292 | ) |
|
1295 | ) | |
1293 | rev = revs.last() |
|
1296 | rev = revs.last() | |
1294 |
|
1297 | |||
1295 | pat = getstring(args[b'file'], _(b"followlines requires a pattern")) |
|
1298 | pat = getstring(args[b'file'], _(b"followlines requires a pattern")) | |
1296 | # i18n: "followlines" is a keyword |
|
1299 | # i18n: "followlines" is a keyword | |
1297 | msg = _(b"followlines expects exactly one file") |
|
1300 | msg = _(b"followlines expects exactly one file") | |
1298 | fname = scmutil.parsefollowlinespattern(repo, rev, pat, msg) |
|
1301 | fname = scmutil.parsefollowlinespattern(repo, rev, pat, msg) | |
1299 | fromline, toline = util.processlinerange( |
|
1302 | fromline, toline = util.processlinerange( | |
1300 | *getintrange( |
|
1303 | *getintrange( | |
1301 | args[b'lines'][0], |
|
1304 | args[b'lines'][0], | |
1302 | # i18n: "followlines" is a keyword |
|
1305 | # i18n: "followlines" is a keyword | |
1303 | _(b"followlines expects a line number or a range"), |
|
1306 | _(b"followlines expects a line number or a range"), | |
1304 | _(b"line range bounds must be integers"), |
|
1307 | _(b"line range bounds must be integers"), | |
1305 | ) |
|
1308 | ) | |
1306 | ) |
|
1309 | ) | |
1307 |
|
1310 | |||
1308 | fctx = repo[rev].filectx(fname) |
|
1311 | fctx = repo[rev].filectx(fname) | |
1309 | descend = False |
|
1312 | descend = False | |
1310 | if b'descend' in args: |
|
1313 | if b'descend' in args: | |
1311 | descend = getboolean( |
|
1314 | descend = getboolean( | |
1312 | args[b'descend'], |
|
1315 | args[b'descend'], | |
1313 | # i18n: "descend" is a keyword |
|
1316 | # i18n: "descend" is a keyword | |
1314 | _(b"descend argument must be a boolean"), |
|
1317 | _(b"descend argument must be a boolean"), | |
1315 | ) |
|
1318 | ) | |
1316 | if descend: |
|
1319 | if descend: | |
1317 | rs = generatorset( |
|
1320 | rs = generatorset( | |
1318 | ( |
|
1321 | ( | |
1319 | c.rev() |
|
1322 | c.rev() | |
1320 | for c, _linerange in dagop.blockdescendants( |
|
1323 | for c, _linerange in dagop.blockdescendants( | |
1321 | fctx, fromline, toline |
|
1324 | fctx, fromline, toline | |
1322 | ) |
|
1325 | ) | |
1323 | ), |
|
1326 | ), | |
1324 | iterasc=True, |
|
1327 | iterasc=True, | |
1325 | ) |
|
1328 | ) | |
1326 | else: |
|
1329 | else: | |
1327 | rs = generatorset( |
|
1330 | rs = generatorset( | |
1328 | ( |
|
1331 | ( | |
1329 | c.rev() |
|
1332 | c.rev() | |
1330 | for c, _linerange in dagop.blockancestors( |
|
1333 | for c, _linerange in dagop.blockancestors( | |
1331 | fctx, fromline, toline |
|
1334 | fctx, fromline, toline | |
1332 | ) |
|
1335 | ) | |
1333 | ), |
|
1336 | ), | |
1334 | iterasc=False, |
|
1337 | iterasc=False, | |
1335 | ) |
|
1338 | ) | |
1336 | return subset & rs |
|
1339 | return subset & rs | |
1337 |
|
1340 | |||
1338 |
|
1341 | |||
1339 | @predicate(b'all()', safe=True) |
|
1342 | @predicate(b'all()', safe=True) | |
1340 | def getall(repo, subset, x): |
|
1343 | def getall(repo, subset, x): | |
1341 | """All changesets, the same as ``0:tip``. |
|
1344 | """All changesets, the same as ``0:tip``. | |
1342 | """ |
|
1345 | """ | |
1343 | # i18n: "all" is a keyword |
|
1346 | # i18n: "all" is a keyword | |
1344 | getargs(x, 0, 0, _(b"all takes no arguments")) |
|
1347 | getargs(x, 0, 0, _(b"all takes no arguments")) | |
1345 | return subset & spanset(repo) # drop "null" if any |
|
1348 | return subset & spanset(repo) # drop "null" if any | |
1346 |
|
1349 | |||
1347 |
|
1350 | |||
1348 | @predicate(b'grep(regex)', weight=10) |
|
1351 | @predicate(b'grep(regex)', weight=10) | |
1349 | def grep(repo, subset, x): |
|
1352 | def grep(repo, subset, x): | |
1350 | """Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')`` |
|
1353 | """Like ``keyword(string)`` but accepts a regex. Use ``grep(r'...')`` | |
1351 | to ensure special escape characters are handled correctly. Unlike |
|
1354 | to ensure special escape characters are handled correctly. Unlike | |
1352 | ``keyword(string)``, the match is case-sensitive. |
|
1355 | ``keyword(string)``, the match is case-sensitive. | |
1353 | """ |
|
1356 | """ | |
1354 | try: |
|
1357 | try: | |
1355 | # i18n: "grep" is a keyword |
|
1358 | # i18n: "grep" is a keyword | |
1356 | gr = re.compile(getstring(x, _(b"grep requires a string"))) |
|
1359 | gr = re.compile(getstring(x, _(b"grep requires a string"))) | |
1357 | except re.error as e: |
|
1360 | except re.error as e: | |
1358 | raise error.ParseError( |
|
1361 | raise error.ParseError( | |
1359 | _(b'invalid match pattern: %s') % stringutil.forcebytestr(e) |
|
1362 | _(b'invalid match pattern: %s') % stringutil.forcebytestr(e) | |
1360 | ) |
|
1363 | ) | |
1361 |
|
1364 | |||
1362 | def matches(x): |
|
1365 | def matches(x): | |
1363 | c = repo[x] |
|
1366 | c = repo[x] | |
1364 | for e in c.files() + [c.user(), c.description()]: |
|
1367 | for e in c.files() + [c.user(), c.description()]: | |
1365 | if gr.search(e): |
|
1368 | if gr.search(e): | |
1366 | return True |
|
1369 | return True | |
1367 | return False |
|
1370 | return False | |
1368 |
|
1371 | |||
1369 | return subset.filter(matches, condrepr=(b'<grep %r>', gr.pattern)) |
|
1372 | return subset.filter(matches, condrepr=(b'<grep %r>', gr.pattern)) | |
1370 |
|
1373 | |||
1371 |
|
1374 | |||
1372 | @predicate(b'_matchfiles', safe=True) |
|
1375 | @predicate(b'_matchfiles', safe=True) | |
1373 | def _matchfiles(repo, subset, x): |
|
1376 | def _matchfiles(repo, subset, x): | |
1374 | # _matchfiles takes a revset list of prefixed arguments: |
|
1377 | # _matchfiles takes a revset list of prefixed arguments: | |
1375 | # |
|
1378 | # | |
1376 | # [p:foo, i:bar, x:baz] |
|
1379 | # [p:foo, i:bar, x:baz] | |
1377 | # |
|
1380 | # | |
1378 | # builds a match object from them and filters subset. Allowed |
|
1381 | # builds a match object from them and filters subset. Allowed | |
1379 | # prefixes are 'p:' for regular patterns, 'i:' for include |
|
1382 | # prefixes are 'p:' for regular patterns, 'i:' for include | |
1380 | # patterns and 'x:' for exclude patterns. Use 'r:' prefix to pass |
|
1383 | # patterns and 'x:' for exclude patterns. Use 'r:' prefix to pass | |
1381 | # a revision identifier, or the empty string to reference the |
|
1384 | # a revision identifier, or the empty string to reference the | |
1382 | # working directory, from which the match object is |
|
1385 | # working directory, from which the match object is | |
1383 | # initialized. Use 'd:' to set the default matching mode, default |
|
1386 | # initialized. Use 'd:' to set the default matching mode, default | |
1384 | # to 'glob'. At most one 'r:' and 'd:' argument can be passed. |
|
1387 | # to 'glob'. At most one 'r:' and 'd:' argument can be passed. | |
1385 |
|
1388 | |||
1386 | l = getargs(x, 1, -1, b"_matchfiles requires at least one argument") |
|
1389 | l = getargs(x, 1, -1, b"_matchfiles requires at least one argument") | |
1387 | pats, inc, exc = [], [], [] |
|
1390 | pats, inc, exc = [], [], [] | |
1388 | rev, default = None, None |
|
1391 | rev, default = None, None | |
1389 | for arg in l: |
|
1392 | for arg in l: | |
1390 | s = getstring(arg, b"_matchfiles requires string arguments") |
|
1393 | s = getstring(arg, b"_matchfiles requires string arguments") | |
1391 | prefix, value = s[:2], s[2:] |
|
1394 | prefix, value = s[:2], s[2:] | |
1392 | if prefix == b'p:': |
|
1395 | if prefix == b'p:': | |
1393 | pats.append(value) |
|
1396 | pats.append(value) | |
1394 | elif prefix == b'i:': |
|
1397 | elif prefix == b'i:': | |
1395 | inc.append(value) |
|
1398 | inc.append(value) | |
1396 | elif prefix == b'x:': |
|
1399 | elif prefix == b'x:': | |
1397 | exc.append(value) |
|
1400 | exc.append(value) | |
1398 | elif prefix == b'r:': |
|
1401 | elif prefix == b'r:': | |
1399 | if rev is not None: |
|
1402 | if rev is not None: | |
1400 | raise error.ParseError( |
|
1403 | raise error.ParseError( | |
1401 | b'_matchfiles expected at most one revision' |
|
1404 | b'_matchfiles expected at most one revision' | |
1402 | ) |
|
1405 | ) | |
1403 | if value == b'': # empty means working directory |
|
1406 | if value == b'': # empty means working directory | |
1404 | rev = node.wdirrev |
|
1407 | rev = node.wdirrev | |
1405 | else: |
|
1408 | else: | |
1406 | rev = value |
|
1409 | rev = value | |
1407 | elif prefix == b'd:': |
|
1410 | elif prefix == b'd:': | |
1408 | if default is not None: |
|
1411 | if default is not None: | |
1409 | raise error.ParseError( |
|
1412 | raise error.ParseError( | |
1410 | b'_matchfiles expected at most one default mode' |
|
1413 | b'_matchfiles expected at most one default mode' | |
1411 | ) |
|
1414 | ) | |
1412 | default = value |
|
1415 | default = value | |
1413 | else: |
|
1416 | else: | |
1414 | raise error.ParseError(b'invalid _matchfiles prefix: %s' % prefix) |
|
1417 | raise error.ParseError(b'invalid _matchfiles prefix: %s' % prefix) | |
1415 | if not default: |
|
1418 | if not default: | |
1416 | default = b'glob' |
|
1419 | default = b'glob' | |
1417 | hasset = any(matchmod.patkind(p) == b'set' for p in pats + inc + exc) |
|
1420 | hasset = any(matchmod.patkind(p) == b'set' for p in pats + inc + exc) | |
1418 |
|
1421 | |||
1419 | mcache = [None] |
|
1422 | mcache = [None] | |
1420 |
|
1423 | |||
1421 | # This directly read the changelog data as creating changectx for all |
|
1424 | # This directly read the changelog data as creating changectx for all | |
1422 | # revisions is quite expensive. |
|
1425 | # revisions is quite expensive. | |
1423 | getfiles = repo.changelog.readfiles |
|
1426 | getfiles = repo.changelog.readfiles | |
1424 | wdirrev = node.wdirrev |
|
1427 | wdirrev = node.wdirrev | |
1425 |
|
1428 | |||
1426 | def matches(x): |
|
1429 | def matches(x): | |
1427 | if x == wdirrev: |
|
1430 | if x == wdirrev: | |
1428 | files = repo[x].files() |
|
1431 | files = repo[x].files() | |
1429 | else: |
|
1432 | else: | |
1430 | files = getfiles(x) |
|
1433 | files = getfiles(x) | |
1431 |
|
1434 | |||
1432 | if not mcache[0] or (hasset and rev is None): |
|
1435 | if not mcache[0] or (hasset and rev is None): | |
1433 | r = x if rev is None else rev |
|
1436 | r = x if rev is None else rev | |
1434 | mcache[0] = matchmod.match( |
|
1437 | mcache[0] = matchmod.match( | |
1435 | repo.root, |
|
1438 | repo.root, | |
1436 | repo.getcwd(), |
|
1439 | repo.getcwd(), | |
1437 | pats, |
|
1440 | pats, | |
1438 | include=inc, |
|
1441 | include=inc, | |
1439 | exclude=exc, |
|
1442 | exclude=exc, | |
1440 | ctx=repo[r], |
|
1443 | ctx=repo[r], | |
1441 | default=default, |
|
1444 | default=default, | |
1442 | ) |
|
1445 | ) | |
1443 | m = mcache[0] |
|
1446 | m = mcache[0] | |
1444 |
|
1447 | |||
1445 | for f in files: |
|
1448 | for f in files: | |
1446 | if m(f): |
|
1449 | if m(f): | |
1447 | return True |
|
1450 | return True | |
1448 | return False |
|
1451 | return False | |
1449 |
|
1452 | |||
1450 | return subset.filter( |
|
1453 | return subset.filter( | |
1451 | matches, |
|
1454 | matches, | |
1452 | condrepr=( |
|
1455 | condrepr=( | |
1453 | b'<matchfiles patterns=%r, include=%r ' |
|
1456 | b'<matchfiles patterns=%r, include=%r ' | |
1454 | b'exclude=%r, default=%r, rev=%r>', |
|
1457 | b'exclude=%r, default=%r, rev=%r>', | |
1455 | pats, |
|
1458 | pats, | |
1456 | inc, |
|
1459 | inc, | |
1457 | exc, |
|
1460 | exc, | |
1458 | default, |
|
1461 | default, | |
1459 | rev, |
|
1462 | rev, | |
1460 | ), |
|
1463 | ), | |
1461 | ) |
|
1464 | ) | |
1462 |
|
1465 | |||
1463 |
|
1466 | |||
1464 | @predicate(b'file(pattern)', safe=True, weight=10) |
|
1467 | @predicate(b'file(pattern)', safe=True, weight=10) | |
1465 | def hasfile(repo, subset, x): |
|
1468 | def hasfile(repo, subset, x): | |
1466 | """Changesets affecting files matched by pattern. |
|
1469 | """Changesets affecting files matched by pattern. | |
1467 |
|
1470 | |||
1468 | For a faster but less accurate result, consider using ``filelog()`` |
|
1471 | For a faster but less accurate result, consider using ``filelog()`` | |
1469 | instead. |
|
1472 | instead. | |
1470 |
|
1473 | |||
1471 | This predicate uses ``glob:`` as the default kind of pattern. |
|
1474 | This predicate uses ``glob:`` as the default kind of pattern. | |
1472 | """ |
|
1475 | """ | |
1473 | # i18n: "file" is a keyword |
|
1476 | # i18n: "file" is a keyword | |
1474 | pat = getstring(x, _(b"file requires a pattern")) |
|
1477 | pat = getstring(x, _(b"file requires a pattern")) | |
1475 | return _matchfiles(repo, subset, (b'string', b'p:' + pat)) |
|
1478 | return _matchfiles(repo, subset, (b'string', b'p:' + pat)) | |
1476 |
|
1479 | |||
1477 |
|
1480 | |||
1478 | @predicate(b'head()', safe=True) |
|
1481 | @predicate(b'head()', safe=True) | |
1479 | def head(repo, subset, x): |
|
1482 | def head(repo, subset, x): | |
1480 | """Changeset is a named branch head. |
|
1483 | """Changeset is a named branch head. | |
1481 | """ |
|
1484 | """ | |
1482 | # i18n: "head" is a keyword |
|
1485 | # i18n: "head" is a keyword | |
1483 | getargs(x, 0, 0, _(b"head takes no arguments")) |
|
1486 | getargs(x, 0, 0, _(b"head takes no arguments")) | |
1484 | hs = set() |
|
1487 | hs = set() | |
1485 | cl = repo.changelog |
|
1488 | cl = repo.changelog | |
1486 | for ls in repo.branchmap().iterheads(): |
|
1489 | for ls in repo.branchmap().iterheads(): | |
1487 | hs.update(cl.rev(h) for h in ls) |
|
1490 | hs.update(cl.rev(h) for h in ls) | |
1488 | return subset & baseset(hs) |
|
1491 | return subset & baseset(hs) | |
1489 |
|
1492 | |||
1490 |
|
1493 | |||
1491 | @predicate(b'heads(set)', safe=True, takeorder=True) |
|
1494 | @predicate(b'heads(set)', safe=True, takeorder=True) | |
1492 | def heads(repo, subset, x, order): |
|
1495 | def heads(repo, subset, x, order): | |
1493 | """Members of set with no children in set. |
|
1496 | """Members of set with no children in set. | |
1494 | """ |
|
1497 | """ | |
1495 | # argument set should never define order |
|
1498 | # argument set should never define order | |
1496 | if order == defineorder: |
|
1499 | if order == defineorder: | |
1497 | order = followorder |
|
1500 | order = followorder | |
1498 | inputset = getset(repo, fullreposet(repo), x, order=order) |
|
1501 | inputset = getset(repo, fullreposet(repo), x, order=order) | |
1499 | wdirparents = None |
|
1502 | wdirparents = None | |
1500 | if node.wdirrev in inputset: |
|
1503 | if node.wdirrev in inputset: | |
1501 | # a bit slower, but not common so good enough for now |
|
1504 | # a bit slower, but not common so good enough for now | |
1502 | wdirparents = [p.rev() for p in repo[None].parents()] |
|
1505 | wdirparents = [p.rev() for p in repo[None].parents()] | |
1503 | inputset = set(inputset) |
|
1506 | inputset = set(inputset) | |
1504 | inputset.discard(node.wdirrev) |
|
1507 | inputset.discard(node.wdirrev) | |
1505 | heads = repo.changelog.headrevs(inputset) |
|
1508 | heads = repo.changelog.headrevs(inputset) | |
1506 | if wdirparents is not None: |
|
1509 | if wdirparents is not None: | |
1507 | heads.difference_update(wdirparents) |
|
1510 | heads.difference_update(wdirparents) | |
1508 | heads.add(node.wdirrev) |
|
1511 | heads.add(node.wdirrev) | |
1509 | heads = baseset(heads) |
|
1512 | heads = baseset(heads) | |
1510 | return subset & heads |
|
1513 | return subset & heads | |
1511 |
|
1514 | |||
1512 |
|
1515 | |||
1513 | @predicate(b'hidden()', safe=True) |
|
1516 | @predicate(b'hidden()', safe=True) | |
1514 | def hidden(repo, subset, x): |
|
1517 | def hidden(repo, subset, x): | |
1515 | """Hidden changesets. |
|
1518 | """Hidden changesets. | |
1516 | """ |
|
1519 | """ | |
1517 | # i18n: "hidden" is a keyword |
|
1520 | # i18n: "hidden" is a keyword | |
1518 | getargs(x, 0, 0, _(b"hidden takes no arguments")) |
|
1521 | getargs(x, 0, 0, _(b"hidden takes no arguments")) | |
1519 | hiddenrevs = repoview.filterrevs(repo, b'visible') |
|
1522 | hiddenrevs = repoview.filterrevs(repo, b'visible') | |
1520 | return subset & hiddenrevs |
|
1523 | return subset & hiddenrevs | |
1521 |
|
1524 | |||
1522 |
|
1525 | |||
1523 | @predicate(b'keyword(string)', safe=True, weight=10) |
|
1526 | @predicate(b'keyword(string)', safe=True, weight=10) | |
1524 | def keyword(repo, subset, x): |
|
1527 | def keyword(repo, subset, x): | |
1525 | """Search commit message, user name, and names of changed files for |
|
1528 | """Search commit message, user name, and names of changed files for | |
1526 | string. The match is case-insensitive. |
|
1529 | string. The match is case-insensitive. | |
1527 |
|
1530 | |||
1528 | For a regular expression or case sensitive search of these fields, use |
|
1531 | For a regular expression or case sensitive search of these fields, use | |
1529 | ``grep(regex)``. |
|
1532 | ``grep(regex)``. | |
1530 | """ |
|
1533 | """ | |
1531 | # i18n: "keyword" is a keyword |
|
1534 | # i18n: "keyword" is a keyword | |
1532 | kw = encoding.lower(getstring(x, _(b"keyword requires a string"))) |
|
1535 | kw = encoding.lower(getstring(x, _(b"keyword requires a string"))) | |
1533 |
|
1536 | |||
1534 | def matches(r): |
|
1537 | def matches(r): | |
1535 | c = repo[r] |
|
1538 | c = repo[r] | |
1536 | return any( |
|
1539 | return any( | |
1537 | kw in encoding.lower(t) |
|
1540 | kw in encoding.lower(t) | |
1538 | for t in c.files() + [c.user(), c.description()] |
|
1541 | for t in c.files() + [c.user(), c.description()] | |
1539 | ) |
|
1542 | ) | |
1540 |
|
1543 | |||
1541 | return subset.filter(matches, condrepr=(b'<keyword %r>', kw)) |
|
1544 | return subset.filter(matches, condrepr=(b'<keyword %r>', kw)) | |
1542 |
|
1545 | |||
1543 |
|
1546 | |||
1544 | @predicate(b'limit(set[, n[, offset]])', safe=True, takeorder=True, weight=0) |
|
1547 | @predicate(b'limit(set[, n[, offset]])', safe=True, takeorder=True, weight=0) | |
1545 | def limit(repo, subset, x, order): |
|
1548 | def limit(repo, subset, x, order): | |
1546 | """First n members of set, defaulting to 1, starting from offset. |
|
1549 | """First n members of set, defaulting to 1, starting from offset. | |
1547 | """ |
|
1550 | """ | |
1548 | args = getargsdict(x, b'limit', b'set n offset') |
|
1551 | args = getargsdict(x, b'limit', b'set n offset') | |
1549 | if b'set' not in args: |
|
1552 | if b'set' not in args: | |
1550 | # i18n: "limit" is a keyword |
|
1553 | # i18n: "limit" is a keyword | |
1551 | raise error.ParseError(_(b"limit requires one to three arguments")) |
|
1554 | raise error.ParseError(_(b"limit requires one to three arguments")) | |
1552 | # i18n: "limit" is a keyword |
|
1555 | # i18n: "limit" is a keyword | |
1553 | lim = getinteger(args.get(b'n'), _(b"limit expects a number"), default=1) |
|
1556 | lim = getinteger(args.get(b'n'), _(b"limit expects a number"), default=1) | |
1554 | if lim < 0: |
|
1557 | if lim < 0: | |
1555 | raise error.ParseError(_(b"negative number to select")) |
|
1558 | raise error.ParseError(_(b"negative number to select")) | |
1556 | # i18n: "limit" is a keyword |
|
1559 | # i18n: "limit" is a keyword | |
1557 | ofs = getinteger( |
|
1560 | ofs = getinteger( | |
1558 | args.get(b'offset'), _(b"limit expects a number"), default=0 |
|
1561 | args.get(b'offset'), _(b"limit expects a number"), default=0 | |
1559 | ) |
|
1562 | ) | |
1560 | if ofs < 0: |
|
1563 | if ofs < 0: | |
1561 | raise error.ParseError(_(b"negative offset")) |
|
1564 | raise error.ParseError(_(b"negative offset")) | |
1562 | os = getset(repo, fullreposet(repo), args[b'set']) |
|
1565 | os = getset(repo, fullreposet(repo), args[b'set']) | |
1563 | ls = os.slice(ofs, ofs + lim) |
|
1566 | ls = os.slice(ofs, ofs + lim) | |
1564 | if order == followorder and lim > 1: |
|
1567 | if order == followorder and lim > 1: | |
1565 | return subset & ls |
|
1568 | return subset & ls | |
1566 | return ls & subset |
|
1569 | return ls & subset | |
1567 |
|
1570 | |||
1568 |
|
1571 | |||
1569 | @predicate(b'last(set, [n])', safe=True, takeorder=True) |
|
1572 | @predicate(b'last(set, [n])', safe=True, takeorder=True) | |
1570 | def last(repo, subset, x, order): |
|
1573 | def last(repo, subset, x, order): | |
1571 | """Last n members of set, defaulting to 1. |
|
1574 | """Last n members of set, defaulting to 1. | |
1572 | """ |
|
1575 | """ | |
1573 | # i18n: "last" is a keyword |
|
1576 | # i18n: "last" is a keyword | |
1574 | l = getargs(x, 1, 2, _(b"last requires one or two arguments")) |
|
1577 | l = getargs(x, 1, 2, _(b"last requires one or two arguments")) | |
1575 | lim = 1 |
|
1578 | lim = 1 | |
1576 | if len(l) == 2: |
|
1579 | if len(l) == 2: | |
1577 | # i18n: "last" is a keyword |
|
1580 | # i18n: "last" is a keyword | |
1578 | lim = getinteger(l[1], _(b"last expects a number")) |
|
1581 | lim = getinteger(l[1], _(b"last expects a number")) | |
1579 | if lim < 0: |
|
1582 | if lim < 0: | |
1580 | raise error.ParseError(_(b"negative number to select")) |
|
1583 | raise error.ParseError(_(b"negative number to select")) | |
1581 | os = getset(repo, fullreposet(repo), l[0]) |
|
1584 | os = getset(repo, fullreposet(repo), l[0]) | |
1582 | os.reverse() |
|
1585 | os.reverse() | |
1583 | ls = os.slice(0, lim) |
|
1586 | ls = os.slice(0, lim) | |
1584 | if order == followorder and lim > 1: |
|
1587 | if order == followorder and lim > 1: | |
1585 | return subset & ls |
|
1588 | return subset & ls | |
1586 | ls.reverse() |
|
1589 | ls.reverse() | |
1587 | return ls & subset |
|
1590 | return ls & subset | |
1588 |
|
1591 | |||
1589 |
|
1592 | |||
1590 | @predicate(b'max(set)', safe=True) |
|
1593 | @predicate(b'max(set)', safe=True) | |
1591 | def maxrev(repo, subset, x): |
|
1594 | def maxrev(repo, subset, x): | |
1592 | """Changeset with highest revision number in set. |
|
1595 | """Changeset with highest revision number in set. | |
1593 | """ |
|
1596 | """ | |
1594 | os = getset(repo, fullreposet(repo), x) |
|
1597 | os = getset(repo, fullreposet(repo), x) | |
1595 | try: |
|
1598 | try: | |
1596 | m = os.max() |
|
1599 | m = os.max() | |
1597 | if m in subset: |
|
1600 | if m in subset: | |
1598 | return baseset([m], datarepr=(b'<max %r, %r>', subset, os)) |
|
1601 | return baseset([m], datarepr=(b'<max %r, %r>', subset, os)) | |
1599 | except ValueError: |
|
1602 | except ValueError: | |
1600 | # os.max() throws a ValueError when the collection is empty. |
|
1603 | # os.max() throws a ValueError when the collection is empty. | |
1601 | # Same as python's max(). |
|
1604 | # Same as python's max(). | |
1602 | pass |
|
1605 | pass | |
1603 | return baseset(datarepr=(b'<max %r, %r>', subset, os)) |
|
1606 | return baseset(datarepr=(b'<max %r, %r>', subset, os)) | |
1604 |
|
1607 | |||
1605 |
|
1608 | |||
1606 | @predicate(b'merge()', safe=True) |
|
1609 | @predicate(b'merge()', safe=True) | |
1607 | def merge(repo, subset, x): |
|
1610 | def merge(repo, subset, x): | |
1608 | """Changeset is a merge changeset. |
|
1611 | """Changeset is a merge changeset. | |
1609 | """ |
|
1612 | """ | |
1610 | # i18n: "merge" is a keyword |
|
1613 | # i18n: "merge" is a keyword | |
1611 | getargs(x, 0, 0, _(b"merge takes no arguments")) |
|
1614 | getargs(x, 0, 0, _(b"merge takes no arguments")) | |
1612 | cl = repo.changelog |
|
1615 | cl = repo.changelog | |
1613 | nullrev = node.nullrev |
|
1616 | nullrev = node.nullrev | |
1614 |
|
1617 | |||
1615 | def ismerge(r): |
|
1618 | def ismerge(r): | |
1616 | try: |
|
1619 | try: | |
1617 | return cl.parentrevs(r)[1] != nullrev |
|
1620 | return cl.parentrevs(r)[1] != nullrev | |
1618 | except error.WdirUnsupported: |
|
1621 | except error.WdirUnsupported: | |
1619 | return bool(repo[r].p2()) |
|
1622 | return bool(repo[r].p2()) | |
1620 |
|
1623 | |||
1621 | return subset.filter(ismerge, condrepr=b'<merge>') |
|
1624 | return subset.filter(ismerge, condrepr=b'<merge>') | |
1622 |
|
1625 | |||
1623 |
|
1626 | |||
1624 | @predicate(b'branchpoint()', safe=True) |
|
1627 | @predicate(b'branchpoint()', safe=True) | |
1625 | def branchpoint(repo, subset, x): |
|
1628 | def branchpoint(repo, subset, x): | |
1626 | """Changesets with more than one child. |
|
1629 | """Changesets with more than one child. | |
1627 | """ |
|
1630 | """ | |
1628 | # i18n: "branchpoint" is a keyword |
|
1631 | # i18n: "branchpoint" is a keyword | |
1629 | getargs(x, 0, 0, _(b"branchpoint takes no arguments")) |
|
1632 | getargs(x, 0, 0, _(b"branchpoint takes no arguments")) | |
1630 | cl = repo.changelog |
|
1633 | cl = repo.changelog | |
1631 | if not subset: |
|
1634 | if not subset: | |
1632 | return baseset() |
|
1635 | return baseset() | |
1633 | # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset |
|
1636 | # XXX this should be 'parentset.min()' assuming 'parentset' is a smartset | |
1634 | # (and if it is not, it should.) |
|
1637 | # (and if it is not, it should.) | |
1635 | baserev = min(subset) |
|
1638 | baserev = min(subset) | |
1636 | parentscount = [0] * (len(repo) - baserev) |
|
1639 | parentscount = [0] * (len(repo) - baserev) | |
1637 | for r in cl.revs(start=baserev + 1): |
|
1640 | for r in cl.revs(start=baserev + 1): | |
1638 | for p in cl.parentrevs(r): |
|
1641 | for p in cl.parentrevs(r): | |
1639 | if p >= baserev: |
|
1642 | if p >= baserev: | |
1640 | parentscount[p - baserev] += 1 |
|
1643 | parentscount[p - baserev] += 1 | |
1641 | return subset.filter( |
|
1644 | return subset.filter( | |
1642 | lambda r: parentscount[r - baserev] > 1, condrepr=b'<branchpoint>' |
|
1645 | lambda r: parentscount[r - baserev] > 1, condrepr=b'<branchpoint>' | |
1643 | ) |
|
1646 | ) | |
1644 |
|
1647 | |||
1645 |
|
1648 | |||
1646 | @predicate(b'min(set)', safe=True) |
|
1649 | @predicate(b'min(set)', safe=True) | |
1647 | def minrev(repo, subset, x): |
|
1650 | def minrev(repo, subset, x): | |
1648 | """Changeset with lowest revision number in set. |
|
1651 | """Changeset with lowest revision number in set. | |
1649 | """ |
|
1652 | """ | |
1650 | os = getset(repo, fullreposet(repo), x) |
|
1653 | os = getset(repo, fullreposet(repo), x) | |
1651 | try: |
|
1654 | try: | |
1652 | m = os.min() |
|
1655 | m = os.min() | |
1653 | if m in subset: |
|
1656 | if m in subset: | |
1654 | return baseset([m], datarepr=(b'<min %r, %r>', subset, os)) |
|
1657 | return baseset([m], datarepr=(b'<min %r, %r>', subset, os)) | |
1655 | except ValueError: |
|
1658 | except ValueError: | |
1656 | # os.min() throws a ValueError when the collection is empty. |
|
1659 | # os.min() throws a ValueError when the collection is empty. | |
1657 | # Same as python's min(). |
|
1660 | # Same as python's min(). | |
1658 | pass |
|
1661 | pass | |
1659 | return baseset(datarepr=(b'<min %r, %r>', subset, os)) |
|
1662 | return baseset(datarepr=(b'<min %r, %r>', subset, os)) | |
1660 |
|
1663 | |||
1661 |
|
1664 | |||
1662 | @predicate(b'modifies(pattern)', safe=True, weight=30) |
|
1665 | @predicate(b'modifies(pattern)', safe=True, weight=30) | |
1663 | def modifies(repo, subset, x): |
|
1666 | def modifies(repo, subset, x): | |
1664 | """Changesets modifying files matched by pattern. |
|
1667 | """Changesets modifying files matched by pattern. | |
1665 |
|
1668 | |||
1666 | The pattern without explicit kind like ``glob:`` is expected to be |
|
1669 | The pattern without explicit kind like ``glob:`` is expected to be | |
1667 | relative to the current directory and match against a file or a |
|
1670 | relative to the current directory and match against a file or a | |
1668 | directory. |
|
1671 | directory. | |
1669 | """ |
|
1672 | """ | |
1670 | # i18n: "modifies" is a keyword |
|
1673 | # i18n: "modifies" is a keyword | |
1671 | pat = getstring(x, _(b"modifies requires a pattern")) |
|
1674 | pat = getstring(x, _(b"modifies requires a pattern")) | |
1672 | return checkstatus(repo, subset, pat, 'modified') |
|
1675 | return checkstatus(repo, subset, pat, 'modified') | |
1673 |
|
1676 | |||
1674 |
|
1677 | |||
1675 | @predicate(b'named(namespace)') |
|
1678 | @predicate(b'named(namespace)') | |
1676 | def named(repo, subset, x): |
|
1679 | def named(repo, subset, x): | |
1677 | """The changesets in a given namespace. |
|
1680 | """The changesets in a given namespace. | |
1678 |
|
1681 | |||
1679 | Pattern matching is supported for `namespace`. See |
|
1682 | Pattern matching is supported for `namespace`. See | |
1680 | :hg:`help revisions.patterns`. |
|
1683 | :hg:`help revisions.patterns`. | |
1681 | """ |
|
1684 | """ | |
1682 | # i18n: "named" is a keyword |
|
1685 | # i18n: "named" is a keyword | |
1683 | args = getargs(x, 1, 1, _(b'named requires a namespace argument')) |
|
1686 | args = getargs(x, 1, 1, _(b'named requires a namespace argument')) | |
1684 |
|
1687 | |||
1685 | ns = getstring( |
|
1688 | ns = getstring( | |
1686 | args[0], |
|
1689 | args[0], | |
1687 | # i18n: "named" is a keyword |
|
1690 | # i18n: "named" is a keyword | |
1688 | _(b'the argument to named must be a string'), |
|
1691 | _(b'the argument to named must be a string'), | |
1689 | ) |
|
1692 | ) | |
1690 | kind, pattern, matcher = stringutil.stringmatcher(ns) |
|
1693 | kind, pattern, matcher = stringutil.stringmatcher(ns) | |
1691 | namespaces = set() |
|
1694 | namespaces = set() | |
1692 | if kind == b'literal': |
|
1695 | if kind == b'literal': | |
1693 | if pattern not in repo.names: |
|
1696 | if pattern not in repo.names: | |
1694 | raise error.RepoLookupError( |
|
1697 | raise error.RepoLookupError( | |
1695 | _(b"namespace '%s' does not exist") % ns |
|
1698 | _(b"namespace '%s' does not exist") % ns | |
1696 | ) |
|
1699 | ) | |
1697 | namespaces.add(repo.names[pattern]) |
|
1700 | namespaces.add(repo.names[pattern]) | |
1698 | else: |
|
1701 | else: | |
1699 | for name, ns in pycompat.iteritems(repo.names): |
|
1702 | for name, ns in pycompat.iteritems(repo.names): | |
1700 | if matcher(name): |
|
1703 | if matcher(name): | |
1701 | namespaces.add(ns) |
|
1704 | namespaces.add(ns) | |
1702 |
|
1705 | |||
1703 | names = set() |
|
1706 | names = set() | |
1704 | for ns in namespaces: |
|
1707 | for ns in namespaces: | |
1705 | for name in ns.listnames(repo): |
|
1708 | for name in ns.listnames(repo): | |
1706 | if name not in ns.deprecated: |
|
1709 | if name not in ns.deprecated: | |
1707 | names.update(repo[n].rev() for n in ns.nodes(repo, name)) |
|
1710 | names.update(repo[n].rev() for n in ns.nodes(repo, name)) | |
1708 |
|
1711 | |||
1709 | names -= {node.nullrev} |
|
1712 | names -= {node.nullrev} | |
1710 | return subset & names |
|
1713 | return subset & names | |
1711 |
|
1714 | |||
1712 |
|
1715 | |||
1713 | @predicate(b'id(string)', safe=True) |
|
1716 | @predicate(b'id(string)', safe=True) | |
1714 | def node_(repo, subset, x): |
|
1717 | def node_(repo, subset, x): | |
1715 | """Revision non-ambiguously specified by the given hex string prefix. |
|
1718 | """Revision non-ambiguously specified by the given hex string prefix. | |
1716 | """ |
|
1719 | """ | |
1717 | # i18n: "id" is a keyword |
|
1720 | # i18n: "id" is a keyword | |
1718 | l = getargs(x, 1, 1, _(b"id requires one argument")) |
|
1721 | l = getargs(x, 1, 1, _(b"id requires one argument")) | |
1719 | # i18n: "id" is a keyword |
|
1722 | # i18n: "id" is a keyword | |
1720 | n = getstring(l[0], _(b"id requires a string")) |
|
1723 | n = getstring(l[0], _(b"id requires a string")) | |
1721 | if len(n) == 40: |
|
1724 | if len(n) == 40: | |
1722 | try: |
|
1725 | try: | |
1723 | rn = repo.changelog.rev(node.bin(n)) |
|
1726 | rn = repo.changelog.rev(node.bin(n)) | |
1724 | except error.WdirUnsupported: |
|
1727 | except error.WdirUnsupported: | |
1725 | rn = node.wdirrev |
|
1728 | rn = node.wdirrev | |
1726 | except (LookupError, TypeError): |
|
1729 | except (LookupError, TypeError): | |
1727 | rn = None |
|
1730 | rn = None | |
1728 | else: |
|
1731 | else: | |
1729 | rn = None |
|
1732 | rn = None | |
1730 | try: |
|
1733 | try: | |
1731 | pm = scmutil.resolvehexnodeidprefix(repo, n) |
|
1734 | pm = scmutil.resolvehexnodeidprefix(repo, n) | |
1732 | if pm is not None: |
|
1735 | if pm is not None: | |
1733 | rn = repo.changelog.rev(pm) |
|
1736 | rn = repo.changelog.rev(pm) | |
1734 | except LookupError: |
|
1737 | except LookupError: | |
1735 | pass |
|
1738 | pass | |
1736 | except error.WdirUnsupported: |
|
1739 | except error.WdirUnsupported: | |
1737 | rn = node.wdirrev |
|
1740 | rn = node.wdirrev | |
1738 |
|
1741 | |||
1739 | if rn is None: |
|
1742 | if rn is None: | |
1740 | return baseset() |
|
1743 | return baseset() | |
1741 | result = baseset([rn]) |
|
1744 | result = baseset([rn]) | |
1742 | return result & subset |
|
1745 | return result & subset | |
1743 |
|
1746 | |||
1744 |
|
1747 | |||
1745 | @predicate(b'none()', safe=True) |
|
1748 | @predicate(b'none()', safe=True) | |
1746 | def none(repo, subset, x): |
|
1749 | def none(repo, subset, x): | |
1747 | """No changesets. |
|
1750 | """No changesets. | |
1748 | """ |
|
1751 | """ | |
1749 | # i18n: "none" is a keyword |
|
1752 | # i18n: "none" is a keyword | |
1750 | getargs(x, 0, 0, _(b"none takes no arguments")) |
|
1753 | getargs(x, 0, 0, _(b"none takes no arguments")) | |
1751 | return baseset() |
|
1754 | return baseset() | |
1752 |
|
1755 | |||
1753 |
|
1756 | |||
1754 | @predicate(b'obsolete()', safe=True) |
|
1757 | @predicate(b'obsolete()', safe=True) | |
1755 | def obsolete(repo, subset, x): |
|
1758 | def obsolete(repo, subset, x): | |
1756 | """Mutable changeset with a newer version. (EXPERIMENTAL)""" |
|
1759 | """Mutable changeset with a newer version. (EXPERIMENTAL)""" | |
1757 | # i18n: "obsolete" is a keyword |
|
1760 | # i18n: "obsolete" is a keyword | |
1758 | getargs(x, 0, 0, _(b"obsolete takes no arguments")) |
|
1761 | getargs(x, 0, 0, _(b"obsolete takes no arguments")) | |
1759 | obsoletes = obsmod.getrevs(repo, b'obsolete') |
|
1762 | obsoletes = obsmod.getrevs(repo, b'obsolete') | |
1760 | return subset & obsoletes |
|
1763 | return subset & obsoletes | |
1761 |
|
1764 | |||
1762 |
|
1765 | |||
1763 | @predicate(b'only(set, [set])', safe=True) |
|
1766 | @predicate(b'only(set, [set])', safe=True) | |
1764 | def only(repo, subset, x): |
|
1767 | def only(repo, subset, x): | |
1765 | """Changesets that are ancestors of the first set that are not ancestors |
|
1768 | """Changesets that are ancestors of the first set that are not ancestors | |
1766 | of any other head in the repo. If a second set is specified, the result |
|
1769 | of any other head in the repo. If a second set is specified, the result | |
1767 | is ancestors of the first set that are not ancestors of the second set |
|
1770 | is ancestors of the first set that are not ancestors of the second set | |
1768 | (i.e. ::<set1> - ::<set2>). |
|
1771 | (i.e. ::<set1> - ::<set2>). | |
1769 | """ |
|
1772 | """ | |
1770 | cl = repo.changelog |
|
1773 | cl = repo.changelog | |
1771 | # i18n: "only" is a keyword |
|
1774 | # i18n: "only" is a keyword | |
1772 | args = getargs(x, 1, 2, _(b'only takes one or two arguments')) |
|
1775 | args = getargs(x, 1, 2, _(b'only takes one or two arguments')) | |
1773 | include = getset(repo, fullreposet(repo), args[0]) |
|
1776 | include = getset(repo, fullreposet(repo), args[0]) | |
1774 | if len(args) == 1: |
|
1777 | if len(args) == 1: | |
1775 | if not include: |
|
1778 | if not include: | |
1776 | return baseset() |
|
1779 | return baseset() | |
1777 |
|
1780 | |||
1778 | descendants = set(dagop.revdescendants(repo, include, False)) |
|
1781 | descendants = set(dagop.revdescendants(repo, include, False)) | |
1779 | exclude = [ |
|
1782 | exclude = [ | |
1780 | rev |
|
1783 | rev | |
1781 | for rev in cl.headrevs() |
|
1784 | for rev in cl.headrevs() | |
1782 | if not rev in descendants and not rev in include |
|
1785 | if not rev in descendants and not rev in include | |
1783 | ] |
|
1786 | ] | |
1784 | else: |
|
1787 | else: | |
1785 | exclude = getset(repo, fullreposet(repo), args[1]) |
|
1788 | exclude = getset(repo, fullreposet(repo), args[1]) | |
1786 |
|
1789 | |||
1787 | results = set(cl.findmissingrevs(common=exclude, heads=include)) |
|
1790 | results = set(cl.findmissingrevs(common=exclude, heads=include)) | |
1788 | # XXX we should turn this into a baseset instead of a set, smartset may do |
|
1791 | # XXX we should turn this into a baseset instead of a set, smartset may do | |
1789 | # some optimizations from the fact this is a baseset. |
|
1792 | # some optimizations from the fact this is a baseset. | |
1790 | return subset & results |
|
1793 | return subset & results | |
1791 |
|
1794 | |||
1792 |
|
1795 | |||
1793 | @predicate(b'origin([set])', safe=True) |
|
1796 | @predicate(b'origin([set])', safe=True) | |
1794 | def origin(repo, subset, x): |
|
1797 | def origin(repo, subset, x): | |
1795 | """ |
|
1798 | """ | |
1796 | Changesets that were specified as a source for the grafts, transplants or |
|
1799 | Changesets that were specified as a source for the grafts, transplants or | |
1797 | rebases that created the given revisions. Omitting the optional set is the |
|
1800 | rebases that created the given revisions. Omitting the optional set is the | |
1798 | same as passing all(). If a changeset created by these operations is itself |
|
1801 | same as passing all(). If a changeset created by these operations is itself | |
1799 | specified as a source for one of these operations, only the source changeset |
|
1802 | specified as a source for one of these operations, only the source changeset | |
1800 | for the first operation is selected. |
|
1803 | for the first operation is selected. | |
1801 | """ |
|
1804 | """ | |
1802 | if x is not None: |
|
1805 | if x is not None: | |
1803 | dests = getset(repo, fullreposet(repo), x) |
|
1806 | dests = getset(repo, fullreposet(repo), x) | |
1804 | else: |
|
1807 | else: | |
1805 | dests = fullreposet(repo) |
|
1808 | dests = fullreposet(repo) | |
1806 |
|
1809 | |||
1807 | def _firstsrc(rev): |
|
1810 | def _firstsrc(rev): | |
1808 | src = _getrevsource(repo, rev) |
|
1811 | src = _getrevsource(repo, rev) | |
1809 | if src is None: |
|
1812 | if src is None: | |
1810 | return None |
|
1813 | return None | |
1811 |
|
1814 | |||
1812 | while True: |
|
1815 | while True: | |
1813 | prev = _getrevsource(repo, src) |
|
1816 | prev = _getrevsource(repo, src) | |
1814 |
|
1817 | |||
1815 | if prev is None: |
|
1818 | if prev is None: | |
1816 | return src |
|
1819 | return src | |
1817 | src = prev |
|
1820 | src = prev | |
1818 |
|
1821 | |||
1819 | o = {_firstsrc(r) for r in dests} |
|
1822 | o = {_firstsrc(r) for r in dests} | |
1820 | o -= {None} |
|
1823 | o -= {None} | |
1821 | # XXX we should turn this into a baseset instead of a set, smartset may do |
|
1824 | # XXX we should turn this into a baseset instead of a set, smartset may do | |
1822 | # some optimizations from the fact this is a baseset. |
|
1825 | # some optimizations from the fact this is a baseset. | |
1823 | return subset & o |
|
1826 | return subset & o | |
1824 |
|
1827 | |||
1825 |
|
1828 | |||
1826 | @predicate(b'outgoing([path])', safe=False, weight=10) |
|
1829 | @predicate(b'outgoing([path])', safe=False, weight=10) | |
1827 | def outgoing(repo, subset, x): |
|
1830 | def outgoing(repo, subset, x): | |
1828 | """Changesets not found in the specified destination repository, or the |
|
1831 | """Changesets not found in the specified destination repository, or the | |
1829 | default push location. |
|
1832 | default push location. | |
1830 | """ |
|
1833 | """ | |
1831 | # Avoid cycles. |
|
1834 | # Avoid cycles. | |
1832 | from . import ( |
|
1835 | from . import ( | |
1833 | discovery, |
|
1836 | discovery, | |
1834 | hg, |
|
1837 | hg, | |
1835 | ) |
|
1838 | ) | |
1836 |
|
1839 | |||
1837 | # i18n: "outgoing" is a keyword |
|
1840 | # i18n: "outgoing" is a keyword | |
1838 | l = getargs(x, 0, 1, _(b"outgoing takes one or no arguments")) |
|
1841 | l = getargs(x, 0, 1, _(b"outgoing takes one or no arguments")) | |
1839 | # i18n: "outgoing" is a keyword |
|
1842 | # i18n: "outgoing" is a keyword | |
1840 | dest = ( |
|
1843 | dest = ( | |
1841 | l and getstring(l[0], _(b"outgoing requires a repository path")) or b'' |
|
1844 | l and getstring(l[0], _(b"outgoing requires a repository path")) or b'' | |
1842 | ) |
|
1845 | ) | |
1843 | if not dest: |
|
1846 | if not dest: | |
1844 | # ui.paths.getpath() explicitly tests for None, not just a boolean |
|
1847 | # ui.paths.getpath() explicitly tests for None, not just a boolean | |
1845 | dest = None |
|
1848 | dest = None | |
1846 | path = repo.ui.paths.getpath(dest, default=(b'default-push', b'default')) |
|
1849 | path = repo.ui.paths.getpath(dest, default=(b'default-push', b'default')) | |
1847 | if not path: |
|
1850 | if not path: | |
1848 | raise error.Abort( |
|
1851 | raise error.Abort( | |
1849 | _(b'default repository not configured!'), |
|
1852 | _(b'default repository not configured!'), | |
1850 | hint=_(b"see 'hg help config.paths'"), |
|
1853 | hint=_(b"see 'hg help config.paths'"), | |
1851 | ) |
|
1854 | ) | |
1852 | dest = path.pushloc or path.loc |
|
1855 | dest = path.pushloc or path.loc | |
1853 | branches = path.branch, [] |
|
1856 | branches = path.branch, [] | |
1854 |
|
1857 | |||
1855 | revs, checkout = hg.addbranchrevs(repo, repo, branches, []) |
|
1858 | revs, checkout = hg.addbranchrevs(repo, repo, branches, []) | |
1856 | if revs: |
|
1859 | if revs: | |
1857 | revs = [repo.lookup(rev) for rev in revs] |
|
1860 | revs = [repo.lookup(rev) for rev in revs] | |
1858 | other = hg.peer(repo, {}, dest) |
|
1861 | other = hg.peer(repo, {}, dest) | |
1859 | repo.ui.pushbuffer() |
|
1862 | repo.ui.pushbuffer() | |
1860 | outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs) |
|
1863 | outgoing = discovery.findcommonoutgoing(repo, other, onlyheads=revs) | |
1861 | repo.ui.popbuffer() |
|
1864 | repo.ui.popbuffer() | |
1862 | cl = repo.changelog |
|
1865 | cl = repo.changelog | |
1863 | o = {cl.rev(r) for r in outgoing.missing} |
|
1866 | o = {cl.rev(r) for r in outgoing.missing} | |
1864 | return subset & o |
|
1867 | return subset & o | |
1865 |
|
1868 | |||
1866 |
|
1869 | |||
1867 | @predicate(b'p1([set])', safe=True) |
|
1870 | @predicate(b'p1([set])', safe=True) | |
1868 | def p1(repo, subset, x): |
|
1871 | def p1(repo, subset, x): | |
1869 | """First parent of changesets in set, or the working directory. |
|
1872 | """First parent of changesets in set, or the working directory. | |
1870 | """ |
|
1873 | """ | |
1871 | if x is None: |
|
1874 | if x is None: | |
1872 | p = repo[x].p1().rev() |
|
1875 | p = repo[x].p1().rev() | |
1873 | if p >= 0: |
|
1876 | if p >= 0: | |
1874 | return subset & baseset([p]) |
|
1877 | return subset & baseset([p]) | |
1875 | return baseset() |
|
1878 | return baseset() | |
1876 |
|
1879 | |||
1877 | ps = set() |
|
1880 | ps = set() | |
1878 | cl = repo.changelog |
|
1881 | cl = repo.changelog | |
1879 | for r in getset(repo, fullreposet(repo), x): |
|
1882 | for r in getset(repo, fullreposet(repo), x): | |
1880 | try: |
|
1883 | try: | |
1881 | ps.add(cl.parentrevs(r)[0]) |
|
1884 | ps.add(cl.parentrevs(r)[0]) | |
1882 | except error.WdirUnsupported: |
|
1885 | except error.WdirUnsupported: | |
1883 | ps.add(repo[r].p1().rev()) |
|
1886 | ps.add(repo[r].p1().rev()) | |
1884 | ps -= {node.nullrev} |
|
1887 | ps -= {node.nullrev} | |
1885 | # XXX we should turn this into a baseset instead of a set, smartset may do |
|
1888 | # XXX we should turn this into a baseset instead of a set, smartset may do | |
1886 | # some optimizations from the fact this is a baseset. |
|
1889 | # some optimizations from the fact this is a baseset. | |
1887 | return subset & ps |
|
1890 | return subset & ps | |
1888 |
|
1891 | |||
1889 |
|
1892 | |||
1890 | @predicate(b'p2([set])', safe=True) |
|
1893 | @predicate(b'p2([set])', safe=True) | |
1891 | def p2(repo, subset, x): |
|
1894 | def p2(repo, subset, x): | |
1892 | """Second parent of changesets in set, or the working directory. |
|
1895 | """Second parent of changesets in set, or the working directory. | |
1893 | """ |
|
1896 | """ | |
1894 | if x is None: |
|
1897 | if x is None: | |
1895 | ps = repo[x].parents() |
|
1898 | ps = repo[x].parents() | |
1896 | try: |
|
1899 | try: | |
1897 | p = ps[1].rev() |
|
1900 | p = ps[1].rev() | |
1898 | if p >= 0: |
|
1901 | if p >= 0: | |
1899 | return subset & baseset([p]) |
|
1902 | return subset & baseset([p]) | |
1900 | return baseset() |
|
1903 | return baseset() | |
1901 | except IndexError: |
|
1904 | except IndexError: | |
1902 | return baseset() |
|
1905 | return baseset() | |
1903 |
|
1906 | |||
1904 | ps = set() |
|
1907 | ps = set() | |
1905 | cl = repo.changelog |
|
1908 | cl = repo.changelog | |
1906 | for r in getset(repo, fullreposet(repo), x): |
|
1909 | for r in getset(repo, fullreposet(repo), x): | |
1907 | try: |
|
1910 | try: | |
1908 | ps.add(cl.parentrevs(r)[1]) |
|
1911 | ps.add(cl.parentrevs(r)[1]) | |
1909 | except error.WdirUnsupported: |
|
1912 | except error.WdirUnsupported: | |
1910 | parents = repo[r].parents() |
|
1913 | parents = repo[r].parents() | |
1911 | if len(parents) == 2: |
|
1914 | if len(parents) == 2: | |
1912 | ps.add(parents[1]) |
|
1915 | ps.add(parents[1]) | |
1913 | ps -= {node.nullrev} |
|
1916 | ps -= {node.nullrev} | |
1914 | # XXX we should turn this into a baseset instead of a set, smartset may do |
|
1917 | # XXX we should turn this into a baseset instead of a set, smartset may do | |
1915 | # some optimizations from the fact this is a baseset. |
|
1918 | # some optimizations from the fact this is a baseset. | |
1916 | return subset & ps |
|
1919 | return subset & ps | |
1917 |
|
1920 | |||
1918 |
|
1921 | |||
1919 | def parentpost(repo, subset, x, order): |
|
1922 | def parentpost(repo, subset, x, order): | |
1920 | return p1(repo, subset, x) |
|
1923 | return p1(repo, subset, x) | |
1921 |
|
1924 | |||
1922 |
|
1925 | |||
1923 | @predicate(b'parents([set])', safe=True) |
|
1926 | @predicate(b'parents([set])', safe=True) | |
1924 | def parents(repo, subset, x): |
|
1927 | def parents(repo, subset, x): | |
1925 | """ |
|
1928 | """ | |
1926 | The set of all parents for all changesets in set, or the working directory. |
|
1929 | The set of all parents for all changesets in set, or the working directory. | |
1927 | """ |
|
1930 | """ | |
1928 | if x is None: |
|
1931 | if x is None: | |
1929 | ps = {p.rev() for p in repo[x].parents()} |
|
1932 | ps = {p.rev() for p in repo[x].parents()} | |
1930 | else: |
|
1933 | else: | |
1931 | ps = set() |
|
1934 | ps = set() | |
1932 | cl = repo.changelog |
|
1935 | cl = repo.changelog | |
1933 | up = ps.update |
|
1936 | up = ps.update | |
1934 | parentrevs = cl.parentrevs |
|
1937 | parentrevs = cl.parentrevs | |
1935 | for r in getset(repo, fullreposet(repo), x): |
|
1938 | for r in getset(repo, fullreposet(repo), x): | |
1936 | try: |
|
1939 | try: | |
1937 | up(parentrevs(r)) |
|
1940 | up(parentrevs(r)) | |
1938 | except error.WdirUnsupported: |
|
1941 | except error.WdirUnsupported: | |
1939 | up(p.rev() for p in repo[r].parents()) |
|
1942 | up(p.rev() for p in repo[r].parents()) | |
1940 | ps -= {node.nullrev} |
|
1943 | ps -= {node.nullrev} | |
1941 | return subset & ps |
|
1944 | return subset & ps | |
1942 |
|
1945 | |||
1943 |
|
1946 | |||
1944 | def _phase(repo, subset, *targets): |
|
1947 | def _phase(repo, subset, *targets): | |
1945 | """helper to select all rev in <targets> phases""" |
|
1948 | """helper to select all rev in <targets> phases""" | |
1946 | return repo._phasecache.getrevset(repo, targets, subset) |
|
1949 | return repo._phasecache.getrevset(repo, targets, subset) | |
1947 |
|
1950 | |||
1948 |
|
1951 | |||
1949 | @predicate(b'_phase(idx)', safe=True) |
|
1952 | @predicate(b'_phase(idx)', safe=True) | |
1950 | def phase(repo, subset, x): |
|
1953 | def phase(repo, subset, x): | |
1951 | l = getargs(x, 1, 1, b"_phase requires one argument") |
|
1954 | l = getargs(x, 1, 1, b"_phase requires one argument") | |
1952 | target = getinteger(l[0], b"_phase expects a number") |
|
1955 | target = getinteger(l[0], b"_phase expects a number") | |
1953 | return _phase(repo, subset, target) |
|
1956 | return _phase(repo, subset, target) | |
1954 |
|
1957 | |||
1955 |
|
1958 | |||
1956 | @predicate(b'draft()', safe=True) |
|
1959 | @predicate(b'draft()', safe=True) | |
1957 | def draft(repo, subset, x): |
|
1960 | def draft(repo, subset, x): | |
1958 | """Changeset in draft phase.""" |
|
1961 | """Changeset in draft phase.""" | |
1959 | # i18n: "draft" is a keyword |
|
1962 | # i18n: "draft" is a keyword | |
1960 | getargs(x, 0, 0, _(b"draft takes no arguments")) |
|
1963 | getargs(x, 0, 0, _(b"draft takes no arguments")) | |
1961 | target = phases.draft |
|
1964 | target = phases.draft | |
1962 | return _phase(repo, subset, target) |
|
1965 | return _phase(repo, subset, target) | |
1963 |
|
1966 | |||
1964 |
|
1967 | |||
1965 | @predicate(b'secret()', safe=True) |
|
1968 | @predicate(b'secret()', safe=True) | |
1966 | def secret(repo, subset, x): |
|
1969 | def secret(repo, subset, x): | |
1967 | """Changeset in secret phase.""" |
|
1970 | """Changeset in secret phase.""" | |
1968 | # i18n: "secret" is a keyword |
|
1971 | # i18n: "secret" is a keyword | |
1969 | getargs(x, 0, 0, _(b"secret takes no arguments")) |
|
1972 | getargs(x, 0, 0, _(b"secret takes no arguments")) | |
1970 | target = phases.secret |
|
1973 | target = phases.secret | |
1971 | return _phase(repo, subset, target) |
|
1974 | return _phase(repo, subset, target) | |
1972 |
|
1975 | |||
1973 |
|
1976 | |||
1974 | @predicate(b'stack([revs])', safe=True) |
|
1977 | @predicate(b'stack([revs])', safe=True) | |
1975 | def stack(repo, subset, x): |
|
1978 | def stack(repo, subset, x): | |
1976 | """Experimental revset for the stack of changesets or working directory |
|
1979 | """Experimental revset for the stack of changesets or working directory | |
1977 | parent. (EXPERIMENTAL) |
|
1980 | parent. (EXPERIMENTAL) | |
1978 | """ |
|
1981 | """ | |
1979 | if x is None: |
|
1982 | if x is None: | |
1980 | stacks = stackmod.getstack(repo) |
|
1983 | stacks = stackmod.getstack(repo) | |
1981 | else: |
|
1984 | else: | |
1982 | stacks = smartset.baseset([]) |
|
1985 | stacks = smartset.baseset([]) | |
1983 | for revision in getset(repo, fullreposet(repo), x): |
|
1986 | for revision in getset(repo, fullreposet(repo), x): | |
1984 | currentstack = stackmod.getstack(repo, revision) |
|
1987 | currentstack = stackmod.getstack(repo, revision) | |
1985 | stacks = stacks + currentstack |
|
1988 | stacks = stacks + currentstack | |
1986 |
|
1989 | |||
1987 | return subset & stacks |
|
1990 | return subset & stacks | |
1988 |
|
1991 | |||
1989 |
|
1992 | |||
1990 | def parentspec(repo, subset, x, n, order): |
|
1993 | def parentspec(repo, subset, x, n, order): | |
1991 | """``set^0`` |
|
1994 | """``set^0`` | |
1992 | The set. |
|
1995 | The set. | |
1993 | ``set^1`` (or ``set^``), ``set^2`` |
|
1996 | ``set^1`` (or ``set^``), ``set^2`` | |
1994 | First or second parent, respectively, of all changesets in set. |
|
1997 | First or second parent, respectively, of all changesets in set. | |
1995 | """ |
|
1998 | """ | |
1996 | try: |
|
1999 | try: | |
1997 | n = int(n[1]) |
|
2000 | n = int(n[1]) | |
1998 | if n not in (0, 1, 2): |
|
2001 | if n not in (0, 1, 2): | |
1999 | raise ValueError |
|
2002 | raise ValueError | |
2000 | except (TypeError, ValueError): |
|
2003 | except (TypeError, ValueError): | |
2001 | raise error.ParseError(_(b"^ expects a number 0, 1, or 2")) |
|
2004 | raise error.ParseError(_(b"^ expects a number 0, 1, or 2")) | |
2002 | ps = set() |
|
2005 | ps = set() | |
2003 | cl = repo.changelog |
|
2006 | cl = repo.changelog | |
2004 | for r in getset(repo, fullreposet(repo), x): |
|
2007 | for r in getset(repo, fullreposet(repo), x): | |
2005 | if n == 0: |
|
2008 | if n == 0: | |
2006 | ps.add(r) |
|
2009 | ps.add(r) | |
2007 | elif n == 1: |
|
2010 | elif n == 1: | |
2008 | try: |
|
2011 | try: | |
2009 | ps.add(cl.parentrevs(r)[0]) |
|
2012 | ps.add(cl.parentrevs(r)[0]) | |
2010 | except error.WdirUnsupported: |
|
2013 | except error.WdirUnsupported: | |
2011 | ps.add(repo[r].p1().rev()) |
|
2014 | ps.add(repo[r].p1().rev()) | |
2012 | else: |
|
2015 | else: | |
2013 | try: |
|
2016 | try: | |
2014 | parents = cl.parentrevs(r) |
|
2017 | parents = cl.parentrevs(r) | |
2015 | if parents[1] != node.nullrev: |
|
2018 | if parents[1] != node.nullrev: | |
2016 | ps.add(parents[1]) |
|
2019 | ps.add(parents[1]) | |
2017 | except error.WdirUnsupported: |
|
2020 | except error.WdirUnsupported: | |
2018 | parents = repo[r].parents() |
|
2021 | parents = repo[r].parents() | |
2019 | if len(parents) == 2: |
|
2022 | if len(parents) == 2: | |
2020 | ps.add(parents[1].rev()) |
|
2023 | ps.add(parents[1].rev()) | |
2021 | return subset & ps |
|
2024 | return subset & ps | |
2022 |
|
2025 | |||
2023 |
|
2026 | |||
2024 | @predicate(b'present(set)', safe=True, takeorder=True) |
|
2027 | @predicate(b'present(set)', safe=True, takeorder=True) | |
2025 | def present(repo, subset, x, order): |
|
2028 | def present(repo, subset, x, order): | |
2026 | """An empty set, if any revision in set isn't found; otherwise, |
|
2029 | """An empty set, if any revision in set isn't found; otherwise, | |
2027 | all revisions in set. |
|
2030 | all revisions in set. | |
2028 |
|
2031 | |||
2029 | If any of specified revisions is not present in the local repository, |
|
2032 | If any of specified revisions is not present in the local repository, | |
2030 | the query is normally aborted. But this predicate allows the query |
|
2033 | the query is normally aborted. But this predicate allows the query | |
2031 | to continue even in such cases. |
|
2034 | to continue even in such cases. | |
2032 | """ |
|
2035 | """ | |
2033 | try: |
|
2036 | try: | |
2034 | return getset(repo, subset, x, order) |
|
2037 | return getset(repo, subset, x, order) | |
2035 | except error.RepoLookupError: |
|
2038 | except error.RepoLookupError: | |
2036 | return baseset() |
|
2039 | return baseset() | |
2037 |
|
2040 | |||
2038 |
|
2041 | |||
2039 | # for internal use |
|
2042 | # for internal use | |
2040 | @predicate(b'_notpublic', safe=True) |
|
2043 | @predicate(b'_notpublic', safe=True) | |
2041 | def _notpublic(repo, subset, x): |
|
2044 | def _notpublic(repo, subset, x): | |
2042 | getargs(x, 0, 0, b"_notpublic takes no arguments") |
|
2045 | getargs(x, 0, 0, b"_notpublic takes no arguments") | |
2043 | return _phase(repo, subset, phases.draft, phases.secret) |
|
2046 | return _phase(repo, subset, phases.draft, phases.secret) | |
2044 |
|
2047 | |||
2045 |
|
2048 | |||
2046 | # for internal use |
|
2049 | # for internal use | |
2047 | @predicate(b'_phaseandancestors(phasename, set)', safe=True) |
|
2050 | @predicate(b'_phaseandancestors(phasename, set)', safe=True) | |
2048 | def _phaseandancestors(repo, subset, x): |
|
2051 | def _phaseandancestors(repo, subset, x): | |
2049 | # equivalent to (phasename() & ancestors(set)) but more efficient |
|
2052 | # equivalent to (phasename() & ancestors(set)) but more efficient | |
2050 | # phasename could be one of 'draft', 'secret', or '_notpublic' |
|
2053 | # phasename could be one of 'draft', 'secret', or '_notpublic' | |
2051 | args = getargs(x, 2, 2, b"_phaseandancestors requires two arguments") |
|
2054 | args = getargs(x, 2, 2, b"_phaseandancestors requires two arguments") | |
2052 | phasename = getsymbol(args[0]) |
|
2055 | phasename = getsymbol(args[0]) | |
2053 | s = getset(repo, fullreposet(repo), args[1]) |
|
2056 | s = getset(repo, fullreposet(repo), args[1]) | |
2054 |
|
2057 | |||
2055 | draft = phases.draft |
|
2058 | draft = phases.draft | |
2056 | secret = phases.secret |
|
2059 | secret = phases.secret | |
2057 | phasenamemap = { |
|
2060 | phasenamemap = { | |
2058 | b'_notpublic': draft, |
|
2061 | b'_notpublic': draft, | |
2059 | b'draft': draft, # follow secret's ancestors |
|
2062 | b'draft': draft, # follow secret's ancestors | |
2060 | b'secret': secret, |
|
2063 | b'secret': secret, | |
2061 | } |
|
2064 | } | |
2062 | if phasename not in phasenamemap: |
|
2065 | if phasename not in phasenamemap: | |
2063 | raise error.ParseError(b'%r is not a valid phasename' % phasename) |
|
2066 | raise error.ParseError(b'%r is not a valid phasename' % phasename) | |
2064 |
|
2067 | |||
2065 | minimalphase = phasenamemap[phasename] |
|
2068 | minimalphase = phasenamemap[phasename] | |
2066 | getphase = repo._phasecache.phase |
|
2069 | getphase = repo._phasecache.phase | |
2067 |
|
2070 | |||
2068 | def cutfunc(rev): |
|
2071 | def cutfunc(rev): | |
2069 | return getphase(repo, rev) < minimalphase |
|
2072 | return getphase(repo, rev) < minimalphase | |
2070 |
|
2073 | |||
2071 | revs = dagop.revancestors(repo, s, cutfunc=cutfunc) |
|
2074 | revs = dagop.revancestors(repo, s, cutfunc=cutfunc) | |
2072 |
|
2075 | |||
2073 | if phasename == b'draft': # need to remove secret changesets |
|
2076 | if phasename == b'draft': # need to remove secret changesets | |
2074 | revs = revs.filter(lambda r: getphase(repo, r) == draft) |
|
2077 | revs = revs.filter(lambda r: getphase(repo, r) == draft) | |
2075 | return subset & revs |
|
2078 | return subset & revs | |
2076 |
|
2079 | |||
2077 |
|
2080 | |||
2078 | @predicate(b'public()', safe=True) |
|
2081 | @predicate(b'public()', safe=True) | |
2079 | def public(repo, subset, x): |
|
2082 | def public(repo, subset, x): | |
2080 | """Changeset in public phase.""" |
|
2083 | """Changeset in public phase.""" | |
2081 | # i18n: "public" is a keyword |
|
2084 | # i18n: "public" is a keyword | |
2082 | getargs(x, 0, 0, _(b"public takes no arguments")) |
|
2085 | getargs(x, 0, 0, _(b"public takes no arguments")) | |
2083 | return _phase(repo, subset, phases.public) |
|
2086 | return _phase(repo, subset, phases.public) | |
2084 |
|
2087 | |||
2085 |
|
2088 | |||
2086 | @predicate(b'remote([id [,path]])', safe=False) |
|
2089 | @predicate(b'remote([id [,path]])', safe=False) | |
2087 | def remote(repo, subset, x): |
|
2090 | def remote(repo, subset, x): | |
2088 | """Local revision that corresponds to the given identifier in a |
|
2091 | """Local revision that corresponds to the given identifier in a | |
2089 | remote repository, if present. Here, the '.' identifier is a |
|
2092 | remote repository, if present. Here, the '.' identifier is a | |
2090 | synonym for the current local branch. |
|
2093 | synonym for the current local branch. | |
2091 | """ |
|
2094 | """ | |
2092 |
|
2095 | |||
2093 | from . import hg # avoid start-up nasties |
|
2096 | from . import hg # avoid start-up nasties | |
2094 |
|
2097 | |||
2095 | # i18n: "remote" is a keyword |
|
2098 | # i18n: "remote" is a keyword | |
2096 | l = getargs(x, 0, 2, _(b"remote takes zero, one, or two arguments")) |
|
2099 | l = getargs(x, 0, 2, _(b"remote takes zero, one, or two arguments")) | |
2097 |
|
2100 | |||
2098 | q = b'.' |
|
2101 | q = b'.' | |
2099 | if len(l) > 0: |
|
2102 | if len(l) > 0: | |
2100 | # i18n: "remote" is a keyword |
|
2103 | # i18n: "remote" is a keyword | |
2101 | q = getstring(l[0], _(b"remote requires a string id")) |
|
2104 | q = getstring(l[0], _(b"remote requires a string id")) | |
2102 | if q == b'.': |
|
2105 | if q == b'.': | |
2103 | q = repo[b'.'].branch() |
|
2106 | q = repo[b'.'].branch() | |
2104 |
|
2107 | |||
2105 | dest = b'' |
|
2108 | dest = b'' | |
2106 | if len(l) > 1: |
|
2109 | if len(l) > 1: | |
2107 | # i18n: "remote" is a keyword |
|
2110 | # i18n: "remote" is a keyword | |
2108 | dest = getstring(l[1], _(b"remote requires a repository path")) |
|
2111 | dest = getstring(l[1], _(b"remote requires a repository path")) | |
2109 | dest = repo.ui.expandpath(dest or b'default') |
|
2112 | dest = repo.ui.expandpath(dest or b'default') | |
2110 | dest, branches = hg.parseurl(dest) |
|
2113 | dest, branches = hg.parseurl(dest) | |
2111 |
|
2114 | |||
2112 | other = hg.peer(repo, {}, dest) |
|
2115 | other = hg.peer(repo, {}, dest) | |
2113 | n = other.lookup(q) |
|
2116 | n = other.lookup(q) | |
2114 | if n in repo: |
|
2117 | if n in repo: | |
2115 | r = repo[n].rev() |
|
2118 | r = repo[n].rev() | |
2116 | if r in subset: |
|
2119 | if r in subset: | |
2117 | return baseset([r]) |
|
2120 | return baseset([r]) | |
2118 | return baseset() |
|
2121 | return baseset() | |
2119 |
|
2122 | |||
2120 |
|
2123 | |||
2121 | @predicate(b'removes(pattern)', safe=True, weight=30) |
|
2124 | @predicate(b'removes(pattern)', safe=True, weight=30) | |
2122 | def removes(repo, subset, x): |
|
2125 | def removes(repo, subset, x): | |
2123 | """Changesets which remove files matching pattern. |
|
2126 | """Changesets which remove files matching pattern. | |
2124 |
|
2127 | |||
2125 | The pattern without explicit kind like ``glob:`` is expected to be |
|
2128 | The pattern without explicit kind like ``glob:`` is expected to be | |
2126 | relative to the current directory and match against a file or a |
|
2129 | relative to the current directory and match against a file or a | |
2127 | directory. |
|
2130 | directory. | |
2128 | """ |
|
2131 | """ | |
2129 | # i18n: "removes" is a keyword |
|
2132 | # i18n: "removes" is a keyword | |
2130 | pat = getstring(x, _(b"removes requires a pattern")) |
|
2133 | pat = getstring(x, _(b"removes requires a pattern")) | |
2131 | return checkstatus(repo, subset, pat, 'removed') |
|
2134 | return checkstatus(repo, subset, pat, 'removed') | |
2132 |
|
2135 | |||
2133 |
|
2136 | |||
2134 | @predicate(b'rev(number)', safe=True) |
|
2137 | @predicate(b'rev(number)', safe=True) | |
2135 | def rev(repo, subset, x): |
|
2138 | def rev(repo, subset, x): | |
2136 | """Revision with the given numeric identifier.""" |
|
2139 | """Revision with the given numeric identifier.""" | |
2137 | try: |
|
2140 | try: | |
2138 | return _rev(repo, subset, x) |
|
2141 | return _rev(repo, subset, x) | |
2139 | except error.RepoLookupError: |
|
2142 | except error.RepoLookupError: | |
2140 | return baseset() |
|
2143 | return baseset() | |
2141 |
|
2144 | |||
2142 |
|
2145 | |||
2143 | @predicate(b'_rev(number)', safe=True) |
|
2146 | @predicate(b'_rev(number)', safe=True) | |
2144 | def _rev(repo, subset, x): |
|
2147 | def _rev(repo, subset, x): | |
2145 | # internal version of "rev(x)" that raise error if "x" is invalid |
|
2148 | # internal version of "rev(x)" that raise error if "x" is invalid | |
2146 | # i18n: "rev" is a keyword |
|
2149 | # i18n: "rev" is a keyword | |
2147 | l = getargs(x, 1, 1, _(b"rev requires one argument")) |
|
2150 | l = getargs(x, 1, 1, _(b"rev requires one argument")) | |
2148 | try: |
|
2151 | try: | |
2149 | # i18n: "rev" is a keyword |
|
2152 | # i18n: "rev" is a keyword | |
2150 | l = int(getstring(l[0], _(b"rev requires a number"))) |
|
2153 | l = int(getstring(l[0], _(b"rev requires a number"))) | |
2151 | except (TypeError, ValueError): |
|
2154 | except (TypeError, ValueError): | |
2152 | # i18n: "rev" is a keyword |
|
2155 | # i18n: "rev" is a keyword | |
2153 | raise error.ParseError(_(b"rev expects a number")) |
|
2156 | raise error.ParseError(_(b"rev expects a number")) | |
2154 | if l not in _virtualrevs: |
|
2157 | if l not in _virtualrevs: | |
2155 | try: |
|
2158 | try: | |
2156 | repo.changelog.node(l) # check that the rev exists |
|
2159 | repo.changelog.node(l) # check that the rev exists | |
2157 | except IndexError: |
|
2160 | except IndexError: | |
2158 | raise error.RepoLookupError(_(b"unknown revision '%d'") % l) |
|
2161 | raise error.RepoLookupError(_(b"unknown revision '%d'") % l) | |
2159 | return subset & baseset([l]) |
|
2162 | return subset & baseset([l]) | |
2160 |
|
2163 | |||
2161 |
|
2164 | |||
2162 | @predicate(b'revset(set)', safe=True, takeorder=True) |
|
2165 | @predicate(b'revset(set)', safe=True, takeorder=True) | |
2163 | def revsetpredicate(repo, subset, x, order): |
|
2166 | def revsetpredicate(repo, subset, x, order): | |
2164 | """Strictly interpret the content as a revset. |
|
2167 | """Strictly interpret the content as a revset. | |
2165 |
|
2168 | |||
2166 | The content of this special predicate will be strictly interpreted as a |
|
2169 | The content of this special predicate will be strictly interpreted as a | |
2167 | revset. For example, ``revset(id(0))`` will be interpreted as "id(0)" |
|
2170 | revset. For example, ``revset(id(0))`` will be interpreted as "id(0)" | |
2168 | without possible ambiguity with a "id(0)" bookmark or tag. |
|
2171 | without possible ambiguity with a "id(0)" bookmark or tag. | |
2169 | """ |
|
2172 | """ | |
2170 | return getset(repo, subset, x, order) |
|
2173 | return getset(repo, subset, x, order) | |
2171 |
|
2174 | |||
2172 |
|
2175 | |||
2173 | @predicate(b'matching(revision [, field])', safe=True) |
|
2176 | @predicate(b'matching(revision [, field])', safe=True) | |
2174 | def matching(repo, subset, x): |
|
2177 | def matching(repo, subset, x): | |
2175 | """Changesets in which a given set of fields match the set of fields in the |
|
2178 | """Changesets in which a given set of fields match the set of fields in the | |
2176 | selected revision or set. |
|
2179 | selected revision or set. | |
2177 |
|
2180 | |||
2178 | To match more than one field pass the list of fields to match separated |
|
2181 | To match more than one field pass the list of fields to match separated | |
2179 | by spaces (e.g. ``author description``). |
|
2182 | by spaces (e.g. ``author description``). | |
2180 |
|
2183 | |||
2181 | Valid fields are most regular revision fields and some special fields. |
|
2184 | Valid fields are most regular revision fields and some special fields. | |
2182 |
|
2185 | |||
2183 | Regular revision fields are ``description``, ``author``, ``branch``, |
|
2186 | Regular revision fields are ``description``, ``author``, ``branch``, | |
2184 | ``date``, ``files``, ``phase``, ``parents``, ``substate``, ``user`` |
|
2187 | ``date``, ``files``, ``phase``, ``parents``, ``substate``, ``user`` | |
2185 | and ``diff``. |
|
2188 | and ``diff``. | |
2186 | Note that ``author`` and ``user`` are synonyms. ``diff`` refers to the |
|
2189 | Note that ``author`` and ``user`` are synonyms. ``diff`` refers to the | |
2187 | contents of the revision. Two revisions matching their ``diff`` will |
|
2190 | contents of the revision. Two revisions matching their ``diff`` will | |
2188 | also match their ``files``. |
|
2191 | also match their ``files``. | |
2189 |
|
2192 | |||
2190 | Special fields are ``summary`` and ``metadata``: |
|
2193 | Special fields are ``summary`` and ``metadata``: | |
2191 | ``summary`` matches the first line of the description. |
|
2194 | ``summary`` matches the first line of the description. | |
2192 | ``metadata`` is equivalent to matching ``description user date`` |
|
2195 | ``metadata`` is equivalent to matching ``description user date`` | |
2193 | (i.e. it matches the main metadata fields). |
|
2196 | (i.e. it matches the main metadata fields). | |
2194 |
|
2197 | |||
2195 | ``metadata`` is the default field which is used when no fields are |
|
2198 | ``metadata`` is the default field which is used when no fields are | |
2196 | specified. You can match more than one field at a time. |
|
2199 | specified. You can match more than one field at a time. | |
2197 | """ |
|
2200 | """ | |
2198 | # i18n: "matching" is a keyword |
|
2201 | # i18n: "matching" is a keyword | |
2199 | l = getargs(x, 1, 2, _(b"matching takes 1 or 2 arguments")) |
|
2202 | l = getargs(x, 1, 2, _(b"matching takes 1 or 2 arguments")) | |
2200 |
|
2203 | |||
2201 | revs = getset(repo, fullreposet(repo), l[0]) |
|
2204 | revs = getset(repo, fullreposet(repo), l[0]) | |
2202 |
|
2205 | |||
2203 | fieldlist = [b'metadata'] |
|
2206 | fieldlist = [b'metadata'] | |
2204 | if len(l) > 1: |
|
2207 | if len(l) > 1: | |
2205 | fieldlist = getstring( |
|
2208 | fieldlist = getstring( | |
2206 | l[1], |
|
2209 | l[1], | |
2207 | # i18n: "matching" is a keyword |
|
2210 | # i18n: "matching" is a keyword | |
2208 | _(b"matching requires a string as its second argument"), |
|
2211 | _(b"matching requires a string as its second argument"), | |
2209 | ).split() |
|
2212 | ).split() | |
2210 |
|
2213 | |||
2211 | # Make sure that there are no repeated fields, |
|
2214 | # Make sure that there are no repeated fields, | |
2212 | # expand the 'special' 'metadata' field type |
|
2215 | # expand the 'special' 'metadata' field type | |
2213 | # and check the 'files' whenever we check the 'diff' |
|
2216 | # and check the 'files' whenever we check the 'diff' | |
2214 | fields = [] |
|
2217 | fields = [] | |
2215 | for field in fieldlist: |
|
2218 | for field in fieldlist: | |
2216 | if field == b'metadata': |
|
2219 | if field == b'metadata': | |
2217 | fields += [b'user', b'description', b'date'] |
|
2220 | fields += [b'user', b'description', b'date'] | |
2218 | elif field == b'diff': |
|
2221 | elif field == b'diff': | |
2219 | # a revision matching the diff must also match the files |
|
2222 | # a revision matching the diff must also match the files | |
2220 | # since matching the diff is very costly, make sure to |
|
2223 | # since matching the diff is very costly, make sure to | |
2221 | # also match the files first |
|
2224 | # also match the files first | |
2222 | fields += [b'files', b'diff'] |
|
2225 | fields += [b'files', b'diff'] | |
2223 | else: |
|
2226 | else: | |
2224 | if field == b'author': |
|
2227 | if field == b'author': | |
2225 | field = b'user' |
|
2228 | field = b'user' | |
2226 | fields.append(field) |
|
2229 | fields.append(field) | |
2227 | fields = set(fields) |
|
2230 | fields = set(fields) | |
2228 | if b'summary' in fields and b'description' in fields: |
|
2231 | if b'summary' in fields and b'description' in fields: | |
2229 | # If a revision matches its description it also matches its summary |
|
2232 | # If a revision matches its description it also matches its summary | |
2230 | fields.discard(b'summary') |
|
2233 | fields.discard(b'summary') | |
2231 |
|
2234 | |||
2232 | # We may want to match more than one field |
|
2235 | # We may want to match more than one field | |
2233 | # Not all fields take the same amount of time to be matched |
|
2236 | # Not all fields take the same amount of time to be matched | |
2234 | # Sort the selected fields in order of increasing matching cost |
|
2237 | # Sort the selected fields in order of increasing matching cost | |
2235 | fieldorder = [ |
|
2238 | fieldorder = [ | |
2236 | b'phase', |
|
2239 | b'phase', | |
2237 | b'parents', |
|
2240 | b'parents', | |
2238 | b'user', |
|
2241 | b'user', | |
2239 | b'date', |
|
2242 | b'date', | |
2240 | b'branch', |
|
2243 | b'branch', | |
2241 | b'summary', |
|
2244 | b'summary', | |
2242 | b'files', |
|
2245 | b'files', | |
2243 | b'description', |
|
2246 | b'description', | |
2244 | b'substate', |
|
2247 | b'substate', | |
2245 | b'diff', |
|
2248 | b'diff', | |
2246 | ] |
|
2249 | ] | |
2247 |
|
2250 | |||
2248 | def fieldkeyfunc(f): |
|
2251 | def fieldkeyfunc(f): | |
2249 | try: |
|
2252 | try: | |
2250 | return fieldorder.index(f) |
|
2253 | return fieldorder.index(f) | |
2251 | except ValueError: |
|
2254 | except ValueError: | |
2252 | # assume an unknown field is very costly |
|
2255 | # assume an unknown field is very costly | |
2253 | return len(fieldorder) |
|
2256 | return len(fieldorder) | |
2254 |
|
2257 | |||
2255 | fields = list(fields) |
|
2258 | fields = list(fields) | |
2256 | fields.sort(key=fieldkeyfunc) |
|
2259 | fields.sort(key=fieldkeyfunc) | |
2257 |
|
2260 | |||
2258 | # Each field will be matched with its own "getfield" function |
|
2261 | # Each field will be matched with its own "getfield" function | |
2259 | # which will be added to the getfieldfuncs array of functions |
|
2262 | # which will be added to the getfieldfuncs array of functions | |
2260 | getfieldfuncs = [] |
|
2263 | getfieldfuncs = [] | |
2261 | _funcs = { |
|
2264 | _funcs = { | |
2262 | b'user': lambda r: repo[r].user(), |
|
2265 | b'user': lambda r: repo[r].user(), | |
2263 | b'branch': lambda r: repo[r].branch(), |
|
2266 | b'branch': lambda r: repo[r].branch(), | |
2264 | b'date': lambda r: repo[r].date(), |
|
2267 | b'date': lambda r: repo[r].date(), | |
2265 | b'description': lambda r: repo[r].description(), |
|
2268 | b'description': lambda r: repo[r].description(), | |
2266 | b'files': lambda r: repo[r].files(), |
|
2269 | b'files': lambda r: repo[r].files(), | |
2267 | b'parents': lambda r: repo[r].parents(), |
|
2270 | b'parents': lambda r: repo[r].parents(), | |
2268 | b'phase': lambda r: repo[r].phase(), |
|
2271 | b'phase': lambda r: repo[r].phase(), | |
2269 | b'substate': lambda r: repo[r].substate, |
|
2272 | b'substate': lambda r: repo[r].substate, | |
2270 | b'summary': lambda r: repo[r].description().splitlines()[0], |
|
2273 | b'summary': lambda r: repo[r].description().splitlines()[0], | |
2271 | b'diff': lambda r: list( |
|
2274 | b'diff': lambda r: list( | |
2272 | repo[r].diff(opts=diffutil.diffallopts(repo.ui, {b'git': True})) |
|
2275 | repo[r].diff(opts=diffutil.diffallopts(repo.ui, {b'git': True})) | |
2273 | ), |
|
2276 | ), | |
2274 | } |
|
2277 | } | |
2275 | for info in fields: |
|
2278 | for info in fields: | |
2276 | getfield = _funcs.get(info, None) |
|
2279 | getfield = _funcs.get(info, None) | |
2277 | if getfield is None: |
|
2280 | if getfield is None: | |
2278 | raise error.ParseError( |
|
2281 | raise error.ParseError( | |
2279 | # i18n: "matching" is a keyword |
|
2282 | # i18n: "matching" is a keyword | |
2280 | _(b"unexpected field name passed to matching: %s") |
|
2283 | _(b"unexpected field name passed to matching: %s") | |
2281 | % info |
|
2284 | % info | |
2282 | ) |
|
2285 | ) | |
2283 | getfieldfuncs.append(getfield) |
|
2286 | getfieldfuncs.append(getfield) | |
2284 | # convert the getfield array of functions into a "getinfo" function |
|
2287 | # convert the getfield array of functions into a "getinfo" function | |
2285 | # which returns an array of field values (or a single value if there |
|
2288 | # which returns an array of field values (or a single value if there | |
2286 | # is only one field to match) |
|
2289 | # is only one field to match) | |
2287 | getinfo = lambda r: [f(r) for f in getfieldfuncs] |
|
2290 | getinfo = lambda r: [f(r) for f in getfieldfuncs] | |
2288 |
|
2291 | |||
2289 | def matches(x): |
|
2292 | def matches(x): | |
2290 | for rev in revs: |
|
2293 | for rev in revs: | |
2291 | target = getinfo(rev) |
|
2294 | target = getinfo(rev) | |
2292 | match = True |
|
2295 | match = True | |
2293 | for n, f in enumerate(getfieldfuncs): |
|
2296 | for n, f in enumerate(getfieldfuncs): | |
2294 | if target[n] != f(x): |
|
2297 | if target[n] != f(x): | |
2295 | match = False |
|
2298 | match = False | |
2296 | if match: |
|
2299 | if match: | |
2297 | return True |
|
2300 | return True | |
2298 | return False |
|
2301 | return False | |
2299 |
|
2302 | |||
2300 | return subset.filter(matches, condrepr=(b'<matching%r %r>', fields, revs)) |
|
2303 | return subset.filter(matches, condrepr=(b'<matching%r %r>', fields, revs)) | |
2301 |
|
2304 | |||
2302 |
|
2305 | |||
2303 | @predicate(b'reverse(set)', safe=True, takeorder=True, weight=0) |
|
2306 | @predicate(b'reverse(set)', safe=True, takeorder=True, weight=0) | |
2304 | def reverse(repo, subset, x, order): |
|
2307 | def reverse(repo, subset, x, order): | |
2305 | """Reverse order of set. |
|
2308 | """Reverse order of set. | |
2306 | """ |
|
2309 | """ | |
2307 | l = getset(repo, subset, x, order) |
|
2310 | l = getset(repo, subset, x, order) | |
2308 | if order == defineorder: |
|
2311 | if order == defineorder: | |
2309 | l.reverse() |
|
2312 | l.reverse() | |
2310 | return l |
|
2313 | return l | |
2311 |
|
2314 | |||
2312 |
|
2315 | |||
2313 | @predicate(b'roots(set)', safe=True) |
|
2316 | @predicate(b'roots(set)', safe=True) | |
2314 | def roots(repo, subset, x): |
|
2317 | def roots(repo, subset, x): | |
2315 | """Changesets in set with no parent changeset in set. |
|
2318 | """Changesets in set with no parent changeset in set. | |
2316 | """ |
|
2319 | """ | |
2317 | s = getset(repo, fullreposet(repo), x) |
|
2320 | s = getset(repo, fullreposet(repo), x) | |
2318 | parents = repo.changelog.parentrevs |
|
2321 | parents = repo.changelog.parentrevs | |
2319 |
|
2322 | |||
2320 | def filter(r): |
|
2323 | def filter(r): | |
2321 | for p in parents(r): |
|
2324 | for p in parents(r): | |
2322 | if 0 <= p and p in s: |
|
2325 | if 0 <= p and p in s: | |
2323 | return False |
|
2326 | return False | |
2324 | return True |
|
2327 | return True | |
2325 |
|
2328 | |||
2326 | return subset & s.filter(filter, condrepr=b'<roots>') |
|
2329 | return subset & s.filter(filter, condrepr=b'<roots>') | |
2327 |
|
2330 | |||
2328 |
|
2331 | |||
2329 | _sortkeyfuncs = { |
|
2332 | _sortkeyfuncs = { | |
2330 | b'rev': scmutil.intrev, |
|
2333 | b'rev': scmutil.intrev, | |
2331 | b'branch': lambda c: c.branch(), |
|
2334 | b'branch': lambda c: c.branch(), | |
2332 | b'desc': lambda c: c.description(), |
|
2335 | b'desc': lambda c: c.description(), | |
2333 | b'user': lambda c: c.user(), |
|
2336 | b'user': lambda c: c.user(), | |
2334 | b'author': lambda c: c.user(), |
|
2337 | b'author': lambda c: c.user(), | |
2335 | b'date': lambda c: c.date()[0], |
|
2338 | b'date': lambda c: c.date()[0], | |
2336 | b'node': scmutil.binnode, |
|
2339 | b'node': scmutil.binnode, | |
2337 | } |
|
2340 | } | |
2338 |
|
2341 | |||
2339 |
|
2342 | |||
2340 | def _getsortargs(x): |
|
2343 | def _getsortargs(x): | |
2341 | """Parse sort options into (set, [(key, reverse)], opts)""" |
|
2344 | """Parse sort options into (set, [(key, reverse)], opts)""" | |
2342 | args = getargsdict(x, b'sort', b'set keys topo.firstbranch') |
|
2345 | args = getargsdict(x, b'sort', b'set keys topo.firstbranch') | |
2343 | if b'set' not in args: |
|
2346 | if b'set' not in args: | |
2344 | # i18n: "sort" is a keyword |
|
2347 | # i18n: "sort" is a keyword | |
2345 | raise error.ParseError(_(b'sort requires one or two arguments')) |
|
2348 | raise error.ParseError(_(b'sort requires one or two arguments')) | |
2346 | keys = b"rev" |
|
2349 | keys = b"rev" | |
2347 | if b'keys' in args: |
|
2350 | if b'keys' in args: | |
2348 | # i18n: "sort" is a keyword |
|
2351 | # i18n: "sort" is a keyword | |
2349 | keys = getstring(args[b'keys'], _(b"sort spec must be a string")) |
|
2352 | keys = getstring(args[b'keys'], _(b"sort spec must be a string")) | |
2350 |
|
2353 | |||
2351 | keyflags = [] |
|
2354 | keyflags = [] | |
2352 | for k in keys.split(): |
|
2355 | for k in keys.split(): | |
2353 | fk = k |
|
2356 | fk = k | |
2354 | reverse = k.startswith(b'-') |
|
2357 | reverse = k.startswith(b'-') | |
2355 | if reverse: |
|
2358 | if reverse: | |
2356 | k = k[1:] |
|
2359 | k = k[1:] | |
2357 | if k not in _sortkeyfuncs and k != b'topo': |
|
2360 | if k not in _sortkeyfuncs and k != b'topo': | |
2358 | raise error.ParseError( |
|
2361 | raise error.ParseError( | |
2359 | _(b"unknown sort key %r") % pycompat.bytestr(fk) |
|
2362 | _(b"unknown sort key %r") % pycompat.bytestr(fk) | |
2360 | ) |
|
2363 | ) | |
2361 | keyflags.append((k, reverse)) |
|
2364 | keyflags.append((k, reverse)) | |
2362 |
|
2365 | |||
2363 | if len(keyflags) > 1 and any(k == b'topo' for k, reverse in keyflags): |
|
2366 | if len(keyflags) > 1 and any(k == b'topo' for k, reverse in keyflags): | |
2364 | # i18n: "topo" is a keyword |
|
2367 | # i18n: "topo" is a keyword | |
2365 | raise error.ParseError( |
|
2368 | raise error.ParseError( | |
2366 | _(b'topo sort order cannot be combined with other sort keys') |
|
2369 | _(b'topo sort order cannot be combined with other sort keys') | |
2367 | ) |
|
2370 | ) | |
2368 |
|
2371 | |||
2369 | opts = {} |
|
2372 | opts = {} | |
2370 | if b'topo.firstbranch' in args: |
|
2373 | if b'topo.firstbranch' in args: | |
2371 | if any(k == b'topo' for k, reverse in keyflags): |
|
2374 | if any(k == b'topo' for k, reverse in keyflags): | |
2372 | opts[b'topo.firstbranch'] = args[b'topo.firstbranch'] |
|
2375 | opts[b'topo.firstbranch'] = args[b'topo.firstbranch'] | |
2373 | else: |
|
2376 | else: | |
2374 | # i18n: "topo" and "topo.firstbranch" are keywords |
|
2377 | # i18n: "topo" and "topo.firstbranch" are keywords | |
2375 | raise error.ParseError( |
|
2378 | raise error.ParseError( | |
2376 | _( |
|
2379 | _( | |
2377 | b'topo.firstbranch can only be used ' |
|
2380 | b'topo.firstbranch can only be used ' | |
2378 | b'when using the topo sort key' |
|
2381 | b'when using the topo sort key' | |
2379 | ) |
|
2382 | ) | |
2380 | ) |
|
2383 | ) | |
2381 |
|
2384 | |||
2382 | return args[b'set'], keyflags, opts |
|
2385 | return args[b'set'], keyflags, opts | |
2383 |
|
2386 | |||
2384 |
|
2387 | |||
2385 | @predicate( |
|
2388 | @predicate( | |
2386 | b'sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, weight=10 |
|
2389 | b'sort(set[, [-]key... [, ...]])', safe=True, takeorder=True, weight=10 | |
2387 | ) |
|
2390 | ) | |
2388 | def sort(repo, subset, x, order): |
|
2391 | def sort(repo, subset, x, order): | |
2389 | """Sort set by keys. The default sort order is ascending, specify a key |
|
2392 | """Sort set by keys. The default sort order is ascending, specify a key | |
2390 | as ``-key`` to sort in descending order. |
|
2393 | as ``-key`` to sort in descending order. | |
2391 |
|
2394 | |||
2392 | The keys can be: |
|
2395 | The keys can be: | |
2393 |
|
2396 | |||
2394 | - ``rev`` for the revision number, |
|
2397 | - ``rev`` for the revision number, | |
2395 | - ``branch`` for the branch name, |
|
2398 | - ``branch`` for the branch name, | |
2396 | - ``desc`` for the commit message (description), |
|
2399 | - ``desc`` for the commit message (description), | |
2397 | - ``user`` for user name (``author`` can be used as an alias), |
|
2400 | - ``user`` for user name (``author`` can be used as an alias), | |
2398 | - ``date`` for the commit date |
|
2401 | - ``date`` for the commit date | |
2399 | - ``topo`` for a reverse topographical sort |
|
2402 | - ``topo`` for a reverse topographical sort | |
2400 | - ``node`` the nodeid of the revision |
|
2403 | - ``node`` the nodeid of the revision | |
2401 |
|
2404 | |||
2402 | The ``topo`` sort order cannot be combined with other sort keys. This sort |
|
2405 | The ``topo`` sort order cannot be combined with other sort keys. This sort | |
2403 | takes one optional argument, ``topo.firstbranch``, which takes a revset that |
|
2406 | takes one optional argument, ``topo.firstbranch``, which takes a revset that | |
2404 | specifies what topographical branches to prioritize in the sort. |
|
2407 | specifies what topographical branches to prioritize in the sort. | |
2405 |
|
2408 | |||
2406 | """ |
|
2409 | """ | |
2407 | s, keyflags, opts = _getsortargs(x) |
|
2410 | s, keyflags, opts = _getsortargs(x) | |
2408 | revs = getset(repo, subset, s, order) |
|
2411 | revs = getset(repo, subset, s, order) | |
2409 |
|
2412 | |||
2410 | if not keyflags or order != defineorder: |
|
2413 | if not keyflags or order != defineorder: | |
2411 | return revs |
|
2414 | return revs | |
2412 | if len(keyflags) == 1 and keyflags[0][0] == b"rev": |
|
2415 | if len(keyflags) == 1 and keyflags[0][0] == b"rev": | |
2413 | revs.sort(reverse=keyflags[0][1]) |
|
2416 | revs.sort(reverse=keyflags[0][1]) | |
2414 | return revs |
|
2417 | return revs | |
2415 | elif keyflags[0][0] == b"topo": |
|
2418 | elif keyflags[0][0] == b"topo": | |
2416 | firstbranch = () |
|
2419 | firstbranch = () | |
2417 | if b'topo.firstbranch' in opts: |
|
2420 | if b'topo.firstbranch' in opts: | |
2418 | firstbranch = getset(repo, subset, opts[b'topo.firstbranch']) |
|
2421 | firstbranch = getset(repo, subset, opts[b'topo.firstbranch']) | |
2419 | revs = baseset( |
|
2422 | revs = baseset( | |
2420 | dagop.toposort(revs, repo.changelog.parentrevs, firstbranch), |
|
2423 | dagop.toposort(revs, repo.changelog.parentrevs, firstbranch), | |
2421 | istopo=True, |
|
2424 | istopo=True, | |
2422 | ) |
|
2425 | ) | |
2423 | if keyflags[0][1]: |
|
2426 | if keyflags[0][1]: | |
2424 | revs.reverse() |
|
2427 | revs.reverse() | |
2425 | return revs |
|
2428 | return revs | |
2426 |
|
2429 | |||
2427 | # sort() is guaranteed to be stable |
|
2430 | # sort() is guaranteed to be stable | |
2428 | ctxs = [repo[r] for r in revs] |
|
2431 | ctxs = [repo[r] for r in revs] | |
2429 | for k, reverse in reversed(keyflags): |
|
2432 | for k, reverse in reversed(keyflags): | |
2430 | ctxs.sort(key=_sortkeyfuncs[k], reverse=reverse) |
|
2433 | ctxs.sort(key=_sortkeyfuncs[k], reverse=reverse) | |
2431 | return baseset([c.rev() for c in ctxs]) |
|
2434 | return baseset([c.rev() for c in ctxs]) | |
2432 |
|
2435 | |||
2433 |
|
2436 | |||
2434 | @predicate(b'subrepo([pattern])') |
|
2437 | @predicate(b'subrepo([pattern])') | |
2435 | def subrepo(repo, subset, x): |
|
2438 | def subrepo(repo, subset, x): | |
2436 | """Changesets that add, modify or remove the given subrepo. If no subrepo |
|
2439 | """Changesets that add, modify or remove the given subrepo. If no subrepo | |
2437 | pattern is named, any subrepo changes are returned. |
|
2440 | pattern is named, any subrepo changes are returned. | |
2438 | """ |
|
2441 | """ | |
2439 | # i18n: "subrepo" is a keyword |
|
2442 | # i18n: "subrepo" is a keyword | |
2440 | args = getargs(x, 0, 1, _(b'subrepo takes at most one argument')) |
|
2443 | args = getargs(x, 0, 1, _(b'subrepo takes at most one argument')) | |
2441 | pat = None |
|
2444 | pat = None | |
2442 | if len(args) != 0: |
|
2445 | if len(args) != 0: | |
2443 | pat = getstring(args[0], _(b"subrepo requires a pattern")) |
|
2446 | pat = getstring(args[0], _(b"subrepo requires a pattern")) | |
2444 |
|
2447 | |||
2445 | m = matchmod.exact([b'.hgsubstate']) |
|
2448 | m = matchmod.exact([b'.hgsubstate']) | |
2446 |
|
2449 | |||
2447 | def submatches(names): |
|
2450 | def submatches(names): | |
2448 | k, p, m = stringutil.stringmatcher(pat) |
|
2451 | k, p, m = stringutil.stringmatcher(pat) | |
2449 | for name in names: |
|
2452 | for name in names: | |
2450 | if m(name): |
|
2453 | if m(name): | |
2451 | yield name |
|
2454 | yield name | |
2452 |
|
2455 | |||
2453 | def matches(x): |
|
2456 | def matches(x): | |
2454 | c = repo[x] |
|
2457 | c = repo[x] | |
2455 | s = repo.status(c.p1().node(), c.node(), match=m) |
|
2458 | s = repo.status(c.p1().node(), c.node(), match=m) | |
2456 |
|
2459 | |||
2457 | if pat is None: |
|
2460 | if pat is None: | |
2458 | return s.added or s.modified or s.removed |
|
2461 | return s.added or s.modified or s.removed | |
2459 |
|
2462 | |||
2460 | if s.added: |
|
2463 | if s.added: | |
2461 | return any(submatches(c.substate.keys())) |
|
2464 | return any(submatches(c.substate.keys())) | |
2462 |
|
2465 | |||
2463 | if s.modified: |
|
2466 | if s.modified: | |
2464 | subs = set(c.p1().substate.keys()) |
|
2467 | subs = set(c.p1().substate.keys()) | |
2465 | subs.update(c.substate.keys()) |
|
2468 | subs.update(c.substate.keys()) | |
2466 |
|
2469 | |||
2467 | for path in submatches(subs): |
|
2470 | for path in submatches(subs): | |
2468 | if c.p1().substate.get(path) != c.substate.get(path): |
|
2471 | if c.p1().substate.get(path) != c.substate.get(path): | |
2469 | return True |
|
2472 | return True | |
2470 |
|
2473 | |||
2471 | if s.removed: |
|
2474 | if s.removed: | |
2472 | return any(submatches(c.p1().substate.keys())) |
|
2475 | return any(submatches(c.p1().substate.keys())) | |
2473 |
|
2476 | |||
2474 | return False |
|
2477 | return False | |
2475 |
|
2478 | |||
2476 | return subset.filter(matches, condrepr=(b'<subrepo %r>', pat)) |
|
2479 | return subset.filter(matches, condrepr=(b'<subrepo %r>', pat)) | |
2477 |
|
2480 | |||
2478 |
|
2481 | |||
2479 | def _mapbynodefunc(repo, s, f): |
|
2482 | def _mapbynodefunc(repo, s, f): | |
2480 | """(repo, smartset, [node] -> [node]) -> smartset |
|
2483 | """(repo, smartset, [node] -> [node]) -> smartset | |
2481 |
|
2484 | |||
2482 | Helper method to map a smartset to another smartset given a function only |
|
2485 | Helper method to map a smartset to another smartset given a function only | |
2483 | talking about nodes. Handles converting between rev numbers and nodes, and |
|
2486 | talking about nodes. Handles converting between rev numbers and nodes, and | |
2484 | filtering. |
|
2487 | filtering. | |
2485 | """ |
|
2488 | """ | |
2486 | cl = repo.unfiltered().changelog |
|
2489 | cl = repo.unfiltered().changelog | |
2487 | torev = cl.index.get_rev |
|
2490 | torev = cl.index.get_rev | |
2488 | tonode = cl.node |
|
2491 | tonode = cl.node | |
2489 | result = {torev(n) for n in f(tonode(r) for r in s)} |
|
2492 | result = {torev(n) for n in f(tonode(r) for r in s)} | |
2490 | result.discard(None) |
|
2493 | result.discard(None) | |
2491 | return smartset.baseset(result - repo.changelog.filteredrevs) |
|
2494 | return smartset.baseset(result - repo.changelog.filteredrevs) | |
2492 |
|
2495 | |||
2493 |
|
2496 | |||
2494 | @predicate(b'successors(set)', safe=True) |
|
2497 | @predicate(b'successors(set)', safe=True) | |
2495 | def successors(repo, subset, x): |
|
2498 | def successors(repo, subset, x): | |
2496 | """All successors for set, including the given set themselves. |
|
2499 | """All successors for set, including the given set themselves. | |
2497 | (EXPERIMENTAL)""" |
|
2500 | (EXPERIMENTAL)""" | |
2498 | s = getset(repo, fullreposet(repo), x) |
|
2501 | s = getset(repo, fullreposet(repo), x) | |
2499 | f = lambda nodes: obsutil.allsuccessors(repo.obsstore, nodes) |
|
2502 | f = lambda nodes: obsutil.allsuccessors(repo.obsstore, nodes) | |
2500 | d = _mapbynodefunc(repo, s, f) |
|
2503 | d = _mapbynodefunc(repo, s, f) | |
2501 | return subset & d |
|
2504 | return subset & d | |
2502 |
|
2505 | |||
2503 |
|
2506 | |||
2504 | def _substringmatcher(pattern, casesensitive=True): |
|
2507 | def _substringmatcher(pattern, casesensitive=True): | |
2505 | kind, pattern, matcher = stringutil.stringmatcher( |
|
2508 | kind, pattern, matcher = stringutil.stringmatcher( | |
2506 | pattern, casesensitive=casesensitive |
|
2509 | pattern, casesensitive=casesensitive | |
2507 | ) |
|
2510 | ) | |
2508 | if kind == b'literal': |
|
2511 | if kind == b'literal': | |
2509 | if not casesensitive: |
|
2512 | if not casesensitive: | |
2510 | pattern = encoding.lower(pattern) |
|
2513 | pattern = encoding.lower(pattern) | |
2511 | matcher = lambda s: pattern in encoding.lower(s) |
|
2514 | matcher = lambda s: pattern in encoding.lower(s) | |
2512 | else: |
|
2515 | else: | |
2513 | matcher = lambda s: pattern in s |
|
2516 | matcher = lambda s: pattern in s | |
2514 | return kind, pattern, matcher |
|
2517 | return kind, pattern, matcher | |
2515 |
|
2518 | |||
2516 |
|
2519 | |||
2517 | @predicate(b'tag([name])', safe=True) |
|
2520 | @predicate(b'tag([name])', safe=True) | |
2518 | def tag(repo, subset, x): |
|
2521 | def tag(repo, subset, x): | |
2519 | """The specified tag by name, or all tagged revisions if no name is given. |
|
2522 | """The specified tag by name, or all tagged revisions if no name is given. | |
2520 |
|
2523 | |||
2521 | Pattern matching is supported for `name`. See |
|
2524 | Pattern matching is supported for `name`. See | |
2522 | :hg:`help revisions.patterns`. |
|
2525 | :hg:`help revisions.patterns`. | |
2523 | """ |
|
2526 | """ | |
2524 | # i18n: "tag" is a keyword |
|
2527 | # i18n: "tag" is a keyword | |
2525 | args = getargs(x, 0, 1, _(b"tag takes one or no arguments")) |
|
2528 | args = getargs(x, 0, 1, _(b"tag takes one or no arguments")) | |
2526 | cl = repo.changelog |
|
2529 | cl = repo.changelog | |
2527 | if args: |
|
2530 | if args: | |
2528 | pattern = getstring( |
|
2531 | pattern = getstring( | |
2529 | args[0], |
|
2532 | args[0], | |
2530 | # i18n: "tag" is a keyword |
|
2533 | # i18n: "tag" is a keyword | |
2531 | _(b'the argument to tag must be a string'), |
|
2534 | _(b'the argument to tag must be a string'), | |
2532 | ) |
|
2535 | ) | |
2533 | kind, pattern, matcher = stringutil.stringmatcher(pattern) |
|
2536 | kind, pattern, matcher = stringutil.stringmatcher(pattern) | |
2534 | if kind == b'literal': |
|
2537 | if kind == b'literal': | |
2535 | # avoid resolving all tags |
|
2538 | # avoid resolving all tags | |
2536 | tn = repo._tagscache.tags.get(pattern, None) |
|
2539 | tn = repo._tagscache.tags.get(pattern, None) | |
2537 | if tn is None: |
|
2540 | if tn is None: | |
2538 | raise error.RepoLookupError( |
|
2541 | raise error.RepoLookupError( | |
2539 | _(b"tag '%s' does not exist") % pattern |
|
2542 | _(b"tag '%s' does not exist") % pattern | |
2540 | ) |
|
2543 | ) | |
2541 | s = {repo[tn].rev()} |
|
2544 | s = {repo[tn].rev()} | |
2542 | else: |
|
2545 | else: | |
2543 | s = {cl.rev(n) for t, n in repo.tagslist() if matcher(t)} |
|
2546 | s = {cl.rev(n) for t, n in repo.tagslist() if matcher(t)} | |
2544 | else: |
|
2547 | else: | |
2545 | s = {cl.rev(n) for t, n in repo.tagslist() if t != b'tip'} |
|
2548 | s = {cl.rev(n) for t, n in repo.tagslist() if t != b'tip'} | |
2546 | return subset & s |
|
2549 | return subset & s | |
2547 |
|
2550 | |||
2548 |
|
2551 | |||
2549 | @predicate(b'tagged', safe=True) |
|
2552 | @predicate(b'tagged', safe=True) | |
2550 | def tagged(repo, subset, x): |
|
2553 | def tagged(repo, subset, x): | |
2551 | return tag(repo, subset, x) |
|
2554 | return tag(repo, subset, x) | |
2552 |
|
2555 | |||
2553 |
|
2556 | |||
2554 | @predicate(b'orphan()', safe=True) |
|
2557 | @predicate(b'orphan()', safe=True) | |
2555 | def orphan(repo, subset, x): |
|
2558 | def orphan(repo, subset, x): | |
2556 | """Non-obsolete changesets with obsolete ancestors. (EXPERIMENTAL) |
|
2559 | """Non-obsolete changesets with obsolete ancestors. (EXPERIMENTAL) | |
2557 | """ |
|
2560 | """ | |
2558 | # i18n: "orphan" is a keyword |
|
2561 | # i18n: "orphan" is a keyword | |
2559 | getargs(x, 0, 0, _(b"orphan takes no arguments")) |
|
2562 | getargs(x, 0, 0, _(b"orphan takes no arguments")) | |
2560 | orphan = obsmod.getrevs(repo, b'orphan') |
|
2563 | orphan = obsmod.getrevs(repo, b'orphan') | |
2561 | return subset & orphan |
|
2564 | return subset & orphan | |
2562 |
|
2565 | |||
2563 |
|
2566 | |||
2564 | @predicate(b'unstable()', safe=True) |
|
2567 | @predicate(b'unstable()', safe=True) | |
2565 | def unstable(repo, subset, x): |
|
2568 | def unstable(repo, subset, x): | |
2566 | """Changesets with instabilities. (EXPERIMENTAL) |
|
2569 | """Changesets with instabilities. (EXPERIMENTAL) | |
2567 | """ |
|
2570 | """ | |
2568 | # i18n: "unstable" is a keyword |
|
2571 | # i18n: "unstable" is a keyword | |
2569 | getargs(x, 0, 0, b'unstable takes no arguments') |
|
2572 | getargs(x, 0, 0, b'unstable takes no arguments') | |
2570 | _unstable = set() |
|
2573 | _unstable = set() | |
2571 | _unstable.update(obsmod.getrevs(repo, b'orphan')) |
|
2574 | _unstable.update(obsmod.getrevs(repo, b'orphan')) | |
2572 | _unstable.update(obsmod.getrevs(repo, b'phasedivergent')) |
|
2575 | _unstable.update(obsmod.getrevs(repo, b'phasedivergent')) | |
2573 | _unstable.update(obsmod.getrevs(repo, b'contentdivergent')) |
|
2576 | _unstable.update(obsmod.getrevs(repo, b'contentdivergent')) | |
2574 | return subset & baseset(_unstable) |
|
2577 | return subset & baseset(_unstable) | |
2575 |
|
2578 | |||
2576 |
|
2579 | |||
2577 | @predicate(b'user(string)', safe=True, weight=10) |
|
2580 | @predicate(b'user(string)', safe=True, weight=10) | |
2578 | def user(repo, subset, x): |
|
2581 | def user(repo, subset, x): | |
2579 | """User name contains string. The match is case-insensitive. |
|
2582 | """User name contains string. The match is case-insensitive. | |
2580 |
|
2583 | |||
2581 | Pattern matching is supported for `string`. See |
|
2584 | Pattern matching is supported for `string`. See | |
2582 | :hg:`help revisions.patterns`. |
|
2585 | :hg:`help revisions.patterns`. | |
2583 | """ |
|
2586 | """ | |
2584 | return author(repo, subset, x) |
|
2587 | return author(repo, subset, x) | |
2585 |
|
2588 | |||
2586 |
|
2589 | |||
2587 | @predicate(b'wdir()', safe=True, weight=0) |
|
2590 | @predicate(b'wdir()', safe=True, weight=0) | |
2588 | def wdir(repo, subset, x): |
|
2591 | def wdir(repo, subset, x): | |
2589 | """Working directory. (EXPERIMENTAL)""" |
|
2592 | """Working directory. (EXPERIMENTAL)""" | |
2590 | # i18n: "wdir" is a keyword |
|
2593 | # i18n: "wdir" is a keyword | |
2591 | getargs(x, 0, 0, _(b"wdir takes no arguments")) |
|
2594 | getargs(x, 0, 0, _(b"wdir takes no arguments")) | |
2592 | if node.wdirrev in subset or isinstance(subset, fullreposet): |
|
2595 | if node.wdirrev in subset or isinstance(subset, fullreposet): | |
2593 | return baseset([node.wdirrev]) |
|
2596 | return baseset([node.wdirrev]) | |
2594 | return baseset() |
|
2597 | return baseset() | |
2595 |
|
2598 | |||
2596 |
|
2599 | |||
2597 | def _orderedlist(repo, subset, x): |
|
2600 | def _orderedlist(repo, subset, x): | |
2598 | s = getstring(x, b"internal error") |
|
2601 | s = getstring(x, b"internal error") | |
2599 | if not s: |
|
2602 | if not s: | |
2600 | return baseset() |
|
2603 | return baseset() | |
2601 | # remove duplicates here. it's difficult for caller to deduplicate sets |
|
2604 | # remove duplicates here. it's difficult for caller to deduplicate sets | |
2602 | # because different symbols can point to the same rev. |
|
2605 | # because different symbols can point to the same rev. | |
2603 | cl = repo.changelog |
|
2606 | cl = repo.changelog | |
2604 | ls = [] |
|
2607 | ls = [] | |
2605 | seen = set() |
|
2608 | seen = set() | |
2606 | for t in s.split(b'\0'): |
|
2609 | for t in s.split(b'\0'): | |
2607 | try: |
|
2610 | try: | |
2608 | # fast path for integer revision |
|
2611 | # fast path for integer revision | |
2609 | r = int(t) |
|
2612 | r = int(t) | |
2610 | if (b'%d' % r) != t or r not in cl: |
|
2613 | if (b'%d' % r) != t or r not in cl: | |
2611 | raise ValueError |
|
2614 | raise ValueError | |
2612 | revs = [r] |
|
2615 | revs = [r] | |
2613 | except ValueError: |
|
2616 | except ValueError: | |
2614 | revs = stringset(repo, subset, t, defineorder) |
|
2617 | revs = stringset(repo, subset, t, defineorder) | |
2615 |
|
2618 | |||
2616 | for r in revs: |
|
2619 | for r in revs: | |
2617 | if r in seen: |
|
2620 | if r in seen: | |
2618 | continue |
|
2621 | continue | |
2619 | if ( |
|
2622 | if ( | |
2620 | r in subset |
|
2623 | r in subset | |
2621 | or r in _virtualrevs |
|
2624 | or r in _virtualrevs | |
2622 | and isinstance(subset, fullreposet) |
|
2625 | and isinstance(subset, fullreposet) | |
2623 | ): |
|
2626 | ): | |
2624 | ls.append(r) |
|
2627 | ls.append(r) | |
2625 | seen.add(r) |
|
2628 | seen.add(r) | |
2626 | return baseset(ls) |
|
2629 | return baseset(ls) | |
2627 |
|
2630 | |||
2628 |
|
2631 | |||
2629 | # for internal use |
|
2632 | # for internal use | |
2630 | @predicate(b'_list', safe=True, takeorder=True) |
|
2633 | @predicate(b'_list', safe=True, takeorder=True) | |
2631 | def _list(repo, subset, x, order): |
|
2634 | def _list(repo, subset, x, order): | |
2632 | if order == followorder: |
|
2635 | if order == followorder: | |
2633 | # slow path to take the subset order |
|
2636 | # slow path to take the subset order | |
2634 | return subset & _orderedlist(repo, fullreposet(repo), x) |
|
2637 | return subset & _orderedlist(repo, fullreposet(repo), x) | |
2635 | else: |
|
2638 | else: | |
2636 | return _orderedlist(repo, subset, x) |
|
2639 | return _orderedlist(repo, subset, x) | |
2637 |
|
2640 | |||
2638 |
|
2641 | |||
2639 | def _orderedintlist(repo, subset, x): |
|
2642 | def _orderedintlist(repo, subset, x): | |
2640 | s = getstring(x, b"internal error") |
|
2643 | s = getstring(x, b"internal error") | |
2641 | if not s: |
|
2644 | if not s: | |
2642 | return baseset() |
|
2645 | return baseset() | |
2643 | ls = [int(r) for r in s.split(b'\0')] |
|
2646 | ls = [int(r) for r in s.split(b'\0')] | |
2644 | s = subset |
|
2647 | s = subset | |
2645 | return baseset([r for r in ls if r in s]) |
|
2648 | return baseset([r for r in ls if r in s]) | |
2646 |
|
2649 | |||
2647 |
|
2650 | |||
2648 | # for internal use |
|
2651 | # for internal use | |
2649 | @predicate(b'_intlist', safe=True, takeorder=True, weight=0) |
|
2652 | @predicate(b'_intlist', safe=True, takeorder=True, weight=0) | |
2650 | def _intlist(repo, subset, x, order): |
|
2653 | def _intlist(repo, subset, x, order): | |
2651 | if order == followorder: |
|
2654 | if order == followorder: | |
2652 | # slow path to take the subset order |
|
2655 | # slow path to take the subset order | |
2653 | return subset & _orderedintlist(repo, fullreposet(repo), x) |
|
2656 | return subset & _orderedintlist(repo, fullreposet(repo), x) | |
2654 | else: |
|
2657 | else: | |
2655 | return _orderedintlist(repo, subset, x) |
|
2658 | return _orderedintlist(repo, subset, x) | |
2656 |
|
2659 | |||
2657 |
|
2660 | |||
2658 | def _orderedhexlist(repo, subset, x): |
|
2661 | def _orderedhexlist(repo, subset, x): | |
2659 | s = getstring(x, b"internal error") |
|
2662 | s = getstring(x, b"internal error") | |
2660 | if not s: |
|
2663 | if not s: | |
2661 | return baseset() |
|
2664 | return baseset() | |
2662 | cl = repo.changelog |
|
2665 | cl = repo.changelog | |
2663 | ls = [cl.rev(node.bin(r)) for r in s.split(b'\0')] |
|
2666 | ls = [cl.rev(node.bin(r)) for r in s.split(b'\0')] | |
2664 | s = subset |
|
2667 | s = subset | |
2665 | return baseset([r for r in ls if r in s]) |
|
2668 | return baseset([r for r in ls if r in s]) | |
2666 |
|
2669 | |||
2667 |
|
2670 | |||
2668 | # for internal use |
|
2671 | # for internal use | |
2669 | @predicate(b'_hexlist', safe=True, takeorder=True) |
|
2672 | @predicate(b'_hexlist', safe=True, takeorder=True) | |
2670 | def _hexlist(repo, subset, x, order): |
|
2673 | def _hexlist(repo, subset, x, order): | |
2671 | if order == followorder: |
|
2674 | if order == followorder: | |
2672 | # slow path to take the subset order |
|
2675 | # slow path to take the subset order | |
2673 | return subset & _orderedhexlist(repo, fullreposet(repo), x) |
|
2676 | return subset & _orderedhexlist(repo, fullreposet(repo), x) | |
2674 | else: |
|
2677 | else: | |
2675 | return _orderedhexlist(repo, subset, x) |
|
2678 | return _orderedhexlist(repo, subset, x) | |
2676 |
|
2679 | |||
2677 |
|
2680 | |||
2678 | methods = { |
|
2681 | methods = { | |
2679 | b"range": rangeset, |
|
2682 | b"range": rangeset, | |
2680 | b"rangeall": rangeall, |
|
2683 | b"rangeall": rangeall, | |
2681 | b"rangepre": rangepre, |
|
2684 | b"rangepre": rangepre, | |
2682 | b"rangepost": rangepost, |
|
2685 | b"rangepost": rangepost, | |
2683 | b"dagrange": dagrange, |
|
2686 | b"dagrange": dagrange, | |
2684 | b"string": stringset, |
|
2687 | b"string": stringset, | |
2685 | b"symbol": stringset, |
|
2688 | b"symbol": stringset, | |
2686 | b"and": andset, |
|
2689 | b"and": andset, | |
2687 | b"andsmally": andsmallyset, |
|
2690 | b"andsmally": andsmallyset, | |
2688 | b"or": orset, |
|
2691 | b"or": orset, | |
2689 | b"not": notset, |
|
2692 | b"not": notset, | |
2690 | b"difference": differenceset, |
|
2693 | b"difference": differenceset, | |
2691 | b"relation": relationset, |
|
2694 | b"relation": relationset, | |
2692 | b"relsubscript": relsubscriptset, |
|
2695 | b"relsubscript": relsubscriptset, | |
2693 | b"subscript": subscriptset, |
|
2696 | b"subscript": subscriptset, | |
2694 | b"list": listset, |
|
2697 | b"list": listset, | |
2695 | b"keyvalue": keyvaluepair, |
|
2698 | b"keyvalue": keyvaluepair, | |
2696 | b"func": func, |
|
2699 | b"func": func, | |
2697 | b"ancestor": ancestorspec, |
|
2700 | b"ancestor": ancestorspec, | |
2698 | b"parent": parentspec, |
|
2701 | b"parent": parentspec, | |
2699 | b"parentpost": parentpost, |
|
2702 | b"parentpost": parentpost, | |
2700 | b"smartset": rawsmartset, |
|
2703 | b"smartset": rawsmartset, | |
2701 | } |
|
2704 | } | |
2702 |
|
2705 | |||
2703 | relations = { |
|
2706 | relations = { | |
2704 | b"g": generationsrel, |
|
2707 | b"g": generationsrel, | |
2705 | b"generations": generationsrel, |
|
2708 | b"generations": generationsrel, | |
2706 | } |
|
2709 | } | |
2707 |
|
2710 | |||
2708 | subscriptrelations = { |
|
2711 | subscriptrelations = { | |
2709 | b"g": generationssubrel, |
|
2712 | b"g": generationssubrel, | |
2710 | b"generations": generationssubrel, |
|
2713 | b"generations": generationssubrel, | |
2711 | } |
|
2714 | } | |
2712 |
|
2715 | |||
2713 |
|
2716 | |||
2714 | def lookupfn(repo): |
|
2717 | def lookupfn(repo): | |
2715 | return lambda symbol: scmutil.isrevsymbol(repo, symbol) |
|
2718 | return lambda symbol: scmutil.isrevsymbol(repo, symbol) | |
2716 |
|
2719 | |||
2717 |
|
2720 | |||
2718 | def match(ui, spec, lookup=None): |
|
2721 | def match(ui, spec, lookup=None): | |
2719 | """Create a matcher for a single revision spec""" |
|
2722 | """Create a matcher for a single revision spec""" | |
2720 | return matchany(ui, [spec], lookup=lookup) |
|
2723 | return matchany(ui, [spec], lookup=lookup) | |
2721 |
|
2724 | |||
2722 |
|
2725 | |||
2723 | def matchany(ui, specs, lookup=None, localalias=None): |
|
2726 | def matchany(ui, specs, lookup=None, localalias=None): | |
2724 | """Create a matcher that will include any revisions matching one of the |
|
2727 | """Create a matcher that will include any revisions matching one of the | |
2725 | given specs |
|
2728 | given specs | |
2726 |
|
2729 | |||
2727 | If lookup function is not None, the parser will first attempt to handle |
|
2730 | If lookup function is not None, the parser will first attempt to handle | |
2728 | old-style ranges, which may contain operator characters. |
|
2731 | old-style ranges, which may contain operator characters. | |
2729 |
|
2732 | |||
2730 | If localalias is not None, it is a dict {name: definitionstring}. It takes |
|
2733 | If localalias is not None, it is a dict {name: definitionstring}. It takes | |
2731 | precedence over [revsetalias] config section. |
|
2734 | precedence over [revsetalias] config section. | |
2732 | """ |
|
2735 | """ | |
2733 | if not specs: |
|
2736 | if not specs: | |
2734 |
|
2737 | |||
2735 | def mfunc(repo, subset=None): |
|
2738 | def mfunc(repo, subset=None): | |
2736 | return baseset() |
|
2739 | return baseset() | |
2737 |
|
2740 | |||
2738 | return mfunc |
|
2741 | return mfunc | |
2739 | if not all(specs): |
|
2742 | if not all(specs): | |
2740 | raise error.ParseError(_(b"empty query")) |
|
2743 | raise error.ParseError(_(b"empty query")) | |
2741 | if len(specs) == 1: |
|
2744 | if len(specs) == 1: | |
2742 | tree = revsetlang.parse(specs[0], lookup) |
|
2745 | tree = revsetlang.parse(specs[0], lookup) | |
2743 | else: |
|
2746 | else: | |
2744 | tree = ( |
|
2747 | tree = ( | |
2745 | b'or', |
|
2748 | b'or', | |
2746 | (b'list',) + tuple(revsetlang.parse(s, lookup) for s in specs), |
|
2749 | (b'list',) + tuple(revsetlang.parse(s, lookup) for s in specs), | |
2747 | ) |
|
2750 | ) | |
2748 |
|
2751 | |||
2749 | aliases = [] |
|
2752 | aliases = [] | |
2750 | warn = None |
|
2753 | warn = None | |
2751 | if ui: |
|
2754 | if ui: | |
2752 | aliases.extend(ui.configitems(b'revsetalias')) |
|
2755 | aliases.extend(ui.configitems(b'revsetalias')) | |
2753 | warn = ui.warn |
|
2756 | warn = ui.warn | |
2754 | if localalias: |
|
2757 | if localalias: | |
2755 | aliases.extend(localalias.items()) |
|
2758 | aliases.extend(localalias.items()) | |
2756 | if aliases: |
|
2759 | if aliases: | |
2757 | tree = revsetlang.expandaliases(tree, aliases, warn=warn) |
|
2760 | tree = revsetlang.expandaliases(tree, aliases, warn=warn) | |
2758 | tree = revsetlang.foldconcat(tree) |
|
2761 | tree = revsetlang.foldconcat(tree) | |
2759 | tree = revsetlang.analyze(tree) |
|
2762 | tree = revsetlang.analyze(tree) | |
2760 | tree = revsetlang.optimize(tree) |
|
2763 | tree = revsetlang.optimize(tree) | |
2761 | return makematcher(tree) |
|
2764 | return makematcher(tree) | |
2762 |
|
2765 | |||
2763 |
|
2766 | |||
2764 | def makematcher(tree): |
|
2767 | def makematcher(tree): | |
2765 | """Create a matcher from an evaluatable tree""" |
|
2768 | """Create a matcher from an evaluatable tree""" | |
2766 |
|
2769 | |||
2767 | def mfunc(repo, subset=None, order=None): |
|
2770 | def mfunc(repo, subset=None, order=None): | |
2768 | if order is None: |
|
2771 | if order is None: | |
2769 | if subset is None: |
|
2772 | if subset is None: | |
2770 | order = defineorder # 'x' |
|
2773 | order = defineorder # 'x' | |
2771 | else: |
|
2774 | else: | |
2772 | order = followorder # 'subset & x' |
|
2775 | order = followorder # 'subset & x' | |
2773 | if subset is None: |
|
2776 | if subset is None: | |
2774 | subset = fullreposet(repo) |
|
2777 | subset = fullreposet(repo) | |
2775 | return getset(repo, subset, tree, order) |
|
2778 | return getset(repo, subset, tree, order) | |
2776 |
|
2779 | |||
2777 | return mfunc |
|
2780 | return mfunc | |
2778 |
|
2781 | |||
2779 |
|
2782 | |||
2780 | def loadpredicate(ui, extname, registrarobj): |
|
2783 | def loadpredicate(ui, extname, registrarobj): | |
2781 | """Load revset predicates from specified registrarobj |
|
2784 | """Load revset predicates from specified registrarobj | |
2782 | """ |
|
2785 | """ | |
2783 | for name, func in pycompat.iteritems(registrarobj._table): |
|
2786 | for name, func in pycompat.iteritems(registrarobj._table): | |
2784 | symbols[name] = func |
|
2787 | symbols[name] = func | |
2785 | if func._safe: |
|
2788 | if func._safe: | |
2786 | safesymbols.add(name) |
|
2789 | safesymbols.add(name) | |
2787 |
|
2790 | |||
2788 |
|
2791 | |||
2789 | # load built-in predicates explicitly to setup safesymbols |
|
2792 | # load built-in predicates explicitly to setup safesymbols | |
2790 | loadpredicate(None, None, predicate) |
|
2793 | loadpredicate(None, None, predicate) | |
2791 |
|
2794 | |||
2792 | # tell hggettext to extract docstrings from these functions: |
|
2795 | # tell hggettext to extract docstrings from these functions: | |
2793 | i18nfunctions = symbols.values() |
|
2796 | i18nfunctions = symbols.values() |
@@ -1,26 +1,29 b'' | |||||
1 | == New Features == |
|
1 | == New Features == | |
2 |
|
2 | |||
3 | * `hg mv -A` can now be used with `--at-rev`. It behaves just like |
|
3 | * `hg mv -A` can now be used with `--at-rev`. It behaves just like | |
4 | `hg cp -A --at-rev`, i.e. it marks the destination as a copy of the |
|
4 | `hg cp -A --at-rev`, i.e. it marks the destination as a copy of the | |
5 | source whether or not the source still exists (but the source must |
|
5 | source whether or not the source still exists (but the source must | |
6 | exist in the parent revision). |
|
6 | exist in the parent revision). | |
7 |
|
7 | |||
|
8 | * New revset predicate `diffcontains(pattern)` for filtering revisions | |||
|
9 | in the same way as `hg grep --diff pattern`. | |||
|
10 | ||||
8 |
|
11 | |||
9 | == New Experimental Features == |
|
12 | == New Experimental Features == | |
10 |
|
13 | |||
11 |
|
14 | |||
12 |
|
15 | |||
13 | == Bug Fixes == |
|
16 | == Bug Fixes == | |
14 |
|
17 | |||
15 |
|
18 | |||
16 |
|
19 | |||
17 | == Backwards Compatibility Changes == |
|
20 | == Backwards Compatibility Changes == | |
18 |
|
21 | |||
19 |
|
22 | |||
20 |
|
23 | |||
21 | == Internal API Changes == |
|
24 | == Internal API Changes == | |
22 |
|
25 | |||
23 | * `merge.update()` is now private (renamed to `_update()`). Hopefully |
|
26 | * `merge.update()` is now private (renamed to `_update()`). Hopefully | |
24 | the higher-level functions available in the same module cover your |
|
27 | the higher-level functions available in the same module cover your | |
25 | use cases. |
|
28 | use cases. | |
26 |
|
29 |
@@ -1,108 +1,108 b'' | |||||
1 | ROOT = CWD + "/../.." |
|
1 | ROOT = CWD + "/../.." | |
2 |
|
2 | |||
3 | IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE |
|
3 | IS_WINDOWS = "windows" in BUILD_TARGET_TRIPLE | |
4 |
|
4 | |||
5 | # Code to run in Python interpreter. |
|
5 | # Code to run in Python interpreter. | |
6 | RUN_CODE = "import hgdemandimport; hgdemandimport.enable(); from mercurial import dispatch; dispatch.run()" |
|
6 | RUN_CODE = "import hgdemandimport; hgdemandimport.enable(); from mercurial import dispatch; dispatch.run()" | |
7 |
|
7 | |||
8 | set_build_path(ROOT + "/build/pyoxidizer") |
|
8 | set_build_path(ROOT + "/build/pyoxidizer") | |
9 |
|
9 | |||
10 | def make_distribution(): |
|
10 | def make_distribution(): | |
11 | return default_python_distribution() |
|
11 | return default_python_distribution() | |
12 |
|
12 | |||
13 | def make_distribution_windows(): |
|
13 | def make_distribution_windows(): | |
14 | return default_python_distribution(flavor = "standalone_dynamic") |
|
14 | return default_python_distribution(flavor = "standalone_dynamic") | |
15 |
|
15 | |||
16 | def resource_callback(policy, resource): |
|
16 | def resource_callback(policy, resource): | |
17 | # We use a custom resource routing policy to influence where things are loaded |
|
17 | # We use a custom resource routing policy to influence where things are loaded | |
18 | # from. |
|
18 | # from. | |
19 | # |
|
19 | # | |
20 | # For Python modules and resources, we load from memory if they are in |
|
20 | # For Python modules and resources, we load from memory if they are in | |
21 | # the standard library and from the filesystem if not. This is because |
|
21 | # the standard library and from the filesystem if not. This is because | |
22 | # parts of Mercurial and some 3rd party packages aren't yet compatible |
|
22 | # parts of Mercurial and some 3rd party packages aren't yet compatible | |
23 | # with memory loading. |
|
23 | # with memory loading. | |
24 | # |
|
24 | # | |
25 | # For Python extension modules, we load from the filesystem because |
|
25 | # For Python extension modules, we load from the filesystem because | |
26 | # this yields greatest compatibility. |
|
26 | # this yields greatest compatibility. | |
27 | if type(resource) in ("PythonModuleSource", "PythonPackageResource", "PythonPackageDistributionResource"): |
|
27 | if type(resource) in ("PythonModuleSource", "PythonPackageResource", "PythonPackageDistributionResource"): | |
28 | if resource.is_stdlib: |
|
28 | if resource.is_stdlib: | |
29 | resource.add_location = "in-memory" |
|
29 | resource.add_location = "in-memory" | |
30 | else: |
|
30 | else: | |
31 | resource.add_location = "filesystem-relative:lib" |
|
31 | resource.add_location = "filesystem-relative:lib" | |
32 |
|
32 | |||
33 | elif type(resource) == "PythonExtensionModule": |
|
33 | elif type(resource) == "PythonExtensionModule": | |
34 | resource.add_location = "filesystem-relative:lib" |
|
34 | resource.add_location = "filesystem-relative:lib" | |
35 |
|
35 | |||
36 | def make_exe(dist): |
|
36 | def make_exe(dist): | |
37 | """Builds a Rust-wrapped Mercurial binary.""" |
|
37 | """Builds a Rust-wrapped Mercurial binary.""" | |
38 | packaging_policy = dist.make_python_packaging_policy() |
|
38 | packaging_policy = dist.make_python_packaging_policy() | |
39 | # Extension may depend on any Python functionality. Include all |
|
39 | # Extension may depend on any Python functionality. Include all | |
40 | # extensions. |
|
40 | # extensions. | |
41 | packaging_policy.extension_module_filter = "all" |
|
41 | packaging_policy.extension_module_filter = "all" | |
42 |
packaging_policy.resources_ |
|
42 | packaging_policy.resources_location = "in-memory" | |
|
43 | packaging_policy.resources_location_fallback = "filesystem-relative:lib" | |||
43 | packaging_policy.register_resource_callback(resource_callback) |
|
44 | packaging_policy.register_resource_callback(resource_callback) | |
44 |
|
45 | |||
45 |
config = |
|
46 | config = dist.make_python_interpreter_config() | |
46 |
|
|
47 | config.raw_allocator = "system" | |
47 |
|
|
48 | config.run_mode = "eval:%s" % RUN_CODE | |
48 |
|
|
49 | # We want to let the user load extensions from the file system | |
49 |
|
|
50 | config.filesystem_importer = True | |
50 |
|
|
51 | # We need this to make resourceutil happy, since it looks for sys.frozen. | |
51 |
|
|
52 | config.sys_frozen = True | |
52 |
|
|
53 | config.legacy_windows_stdio = True | |
53 | ) |
|
|||
54 |
|
54 | |||
55 | exe = dist.to_python_executable( |
|
55 | exe = dist.to_python_executable( | |
56 | name = "hg", |
|
56 | name = "hg", | |
57 | packaging_policy = packaging_policy, |
|
57 | packaging_policy = packaging_policy, | |
58 | config = config, |
|
58 | config = config, | |
59 | ) |
|
59 | ) | |
60 |
|
60 | |||
61 | # Add Mercurial to resources. |
|
61 | # Add Mercurial to resources. | |
62 | exe.add_python_resources(exe.pip_install(["--verbose", ROOT])) |
|
62 | exe.add_python_resources(exe.pip_install(["--verbose", ROOT])) | |
63 |
|
63 | |||
64 | # On Windows, we install extra packages for convenience. |
|
64 | # On Windows, we install extra packages for convenience. | |
65 | if IS_WINDOWS: |
|
65 | if IS_WINDOWS: | |
66 | exe.add_python_resources( |
|
66 | exe.add_python_resources( | |
67 |
exe.pip_install(["-r", ROOT + "/contrib/packaging/requirements |
|
67 | exe.pip_install(["-r", ROOT + "/contrib/packaging/requirements-windows-py2.txt"]), | |
68 | ) |
|
68 | ) | |
69 |
|
69 | |||
70 | return exe |
|
70 | return exe | |
71 |
|
71 | |||
72 | def make_manifest(dist, exe): |
|
72 | def make_manifest(dist, exe): | |
73 | m = FileManifest() |
|
73 | m = FileManifest() | |
74 | m.add_python_resource(".", exe) |
|
74 | m.add_python_resource(".", exe) | |
75 |
|
75 | |||
76 | return m |
|
76 | return m | |
77 |
|
77 | |||
78 | def make_embedded_resources(exe): |
|
78 | def make_embedded_resources(exe): | |
79 | return exe.to_embedded_resources() |
|
79 | return exe.to_embedded_resources() | |
80 |
|
80 | |||
81 | register_target("distribution_posix", make_distribution) |
|
81 | register_target("distribution_posix", make_distribution) | |
82 | register_target("distribution_windows", make_distribution_windows) |
|
82 | register_target("distribution_windows", make_distribution_windows) | |
83 |
|
83 | |||
84 | register_target("exe_posix", make_exe, depends = ["distribution_posix"]) |
|
84 | register_target("exe_posix", make_exe, depends = ["distribution_posix"]) | |
85 | register_target("exe_windows", make_exe, depends = ["distribution_windows"]) |
|
85 | register_target("exe_windows", make_exe, depends = ["distribution_windows"]) | |
86 |
|
86 | |||
87 | register_target( |
|
87 | register_target( | |
88 | "app_posix", |
|
88 | "app_posix", | |
89 | make_manifest, |
|
89 | make_manifest, | |
90 | depends = ["distribution_posix", "exe_posix"], |
|
90 | depends = ["distribution_posix", "exe_posix"], | |
91 | default = "windows" not in BUILD_TARGET_TRIPLE, |
|
91 | default = "windows" not in BUILD_TARGET_TRIPLE, | |
92 | ) |
|
92 | ) | |
93 | register_target( |
|
93 | register_target( | |
94 | "app_windows", |
|
94 | "app_windows", | |
95 | make_manifest, |
|
95 | make_manifest, | |
96 | depends = ["distribution_windows", "exe_windows"], |
|
96 | depends = ["distribution_windows", "exe_windows"], | |
97 | default = "windows" in BUILD_TARGET_TRIPLE, |
|
97 | default = "windows" in BUILD_TARGET_TRIPLE, | |
98 | ) |
|
98 | ) | |
99 |
|
99 | |||
100 | resolve_targets() |
|
100 | resolve_targets() | |
101 |
|
101 | |||
102 | # END OF COMMON USER-ADJUSTED SETTINGS. |
|
102 | # END OF COMMON USER-ADJUSTED SETTINGS. | |
103 | # |
|
103 | # | |
104 | # Everything below this is typically managed by PyOxidizer and doesn't need |
|
104 | # Everything below this is typically managed by PyOxidizer and doesn't need | |
105 | # to be updated by people. |
|
105 | # to be updated by people. | |
106 |
|
106 | |||
107 |
PYOXIDIZER_VERSION = "0. |
|
107 | PYOXIDIZER_VERSION = "0.9.0" | |
108 | PYOXIDIZER_COMMIT = "4697fb25918dfad6dc73288daeea501063963a08" |
|
108 | PYOXIDIZER_COMMIT = "1fbc264cc004226cd76ee452e0a386ffca6ccfb1" |
@@ -1,1464 +1,1464 b'' | |||||
1 | $ hg init t |
|
1 | $ hg init t | |
2 | $ cd t |
|
2 | $ cd t | |
3 | $ echo import > port |
|
3 | $ echo import > port | |
4 | $ hg add port |
|
4 | $ hg add port | |
5 | $ hg commit -m 0 -u spam -d '0 0' |
|
5 | $ hg commit -m 0 -u spam -d '0 0' | |
6 | $ echo export >> port |
|
6 | $ echo export >> port | |
7 | $ hg commit -m 1 -u eggs -d '1 0' |
|
7 | $ hg commit -m 1 -u eggs -d '1 0' | |
8 | $ echo export > port |
|
8 | $ echo export > port | |
9 | $ echo vaportight >> port |
|
9 | $ echo vaportight >> port | |
10 | $ echo 'import/export' >> port |
|
10 | $ echo 'import/export' >> port | |
11 | $ hg commit -m 2 -u spam -d '2 0' |
|
11 | $ hg commit -m 2 -u spam -d '2 0' | |
12 | $ echo 'import/export' >> port |
|
12 | $ echo 'import/export' >> port | |
13 | $ hg commit -m 3 -u eggs -d '3 0' |
|
13 | $ hg commit -m 3 -u eggs -d '3 0' | |
14 | $ head -n 3 port > port1 |
|
14 | $ head -n 3 port > port1 | |
15 | $ mv port1 port |
|
15 | $ mv port1 port | |
16 | $ hg commit -m 4 -u spam -d '4 0' |
|
16 | $ hg commit -m 4 -u spam -d '4 0' | |
17 |
|
17 | |||
18 | pattern error |
|
18 | pattern error | |
19 |
|
19 | |||
20 | $ hg grep '**test**' |
|
20 | $ hg grep '**test**' | |
21 | grep: invalid match pattern: nothing to repeat* (glob) |
|
21 | grep: invalid match pattern: nothing to repeat* (glob) | |
22 | [1] |
|
22 | [1] | |
23 |
|
23 | |||
24 | invalid revset syntax |
|
24 | invalid revset syntax | |
25 |
|
25 | |||
26 | $ hg log -r 'diff()' |
|
26 | $ hg log -r 'diffcontains()' | |
27 | hg: parse error: diff takes at least 1 argument |
|
27 | hg: parse error: diffcontains takes at least 1 argument | |
28 | [255] |
|
28 | [255] | |
29 | $ hg log -r 'diff(:)' |
|
29 | $ hg log -r 'diffcontains(:)' | |
30 | hg: parse error: diff requires a string pattern |
|
30 | hg: parse error: diffcontains requires a string pattern | |
31 | [255] |
|
31 | [255] | |
32 | $ hg log -r 'diff("re:**test**")' |
|
32 | $ hg log -r 'diffcontains("re:**test**")' | |
33 | hg: parse error: invalid regular expression: nothing to repeat* (glob) |
|
33 | hg: parse error: invalid regular expression: nothing to repeat* (glob) | |
34 | [255] |
|
34 | [255] | |
35 |
|
35 | |||
36 | simple |
|
36 | simple | |
37 |
|
37 | |||
38 | $ hg grep -r tip:0 '.*' |
|
38 | $ hg grep -r tip:0 '.*' | |
39 | port:4:export |
|
39 | port:4:export | |
40 | port:4:vaportight |
|
40 | port:4:vaportight | |
41 | port:4:import/export |
|
41 | port:4:import/export | |
42 | port:3:export |
|
42 | port:3:export | |
43 | port:3:vaportight |
|
43 | port:3:vaportight | |
44 | port:3:import/export |
|
44 | port:3:import/export | |
45 | port:3:import/export |
|
45 | port:3:import/export | |
46 | port:2:export |
|
46 | port:2:export | |
47 | port:2:vaportight |
|
47 | port:2:vaportight | |
48 | port:2:import/export |
|
48 | port:2:import/export | |
49 | port:1:import |
|
49 | port:1:import | |
50 | port:1:export |
|
50 | port:1:export | |
51 | port:0:import |
|
51 | port:0:import | |
52 | $ hg grep -r tip:0 port port |
|
52 | $ hg grep -r tip:0 port port | |
53 | port:4:export |
|
53 | port:4:export | |
54 | port:4:vaportight |
|
54 | port:4:vaportight | |
55 | port:4:import/export |
|
55 | port:4:import/export | |
56 | port:3:export |
|
56 | port:3:export | |
57 | port:3:vaportight |
|
57 | port:3:vaportight | |
58 | port:3:import/export |
|
58 | port:3:import/export | |
59 | port:3:import/export |
|
59 | port:3:import/export | |
60 | port:2:export |
|
60 | port:2:export | |
61 | port:2:vaportight |
|
61 | port:2:vaportight | |
62 | port:2:import/export |
|
62 | port:2:import/export | |
63 | port:1:import |
|
63 | port:1:import | |
64 | port:1:export |
|
64 | port:1:export | |
65 | port:0:import |
|
65 | port:0:import | |
66 |
|
66 | |||
67 | simple from subdirectory |
|
67 | simple from subdirectory | |
68 |
|
68 | |||
69 | $ mkdir dir |
|
69 | $ mkdir dir | |
70 | $ cd dir |
|
70 | $ cd dir | |
71 | $ hg grep -r tip:0 port |
|
71 | $ hg grep -r tip:0 port | |
72 | port:4:export |
|
72 | port:4:export | |
73 | port:4:vaportight |
|
73 | port:4:vaportight | |
74 | port:4:import/export |
|
74 | port:4:import/export | |
75 | port:3:export |
|
75 | port:3:export | |
76 | port:3:vaportight |
|
76 | port:3:vaportight | |
77 | port:3:import/export |
|
77 | port:3:import/export | |
78 | port:3:import/export |
|
78 | port:3:import/export | |
79 | port:2:export |
|
79 | port:2:export | |
80 | port:2:vaportight |
|
80 | port:2:vaportight | |
81 | port:2:import/export |
|
81 | port:2:import/export | |
82 | port:1:import |
|
82 | port:1:import | |
83 | port:1:export |
|
83 | port:1:export | |
84 | port:0:import |
|
84 | port:0:import | |
85 | $ hg grep -r tip:0 port --config ui.relative-paths=yes |
|
85 | $ hg grep -r tip:0 port --config ui.relative-paths=yes | |
86 | ../port:4:export |
|
86 | ../port:4:export | |
87 | ../port:4:vaportight |
|
87 | ../port:4:vaportight | |
88 | ../port:4:import/export |
|
88 | ../port:4:import/export | |
89 | ../port:3:export |
|
89 | ../port:3:export | |
90 | ../port:3:vaportight |
|
90 | ../port:3:vaportight | |
91 | ../port:3:import/export |
|
91 | ../port:3:import/export | |
92 | ../port:3:import/export |
|
92 | ../port:3:import/export | |
93 | ../port:2:export |
|
93 | ../port:2:export | |
94 | ../port:2:vaportight |
|
94 | ../port:2:vaportight | |
95 | ../port:2:import/export |
|
95 | ../port:2:import/export | |
96 | ../port:1:import |
|
96 | ../port:1:import | |
97 | ../port:1:export |
|
97 | ../port:1:export | |
98 | ../port:0:import |
|
98 | ../port:0:import | |
99 | $ cd .. |
|
99 | $ cd .. | |
100 |
|
100 | |||
101 | simple with color |
|
101 | simple with color | |
102 |
|
102 | |||
103 | $ hg --config extensions.color= grep --config color.mode=ansi \ |
|
103 | $ hg --config extensions.color= grep --config color.mode=ansi \ | |
104 | > --color=always port port -r tip:0 |
|
104 | > --color=always port port -r tip:0 | |
105 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) |
|
105 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m4\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) | |
106 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc) |
|
106 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m4\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc) | |
107 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) |
|
107 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m4\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) | |
108 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) |
|
108 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) | |
109 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc) |
|
109 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc) | |
110 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) |
|
110 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) | |
111 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) |
|
111 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) | |
112 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) |
|
112 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) | |
113 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc) |
|
113 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0mva\x1b[0;31;1mport\x1b[0might (esc) | |
114 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) |
|
114 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m/ex\x1b[0;31;1mport\x1b[0m (esc) | |
115 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m1\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m (esc) |
|
115 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m1\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m (esc) | |
116 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m1\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) |
|
116 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m1\x1b[0m\x1b[0;36m:\x1b[0mex\x1b[0;31;1mport\x1b[0m (esc) | |
117 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m0\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m (esc) |
|
117 | \x1b[0;35mport\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m0\x1b[0m\x1b[0;36m:\x1b[0mim\x1b[0;31;1mport\x1b[0m (esc) | |
118 |
|
118 | |||
119 | simple templated |
|
119 | simple templated | |
120 |
|
120 | |||
121 | $ hg grep port -r tip:0 \ |
|
121 | $ hg grep port -r tip:0 \ | |
122 | > -T '{path}:{rev}:{node|short}:{texts % "{if(matched, text|upper, text)}"}\n' |
|
122 | > -T '{path}:{rev}:{node|short}:{texts % "{if(matched, text|upper, text)}"}\n' | |
123 | port:4:914fa752cdea:exPORT |
|
123 | port:4:914fa752cdea:exPORT | |
124 | port:4:914fa752cdea:vaPORTight |
|
124 | port:4:914fa752cdea:vaPORTight | |
125 | port:4:914fa752cdea:imPORT/exPORT |
|
125 | port:4:914fa752cdea:imPORT/exPORT | |
126 | port:3:95040cfd017d:exPORT |
|
126 | port:3:95040cfd017d:exPORT | |
127 | port:3:95040cfd017d:vaPORTight |
|
127 | port:3:95040cfd017d:vaPORTight | |
128 | port:3:95040cfd017d:imPORT/exPORT |
|
128 | port:3:95040cfd017d:imPORT/exPORT | |
129 | port:3:95040cfd017d:imPORT/exPORT |
|
129 | port:3:95040cfd017d:imPORT/exPORT | |
130 | port:2:3b325e3481a1:exPORT |
|
130 | port:2:3b325e3481a1:exPORT | |
131 | port:2:3b325e3481a1:vaPORTight |
|
131 | port:2:3b325e3481a1:vaPORTight | |
132 | port:2:3b325e3481a1:imPORT/exPORT |
|
132 | port:2:3b325e3481a1:imPORT/exPORT | |
133 | port:1:8b20f75c1585:imPORT |
|
133 | port:1:8b20f75c1585:imPORT | |
134 | port:1:8b20f75c1585:exPORT |
|
134 | port:1:8b20f75c1585:exPORT | |
135 | port:0:f31323c92170:imPORT |
|
135 | port:0:f31323c92170:imPORT | |
136 |
|
136 | |||
137 | $ hg grep port -r tip:0 -T '{path}:{rev}:{texts}\n' |
|
137 | $ hg grep port -r tip:0 -T '{path}:{rev}:{texts}\n' | |
138 | port:4:export |
|
138 | port:4:export | |
139 | port:4:vaportight |
|
139 | port:4:vaportight | |
140 | port:4:import/export |
|
140 | port:4:import/export | |
141 | port:3:export |
|
141 | port:3:export | |
142 | port:3:vaportight |
|
142 | port:3:vaportight | |
143 | port:3:import/export |
|
143 | port:3:import/export | |
144 | port:3:import/export |
|
144 | port:3:import/export | |
145 | port:2:export |
|
145 | port:2:export | |
146 | port:2:vaportight |
|
146 | port:2:vaportight | |
147 | port:2:import/export |
|
147 | port:2:import/export | |
148 | port:1:import |
|
148 | port:1:import | |
149 | port:1:export |
|
149 | port:1:export | |
150 | port:0:import |
|
150 | port:0:import | |
151 |
|
151 | |||
152 | $ hg grep port -r tip:0 -T '{path}:{tags}:{texts}\n' |
|
152 | $ hg grep port -r tip:0 -T '{path}:{tags}:{texts}\n' | |
153 | port:tip:export |
|
153 | port:tip:export | |
154 | port:tip:vaportight |
|
154 | port:tip:vaportight | |
155 | port:tip:import/export |
|
155 | port:tip:import/export | |
156 | port::export |
|
156 | port::export | |
157 | port::vaportight |
|
157 | port::vaportight | |
158 | port::import/export |
|
158 | port::import/export | |
159 | port::import/export |
|
159 | port::import/export | |
160 | port::export |
|
160 | port::export | |
161 | port::vaportight |
|
161 | port::vaportight | |
162 | port::import/export |
|
162 | port::import/export | |
163 | port::import |
|
163 | port::import | |
164 | port::export |
|
164 | port::export | |
165 | port::import |
|
165 | port::import | |
166 |
|
166 | |||
167 | simple JSON (no "change" field) |
|
167 | simple JSON (no "change" field) | |
168 |
|
168 | |||
169 | $ hg grep -r tip:0 -Tjson port |
|
169 | $ hg grep -r tip:0 -Tjson port | |
170 | [ |
|
170 | [ | |
171 | { |
|
171 | { | |
172 | "date": [4, 0], |
|
172 | "date": [4, 0], | |
173 | "lineno": 1, |
|
173 | "lineno": 1, | |
174 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", |
|
174 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", | |
175 | "path": "port", |
|
175 | "path": "port", | |
176 | "rev": 4, |
|
176 | "rev": 4, | |
177 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], |
|
177 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], | |
178 | "user": "spam" |
|
178 | "user": "spam" | |
179 | }, |
|
179 | }, | |
180 | { |
|
180 | { | |
181 | "date": [4, 0], |
|
181 | "date": [4, 0], | |
182 | "lineno": 2, |
|
182 | "lineno": 2, | |
183 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", |
|
183 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", | |
184 | "path": "port", |
|
184 | "path": "port", | |
185 | "rev": 4, |
|
185 | "rev": 4, | |
186 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], |
|
186 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], | |
187 | "user": "spam" |
|
187 | "user": "spam" | |
188 | }, |
|
188 | }, | |
189 | { |
|
189 | { | |
190 | "date": [4, 0], |
|
190 | "date": [4, 0], | |
191 | "lineno": 3, |
|
191 | "lineno": 3, | |
192 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", |
|
192 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", | |
193 | "path": "port", |
|
193 | "path": "port", | |
194 | "rev": 4, |
|
194 | "rev": 4, | |
195 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
195 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
196 | "user": "spam" |
|
196 | "user": "spam" | |
197 | }, |
|
197 | }, | |
198 | { |
|
198 | { | |
199 | "date": [3, 0], |
|
199 | "date": [3, 0], | |
200 | "lineno": 1, |
|
200 | "lineno": 1, | |
201 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", |
|
201 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", | |
202 | "path": "port", |
|
202 | "path": "port", | |
203 | "rev": 3, |
|
203 | "rev": 3, | |
204 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], |
|
204 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], | |
205 | "user": "eggs" |
|
205 | "user": "eggs" | |
206 | }, |
|
206 | }, | |
207 | { |
|
207 | { | |
208 | "date": [3, 0], |
|
208 | "date": [3, 0], | |
209 | "lineno": 2, |
|
209 | "lineno": 2, | |
210 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", |
|
210 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", | |
211 | "path": "port", |
|
211 | "path": "port", | |
212 | "rev": 3, |
|
212 | "rev": 3, | |
213 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], |
|
213 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], | |
214 | "user": "eggs" |
|
214 | "user": "eggs" | |
215 | }, |
|
215 | }, | |
216 | { |
|
216 | { | |
217 | "date": [3, 0], |
|
217 | "date": [3, 0], | |
218 | "lineno": 3, |
|
218 | "lineno": 3, | |
219 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", |
|
219 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", | |
220 | "path": "port", |
|
220 | "path": "port", | |
221 | "rev": 3, |
|
221 | "rev": 3, | |
222 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
222 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
223 | "user": "eggs" |
|
223 | "user": "eggs" | |
224 | }, |
|
224 | }, | |
225 | { |
|
225 | { | |
226 | "date": [3, 0], |
|
226 | "date": [3, 0], | |
227 | "lineno": 4, |
|
227 | "lineno": 4, | |
228 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", |
|
228 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", | |
229 | "path": "port", |
|
229 | "path": "port", | |
230 | "rev": 3, |
|
230 | "rev": 3, | |
231 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
231 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
232 | "user": "eggs" |
|
232 | "user": "eggs" | |
233 | }, |
|
233 | }, | |
234 | { |
|
234 | { | |
235 | "date": [2, 0], |
|
235 | "date": [2, 0], | |
236 | "lineno": 1, |
|
236 | "lineno": 1, | |
237 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
237 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
238 | "path": "port", |
|
238 | "path": "port", | |
239 | "rev": 2, |
|
239 | "rev": 2, | |
240 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], |
|
240 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], | |
241 | "user": "spam" |
|
241 | "user": "spam" | |
242 | }, |
|
242 | }, | |
243 | { |
|
243 | { | |
244 | "date": [2, 0], |
|
244 | "date": [2, 0], | |
245 | "lineno": 2, |
|
245 | "lineno": 2, | |
246 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
246 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
247 | "path": "port", |
|
247 | "path": "port", | |
248 | "rev": 2, |
|
248 | "rev": 2, | |
249 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], |
|
249 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], | |
250 | "user": "spam" |
|
250 | "user": "spam" | |
251 | }, |
|
251 | }, | |
252 | { |
|
252 | { | |
253 | "date": [2, 0], |
|
253 | "date": [2, 0], | |
254 | "lineno": 3, |
|
254 | "lineno": 3, | |
255 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
255 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
256 | "path": "port", |
|
256 | "path": "port", | |
257 | "rev": 2, |
|
257 | "rev": 2, | |
258 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
258 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
259 | "user": "spam" |
|
259 | "user": "spam" | |
260 | }, |
|
260 | }, | |
261 | { |
|
261 | { | |
262 | "date": [1, 0], |
|
262 | "date": [1, 0], | |
263 | "lineno": 1, |
|
263 | "lineno": 1, | |
264 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", |
|
264 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", | |
265 | "path": "port", |
|
265 | "path": "port", | |
266 | "rev": 1, |
|
266 | "rev": 1, | |
267 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], |
|
267 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], | |
268 | "user": "eggs" |
|
268 | "user": "eggs" | |
269 | }, |
|
269 | }, | |
270 | { |
|
270 | { | |
271 | "date": [1, 0], |
|
271 | "date": [1, 0], | |
272 | "lineno": 2, |
|
272 | "lineno": 2, | |
273 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", |
|
273 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", | |
274 | "path": "port", |
|
274 | "path": "port", | |
275 | "rev": 1, |
|
275 | "rev": 1, | |
276 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], |
|
276 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], | |
277 | "user": "eggs" |
|
277 | "user": "eggs" | |
278 | }, |
|
278 | }, | |
279 | { |
|
279 | { | |
280 | "date": [0, 0], |
|
280 | "date": [0, 0], | |
281 | "lineno": 1, |
|
281 | "lineno": 1, | |
282 | "node": "f31323c9217050ba245ee8b537c713ec2e8ab226", |
|
282 | "node": "f31323c9217050ba245ee8b537c713ec2e8ab226", | |
283 | "path": "port", |
|
283 | "path": "port", | |
284 | "rev": 0, |
|
284 | "rev": 0, | |
285 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], |
|
285 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], | |
286 | "user": "spam" |
|
286 | "user": "spam" | |
287 | } |
|
287 | } | |
288 | ] |
|
288 | ] | |
289 |
|
289 | |||
290 | simple JSON without matching lines |
|
290 | simple JSON without matching lines | |
291 |
|
291 | |||
292 | $ hg grep -r tip:0 -Tjson -l port |
|
292 | $ hg grep -r tip:0 -Tjson -l port | |
293 | [ |
|
293 | [ | |
294 | { |
|
294 | { | |
295 | "date": [4, 0], |
|
295 | "date": [4, 0], | |
296 | "lineno": 1, |
|
296 | "lineno": 1, | |
297 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", |
|
297 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", | |
298 | "path": "port", |
|
298 | "path": "port", | |
299 | "rev": 4, |
|
299 | "rev": 4, | |
300 | "user": "spam" |
|
300 | "user": "spam" | |
301 | }, |
|
301 | }, | |
302 | { |
|
302 | { | |
303 | "date": [3, 0], |
|
303 | "date": [3, 0], | |
304 | "lineno": 1, |
|
304 | "lineno": 1, | |
305 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", |
|
305 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", | |
306 | "path": "port", |
|
306 | "path": "port", | |
307 | "rev": 3, |
|
307 | "rev": 3, | |
308 | "user": "eggs" |
|
308 | "user": "eggs" | |
309 | }, |
|
309 | }, | |
310 | { |
|
310 | { | |
311 | "date": [2, 0], |
|
311 | "date": [2, 0], | |
312 | "lineno": 1, |
|
312 | "lineno": 1, | |
313 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
313 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
314 | "path": "port", |
|
314 | "path": "port", | |
315 | "rev": 2, |
|
315 | "rev": 2, | |
316 | "user": "spam" |
|
316 | "user": "spam" | |
317 | }, |
|
317 | }, | |
318 | { |
|
318 | { | |
319 | "date": [1, 0], |
|
319 | "date": [1, 0], | |
320 | "lineno": 1, |
|
320 | "lineno": 1, | |
321 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", |
|
321 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", | |
322 | "path": "port", |
|
322 | "path": "port", | |
323 | "rev": 1, |
|
323 | "rev": 1, | |
324 | "user": "eggs" |
|
324 | "user": "eggs" | |
325 | }, |
|
325 | }, | |
326 | { |
|
326 | { | |
327 | "date": [0, 0], |
|
327 | "date": [0, 0], | |
328 | "lineno": 1, |
|
328 | "lineno": 1, | |
329 | "node": "f31323c9217050ba245ee8b537c713ec2e8ab226", |
|
329 | "node": "f31323c9217050ba245ee8b537c713ec2e8ab226", | |
330 | "path": "port", |
|
330 | "path": "port", | |
331 | "rev": 0, |
|
331 | "rev": 0, | |
332 | "user": "spam" |
|
332 | "user": "spam" | |
333 | } |
|
333 | } | |
334 | ] |
|
334 | ] | |
335 |
|
335 | |||
336 | diff of each revision for reference |
|
336 | diff of each revision for reference | |
337 |
|
337 | |||
338 | $ hg log -p -T'== rev: {rev} ==\n' |
|
338 | $ hg log -p -T'== rev: {rev} ==\n' | |
339 | == rev: 4 == |
|
339 | == rev: 4 == | |
340 | diff -r 95040cfd017d -r 914fa752cdea port |
|
340 | diff -r 95040cfd017d -r 914fa752cdea port | |
341 | --- a/port Thu Jan 01 00:00:03 1970 +0000 |
|
341 | --- a/port Thu Jan 01 00:00:03 1970 +0000 | |
342 | +++ b/port Thu Jan 01 00:00:04 1970 +0000 |
|
342 | +++ b/port Thu Jan 01 00:00:04 1970 +0000 | |
343 | @@ -1,4 +1,3 @@ |
|
343 | @@ -1,4 +1,3 @@ | |
344 | export |
|
344 | export | |
345 | vaportight |
|
345 | vaportight | |
346 | import/export |
|
346 | import/export | |
347 | -import/export |
|
347 | -import/export | |
348 |
|
348 | |||
349 | == rev: 3 == |
|
349 | == rev: 3 == | |
350 | diff -r 3b325e3481a1 -r 95040cfd017d port |
|
350 | diff -r 3b325e3481a1 -r 95040cfd017d port | |
351 | --- a/port Thu Jan 01 00:00:02 1970 +0000 |
|
351 | --- a/port Thu Jan 01 00:00:02 1970 +0000 | |
352 | +++ b/port Thu Jan 01 00:00:03 1970 +0000 |
|
352 | +++ b/port Thu Jan 01 00:00:03 1970 +0000 | |
353 | @@ -1,3 +1,4 @@ |
|
353 | @@ -1,3 +1,4 @@ | |
354 | export |
|
354 | export | |
355 | vaportight |
|
355 | vaportight | |
356 | import/export |
|
356 | import/export | |
357 | +import/export |
|
357 | +import/export | |
358 |
|
358 | |||
359 | == rev: 2 == |
|
359 | == rev: 2 == | |
360 | diff -r 8b20f75c1585 -r 3b325e3481a1 port |
|
360 | diff -r 8b20f75c1585 -r 3b325e3481a1 port | |
361 | --- a/port Thu Jan 01 00:00:01 1970 +0000 |
|
361 | --- a/port Thu Jan 01 00:00:01 1970 +0000 | |
362 | +++ b/port Thu Jan 01 00:00:02 1970 +0000 |
|
362 | +++ b/port Thu Jan 01 00:00:02 1970 +0000 | |
363 | @@ -1,2 +1,3 @@ |
|
363 | @@ -1,2 +1,3 @@ | |
364 | -import |
|
364 | -import | |
365 | export |
|
365 | export | |
366 | +vaportight |
|
366 | +vaportight | |
367 | +import/export |
|
367 | +import/export | |
368 |
|
368 | |||
369 | == rev: 1 == |
|
369 | == rev: 1 == | |
370 | diff -r f31323c92170 -r 8b20f75c1585 port |
|
370 | diff -r f31323c92170 -r 8b20f75c1585 port | |
371 | --- a/port Thu Jan 01 00:00:00 1970 +0000 |
|
371 | --- a/port Thu Jan 01 00:00:00 1970 +0000 | |
372 | +++ b/port Thu Jan 01 00:00:01 1970 +0000 |
|
372 | +++ b/port Thu Jan 01 00:00:01 1970 +0000 | |
373 | @@ -1,1 +1,2 @@ |
|
373 | @@ -1,1 +1,2 @@ | |
374 | import |
|
374 | import | |
375 | +export |
|
375 | +export | |
376 |
|
376 | |||
377 | == rev: 0 == |
|
377 | == rev: 0 == | |
378 | diff -r 000000000000 -r f31323c92170 port |
|
378 | diff -r 000000000000 -r f31323c92170 port | |
379 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|
379 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 | |
380 | +++ b/port Thu Jan 01 00:00:00 1970 +0000 |
|
380 | +++ b/port Thu Jan 01 00:00:00 1970 +0000 | |
381 | @@ -0,0 +1,1 @@ |
|
381 | @@ -0,0 +1,1 @@ | |
382 | +import |
|
382 | +import | |
383 |
|
383 | |||
384 |
|
384 | |||
385 | all |
|
385 | all | |
386 |
|
386 | |||
387 | $ hg grep --traceback --all -nu port port |
|
387 | $ hg grep --traceback --all -nu port port | |
388 | port:4:4:-:spam:import/export |
|
388 | port:4:4:-:spam:import/export | |
389 | port:3:4:+:eggs:import/export |
|
389 | port:3:4:+:eggs:import/export | |
390 | port:2:1:-:spam:import |
|
390 | port:2:1:-:spam:import | |
391 | port:2:2:+:spam:vaportight |
|
391 | port:2:2:+:spam:vaportight | |
392 | port:2:3:+:spam:import/export |
|
392 | port:2:3:+:spam:import/export | |
393 | port:1:2:+:eggs:export |
|
393 | port:1:2:+:eggs:export | |
394 | port:0:1:+:spam:import |
|
394 | port:0:1:+:spam:import | |
395 |
|
395 | |||
396 | all JSON |
|
396 | all JSON | |
397 |
|
397 | |||
398 | $ hg grep --all -Tjson port port |
|
398 | $ hg grep --all -Tjson port port | |
399 | [ |
|
399 | [ | |
400 | { |
|
400 | { | |
401 | "change": "-", |
|
401 | "change": "-", | |
402 | "date": [4, 0], |
|
402 | "date": [4, 0], | |
403 | "lineno": 4, |
|
403 | "lineno": 4, | |
404 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", |
|
404 | "node": "914fa752cdea87777ac1a8d5c858b0c736218f6c", | |
405 | "path": "port", |
|
405 | "path": "port", | |
406 | "rev": 4, |
|
406 | "rev": 4, | |
407 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
407 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
408 | "user": "spam" |
|
408 | "user": "spam" | |
409 | }, |
|
409 | }, | |
410 | { |
|
410 | { | |
411 | "change": "+", |
|
411 | "change": "+", | |
412 | "date": [3, 0], |
|
412 | "date": [3, 0], | |
413 | "lineno": 4, |
|
413 | "lineno": 4, | |
414 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", |
|
414 | "node": "95040cfd017d658c536071c6290230a613c4c2a6", | |
415 | "path": "port", |
|
415 | "path": "port", | |
416 | "rev": 3, |
|
416 | "rev": 3, | |
417 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
417 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
418 | "user": "eggs" |
|
418 | "user": "eggs" | |
419 | }, |
|
419 | }, | |
420 | { |
|
420 | { | |
421 | "change": "-", |
|
421 | "change": "-", | |
422 | "date": [2, 0], |
|
422 | "date": [2, 0], | |
423 | "lineno": 1, |
|
423 | "lineno": 1, | |
424 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
424 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
425 | "path": "port", |
|
425 | "path": "port", | |
426 | "rev": 2, |
|
426 | "rev": 2, | |
427 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], |
|
427 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], | |
428 | "user": "spam" |
|
428 | "user": "spam" | |
429 | }, |
|
429 | }, | |
430 | { |
|
430 | { | |
431 | "change": "+", |
|
431 | "change": "+", | |
432 | "date": [2, 0], |
|
432 | "date": [2, 0], | |
433 | "lineno": 2, |
|
433 | "lineno": 2, | |
434 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
434 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
435 | "path": "port", |
|
435 | "path": "port", | |
436 | "rev": 2, |
|
436 | "rev": 2, | |
437 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], |
|
437 | "texts": [{"matched": false, "text": "va"}, {"matched": true, "text": "port"}, {"matched": false, "text": "ight"}], | |
438 | "user": "spam" |
|
438 | "user": "spam" | |
439 | }, |
|
439 | }, | |
440 | { |
|
440 | { | |
441 | "change": "+", |
|
441 | "change": "+", | |
442 | "date": [2, 0], |
|
442 | "date": [2, 0], | |
443 | "lineno": 3, |
|
443 | "lineno": 3, | |
444 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", |
|
444 | "node": "3b325e3481a1f07435d81dfdbfa434d9a0245b47", | |
445 | "path": "port", |
|
445 | "path": "port", | |
446 | "rev": 2, |
|
446 | "rev": 2, | |
447 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], |
|
447 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}, {"matched": false, "text": "/ex"}, {"matched": true, "text": "port"}], | |
448 | "user": "spam" |
|
448 | "user": "spam" | |
449 | }, |
|
449 | }, | |
450 | { |
|
450 | { | |
451 | "change": "+", |
|
451 | "change": "+", | |
452 | "date": [1, 0], |
|
452 | "date": [1, 0], | |
453 | "lineno": 2, |
|
453 | "lineno": 2, | |
454 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", |
|
454 | "node": "8b20f75c158513ff5ac80bd0e5219bfb6f0eb587", | |
455 | "path": "port", |
|
455 | "path": "port", | |
456 | "rev": 1, |
|
456 | "rev": 1, | |
457 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], |
|
457 | "texts": [{"matched": false, "text": "ex"}, {"matched": true, "text": "port"}], | |
458 | "user": "eggs" |
|
458 | "user": "eggs" | |
459 | }, |
|
459 | }, | |
460 | { |
|
460 | { | |
461 | "change": "+", |
|
461 | "change": "+", | |
462 | "date": [0, 0], |
|
462 | "date": [0, 0], | |
463 | "lineno": 1, |
|
463 | "lineno": 1, | |
464 | "node": "f31323c9217050ba245ee8b537c713ec2e8ab226", |
|
464 | "node": "f31323c9217050ba245ee8b537c713ec2e8ab226", | |
465 | "path": "port", |
|
465 | "path": "port", | |
466 | "rev": 0, |
|
466 | "rev": 0, | |
467 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], |
|
467 | "texts": [{"matched": false, "text": "im"}, {"matched": true, "text": "port"}], | |
468 | "user": "spam" |
|
468 | "user": "spam" | |
469 | } |
|
469 | } | |
470 | ] |
|
470 | ] | |
471 |
|
471 | |||
472 | other |
|
472 | other | |
473 |
|
473 | |||
474 | $ hg grep -r tip:0 -l port port |
|
474 | $ hg grep -r tip:0 -l port port | |
475 | port:4 |
|
475 | port:4 | |
476 | port:3 |
|
476 | port:3 | |
477 | port:2 |
|
477 | port:2 | |
478 | port:1 |
|
478 | port:1 | |
479 | port:0 |
|
479 | port:0 | |
480 | $ hg grep -r tip:0 import port |
|
480 | $ hg grep -r tip:0 import port | |
481 | port:4:import/export |
|
481 | port:4:import/export | |
482 | port:3:import/export |
|
482 | port:3:import/export | |
483 | port:3:import/export |
|
483 | port:3:import/export | |
484 | port:2:import/export |
|
484 | port:2:import/export | |
485 | port:1:import |
|
485 | port:1:import | |
486 | port:0:import |
|
486 | port:0:import | |
487 |
|
487 | |||
488 | $ hg cp port port2 |
|
488 | $ hg cp port port2 | |
489 | $ hg commit -m 4 -u spam -d '5 0' |
|
489 | $ hg commit -m 4 -u spam -d '5 0' | |
490 |
|
490 | |||
491 | follow |
|
491 | follow | |
492 |
|
492 | |||
493 | $ hg grep -r tip:0 --traceback -f 'import\n\Z' port2 |
|
493 | $ hg grep -r tip:0 --traceback -f 'import\n\Z' port2 | |
494 | [1] |
|
494 | [1] | |
495 | $ echo deport >> port2 |
|
495 | $ echo deport >> port2 | |
496 | $ hg commit -m 5 -u eggs -d '6 0' |
|
496 | $ hg commit -m 5 -u eggs -d '6 0' | |
497 | $ hg grep -f --all -nu port port2 |
|
497 | $ hg grep -f --all -nu port port2 | |
498 | port2:6:4:+:eggs:deport |
|
498 | port2:6:4:+:eggs:deport | |
499 | port:4:4:-:spam:import/export |
|
499 | port:4:4:-:spam:import/export | |
500 | port:3:4:+:eggs:import/export |
|
500 | port:3:4:+:eggs:import/export | |
501 | port:2:1:-:spam:import |
|
501 | port:2:1:-:spam:import | |
502 | port:2:2:+:spam:vaportight |
|
502 | port:2:2:+:spam:vaportight | |
503 | port:2:3:+:spam:import/export |
|
503 | port:2:3:+:spam:import/export | |
504 | port:1:2:+:eggs:export |
|
504 | port:1:2:+:eggs:export | |
505 | port:0:1:+:spam:import |
|
505 | port:0:1:+:spam:import | |
506 |
|
506 | |||
507 | $ hg up -q null |
|
507 | $ hg up -q null | |
508 | $ hg grep -r 'reverse(:.)' -f port |
|
508 | $ hg grep -r 'reverse(:.)' -f port | |
509 | port:0:import |
|
509 | port:0:import | |
510 |
|
510 | |||
511 | Test wdir |
|
511 | Test wdir | |
512 | (at least, this shouldn't crash) |
|
512 | (at least, this shouldn't crash) | |
513 |
|
513 | |||
514 | $ hg up -q |
|
514 | $ hg up -q | |
515 | $ echo wport >> port2 |
|
515 | $ echo wport >> port2 | |
516 | $ hg stat |
|
516 | $ hg stat | |
517 | M port2 |
|
517 | M port2 | |
518 | $ hg grep -r 'wdir()' port |
|
518 | $ hg grep -r 'wdir()' port | |
519 | port:2147483647:export |
|
519 | port:2147483647:export | |
520 | port:2147483647:vaportight |
|
520 | port:2147483647:vaportight | |
521 | port:2147483647:import/export |
|
521 | port:2147483647:import/export | |
522 | port2:2147483647:export |
|
522 | port2:2147483647:export | |
523 | port2:2147483647:vaportight |
|
523 | port2:2147483647:vaportight | |
524 | port2:2147483647:import/export |
|
524 | port2:2147483647:import/export | |
525 | port2:2147483647:deport |
|
525 | port2:2147483647:deport | |
526 | port2:2147483647:wport |
|
526 | port2:2147483647:wport | |
527 |
|
527 | |||
528 | $ cd .. |
|
528 | $ cd .. | |
529 | $ hg init t2 |
|
529 | $ hg init t2 | |
530 | $ cd t2 |
|
530 | $ cd t2 | |
531 | $ hg grep -r tip:0 foobar foo |
|
531 | $ hg grep -r tip:0 foobar foo | |
532 | [1] |
|
532 | [1] | |
533 | $ hg grep -r tip:0 foobar |
|
533 | $ hg grep -r tip:0 foobar | |
534 | [1] |
|
534 | [1] | |
535 | $ echo blue >> color |
|
535 | $ echo blue >> color | |
536 | $ echo black >> color |
|
536 | $ echo black >> color | |
537 | $ hg add color |
|
537 | $ hg add color | |
538 | $ hg ci -m 0 |
|
538 | $ hg ci -m 0 | |
539 | $ echo orange >> color |
|
539 | $ echo orange >> color | |
540 | $ hg ci -m 1 |
|
540 | $ hg ci -m 1 | |
541 | $ echo black > color |
|
541 | $ echo black > color | |
542 | $ hg ci -m 2 |
|
542 | $ hg ci -m 2 | |
543 | $ echo orange >> color |
|
543 | $ echo orange >> color | |
544 | $ echo blue >> color |
|
544 | $ echo blue >> color | |
545 | $ hg ci -m 3 |
|
545 | $ hg ci -m 3 | |
546 | $ hg grep -r tip:0 orange |
|
546 | $ hg grep -r tip:0 orange | |
547 | color:3:orange |
|
547 | color:3:orange | |
548 | color:1:orange |
|
548 | color:1:orange | |
549 | $ hg grep --all orange |
|
549 | $ hg grep --all orange | |
550 | color:3:+:orange |
|
550 | color:3:+:orange | |
551 | color:2:-:orange |
|
551 | color:2:-:orange | |
552 | color:1:+:orange |
|
552 | color:1:+:orange | |
553 | $ hg grep --diff orange --color=debug |
|
553 | $ hg grep --diff orange --color=debug | |
554 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.inserted grep.change|+][grep.sep|:][grep.match|orange] |
|
554 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.inserted grep.change|+][grep.sep|:][grep.match|orange] | |
555 | [grep.filename|color][grep.sep|:][grep.rev|2][grep.sep|:][grep.deleted grep.change|-][grep.sep|:][grep.match|orange] |
|
555 | [grep.filename|color][grep.sep|:][grep.rev|2][grep.sep|:][grep.deleted grep.change|-][grep.sep|:][grep.match|orange] | |
556 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.inserted grep.change|+][grep.sep|:][grep.match|orange] |
|
556 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.inserted grep.change|+][grep.sep|:][grep.match|orange] | |
557 |
|
557 | |||
558 | $ hg grep --diff orange --color=yes |
|
558 | $ hg grep --diff orange --color=yes | |
559 | \x1b[0;35mcolor\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32;1m+\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1morange\x1b[0m (esc) |
|
559 | \x1b[0;35mcolor\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m3\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32;1m+\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1morange\x1b[0m (esc) | |
560 | \x1b[0;35mcolor\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1m-\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1morange\x1b[0m (esc) |
|
560 | \x1b[0;35mcolor\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m2\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1m-\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1morange\x1b[0m (esc) | |
561 | \x1b[0;35mcolor\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m1\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32;1m+\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1morange\x1b[0m (esc) |
|
561 | \x1b[0;35mcolor\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;34m1\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;32;1m+\x1b[0m\x1b[0;36m:\x1b[0m\x1b[0;31;1morange\x1b[0m (esc) | |
562 |
|
562 | |||
563 | $ hg grep --diff orange |
|
563 | $ hg grep --diff orange | |
564 | color:3:+:orange |
|
564 | color:3:+:orange | |
565 | color:2:-:orange |
|
565 | color:2:-:orange | |
566 | color:1:+:orange |
|
566 | color:1:+:orange | |
567 |
|
567 | |||
568 | revset predicate for "grep --diff" |
|
568 | revset predicate for "grep --diff" | |
569 |
|
569 | |||
570 | $ hg log -qr 'diff("re:^bl...$")' |
|
570 | $ hg log -qr 'diffcontains("re:^bl...$")' | |
571 | 0:203191eb5e21 |
|
571 | 0:203191eb5e21 | |
572 | $ hg log -qr 'diff("orange")' |
|
572 | $ hg log -qr 'diffcontains("orange")' | |
573 | 1:7c585a21e0d1 |
|
573 | 1:7c585a21e0d1 | |
574 | 2:11bd8bc8d653 |
|
574 | 2:11bd8bc8d653 | |
575 | 3:e0116d3829f8 |
|
575 | 3:e0116d3829f8 | |
576 | $ hg log -qr '2:0 & diff("orange")' |
|
576 | $ hg log -qr '2:0 & diffcontains("orange")' | |
577 | 2:11bd8bc8d653 |
|
577 | 2:11bd8bc8d653 | |
578 | 1:7c585a21e0d1 |
|
578 | 1:7c585a21e0d1 | |
579 |
|
579 | |||
580 | test substring match: '^' should only match at the beginning |
|
580 | test substring match: '^' should only match at the beginning | |
581 |
|
581 | |||
582 | $ hg grep -r tip:0 '^.' --config extensions.color= --color debug |
|
582 | $ hg grep -r tip:0 '^.' --config extensions.color= --color debug | |
583 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lack |
|
583 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lack | |
584 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|o]range |
|
584 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|o]range | |
585 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lue |
|
585 | [grep.filename|color][grep.sep|:][grep.rev|3][grep.sep|:][grep.match|b]lue | |
586 | [grep.filename|color][grep.sep|:][grep.rev|2][grep.sep|:][grep.match|b]lack |
|
586 | [grep.filename|color][grep.sep|:][grep.rev|2][grep.sep|:][grep.match|b]lack | |
587 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.match|b]lue |
|
587 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.match|b]lue | |
588 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.match|b]lack |
|
588 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.match|b]lack | |
589 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.match|o]range |
|
589 | [grep.filename|color][grep.sep|:][grep.rev|1][grep.sep|:][grep.match|o]range | |
590 | [grep.filename|color][grep.sep|:][grep.rev|0][grep.sep|:][grep.match|b]lue |
|
590 | [grep.filename|color][grep.sep|:][grep.rev|0][grep.sep|:][grep.match|b]lue | |
591 | [grep.filename|color][grep.sep|:][grep.rev|0][grep.sep|:][grep.match|b]lack |
|
591 | [grep.filename|color][grep.sep|:][grep.rev|0][grep.sep|:][grep.match|b]lack | |
592 |
|
592 | |||
593 | match in last "line" without newline |
|
593 | match in last "line" without newline | |
594 |
|
594 | |||
595 | $ "$PYTHON" -c 'fp = open("noeol", "wb"); fp.write(b"no infinite loop"); fp.close();' |
|
595 | $ "$PYTHON" -c 'fp = open("noeol", "wb"); fp.write(b"no infinite loop"); fp.close();' | |
596 | $ hg ci -Amnoeol |
|
596 | $ hg ci -Amnoeol | |
597 | adding noeol |
|
597 | adding noeol | |
598 | $ hg grep -r tip:0 loop |
|
598 | $ hg grep -r tip:0 loop | |
599 | noeol:4:no infinite loop |
|
599 | noeol:4:no infinite loop | |
600 |
|
600 | |||
601 | $ cd .. |
|
601 | $ cd .. | |
602 |
|
602 | |||
603 | Issue685: traceback in grep -r after rename |
|
603 | Issue685: traceback in grep -r after rename | |
604 |
|
604 | |||
605 | Got a traceback when using grep on a single |
|
605 | Got a traceback when using grep on a single | |
606 | revision with renamed files. |
|
606 | revision with renamed files. | |
607 |
|
607 | |||
608 | $ hg init issue685 |
|
608 | $ hg init issue685 | |
609 | $ cd issue685 |
|
609 | $ cd issue685 | |
610 | $ echo octarine > color |
|
610 | $ echo octarine > color | |
611 | $ hg ci -Amcolor |
|
611 | $ hg ci -Amcolor | |
612 | adding color |
|
612 | adding color | |
613 | $ hg rename color colour |
|
613 | $ hg rename color colour | |
614 | $ hg ci -Am rename |
|
614 | $ hg ci -Am rename | |
615 | $ hg grep -r tip:0 octarine |
|
615 | $ hg grep -r tip:0 octarine | |
616 | colour:1:octarine |
|
616 | colour:1:octarine | |
617 | color:0:octarine |
|
617 | color:0:octarine | |
618 |
|
618 | |||
619 | Used to crash here |
|
619 | Used to crash here | |
620 |
|
620 | |||
621 | $ hg grep -r 1 octarine |
|
621 | $ hg grep -r 1 octarine | |
622 | colour:1:octarine |
|
622 | colour:1:octarine | |
623 | $ cd .. |
|
623 | $ cd .. | |
624 |
|
624 | |||
625 |
|
625 | |||
626 | Issue337: test that grep follows parent-child relationships instead |
|
626 | Issue337: test that grep follows parent-child relationships instead | |
627 | of just using revision numbers. |
|
627 | of just using revision numbers. | |
628 |
|
628 | |||
629 | $ hg init issue337 |
|
629 | $ hg init issue337 | |
630 | $ cd issue337 |
|
630 | $ cd issue337 | |
631 |
|
631 | |||
632 | $ echo white > color |
|
632 | $ echo white > color | |
633 | $ hg commit -A -m "0 white" |
|
633 | $ hg commit -A -m "0 white" | |
634 | adding color |
|
634 | adding color | |
635 |
|
635 | |||
636 | $ echo red > color |
|
636 | $ echo red > color | |
637 | $ hg commit -A -m "1 red" |
|
637 | $ hg commit -A -m "1 red" | |
638 |
|
638 | |||
639 | $ hg update 0 |
|
639 | $ hg update 0 | |
640 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
640 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
641 | $ echo black > color |
|
641 | $ echo black > color | |
642 | $ hg commit -A -m "2 black" |
|
642 | $ hg commit -A -m "2 black" | |
643 | created new head |
|
643 | created new head | |
644 |
|
644 | |||
645 | $ hg update --clean 1 |
|
645 | $ hg update --clean 1 | |
646 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
646 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved | |
647 | $ echo blue > color |
|
647 | $ echo blue > color | |
648 | $ hg commit -A -m "3 blue" |
|
648 | $ hg commit -A -m "3 blue" | |
649 |
|
649 | |||
650 | $ hg grep --all red |
|
650 | $ hg grep --all red | |
651 | color:3:-:red |
|
651 | color:3:-:red | |
652 | color:1:+:red |
|
652 | color:1:+:red | |
653 |
|
653 | |||
654 | $ hg grep --diff red |
|
654 | $ hg grep --diff red | |
655 | color:3:-:red |
|
655 | color:3:-:red | |
656 | color:1:+:red |
|
656 | color:1:+:red | |
657 |
|
657 | |||
658 | Issue3885: test that changing revision order does not alter the |
|
658 | Issue3885: test that changing revision order does not alter the | |
659 | revisions printed, just their order. |
|
659 | revisions printed, just their order. | |
660 |
|
660 | |||
661 | $ hg grep --all red -r "all()" |
|
661 | $ hg grep --all red -r "all()" | |
662 | color:1:+:red |
|
662 | color:1:+:red | |
663 | color:3:-:red |
|
663 | color:3:-:red | |
664 |
|
664 | |||
665 | $ hg grep --all red -r "reverse(all())" |
|
665 | $ hg grep --all red -r "reverse(all())" | |
666 | color:3:-:red |
|
666 | color:3:-:red | |
667 | color:1:+:red |
|
667 | color:1:+:red | |
668 |
|
668 | |||
669 | $ hg grep --diff red -r "all()" |
|
669 | $ hg grep --diff red -r "all()" | |
670 | color:1:+:red |
|
670 | color:1:+:red | |
671 | color:3:-:red |
|
671 | color:3:-:red | |
672 |
|
672 | |||
673 | $ hg grep --diff red -r "reverse(all())" |
|
673 | $ hg grep --diff red -r "reverse(all())" | |
674 | color:3:-:red |
|
674 | color:3:-:red | |
675 | color:1:+:red |
|
675 | color:1:+:red | |
676 |
|
676 | |||
677 | $ cd .. |
|
677 | $ cd .. | |
678 |
|
678 | |||
679 | $ hg init a |
|
679 | $ hg init a | |
680 | $ cd a |
|
680 | $ cd a | |
681 | $ cp "$TESTDIR/binfile.bin" . |
|
681 | $ cp "$TESTDIR/binfile.bin" . | |
682 | $ hg add binfile.bin |
|
682 | $ hg add binfile.bin | |
683 | $ hg ci -m 'add binfile.bin' |
|
683 | $ hg ci -m 'add binfile.bin' | |
684 | $ hg grep "MaCam" --all |
|
684 | $ hg grep "MaCam" --all | |
685 | binfile.bin:0:+: Binary file matches |
|
685 | binfile.bin:0:+: Binary file matches | |
686 |
|
686 | |||
687 | $ hg grep "MaCam" --diff |
|
687 | $ hg grep "MaCam" --diff | |
688 | binfile.bin:0:+: Binary file matches |
|
688 | binfile.bin:0:+: Binary file matches | |
689 |
|
689 | |||
690 | $ cd .. |
|
690 | $ cd .. | |
691 |
|
691 | |||
692 | Moved line may not be collected by "grep --diff" since it first filters |
|
692 | Moved line may not be collected by "grep --diff" since it first filters | |
693 | the contents to be diffed by the pattern. (i.e. |
|
693 | the contents to be diffed by the pattern. (i.e. | |
694 | "diff <(grep pat a) <(grep pat b)", not "diff a b | grep pat".) |
|
694 | "diff <(grep pat a) <(grep pat b)", not "diff a b | grep pat".) | |
695 | This is much faster than generating full diff per revision. |
|
695 | This is much faster than generating full diff per revision. | |
696 |
|
696 | |||
697 | $ hg init moved-line |
|
697 | $ hg init moved-line | |
698 | $ cd moved-line |
|
698 | $ cd moved-line | |
699 | $ cat <<'EOF' > a |
|
699 | $ cat <<'EOF' > a | |
700 | > foo |
|
700 | > foo | |
701 | > bar |
|
701 | > bar | |
702 | > baz |
|
702 | > baz | |
703 | > EOF |
|
703 | > EOF | |
704 | $ hg ci -Am initial |
|
704 | $ hg ci -Am initial | |
705 | adding a |
|
705 | adding a | |
706 | $ cat <<'EOF' > a |
|
706 | $ cat <<'EOF' > a | |
707 | > bar |
|
707 | > bar | |
708 | > baz |
|
708 | > baz | |
709 | > foo |
|
709 | > foo | |
710 | > EOF |
|
710 | > EOF | |
711 | $ hg ci -m reorder |
|
711 | $ hg ci -m reorder | |
712 |
|
712 | |||
713 | $ hg diff -c 1 |
|
713 | $ hg diff -c 1 | |
714 | diff -r a593cc55e81b -r 69789a3b6e80 a |
|
714 | diff -r a593cc55e81b -r 69789a3b6e80 a | |
715 | --- a/a Thu Jan 01 00:00:00 1970 +0000 |
|
715 | --- a/a Thu Jan 01 00:00:00 1970 +0000 | |
716 | +++ b/a Thu Jan 01 00:00:00 1970 +0000 |
|
716 | +++ b/a Thu Jan 01 00:00:00 1970 +0000 | |
717 | @@ -1,3 +1,3 @@ |
|
717 | @@ -1,3 +1,3 @@ | |
718 | -foo |
|
718 | -foo | |
719 | bar |
|
719 | bar | |
720 | baz |
|
720 | baz | |
721 | +foo |
|
721 | +foo | |
722 |
|
722 | |||
723 | can't find the move of "foo" at the revision 1: |
|
723 | can't find the move of "foo" at the revision 1: | |
724 |
|
724 | |||
725 | $ hg grep --diff foo -r1 |
|
725 | $ hg grep --diff foo -r1 | |
726 | [1] |
|
726 | [1] | |
727 |
|
727 | |||
728 | "bar" isn't moved at the revisoin 1: |
|
728 | "bar" isn't moved at the revisoin 1: | |
729 |
|
729 | |||
730 | $ hg grep --diff bar -r1 |
|
730 | $ hg grep --diff bar -r1 | |
731 | [1] |
|
731 | [1] | |
732 |
|
732 | |||
733 | $ cd .. |
|
733 | $ cd .. | |
734 |
|
734 | |||
735 | Test for showing working of allfiles flag |
|
735 | Test for showing working of allfiles flag | |
736 |
|
736 | |||
737 | $ hg init sng |
|
737 | $ hg init sng | |
738 | $ cd sng |
|
738 | $ cd sng | |
739 | $ echo "unmod" >> um |
|
739 | $ echo "unmod" >> um | |
740 | $ echo old > old |
|
740 | $ echo old > old | |
741 | $ hg ci -q -A -m "adds unmod to um" |
|
741 | $ hg ci -q -A -m "adds unmod to um" | |
742 | $ echo "something else" >> new |
|
742 | $ echo "something else" >> new | |
743 | $ hg ci -A -m "second commit" |
|
743 | $ hg ci -A -m "second commit" | |
744 | adding new |
|
744 | adding new | |
745 | $ hg grep -r "." "unmod" |
|
745 | $ hg grep -r "." "unmod" | |
746 | um:1:unmod |
|
746 | um:1:unmod | |
747 |
|
747 | |||
748 | Existing tracked files in the working directory are searched by default |
|
748 | Existing tracked files in the working directory are searched by default | |
749 |
|
749 | |||
750 | $ echo modified >> new |
|
750 | $ echo modified >> new | |
751 | $ echo 'added' > added; hg add added |
|
751 | $ echo 'added' > added; hg add added | |
752 | $ echo 'added, missing' > added-missing; hg add added-missing; rm added-missing |
|
752 | $ echo 'added, missing' > added-missing; hg add added-missing; rm added-missing | |
753 | $ echo 'untracked' > untracked |
|
753 | $ echo 'untracked' > untracked | |
754 | $ hg rm old |
|
754 | $ hg rm old | |
755 | $ hg grep '' |
|
755 | $ hg grep '' | |
756 | added:added |
|
756 | added:added | |
757 | new:something else |
|
757 | new:something else | |
758 | new:modified |
|
758 | new:modified | |
759 | um:unmod |
|
759 | um:unmod | |
760 |
|
760 | |||
761 | #if symlink |
|
761 | #if symlink | |
762 | Grepping a symlink greps its destination |
|
762 | Grepping a symlink greps its destination | |
763 |
|
763 | |||
764 | $ rm -f added; ln -s symlink-added added |
|
764 | $ rm -f added; ln -s symlink-added added | |
765 | $ hg grep '' | grep added |
|
765 | $ hg grep '' | grep added | |
766 | added:symlink-added |
|
766 | added:symlink-added | |
767 |
|
767 | |||
768 | But we reject symlinks as directories components of a tracked file as |
|
768 | But we reject symlinks as directories components of a tracked file as | |
769 | usual: |
|
769 | usual: | |
770 |
|
770 | |||
771 | $ mkdir dir; touch dir/f; hg add dir/f |
|
771 | $ mkdir dir; touch dir/f; hg add dir/f | |
772 | $ rm -rf dir; ln -s / dir |
|
772 | $ rm -rf dir; ln -s / dir | |
773 | $ hg grep '' |
|
773 | $ hg grep '' | |
774 | abort: path 'dir/f' traverses symbolic link 'dir' |
|
774 | abort: path 'dir/f' traverses symbolic link 'dir' | |
775 | [255] |
|
775 | [255] | |
776 | #endif |
|
776 | #endif | |
777 |
|
777 | |||
778 | But we can search files from some other revision with -rREV |
|
778 | But we can search files from some other revision with -rREV | |
779 |
|
779 | |||
780 | $ hg grep -r. mod |
|
780 | $ hg grep -r. mod | |
781 | um:1:unmod |
|
781 | um:1:unmod | |
782 |
|
782 | |||
783 | $ hg grep --diff mod |
|
783 | $ hg grep --diff mod | |
784 | um:0:+:unmod |
|
784 | um:0:+:unmod | |
785 |
|
785 | |||
786 | $ cd .. |
|
786 | $ cd .. | |
787 |
|
787 | |||
788 | Change Default of grep by ui.tweakdefaults, that is, the files not in current |
|
788 | Change Default of grep by ui.tweakdefaults, that is, the files not in current | |
789 | working directory should not be grepp-ed on |
|
789 | working directory should not be grepp-ed on | |
790 |
|
790 | |||
791 | $ hg init ab |
|
791 | $ hg init ab | |
792 | $ cd ab |
|
792 | $ cd ab | |
793 | $ cat <<'EOF' >> .hg/hgrc |
|
793 | $ cat <<'EOF' >> .hg/hgrc | |
794 | > [ui] |
|
794 | > [ui] | |
795 | > tweakdefaults = True |
|
795 | > tweakdefaults = True | |
796 | > EOF |
|
796 | > EOF | |
797 | $ echo "some text">>file1 |
|
797 | $ echo "some text">>file1 | |
798 | $ hg add file1 |
|
798 | $ hg add file1 | |
799 | $ hg commit -m "adds file1" |
|
799 | $ hg commit -m "adds file1" | |
800 | $ hg mv file1 file2 |
|
800 | $ hg mv file1 file2 | |
801 |
|
801 | |||
802 | wdir revision is hidden by default: |
|
802 | wdir revision is hidden by default: | |
803 |
|
803 | |||
804 | $ hg grep "some" |
|
804 | $ hg grep "some" | |
805 | file2:some text |
|
805 | file2:some text | |
806 |
|
806 | |||
807 | but it should be available in template dict: |
|
807 | but it should be available in template dict: | |
808 |
|
808 | |||
809 | $ hg grep "some" -Tjson |
|
809 | $ hg grep "some" -Tjson | |
810 | [ |
|
810 | [ | |
811 | { |
|
811 | { | |
812 | "date": [0, 0], |
|
812 | "date": [0, 0], | |
813 | "lineno": 1, |
|
813 | "lineno": 1, | |
814 | "node": "ffffffffffffffffffffffffffffffffffffffff", |
|
814 | "node": "ffffffffffffffffffffffffffffffffffffffff", | |
815 | "path": "file2", |
|
815 | "path": "file2", | |
816 | "rev": 2147483647, |
|
816 | "rev": 2147483647, | |
817 | "texts": [{"matched": true, "text": "some"}, {"matched": false, "text": " text"}], |
|
817 | "texts": [{"matched": true, "text": "some"}, {"matched": false, "text": " text"}], | |
818 | "user": "test" |
|
818 | "user": "test" | |
819 | } |
|
819 | } | |
820 | ] |
|
820 | ] | |
821 |
|
821 | |||
822 | $ cd .. |
|
822 | $ cd .. | |
823 |
|
823 | |||
824 | test -rMULTIREV |
|
824 | test -rMULTIREV | |
825 |
|
825 | |||
826 | $ cd sng |
|
826 | $ cd sng | |
827 | $ hg rm um |
|
827 | $ hg rm um | |
828 | $ hg commit -m "deletes um" |
|
828 | $ hg commit -m "deletes um" | |
829 | $ hg grep -r "0:2" "unmod" |
|
829 | $ hg grep -r "0:2" "unmod" | |
830 | um:0:unmod |
|
830 | um:0:unmod | |
831 | um:1:unmod |
|
831 | um:1:unmod | |
832 | $ hg grep -r "0:2" "unmod" um |
|
832 | $ hg grep -r "0:2" "unmod" um | |
833 | um:0:unmod |
|
833 | um:0:unmod | |
834 | um:1:unmod |
|
834 | um:1:unmod | |
835 | $ hg grep -r "0:2" "unmod" "glob:**/um" # Check that patterns also work |
|
835 | $ hg grep -r "0:2" "unmod" "glob:**/um" # Check that patterns also work | |
836 | um:0:unmod |
|
836 | um:0:unmod | |
837 | um:1:unmod |
|
837 | um:1:unmod | |
838 | $ cd .. |
|
838 | $ cd .. | |
839 |
|
839 | |||
840 | --follow with/without --diff and/or paths |
|
840 | --follow with/without --diff and/or paths | |
841 | ----------------------------------------- |
|
841 | ----------------------------------------- | |
842 |
|
842 | |||
843 | For each test case, we compare the history traversal of "hg log", |
|
843 | For each test case, we compare the history traversal of "hg log", | |
844 | "hg grep --diff", and "hg grep" (--all-files). |
|
844 | "hg grep --diff", and "hg grep" (--all-files). | |
845 |
|
845 | |||
846 | "hg grep --diff" should traverse the log in the same way as "hg log". |
|
846 | "hg grep --diff" should traverse the log in the same way as "hg log". | |
847 | "hg grep" (--all-files) is slightly different in that it includes |
|
847 | "hg grep" (--all-files) is slightly different in that it includes | |
848 | unmodified changes. |
|
848 | unmodified changes. | |
849 |
|
849 | |||
850 | $ hg init follow |
|
850 | $ hg init follow | |
851 | $ cd follow |
|
851 | $ cd follow | |
852 |
|
852 | |||
853 | $ cat <<'EOF' >> .hg/hgrc |
|
853 | $ cat <<'EOF' >> .hg/hgrc | |
854 | > [ui] |
|
854 | > [ui] | |
855 | > logtemplate = '{rev}: {join(files % "{status} {path}", ", ")}\n' |
|
855 | > logtemplate = '{rev}: {join(files % "{status} {path}", ", ")}\n' | |
856 | > EOF |
|
856 | > EOF | |
857 |
|
857 | |||
858 | $ for f in add0 add0-mod1 add0-rm1 add0-mod2 add0-rm2 add0-mod3 add0-mod4 add0-rm4; do |
|
858 | $ for f in add0 add0-mod1 add0-rm1 add0-mod2 add0-rm2 add0-mod3 add0-mod4 add0-rm4; do | |
859 | > echo data0 >> $f |
|
859 | > echo data0 >> $f | |
860 | > done |
|
860 | > done | |
861 | $ hg ci -qAm0 |
|
861 | $ hg ci -qAm0 | |
862 |
|
862 | |||
863 | $ hg cp add0 add0-cp1 |
|
863 | $ hg cp add0 add0-cp1 | |
864 | $ hg cp add0 add0-cp1-mod1 |
|
864 | $ hg cp add0 add0-cp1-mod1 | |
865 | $ hg cp add0 add0-cp1-mod1-rm3 |
|
865 | $ hg cp add0 add0-cp1-mod1-rm3 | |
866 | $ hg rm add0-rm1 |
|
866 | $ hg rm add0-rm1 | |
867 | $ for f in *mod1*; do |
|
867 | $ for f in *mod1*; do | |
868 | > echo data1 >> $f |
|
868 | > echo data1 >> $f | |
869 | > done |
|
869 | > done | |
870 | $ hg ci -qAm1 |
|
870 | $ hg ci -qAm1 | |
871 |
|
871 | |||
872 | $ hg update -q 0 |
|
872 | $ hg update -q 0 | |
873 | $ hg cp add0 add0-cp2 |
|
873 | $ hg cp add0 add0-cp2 | |
874 | $ hg cp add0 add0-cp2-mod2 |
|
874 | $ hg cp add0 add0-cp2-mod2 | |
875 | $ hg rm add0-rm2 |
|
875 | $ hg rm add0-rm2 | |
876 | $ for f in *mod2*; do |
|
876 | $ for f in *mod2*; do | |
877 | > echo data2 >> $f |
|
877 | > echo data2 >> $f | |
878 | > done |
|
878 | > done | |
879 | $ hg ci -qAm2 |
|
879 | $ hg ci -qAm2 | |
880 |
|
880 | |||
881 | $ hg update -q 1 |
|
881 | $ hg update -q 1 | |
882 | $ hg cp add0-cp1 add0-cp1-cp3 |
|
882 | $ hg cp add0-cp1 add0-cp1-cp3 | |
883 | $ hg cp add0-cp1-mod1 add0-cp1-mod1-cp3-mod3 |
|
883 | $ hg cp add0-cp1-mod1 add0-cp1-mod1-cp3-mod3 | |
884 | $ hg rm add0-cp1-mod1-rm3 |
|
884 | $ hg rm add0-cp1-mod1-rm3 | |
885 | $ for f in *mod3*; do |
|
885 | $ for f in *mod3*; do | |
886 | > echo data3 >> $f |
|
886 | > echo data3 >> $f | |
887 | > done |
|
887 | > done | |
888 | $ hg ci -qAm3 |
|
888 | $ hg ci -qAm3 | |
889 |
|
889 | |||
890 | $ hg cp add0 add0-cp4 |
|
890 | $ hg cp add0 add0-cp4 | |
891 | $ hg cp add0 add0-cp4-mod4 |
|
891 | $ hg cp add0 add0-cp4-mod4 | |
892 | $ hg rm add0-rm4 |
|
892 | $ hg rm add0-rm4 | |
893 | $ for f in *mod4*; do |
|
893 | $ for f in *mod4*; do | |
894 | > echo data4 >> $f |
|
894 | > echo data4 >> $f | |
895 | > done |
|
895 | > done | |
896 |
|
896 | |||
897 | $ hg log -Gr':wdir()' |
|
897 | $ hg log -Gr':wdir()' | |
898 | o 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
898 | o 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
899 | | |
|
899 | | | |
900 | @ 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
900 | @ 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
901 | | |
|
901 | | | |
902 | | o 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
902 | | o 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
903 | | | |
|
903 | | | | |
904 | o | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
904 | o | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
905 | |/ |
|
905 | |/ | |
906 | o 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
906 | o 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
907 |
|
907 | |||
908 |
|
908 | |||
909 | follow revision history from wdir parent: |
|
909 | follow revision history from wdir parent: | |
910 |
|
910 | |||
911 | $ hg log -f |
|
911 | $ hg log -f | |
912 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
912 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
913 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
913 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
914 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
914 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
915 |
|
915 | |||
916 | $ hg grep --diff -f data |
|
916 | $ hg grep --diff -f data | |
917 | add0-cp1-mod1-cp3-mod3:3:+:data3 |
|
917 | add0-cp1-mod1-cp3-mod3:3:+:data3 | |
918 | add0-mod3:3:+:data3 |
|
918 | add0-mod3:3:+:data3 | |
919 | add0-cp1-mod1:1:+:data1 |
|
919 | add0-cp1-mod1:1:+:data1 | |
920 | add0-cp1-mod1-rm3:1:+:data1 |
|
920 | add0-cp1-mod1-rm3:1:+:data1 | |
921 | add0-mod1:1:+:data1 |
|
921 | add0-mod1:1:+:data1 | |
922 | add0:0:+:data0 |
|
922 | add0:0:+:data0 | |
923 | add0-mod1:0:+:data0 |
|
923 | add0-mod1:0:+:data0 | |
924 | add0-mod2:0:+:data0 |
|
924 | add0-mod2:0:+:data0 | |
925 | add0-mod3:0:+:data0 |
|
925 | add0-mod3:0:+:data0 | |
926 | add0-mod4:0:+:data0 |
|
926 | add0-mod4:0:+:data0 | |
927 | add0-rm1:0:+:data0 |
|
927 | add0-rm1:0:+:data0 | |
928 | add0-rm2:0:+:data0 |
|
928 | add0-rm2:0:+:data0 | |
929 | add0-rm4:0:+:data0 |
|
929 | add0-rm4:0:+:data0 | |
930 |
|
930 | |||
931 | $ hg grep -f data |
|
931 | $ hg grep -f data | |
932 | add0:3:data0 |
|
932 | add0:3:data0 | |
933 | add0-cp1:3:data0 |
|
933 | add0-cp1:3:data0 | |
934 | add0-cp1-cp3:3:data0 |
|
934 | add0-cp1-cp3:3:data0 | |
935 | add0-cp1-mod1:3:data0 |
|
935 | add0-cp1-mod1:3:data0 | |
936 | add0-cp1-mod1:3:data1 |
|
936 | add0-cp1-mod1:3:data1 | |
937 | add0-cp1-mod1-cp3-mod3:3:data0 |
|
937 | add0-cp1-mod1-cp3-mod3:3:data0 | |
938 | add0-cp1-mod1-cp3-mod3:3:data1 |
|
938 | add0-cp1-mod1-cp3-mod3:3:data1 | |
939 | add0-cp1-mod1-cp3-mod3:3:data3 |
|
939 | add0-cp1-mod1-cp3-mod3:3:data3 | |
940 | add0-mod1:3:data0 |
|
940 | add0-mod1:3:data0 | |
941 | add0-mod1:3:data1 |
|
941 | add0-mod1:3:data1 | |
942 | add0-mod2:3:data0 |
|
942 | add0-mod2:3:data0 | |
943 | add0-mod3:3:data0 |
|
943 | add0-mod3:3:data0 | |
944 | add0-mod3:3:data3 |
|
944 | add0-mod3:3:data3 | |
945 | add0-mod4:3:data0 |
|
945 | add0-mod4:3:data0 | |
946 | add0-rm2:3:data0 |
|
946 | add0-rm2:3:data0 | |
947 | add0-rm4:3:data0 |
|
947 | add0-rm4:3:data0 | |
948 | add0:1:data0 |
|
948 | add0:1:data0 | |
949 | add0-cp1:1:data0 |
|
949 | add0-cp1:1:data0 | |
950 | add0-cp1-mod1:1:data0 |
|
950 | add0-cp1-mod1:1:data0 | |
951 | add0-cp1-mod1:1:data1 |
|
951 | add0-cp1-mod1:1:data1 | |
952 | add0-cp1-mod1-rm3:1:data0 |
|
952 | add0-cp1-mod1-rm3:1:data0 | |
953 | add0-cp1-mod1-rm3:1:data1 |
|
953 | add0-cp1-mod1-rm3:1:data1 | |
954 | add0-mod1:1:data0 |
|
954 | add0-mod1:1:data0 | |
955 | add0-mod1:1:data1 |
|
955 | add0-mod1:1:data1 | |
956 | add0-mod2:1:data0 |
|
956 | add0-mod2:1:data0 | |
957 | add0-mod3:1:data0 |
|
957 | add0-mod3:1:data0 | |
958 | add0-mod4:1:data0 |
|
958 | add0-mod4:1:data0 | |
959 | add0-rm2:1:data0 |
|
959 | add0-rm2:1:data0 | |
960 | add0-rm4:1:data0 |
|
960 | add0-rm4:1:data0 | |
961 | add0:0:data0 |
|
961 | add0:0:data0 | |
962 | add0-mod1:0:data0 |
|
962 | add0-mod1:0:data0 | |
963 | add0-mod2:0:data0 |
|
963 | add0-mod2:0:data0 | |
964 | add0-mod3:0:data0 |
|
964 | add0-mod3:0:data0 | |
965 | add0-mod4:0:data0 |
|
965 | add0-mod4:0:data0 | |
966 | add0-rm1:0:data0 |
|
966 | add0-rm1:0:data0 | |
967 | add0-rm2:0:data0 |
|
967 | add0-rm2:0:data0 | |
968 | add0-rm4:0:data0 |
|
968 | add0-rm4:0:data0 | |
969 |
|
969 | |||
970 | follow revision history from specified revision: |
|
970 | follow revision history from specified revision: | |
971 |
|
971 | |||
972 | $ hg log -fr2 |
|
972 | $ hg log -fr2 | |
973 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
973 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
974 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
974 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
975 |
|
975 | |||
976 | $ hg grep --diff -fr2 data |
|
976 | $ hg grep --diff -fr2 data | |
977 | add0-cp2-mod2:2:+:data2 |
|
977 | add0-cp2-mod2:2:+:data2 | |
978 | add0-mod2:2:+:data2 |
|
978 | add0-mod2:2:+:data2 | |
979 | add0:0:+:data0 |
|
979 | add0:0:+:data0 | |
980 | add0-mod1:0:+:data0 |
|
980 | add0-mod1:0:+:data0 | |
981 | add0-mod2:0:+:data0 |
|
981 | add0-mod2:0:+:data0 | |
982 | add0-mod3:0:+:data0 |
|
982 | add0-mod3:0:+:data0 | |
983 | add0-mod4:0:+:data0 |
|
983 | add0-mod4:0:+:data0 | |
984 | add0-rm1:0:+:data0 |
|
984 | add0-rm1:0:+:data0 | |
985 | add0-rm2:0:+:data0 |
|
985 | add0-rm2:0:+:data0 | |
986 | add0-rm4:0:+:data0 |
|
986 | add0-rm4:0:+:data0 | |
987 |
|
987 | |||
988 | $ hg grep -fr2 data |
|
988 | $ hg grep -fr2 data | |
989 | add0:2:data0 |
|
989 | add0:2:data0 | |
990 | add0-cp2:2:data0 |
|
990 | add0-cp2:2:data0 | |
991 | add0-cp2-mod2:2:data0 |
|
991 | add0-cp2-mod2:2:data0 | |
992 | add0-cp2-mod2:2:data2 |
|
992 | add0-cp2-mod2:2:data2 | |
993 | add0-mod1:2:data0 |
|
993 | add0-mod1:2:data0 | |
994 | add0-mod2:2:data0 |
|
994 | add0-mod2:2:data0 | |
995 | add0-mod2:2:data2 |
|
995 | add0-mod2:2:data2 | |
996 | add0-mod3:2:data0 |
|
996 | add0-mod3:2:data0 | |
997 | add0-mod4:2:data0 |
|
997 | add0-mod4:2:data0 | |
998 | add0-rm1:2:data0 |
|
998 | add0-rm1:2:data0 | |
999 | add0-rm4:2:data0 |
|
999 | add0-rm4:2:data0 | |
1000 | add0:0:data0 |
|
1000 | add0:0:data0 | |
1001 | add0-mod1:0:data0 |
|
1001 | add0-mod1:0:data0 | |
1002 | add0-mod2:0:data0 |
|
1002 | add0-mod2:0:data0 | |
1003 | add0-mod3:0:data0 |
|
1003 | add0-mod3:0:data0 | |
1004 | add0-mod4:0:data0 |
|
1004 | add0-mod4:0:data0 | |
1005 | add0-rm1:0:data0 |
|
1005 | add0-rm1:0:data0 | |
1006 | add0-rm2:0:data0 |
|
1006 | add0-rm2:0:data0 | |
1007 | add0-rm4:0:data0 |
|
1007 | add0-rm4:0:data0 | |
1008 |
|
1008 | |||
1009 | follow revision history from wdir: |
|
1009 | follow revision history from wdir: | |
1010 |
|
1010 | |||
1011 | $ hg log -fr'wdir()' |
|
1011 | $ hg log -fr'wdir()' | |
1012 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
1012 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
1013 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1013 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1014 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
1014 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
1015 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1015 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1016 |
|
1016 | |||
1017 | BROKEN: should not abort because of removed file |
|
1017 | BROKEN: should not abort because of removed file | |
1018 | $ hg grep --diff -fr'wdir()' data |
|
1018 | $ hg grep --diff -fr'wdir()' data | |
1019 | add0-cp4-mod4:2147483647:+:data4 |
|
1019 | add0-cp4-mod4:2147483647:+:data4 | |
1020 | add0-mod4:2147483647:+:data4 |
|
1020 | add0-mod4:2147483647:+:data4 | |
1021 | add0-rm4:2147483647:-:abort: add0-rm4@None: not found in manifest! |
|
1021 | add0-rm4:2147483647:-:abort: add0-rm4@None: not found in manifest! | |
1022 | [255] |
|
1022 | [255] | |
1023 |
|
1023 | |||
1024 | $ hg grep -fr'wdir()' data |
|
1024 | $ hg grep -fr'wdir()' data | |
1025 | add0:2147483647:data0 |
|
1025 | add0:2147483647:data0 | |
1026 | add0-cp1:2147483647:data0 |
|
1026 | add0-cp1:2147483647:data0 | |
1027 | add0-cp1-cp3:2147483647:data0 |
|
1027 | add0-cp1-cp3:2147483647:data0 | |
1028 | add0-cp1-mod1:2147483647:data0 |
|
1028 | add0-cp1-mod1:2147483647:data0 | |
1029 | add0-cp1-mod1:2147483647:data1 |
|
1029 | add0-cp1-mod1:2147483647:data1 | |
1030 | add0-cp1-mod1-cp3-mod3:2147483647:data0 |
|
1030 | add0-cp1-mod1-cp3-mod3:2147483647:data0 | |
1031 | add0-cp1-mod1-cp3-mod3:2147483647:data1 |
|
1031 | add0-cp1-mod1-cp3-mod3:2147483647:data1 | |
1032 | add0-cp1-mod1-cp3-mod3:2147483647:data3 |
|
1032 | add0-cp1-mod1-cp3-mod3:2147483647:data3 | |
1033 | add0-cp4:2147483647:data0 |
|
1033 | add0-cp4:2147483647:data0 | |
1034 | add0-cp4-mod4:2147483647:data0 |
|
1034 | add0-cp4-mod4:2147483647:data0 | |
1035 | add0-cp4-mod4:2147483647:data4 |
|
1035 | add0-cp4-mod4:2147483647:data4 | |
1036 | add0-mod1:2147483647:data0 |
|
1036 | add0-mod1:2147483647:data0 | |
1037 | add0-mod1:2147483647:data1 |
|
1037 | add0-mod1:2147483647:data1 | |
1038 | add0-mod2:2147483647:data0 |
|
1038 | add0-mod2:2147483647:data0 | |
1039 | add0-mod3:2147483647:data0 |
|
1039 | add0-mod3:2147483647:data0 | |
1040 | add0-mod3:2147483647:data3 |
|
1040 | add0-mod3:2147483647:data3 | |
1041 | add0-mod4:2147483647:data0 |
|
1041 | add0-mod4:2147483647:data0 | |
1042 | add0-mod4:2147483647:data4 |
|
1042 | add0-mod4:2147483647:data4 | |
1043 | add0-rm2:2147483647:data0 |
|
1043 | add0-rm2:2147483647:data0 | |
1044 | add0:3:data0 |
|
1044 | add0:3:data0 | |
1045 | add0-cp1:3:data0 |
|
1045 | add0-cp1:3:data0 | |
1046 | add0-cp1-cp3:3:data0 |
|
1046 | add0-cp1-cp3:3:data0 | |
1047 | add0-cp1-mod1:3:data0 |
|
1047 | add0-cp1-mod1:3:data0 | |
1048 | add0-cp1-mod1:3:data1 |
|
1048 | add0-cp1-mod1:3:data1 | |
1049 | add0-cp1-mod1-cp3-mod3:3:data0 |
|
1049 | add0-cp1-mod1-cp3-mod3:3:data0 | |
1050 | add0-cp1-mod1-cp3-mod3:3:data1 |
|
1050 | add0-cp1-mod1-cp3-mod3:3:data1 | |
1051 | add0-cp1-mod1-cp3-mod3:3:data3 |
|
1051 | add0-cp1-mod1-cp3-mod3:3:data3 | |
1052 | add0-mod1:3:data0 |
|
1052 | add0-mod1:3:data0 | |
1053 | add0-mod1:3:data1 |
|
1053 | add0-mod1:3:data1 | |
1054 | add0-mod2:3:data0 |
|
1054 | add0-mod2:3:data0 | |
1055 | add0-mod3:3:data0 |
|
1055 | add0-mod3:3:data0 | |
1056 | add0-mod3:3:data3 |
|
1056 | add0-mod3:3:data3 | |
1057 | add0-mod4:3:data0 |
|
1057 | add0-mod4:3:data0 | |
1058 | add0-rm2:3:data0 |
|
1058 | add0-rm2:3:data0 | |
1059 | add0-rm4:3:data0 |
|
1059 | add0-rm4:3:data0 | |
1060 | add0:1:data0 |
|
1060 | add0:1:data0 | |
1061 | add0-cp1:1:data0 |
|
1061 | add0-cp1:1:data0 | |
1062 | add0-cp1-mod1:1:data0 |
|
1062 | add0-cp1-mod1:1:data0 | |
1063 | add0-cp1-mod1:1:data1 |
|
1063 | add0-cp1-mod1:1:data1 | |
1064 | add0-cp1-mod1-rm3:1:data0 |
|
1064 | add0-cp1-mod1-rm3:1:data0 | |
1065 | add0-cp1-mod1-rm3:1:data1 |
|
1065 | add0-cp1-mod1-rm3:1:data1 | |
1066 | add0-mod1:1:data0 |
|
1066 | add0-mod1:1:data0 | |
1067 | add0-mod1:1:data1 |
|
1067 | add0-mod1:1:data1 | |
1068 | add0-mod2:1:data0 |
|
1068 | add0-mod2:1:data0 | |
1069 | add0-mod3:1:data0 |
|
1069 | add0-mod3:1:data0 | |
1070 | add0-mod4:1:data0 |
|
1070 | add0-mod4:1:data0 | |
1071 | add0-rm2:1:data0 |
|
1071 | add0-rm2:1:data0 | |
1072 | add0-rm4:1:data0 |
|
1072 | add0-rm4:1:data0 | |
1073 | add0:0:data0 |
|
1073 | add0:0:data0 | |
1074 | add0-mod1:0:data0 |
|
1074 | add0-mod1:0:data0 | |
1075 | add0-mod2:0:data0 |
|
1075 | add0-mod2:0:data0 | |
1076 | add0-mod3:0:data0 |
|
1076 | add0-mod3:0:data0 | |
1077 | add0-mod4:0:data0 |
|
1077 | add0-mod4:0:data0 | |
1078 | add0-rm1:0:data0 |
|
1078 | add0-rm1:0:data0 | |
1079 | add0-rm2:0:data0 |
|
1079 | add0-rm2:0:data0 | |
1080 | add0-rm4:0:data0 |
|
1080 | add0-rm4:0:data0 | |
1081 |
|
1081 | |||
1082 | follow revision history from multiple revisions: |
|
1082 | follow revision history from multiple revisions: | |
1083 |
|
1083 | |||
1084 | $ hg log -fr'1+2' |
|
1084 | $ hg log -fr'1+2' | |
1085 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
1085 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
1086 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
1086 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
1087 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1087 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1088 |
|
1088 | |||
1089 | $ hg grep --diff -fr'1+2' data |
|
1089 | $ hg grep --diff -fr'1+2' data | |
1090 | add0-cp2-mod2:2:+:data2 |
|
1090 | add0-cp2-mod2:2:+:data2 | |
1091 | add0-mod2:2:+:data2 |
|
1091 | add0-mod2:2:+:data2 | |
1092 | add0-cp1-mod1:1:+:data1 |
|
1092 | add0-cp1-mod1:1:+:data1 | |
1093 | add0-cp1-mod1-rm3:1:+:data1 |
|
1093 | add0-cp1-mod1-rm3:1:+:data1 | |
1094 | add0-mod1:1:+:data1 |
|
1094 | add0-mod1:1:+:data1 | |
1095 | add0:0:+:data0 |
|
1095 | add0:0:+:data0 | |
1096 | add0-mod1:0:+:data0 |
|
1096 | add0-mod1:0:+:data0 | |
1097 | add0-mod2:0:+:data0 |
|
1097 | add0-mod2:0:+:data0 | |
1098 | add0-mod3:0:+:data0 |
|
1098 | add0-mod3:0:+:data0 | |
1099 | add0-mod4:0:+:data0 |
|
1099 | add0-mod4:0:+:data0 | |
1100 | add0-rm1:0:+:data0 |
|
1100 | add0-rm1:0:+:data0 | |
1101 | add0-rm2:0:+:data0 |
|
1101 | add0-rm2:0:+:data0 | |
1102 | add0-rm4:0:+:data0 |
|
1102 | add0-rm4:0:+:data0 | |
1103 |
|
1103 | |||
1104 | $ hg grep -fr'1+2' data |
|
1104 | $ hg grep -fr'1+2' data | |
1105 | add0:2:data0 |
|
1105 | add0:2:data0 | |
1106 | add0-cp2:2:data0 |
|
1106 | add0-cp2:2:data0 | |
1107 | add0-cp2-mod2:2:data0 |
|
1107 | add0-cp2-mod2:2:data0 | |
1108 | add0-cp2-mod2:2:data2 |
|
1108 | add0-cp2-mod2:2:data2 | |
1109 | add0-mod1:2:data0 |
|
1109 | add0-mod1:2:data0 | |
1110 | add0-mod2:2:data0 |
|
1110 | add0-mod2:2:data0 | |
1111 | add0-mod2:2:data2 |
|
1111 | add0-mod2:2:data2 | |
1112 | add0-mod3:2:data0 |
|
1112 | add0-mod3:2:data0 | |
1113 | add0-mod4:2:data0 |
|
1113 | add0-mod4:2:data0 | |
1114 | add0-rm1:2:data0 |
|
1114 | add0-rm1:2:data0 | |
1115 | add0-rm4:2:data0 |
|
1115 | add0-rm4:2:data0 | |
1116 | add0:1:data0 |
|
1116 | add0:1:data0 | |
1117 | add0-cp1:1:data0 |
|
1117 | add0-cp1:1:data0 | |
1118 | add0-cp1-mod1:1:data0 |
|
1118 | add0-cp1-mod1:1:data0 | |
1119 | add0-cp1-mod1:1:data1 |
|
1119 | add0-cp1-mod1:1:data1 | |
1120 | add0-cp1-mod1-rm3:1:data0 |
|
1120 | add0-cp1-mod1-rm3:1:data0 | |
1121 | add0-cp1-mod1-rm3:1:data1 |
|
1121 | add0-cp1-mod1-rm3:1:data1 | |
1122 | add0-mod1:1:data0 |
|
1122 | add0-mod1:1:data0 | |
1123 | add0-mod1:1:data1 |
|
1123 | add0-mod1:1:data1 | |
1124 | add0-mod2:1:data0 |
|
1124 | add0-mod2:1:data0 | |
1125 | add0-mod3:1:data0 |
|
1125 | add0-mod3:1:data0 | |
1126 | add0-mod4:1:data0 |
|
1126 | add0-mod4:1:data0 | |
1127 | add0-rm2:1:data0 |
|
1127 | add0-rm2:1:data0 | |
1128 | add0-rm4:1:data0 |
|
1128 | add0-rm4:1:data0 | |
1129 | add0:0:data0 |
|
1129 | add0:0:data0 | |
1130 | add0-mod1:0:data0 |
|
1130 | add0-mod1:0:data0 | |
1131 | add0-mod2:0:data0 |
|
1131 | add0-mod2:0:data0 | |
1132 | add0-mod3:0:data0 |
|
1132 | add0-mod3:0:data0 | |
1133 | add0-mod4:0:data0 |
|
1133 | add0-mod4:0:data0 | |
1134 | add0-rm1:0:data0 |
|
1134 | add0-rm1:0:data0 | |
1135 | add0-rm2:0:data0 |
|
1135 | add0-rm2:0:data0 | |
1136 | add0-rm4:0:data0 |
|
1136 | add0-rm4:0:data0 | |
1137 |
|
1137 | |||
1138 | follow file history from wdir parent, unmodified in wdir: |
|
1138 | follow file history from wdir parent, unmodified in wdir: | |
1139 |
|
1139 | |||
1140 | $ hg log -f add0-mod3 |
|
1140 | $ hg log -f add0-mod3 | |
1141 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1141 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1142 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1142 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1143 |
|
1143 | |||
1144 | $ hg grep --diff -f data add0-mod3 |
|
1144 | $ hg grep --diff -f data add0-mod3 | |
1145 | add0-mod3:3:+:data3 |
|
1145 | add0-mod3:3:+:data3 | |
1146 | add0-mod3:0:+:data0 |
|
1146 | add0-mod3:0:+:data0 | |
1147 |
|
1147 | |||
1148 | $ hg grep -f data add0-mod3 |
|
1148 | $ hg grep -f data add0-mod3 | |
1149 | add0-mod3:3:data0 |
|
1149 | add0-mod3:3:data0 | |
1150 | add0-mod3:3:data3 |
|
1150 | add0-mod3:3:data3 | |
1151 | add0-mod3:1:data0 |
|
1151 | add0-mod3:1:data0 | |
1152 | add0-mod3:0:data0 |
|
1152 | add0-mod3:0:data0 | |
1153 |
|
1153 | |||
1154 | follow file history from wdir parent, modified in wdir: |
|
1154 | follow file history from wdir parent, modified in wdir: | |
1155 |
|
1155 | |||
1156 | $ hg log -f add0-mod4 |
|
1156 | $ hg log -f add0-mod4 | |
1157 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1157 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1158 |
|
1158 | |||
1159 | $ hg grep --diff -f data add0-mod4 |
|
1159 | $ hg grep --diff -f data add0-mod4 | |
1160 | add0-mod4:0:+:data0 |
|
1160 | add0-mod4:0:+:data0 | |
1161 |
|
1161 | |||
1162 | $ hg grep -f data add0-mod4 |
|
1162 | $ hg grep -f data add0-mod4 | |
1163 | add0-mod4:3:data0 |
|
1163 | add0-mod4:3:data0 | |
1164 | add0-mod4:1:data0 |
|
1164 | add0-mod4:1:data0 | |
1165 | add0-mod4:0:data0 |
|
1165 | add0-mod4:0:data0 | |
1166 |
|
1166 | |||
1167 | follow file history from wdir parent, copied but unmodified: |
|
1167 | follow file history from wdir parent, copied but unmodified: | |
1168 |
|
1168 | |||
1169 | $ hg log -f add0-cp1-cp3 |
|
1169 | $ hg log -f add0-cp1-cp3 | |
1170 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1170 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1171 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
1171 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
1172 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1172 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1173 |
|
1173 | |||
1174 | $ hg grep --diff -f data add0-cp1-cp3 |
|
1174 | $ hg grep --diff -f data add0-cp1-cp3 | |
1175 | add0:0:+:data0 |
|
1175 | add0:0:+:data0 | |
1176 |
|
1176 | |||
1177 | BROKEN: should follow history across renames |
|
1177 | BROKEN: should follow history across renames | |
1178 | $ hg grep -f data add0-cp1-cp3 |
|
1178 | $ hg grep -f data add0-cp1-cp3 | |
1179 | add0-cp1-cp3:3:data0 |
|
1179 | add0-cp1-cp3:3:data0 | |
1180 |
|
1180 | |||
1181 | follow file history from wdir parent, copied and modified: |
|
1181 | follow file history from wdir parent, copied and modified: | |
1182 |
|
1182 | |||
1183 | $ hg log -f add0-cp1-mod1-cp3-mod3 |
|
1183 | $ hg log -f add0-cp1-mod1-cp3-mod3 | |
1184 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1184 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1185 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
1185 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
1186 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1186 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1187 |
|
1187 | |||
1188 | $ hg grep --diff -f data add0-cp1-mod1-cp3-mod3 |
|
1188 | $ hg grep --diff -f data add0-cp1-mod1-cp3-mod3 | |
1189 | add0-cp1-mod1-cp3-mod3:3:+:data3 |
|
1189 | add0-cp1-mod1-cp3-mod3:3:+:data3 | |
1190 | add0-cp1-mod1:1:+:data1 |
|
1190 | add0-cp1-mod1:1:+:data1 | |
1191 | add0:0:+:data0 |
|
1191 | add0:0:+:data0 | |
1192 |
|
1192 | |||
1193 | BROKEN: should follow history across renames |
|
1193 | BROKEN: should follow history across renames | |
1194 | $ hg grep -f data add0-cp1-mod1-cp3-mod3 |
|
1194 | $ hg grep -f data add0-cp1-mod1-cp3-mod3 | |
1195 | add0-cp1-mod1-cp3-mod3:3:data0 |
|
1195 | add0-cp1-mod1-cp3-mod3:3:data0 | |
1196 | add0-cp1-mod1-cp3-mod3:3:data1 |
|
1196 | add0-cp1-mod1-cp3-mod3:3:data1 | |
1197 | add0-cp1-mod1-cp3-mod3:3:data3 |
|
1197 | add0-cp1-mod1-cp3-mod3:3:data3 | |
1198 |
|
1198 | |||
1199 | follow file history from wdir parent, copied in wdir: |
|
1199 | follow file history from wdir parent, copied in wdir: | |
1200 |
|
1200 | |||
1201 | $ hg log -f add0-cp4 |
|
1201 | $ hg log -f add0-cp4 | |
1202 | abort: cannot follow nonexistent file: "add0-cp4" |
|
1202 | abort: cannot follow nonexistent file: "add0-cp4" | |
1203 | [255] |
|
1203 | [255] | |
1204 |
|
1204 | |||
1205 | $ hg grep --diff -f data add0-cp4 |
|
1205 | $ hg grep --diff -f data add0-cp4 | |
1206 | abort: cannot follow nonexistent file: "add0-cp4" |
|
1206 | abort: cannot follow nonexistent file: "add0-cp4" | |
1207 | [255] |
|
1207 | [255] | |
1208 |
|
1208 | |||
1209 | BROKEN: maybe better to abort |
|
1209 | BROKEN: maybe better to abort | |
1210 | $ hg grep -f data add0-cp4 |
|
1210 | $ hg grep -f data add0-cp4 | |
1211 | [1] |
|
1211 | [1] | |
1212 |
|
1212 | |||
1213 | follow file history from wdir parent, removed: |
|
1213 | follow file history from wdir parent, removed: | |
1214 |
|
1214 | |||
1215 | $ hg log -f add0-cp1-mod1-rm3 |
|
1215 | $ hg log -f add0-cp1-mod1-rm3 | |
1216 | abort: cannot follow file not in parent revision: "add0-cp1-mod1-rm3" |
|
1216 | abort: cannot follow file not in parent revision: "add0-cp1-mod1-rm3" | |
1217 | [255] |
|
1217 | [255] | |
1218 |
|
1218 | |||
1219 | $ hg grep --diff -f data add0-cp1-mod1-rm3 |
|
1219 | $ hg grep --diff -f data add0-cp1-mod1-rm3 | |
1220 | abort: cannot follow file not in parent revision: "add0-cp1-mod1-rm3" |
|
1220 | abort: cannot follow file not in parent revision: "add0-cp1-mod1-rm3" | |
1221 | [255] |
|
1221 | [255] | |
1222 |
|
1222 | |||
1223 | BROKEN: maybe better to abort |
|
1223 | BROKEN: maybe better to abort | |
1224 | $ hg grep -f data add0-cp1-mod1-rm3 |
|
1224 | $ hg grep -f data add0-cp1-mod1-rm3 | |
1225 | add0-cp1-mod1-rm3:1:data0 |
|
1225 | add0-cp1-mod1-rm3:1:data0 | |
1226 | add0-cp1-mod1-rm3:1:data1 |
|
1226 | add0-cp1-mod1-rm3:1:data1 | |
1227 |
|
1227 | |||
1228 | follow file history from wdir parent (explicit), removed: |
|
1228 | follow file history from wdir parent (explicit), removed: | |
1229 |
|
1229 | |||
1230 | $ hg log -fr. add0-cp1-mod1-rm3 |
|
1230 | $ hg log -fr. add0-cp1-mod1-rm3 | |
1231 | abort: cannot follow file not in any of the specified revisions: "add0-cp1-mod1-rm3" |
|
1231 | abort: cannot follow file not in any of the specified revisions: "add0-cp1-mod1-rm3" | |
1232 | [255] |
|
1232 | [255] | |
1233 |
|
1233 | |||
1234 | $ hg grep --diff -fr. data add0-cp1-mod1-rm3 |
|
1234 | $ hg grep --diff -fr. data add0-cp1-mod1-rm3 | |
1235 | abort: cannot follow file not in any of the specified revisions: "add0-cp1-mod1-rm3" |
|
1235 | abort: cannot follow file not in any of the specified revisions: "add0-cp1-mod1-rm3" | |
1236 | [255] |
|
1236 | [255] | |
1237 |
|
1237 | |||
1238 | BROKEN: should abort |
|
1238 | BROKEN: should abort | |
1239 | $ hg grep -fr. data add0-cp1-mod1-rm3 |
|
1239 | $ hg grep -fr. data add0-cp1-mod1-rm3 | |
1240 | add0-cp1-mod1-rm3:1:data0 |
|
1240 | add0-cp1-mod1-rm3:1:data0 | |
1241 | add0-cp1-mod1-rm3:1:data1 |
|
1241 | add0-cp1-mod1-rm3:1:data1 | |
1242 |
|
1242 | |||
1243 | follow file history from wdir parent, removed in wdir: |
|
1243 | follow file history from wdir parent, removed in wdir: | |
1244 |
|
1244 | |||
1245 | $ hg log -f add0-rm4 |
|
1245 | $ hg log -f add0-rm4 | |
1246 | abort: cannot follow file not in parent revision: "add0-rm4" |
|
1246 | abort: cannot follow file not in parent revision: "add0-rm4" | |
1247 | [255] |
|
1247 | [255] | |
1248 |
|
1248 | |||
1249 | $ hg grep --diff -f data add0-rm4 |
|
1249 | $ hg grep --diff -f data add0-rm4 | |
1250 | abort: cannot follow file not in parent revision: "add0-rm4" |
|
1250 | abort: cannot follow file not in parent revision: "add0-rm4" | |
1251 | [255] |
|
1251 | [255] | |
1252 |
|
1252 | |||
1253 | BROKEN: should abort |
|
1253 | BROKEN: should abort | |
1254 | $ hg grep -f data add0-rm4 |
|
1254 | $ hg grep -f data add0-rm4 | |
1255 | add0-rm4:3:data0 |
|
1255 | add0-rm4:3:data0 | |
1256 | add0-rm4:1:data0 |
|
1256 | add0-rm4:1:data0 | |
1257 | add0-rm4:0:data0 |
|
1257 | add0-rm4:0:data0 | |
1258 |
|
1258 | |||
1259 | follow file history from wdir parent (explicit), removed in wdir: |
|
1259 | follow file history from wdir parent (explicit), removed in wdir: | |
1260 |
|
1260 | |||
1261 | $ hg log -fr. add0-rm4 |
|
1261 | $ hg log -fr. add0-rm4 | |
1262 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1262 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1263 |
|
1263 | |||
1264 | $ hg grep --diff -fr. data add0-rm4 |
|
1264 | $ hg grep --diff -fr. data add0-rm4 | |
1265 | add0-rm4:0:+:data0 |
|
1265 | add0-rm4:0:+:data0 | |
1266 |
|
1266 | |||
1267 | $ hg grep -fr. data add0-rm4 |
|
1267 | $ hg grep -fr. data add0-rm4 | |
1268 | add0-rm4:3:data0 |
|
1268 | add0-rm4:3:data0 | |
1269 | add0-rm4:1:data0 |
|
1269 | add0-rm4:1:data0 | |
1270 | add0-rm4:0:data0 |
|
1270 | add0-rm4:0:data0 | |
1271 |
|
1271 | |||
1272 | follow file history from wdir parent, multiple files: |
|
1272 | follow file history from wdir parent, multiple files: | |
1273 |
|
1273 | |||
1274 | $ hg log -f add0-mod3 add0-cp1-mod1 |
|
1274 | $ hg log -f add0-mod3 add0-cp1-mod1 | |
1275 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1275 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1276 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 |
|
1276 | 1: A add0-cp1, A add0-cp1-mod1, A add0-cp1-mod1-rm3, M add0-mod1, R add0-rm1 | |
1277 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1277 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1278 |
|
1278 | |||
1279 | $ hg grep --diff -f data add0-mod3 add0-cp1-mod1 |
|
1279 | $ hg grep --diff -f data add0-mod3 add0-cp1-mod1 | |
1280 | add0-mod3:3:+:data3 |
|
1280 | add0-mod3:3:+:data3 | |
1281 | add0-cp1-mod1:1:+:data1 |
|
1281 | add0-cp1-mod1:1:+:data1 | |
1282 | add0:0:+:data0 |
|
1282 | add0:0:+:data0 | |
1283 | add0-mod3:0:+:data0 |
|
1283 | add0-mod3:0:+:data0 | |
1284 |
|
1284 | |||
1285 | BROKEN: should follow history across renames |
|
1285 | BROKEN: should follow history across renames | |
1286 | $ hg grep -f data add0-mod3 add0-cp1-mod1 |
|
1286 | $ hg grep -f data add0-mod3 add0-cp1-mod1 | |
1287 | add0-cp1-mod1:3:data0 |
|
1287 | add0-cp1-mod1:3:data0 | |
1288 | add0-cp1-mod1:3:data1 |
|
1288 | add0-cp1-mod1:3:data1 | |
1289 | add0-mod3:3:data0 |
|
1289 | add0-mod3:3:data0 | |
1290 | add0-mod3:3:data3 |
|
1290 | add0-mod3:3:data3 | |
1291 | add0-cp1-mod1:1:data0 |
|
1291 | add0-cp1-mod1:1:data0 | |
1292 | add0-cp1-mod1:1:data1 |
|
1292 | add0-cp1-mod1:1:data1 | |
1293 | add0-mod3:1:data0 |
|
1293 | add0-mod3:1:data0 | |
1294 | add0-mod3:0:data0 |
|
1294 | add0-mod3:0:data0 | |
1295 |
|
1295 | |||
1296 | follow file history from specified revision, modified: |
|
1296 | follow file history from specified revision, modified: | |
1297 |
|
1297 | |||
1298 | $ hg log -fr2 add0-mod2 |
|
1298 | $ hg log -fr2 add0-mod2 | |
1299 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
1299 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
1300 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1300 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1301 |
|
1301 | |||
1302 | $ hg grep --diff -fr2 data add0-mod2 |
|
1302 | $ hg grep --diff -fr2 data add0-mod2 | |
1303 | add0-mod2:2:+:data2 |
|
1303 | add0-mod2:2:+:data2 | |
1304 | add0-mod2:0:+:data0 |
|
1304 | add0-mod2:0:+:data0 | |
1305 |
|
1305 | |||
1306 | $ hg grep -fr2 data add0-mod2 |
|
1306 | $ hg grep -fr2 data add0-mod2 | |
1307 | add0-mod2:2:data0 |
|
1307 | add0-mod2:2:data0 | |
1308 | add0-mod2:2:data2 |
|
1308 | add0-mod2:2:data2 | |
1309 | add0-mod2:0:data0 |
|
1309 | add0-mod2:0:data0 | |
1310 |
|
1310 | |||
1311 | follow file history from specified revision, copied but unmodified: |
|
1311 | follow file history from specified revision, copied but unmodified: | |
1312 |
|
1312 | |||
1313 | $ hg log -fr2 add0-cp2 |
|
1313 | $ hg log -fr2 add0-cp2 | |
1314 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
1314 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
1315 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1315 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1316 |
|
1316 | |||
1317 | $ hg grep --diff -fr2 data add0-cp2 |
|
1317 | $ hg grep --diff -fr2 data add0-cp2 | |
1318 | add0:0:+:data0 |
|
1318 | add0:0:+:data0 | |
1319 |
|
1319 | |||
1320 | BROKEN: should follow history across renames |
|
1320 | BROKEN: should follow history across renames | |
1321 | $ hg grep -fr2 data add0-cp2 |
|
1321 | $ hg grep -fr2 data add0-cp2 | |
1322 | add0-cp2:2:data0 |
|
1322 | add0-cp2:2:data0 | |
1323 |
|
1323 | |||
1324 | follow file history from specified revision, copied and modified: |
|
1324 | follow file history from specified revision, copied and modified: | |
1325 |
|
1325 | |||
1326 | $ hg log -fr2 add0-cp2-mod2 |
|
1326 | $ hg log -fr2 add0-cp2-mod2 | |
1327 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
1327 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
1328 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1328 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1329 |
|
1329 | |||
1330 | $ hg grep --diff -fr2 data add0-cp2-mod2 |
|
1330 | $ hg grep --diff -fr2 data add0-cp2-mod2 | |
1331 | add0-cp2-mod2:2:+:data2 |
|
1331 | add0-cp2-mod2:2:+:data2 | |
1332 | add0:0:+:data0 |
|
1332 | add0:0:+:data0 | |
1333 |
|
1333 | |||
1334 | BROKEN: should follow history across renames |
|
1334 | BROKEN: should follow history across renames | |
1335 | $ hg grep -fr2 data add0-cp2-mod2 |
|
1335 | $ hg grep -fr2 data add0-cp2-mod2 | |
1336 | add0-cp2-mod2:2:data0 |
|
1336 | add0-cp2-mod2:2:data0 | |
1337 | add0-cp2-mod2:2:data2 |
|
1337 | add0-cp2-mod2:2:data2 | |
1338 |
|
1338 | |||
1339 | follow file history from specified revision, removed: |
|
1339 | follow file history from specified revision, removed: | |
1340 |
|
1340 | |||
1341 | $ hg log -fr2 add0-rm2 |
|
1341 | $ hg log -fr2 add0-rm2 | |
1342 | abort: cannot follow file not in any of the specified revisions: "add0-rm2" |
|
1342 | abort: cannot follow file not in any of the specified revisions: "add0-rm2" | |
1343 | [255] |
|
1343 | [255] | |
1344 |
|
1344 | |||
1345 | $ hg grep --diff -fr2 data add0-rm2 |
|
1345 | $ hg grep --diff -fr2 data add0-rm2 | |
1346 | abort: cannot follow file not in any of the specified revisions: "add0-rm2" |
|
1346 | abort: cannot follow file not in any of the specified revisions: "add0-rm2" | |
1347 | [255] |
|
1347 | [255] | |
1348 |
|
1348 | |||
1349 | BROKEN: should abort |
|
1349 | BROKEN: should abort | |
1350 | $ hg grep -fr2 data add0-rm2 |
|
1350 | $ hg grep -fr2 data add0-rm2 | |
1351 | add0-rm2:0:data0 |
|
1351 | add0-rm2:0:data0 | |
1352 |
|
1352 | |||
1353 | follow file history from specified revision, multiple files: |
|
1353 | follow file history from specified revision, multiple files: | |
1354 |
|
1354 | |||
1355 | $ hg log -fr2 add0-cp2 add0-mod2 |
|
1355 | $ hg log -fr2 add0-cp2 add0-mod2 | |
1356 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 |
|
1356 | 2: A add0-cp2, A add0-cp2-mod2, M add0-mod2, R add0-rm2 | |
1357 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1357 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1358 |
|
1358 | |||
1359 | $ hg grep --diff -fr2 data add0-cp2 add0-mod2 |
|
1359 | $ hg grep --diff -fr2 data add0-cp2 add0-mod2 | |
1360 | add0-mod2:2:+:data2 |
|
1360 | add0-mod2:2:+:data2 | |
1361 | add0:0:+:data0 |
|
1361 | add0:0:+:data0 | |
1362 | add0-mod2:0:+:data0 |
|
1362 | add0-mod2:0:+:data0 | |
1363 |
|
1363 | |||
1364 | BROKEN: should follow history across renames |
|
1364 | BROKEN: should follow history across renames | |
1365 | $ hg grep -fr2 data add0-cp2 add0-mod2 |
|
1365 | $ hg grep -fr2 data add0-cp2 add0-mod2 | |
1366 | add0-cp2:2:data0 |
|
1366 | add0-cp2:2:data0 | |
1367 | add0-mod2:2:data0 |
|
1367 | add0-mod2:2:data0 | |
1368 | add0-mod2:2:data2 |
|
1368 | add0-mod2:2:data2 | |
1369 | add0-mod2:0:data0 |
|
1369 | add0-mod2:0:data0 | |
1370 |
|
1370 | |||
1371 | follow file history from wdir, unmodified: |
|
1371 | follow file history from wdir, unmodified: | |
1372 |
|
1372 | |||
1373 | $ hg log -fr'wdir()' add0-mod3 |
|
1373 | $ hg log -fr'wdir()' add0-mod3 | |
1374 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
1374 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
1375 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1375 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1376 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1376 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1377 |
|
1377 | |||
1378 | $ hg grep --diff -fr'wdir()' data add0-mod3 |
|
1378 | $ hg grep --diff -fr'wdir()' data add0-mod3 | |
1379 | add0-mod3:3:+:data3 |
|
1379 | add0-mod3:3:+:data3 | |
1380 | add0-mod3:0:+:data0 |
|
1380 | add0-mod3:0:+:data0 | |
1381 |
|
1381 | |||
1382 | $ hg grep -fr'wdir()' data add0-mod3 |
|
1382 | $ hg grep -fr'wdir()' data add0-mod3 | |
1383 | add0-mod3:2147483647:data0 |
|
1383 | add0-mod3:2147483647:data0 | |
1384 | add0-mod3:2147483647:data3 |
|
1384 | add0-mod3:2147483647:data3 | |
1385 | add0-mod3:3:data0 |
|
1385 | add0-mod3:3:data0 | |
1386 | add0-mod3:3:data3 |
|
1386 | add0-mod3:3:data3 | |
1387 | add0-mod3:1:data0 |
|
1387 | add0-mod3:1:data0 | |
1388 | add0-mod3:0:data0 |
|
1388 | add0-mod3:0:data0 | |
1389 |
|
1389 | |||
1390 | follow file history from wdir, modified: |
|
1390 | follow file history from wdir, modified: | |
1391 |
|
1391 | |||
1392 | $ hg log -fr'wdir()' add0-mod4 |
|
1392 | $ hg log -fr'wdir()' add0-mod4 | |
1393 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
1393 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
1394 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1394 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1395 |
|
1395 | |||
1396 | $ hg grep --diff -fr'wdir()' data add0-mod4 |
|
1396 | $ hg grep --diff -fr'wdir()' data add0-mod4 | |
1397 | add0-mod4:2147483647:+:data4 |
|
1397 | add0-mod4:2147483647:+:data4 | |
1398 | add0-mod4:0:+:data0 |
|
1398 | add0-mod4:0:+:data0 | |
1399 |
|
1399 | |||
1400 | $ hg grep -fr'wdir()' data add0-mod4 |
|
1400 | $ hg grep -fr'wdir()' data add0-mod4 | |
1401 | add0-mod4:2147483647:data0 |
|
1401 | add0-mod4:2147483647:data0 | |
1402 | add0-mod4:2147483647:data4 |
|
1402 | add0-mod4:2147483647:data4 | |
1403 | add0-mod4:3:data0 |
|
1403 | add0-mod4:3:data0 | |
1404 | add0-mod4:1:data0 |
|
1404 | add0-mod4:1:data0 | |
1405 | add0-mod4:0:data0 |
|
1405 | add0-mod4:0:data0 | |
1406 |
|
1406 | |||
1407 | follow file history from wdir, copied but unmodified: |
|
1407 | follow file history from wdir, copied but unmodified: | |
1408 |
|
1408 | |||
1409 | $ hg log -fr'wdir()' add0-cp4 |
|
1409 | $ hg log -fr'wdir()' add0-cp4 | |
1410 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
1410 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
1411 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1411 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1412 |
|
1412 | |||
1413 | $ hg grep --diff -fr'wdir()' data add0-cp4 |
|
1413 | $ hg grep --diff -fr'wdir()' data add0-cp4 | |
1414 | add0:0:+:data0 |
|
1414 | add0:0:+:data0 | |
1415 |
|
1415 | |||
1416 | BROKEN: should follow history across renames |
|
1416 | BROKEN: should follow history across renames | |
1417 | $ hg grep -fr'wdir()' data add0-cp4 |
|
1417 | $ hg grep -fr'wdir()' data add0-cp4 | |
1418 | add0-cp4:2147483647:data0 |
|
1418 | add0-cp4:2147483647:data0 | |
1419 |
|
1419 | |||
1420 | follow file history from wdir, copied and modified: |
|
1420 | follow file history from wdir, copied and modified: | |
1421 |
|
1421 | |||
1422 | $ hg log -fr'wdir()' add0-cp4-mod4 |
|
1422 | $ hg log -fr'wdir()' add0-cp4-mod4 | |
1423 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
1423 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
1424 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1424 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1425 |
|
1425 | |||
1426 | $ hg grep --diff -fr'wdir()' data add0-cp4-mod4 |
|
1426 | $ hg grep --diff -fr'wdir()' data add0-cp4-mod4 | |
1427 | add0-cp4-mod4:2147483647:+:data4 |
|
1427 | add0-cp4-mod4:2147483647:+:data4 | |
1428 | add0:0:+:data0 |
|
1428 | add0:0:+:data0 | |
1429 |
|
1429 | |||
1430 | BROKEN: should follow history across renames |
|
1430 | BROKEN: should follow history across renames | |
1431 | $ hg grep -fr'wdir()' data add0-cp4-mod4 |
|
1431 | $ hg grep -fr'wdir()' data add0-cp4-mod4 | |
1432 | add0-cp4-mod4:2147483647:data0 |
|
1432 | add0-cp4-mod4:2147483647:data0 | |
1433 | add0-cp4-mod4:2147483647:data4 |
|
1433 | add0-cp4-mod4:2147483647:data4 | |
1434 |
|
1434 | |||
1435 | follow file history from wdir, multiple files: |
|
1435 | follow file history from wdir, multiple files: | |
1436 |
|
1436 | |||
1437 | $ hg log -fr'wdir()' add0-cp4 add0-mod4 add0-mod3 |
|
1437 | $ hg log -fr'wdir()' add0-cp4 add0-mod4 add0-mod3 | |
1438 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 |
|
1438 | 2147483647: A add0-cp4, A add0-cp4-mod4, M add0-mod4, R add0-rm4 | |
1439 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 |
|
1439 | 3: A add0-cp1-cp3, A add0-cp1-mod1-cp3-mod3, R add0-cp1-mod1-rm3, M add0-mod3 | |
1440 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 |
|
1440 | 0: A add0, A add0-mod1, A add0-mod2, A add0-mod3, A add0-mod4, A add0-rm1, A add0-rm2, A add0-rm4 | |
1441 |
|
1441 | |||
1442 | $ hg grep --diff -fr'wdir()' data add0-cp4 add0-mod4 add0-mod3 |
|
1442 | $ hg grep --diff -fr'wdir()' data add0-cp4 add0-mod4 add0-mod3 | |
1443 | add0-mod4:2147483647:+:data4 |
|
1443 | add0-mod4:2147483647:+:data4 | |
1444 | add0-mod3:3:+:data3 |
|
1444 | add0-mod3:3:+:data3 | |
1445 | add0:0:+:data0 |
|
1445 | add0:0:+:data0 | |
1446 | add0-mod3:0:+:data0 |
|
1446 | add0-mod3:0:+:data0 | |
1447 | add0-mod4:0:+:data0 |
|
1447 | add0-mod4:0:+:data0 | |
1448 |
|
1448 | |||
1449 | BROKEN: should follow history across renames |
|
1449 | BROKEN: should follow history across renames | |
1450 | $ hg grep -fr'wdir()' data add0-cp4 add0-mod4 add0-mod3 |
|
1450 | $ hg grep -fr'wdir()' data add0-cp4 add0-mod4 add0-mod3 | |
1451 | add0-cp4:2147483647:data0 |
|
1451 | add0-cp4:2147483647:data0 | |
1452 | add0-mod3:2147483647:data0 |
|
1452 | add0-mod3:2147483647:data0 | |
1453 | add0-mod3:2147483647:data3 |
|
1453 | add0-mod3:2147483647:data3 | |
1454 | add0-mod4:2147483647:data0 |
|
1454 | add0-mod4:2147483647:data0 | |
1455 | add0-mod4:2147483647:data4 |
|
1455 | add0-mod4:2147483647:data4 | |
1456 | add0-mod3:3:data0 |
|
1456 | add0-mod3:3:data0 | |
1457 | add0-mod3:3:data3 |
|
1457 | add0-mod3:3:data3 | |
1458 | add0-mod4:3:data0 |
|
1458 | add0-mod4:3:data0 | |
1459 | add0-mod3:1:data0 |
|
1459 | add0-mod3:1:data0 | |
1460 | add0-mod4:1:data0 |
|
1460 | add0-mod4:1:data0 | |
1461 | add0-mod3:0:data0 |
|
1461 | add0-mod3:0:data0 | |
1462 | add0-mod4:0:data0 |
|
1462 | add0-mod4:0:data0 | |
1463 |
|
1463 | |||
1464 | $ cd .. |
|
1464 | $ cd .. |
@@ -1,67 +1,62 b'' | |||||
1 | Test that, when an hg push is interrupted and the remote side recieves SIGPIPE, |
|
1 | Test that, when an hg push is interrupted and the remote side recieves SIGPIPE, | |
2 | the remote hg is able to successfully roll back the transaction. |
|
2 | the remote hg is able to successfully roll back the transaction. | |
3 |
|
3 | |||
4 | $ hg init -q remote |
|
4 | $ hg init -q remote | |
5 | $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" -q ssh://user@dummy/`pwd`/remote local |
|
5 | $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" -q ssh://user@dummy/`pwd`/remote local | |
6 |
|
6 | |||
7 | $ check_for_abandoned_transaction() { |
|
7 | $ check_for_abandoned_transaction() { | |
8 |
> |
|
8 | > [ -f $TESTTMP/remote/.hg/store/journal ] && echo "Abandoned transaction!" | |
9 | > } |
|
9 | > } | |
10 |
|
10 | |||
11 | $ pidfile=`pwd`/pidfile |
|
11 | $ pidfile=`pwd`/pidfile | |
12 | $ >$pidfile |
|
12 | $ >$pidfile | |
13 |
|
13 | |||
14 | $ script() { |
|
14 | $ script() { | |
15 | > cat >"$1" |
|
15 | > cat >"$1" | |
16 | > chmod +x "$1" |
|
16 | > chmod +x "$1" | |
17 | > } |
|
17 | > } | |
18 |
|
18 | |||
19 | On the remote end, run hg, piping stdout and stderr through processes that we |
|
19 | On the remote end, run hg, piping stdout and stderr through processes that we | |
20 | know the PIDs of. We will later kill these to simulate an ssh client |
|
20 | know the PIDs of. We will later kill these to simulate an ssh client | |
21 | disconnecting. |
|
21 | disconnecting. | |
22 |
|
22 | |||
23 | $ killable_pipe=`pwd`/killable_pipe.sh |
|
23 | $ killable_pipe=`pwd`/killable_pipe.sh | |
24 | $ script $killable_pipe <<EOF |
|
24 | $ script $killable_pipe <<EOF | |
25 | > #!/bin/bash |
|
25 | > #!/bin/bash | |
26 | > echo \$\$ >> $pidfile |
|
26 | > echo \$\$ >> $pidfile | |
27 | > exec cat |
|
27 | > exec cat | |
28 | > EOF |
|
28 | > EOF | |
29 |
|
29 | |||
30 | $ remotecmd=`pwd`/remotecmd.sh |
|
30 | $ remotecmd=`pwd`/remotecmd.sh | |
31 | $ script $remotecmd <<EOF |
|
31 | $ script $remotecmd <<EOF | |
32 | > #!/bin/bash |
|
32 | > #!/bin/bash | |
33 | > hg "\$@" 1> >($killable_pipe) 2> >($killable_pipe >&2) |
|
33 | > hg "\$@" 1> >($killable_pipe) 2> >($killable_pipe >&2) | |
34 | > EOF |
|
34 | > EOF | |
35 |
|
35 | |||
36 | In the pretxnchangegroup hook, kill the PIDs recorded above to simulate ssh |
|
36 | In the pretxnchangegroup hook, kill the PIDs recorded above to simulate ssh | |
37 | disconnecting. Then exit nonzero, to force a transaction rollback. |
|
37 | disconnecting. Then exit nonzero, to force a transaction rollback. | |
38 |
|
38 | |||
39 | $ hook_script=`pwd`/pretxnchangegroup.sh |
|
39 | $ hook_script=`pwd`/pretxnchangegroup.sh | |
40 | $ script $hook_script <<EOF |
|
40 | $ script $hook_script <<EOF | |
41 | > #!/bin/bash |
|
41 | > #!/bin/bash | |
42 | > for pid in \$(cat $pidfile) ; do |
|
42 | > for pid in \$(cat $pidfile) ; do | |
43 | > kill \$pid |
|
43 | > kill \$pid | |
44 | > while kill -0 \$pid 2>/dev/null ; do |
|
44 | > while kill -0 \$pid 2>/dev/null ; do | |
45 | > sleep 0.1 |
|
45 | > sleep 0.1 | |
46 | > done |
|
46 | > done | |
47 | > done |
|
47 | > done | |
48 | > exit 1 |
|
48 | > exit 1 | |
49 | > EOF |
|
49 | > EOF | |
50 |
|
50 | |||
51 | $ cat >remote/.hg/hgrc <<EOF |
|
51 | $ cat >remote/.hg/hgrc <<EOF | |
52 | > [hooks] |
|
52 | > [hooks] | |
53 | > pretxnchangegroup.break-things=$hook_script |
|
53 | > pretxnchangegroup.break-things=$hook_script | |
54 | > EOF |
|
54 | > EOF | |
55 |
|
55 | |||
56 | $ cd local |
|
56 | $ cd local | |
57 | $ echo foo > foo ; hg commit -qAm "commit" |
|
57 | $ echo foo > foo ; hg commit -qAm "commit" | |
58 | $ hg push -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --remotecmd $remotecmd 2>&1 | grep -v $killable_pipe |
|
58 | $ hg push -q -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --remotecmd $remotecmd 2>&1 | grep -v $killable_pipe | |
59 | pushing to ssh://user@dummy/$TESTTMP/remote |
|
|||
60 | searching for changes |
|
|||
61 | remote: adding changesets |
|
|||
62 | remote: adding manifests |
|
|||
63 | remote: adding file changes |
|
|||
64 | abort: stream ended unexpectedly (got 0 bytes, expected 4) |
|
59 | abort: stream ended unexpectedly (got 0 bytes, expected 4) | |
65 |
|
60 | |||
66 | $ check_for_abandoned_transaction |
|
61 | $ check_for_abandoned_transaction | |
67 | [1] |
|
62 | [1] |
General Comments 0
You need to be logged in to leave comments.
Login now