##// END OF EJS Templates
branching: merge stable into default
Raphaël Gomès -
r50367:f59e49f6 merge default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
The requested commit or file is too big and content was truncated. Show full diff
@@ -1,233 +1,235 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 335a558f81dc73afeab4d7be63617392b130117f 0 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
@@ -1,246 +1,248 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
218 0e06a7ab9e0d5c65af4e511aee1e0342998799df 5.6rc0
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
219 18c17d63fdabd009e70bf994e5efb7db422f4f7f 5.6
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
220 1d5189a57405ceca5aa244052c9f948977f4699b 5.6.1
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
221 9da65e3cf3706ff41e08b311381c588440c27baf 5.7rc0
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
222 0e2e7300f4302b02412b0b734717697049494c4c 5.7
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
223 d5d9177c0045d206db575bae6daa98e2cb2fe5bc 5.7.1
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
224 f67b8946bb1b6cfa8328dbf8d6a9128b69ccdcb4 5.8rc0
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
225 8d2b62d716b095507effaa8d56f87cd27ba659ab 5.8rc1
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
226 067f2c53fb24506c9e9fb4639871b13b19a85f8a 5.8
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
227 411dc27fd9fd076d6a031a08fcaace659afe2fe3 5.8.1
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
228 d7515d29761d5ada7d9c765f517db67db75dea9a 5.9rc0
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
229 2813d406b03607cdb8c06cb04c44efcc9a79d9a2 5.9rc1
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
230 53221078e0de65d1a821ce5311dec45a7a978301 5.9
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
231 86a60679cf619e14cee9442f865fcf31b142cb9f 5.9.1
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
232 750920b18aaaddd654756be40dec59d90f2643be 5.9.2
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
233 6ee0244fc1cf889ae543d2ce0ec45201ae0be6e1 5.9.3
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
234 a44bb185f6bdbecc754996d8386722e2f0123b0a 6.0rc0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
235 5d08b289e2e526259d7d5ea32b70fe76d5b327d7 6.0
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
236 799fdf4cca80cb9ae40537a90995e6bd163ebc0b 6.0.1
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
237 75676122c2bf7594ac732b7388db4c74c648b365 6.0.2
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
238 dcec16e799ddb6d33fcd11b04af530250a417a58 6.0.3
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
239 c00d3ce4e94bb0ee8d809e25e1dcb2a5fab84e2c 6.1rc0
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
240 d4486810a1795fba9521449b8885ced034f3a6dd 6.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
241 5bd6bcd31dd1ebb63b8914b00064f96297267af7 6.1.1
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
242 0ddd5e1f5f67438af85d12e4ce6c39021dde9916 6.1.2
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
243 6b10151b962108f65bfa12b3918b1021ca334f73 6.1.3
244 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4
244 0cc5f74ff7f0f4ac2427096bddbe102dbc2453ae 6.1.4
245 288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0
245 288de6f5d724bba7bf1669e2838f196962bb7528 6.2rc0
246 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2
246 094a5fa3cf52f936e0de3f1e507c818bee5ece6b 6.2
247 f69bffd00abe3a1b94d1032eb2c92e611d16a192 6.2.1
248 b5c8524827d20fe2e0ca8fb1234a0fe35a1a36c7 6.2.2
@@ -1,1325 +1,1330 b''
1 # aws.py - Automation code for Amazon Web Services
1 # aws.py - Automation code for Amazon Web Services
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 contextlib
10 import contextlib
11 import copy
11 import copy
12 import hashlib
12 import hashlib
13 import json
13 import json
14 import os
14 import os
15 import pathlib
15 import pathlib
16 import subprocess
16 import subprocess
17 import time
17 import time
18
18
19 import boto3
19 import boto3
20 import botocore.exceptions
20 import botocore.exceptions
21
21
22 from .linux import BOOTSTRAP_DEBIAN
22 from .linux import BOOTSTRAP_DEBIAN
23 from .ssh import (
23 from .ssh import (
24 exec_command as ssh_exec_command,
24 exec_command as ssh_exec_command,
25 wait_for_ssh,
25 wait_for_ssh,
26 )
26 )
27 from .winrm import (
27 from .winrm import (
28 run_powershell,
28 run_powershell,
29 wait_for_winrm,
29 wait_for_winrm,
30 )
30 )
31
31
32
32
33 SOURCE_ROOT = pathlib.Path(
33 SOURCE_ROOT = pathlib.Path(
34 os.path.abspath(__file__)
34 os.path.abspath(__file__)
35 ).parent.parent.parent.parent
35 ).parent.parent.parent.parent
36
36
37 INSTALL_WINDOWS_DEPENDENCIES = (
37 INSTALL_WINDOWS_DEPENDENCIES = (
38 SOURCE_ROOT / 'contrib' / 'install-windows-dependencies.ps1'
38 SOURCE_ROOT / 'contrib' / 'install-windows-dependencies.ps1'
39 )
39 )
40
40
41
41
42 INSTANCE_TYPES_WITH_STORAGE = {
42 INSTANCE_TYPES_WITH_STORAGE = {
43 'c5d',
43 'c5d',
44 'd2',
44 'd2',
45 'h1',
45 'h1',
46 'i3',
46 'i3',
47 'm5ad',
47 'm5ad',
48 'm5d',
48 'm5d',
49 'r5d',
49 'r5d',
50 'r5ad',
50 'r5ad',
51 'x1',
51 'x1',
52 'z1d',
52 'z1d',
53 }
53 }
54
54
55
55
56 AMAZON_ACCOUNT_ID = '801119661308'
56 AMAZON_ACCOUNT_ID = '801119661308'
57 DEBIAN_ACCOUNT_ID = '379101102735'
57 DEBIAN_ACCOUNT_ID = '379101102735'
58 DEBIAN_ACCOUNT_ID_2 = '136693071363'
58 DEBIAN_ACCOUNT_ID_2 = '136693071363'
59 UBUNTU_ACCOUNT_ID = '099720109477'
59 UBUNTU_ACCOUNT_ID = '099720109477'
60
60
61
61
62 WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2019-English-Full-Base-*'
62 WINDOWS_BASE_IMAGE_NAME = 'Windows_Server-2022-English-Full-Base-*'
63
63
64
64
65 KEY_PAIRS = {
65 KEY_PAIRS = {
66 'automation',
66 'automation',
67 }
67 }
68
68
69
69
70 SECURITY_GROUPS = {
70 SECURITY_GROUPS = {
71 'linux-dev-1': {
71 'linux-dev-1': {
72 'description': 'Mercurial Linux instances that perform build/test automation',
72 'description': 'Mercurial Linux instances that perform build/test automation',
73 'ingress': [
73 'ingress': [
74 {
74 {
75 'FromPort': 22,
75 'FromPort': 22,
76 'ToPort': 22,
76 'ToPort': 22,
77 'IpProtocol': 'tcp',
77 'IpProtocol': 'tcp',
78 'IpRanges': [
78 'IpRanges': [
79 {
79 {
80 'CidrIp': '0.0.0.0/0',
80 'CidrIp': '0.0.0.0/0',
81 'Description': 'SSH from entire Internet',
81 'Description': 'SSH from entire Internet',
82 },
82 },
83 ],
83 ],
84 },
84 },
85 ],
85 ],
86 },
86 },
87 'windows-dev-1': {
87 'windows-dev-1': {
88 'description': 'Mercurial Windows instances that perform build automation',
88 'description': 'Mercurial Windows instances that perform build automation',
89 'ingress': [
89 'ingress': [
90 {
90 {
91 'FromPort': 22,
91 'FromPort': 22,
92 'ToPort': 22,
92 'ToPort': 22,
93 'IpProtocol': 'tcp',
93 'IpProtocol': 'tcp',
94 'IpRanges': [
94 'IpRanges': [
95 {
95 {
96 'CidrIp': '0.0.0.0/0',
96 'CidrIp': '0.0.0.0/0',
97 'Description': 'SSH from entire Internet',
97 'Description': 'SSH from entire Internet',
98 },
98 },
99 ],
99 ],
100 },
100 },
101 {
101 {
102 'FromPort': 3389,
102 'FromPort': 3389,
103 'ToPort': 3389,
103 'ToPort': 3389,
104 'IpProtocol': 'tcp',
104 'IpProtocol': 'tcp',
105 'IpRanges': [
105 'IpRanges': [
106 {
106 {
107 'CidrIp': '0.0.0.0/0',
107 'CidrIp': '0.0.0.0/0',
108 'Description': 'RDP from entire Internet',
108 'Description': 'RDP from entire Internet',
109 },
109 },
110 ],
110 ],
111 },
111 },
112 {
112 {
113 'FromPort': 5985,
113 'FromPort': 5985,
114 'ToPort': 5986,
114 'ToPort': 5986,
115 'IpProtocol': 'tcp',
115 'IpProtocol': 'tcp',
116 'IpRanges': [
116 'IpRanges': [
117 {
117 {
118 'CidrIp': '0.0.0.0/0',
118 'CidrIp': '0.0.0.0/0',
119 'Description': 'PowerShell Remoting (Windows Remote Management)',
119 'Description': 'PowerShell Remoting (Windows Remote Management)',
120 },
120 },
121 ],
121 ],
122 },
122 },
123 ],
123 ],
124 },
124 },
125 }
125 }
126
126
127
127
128 IAM_ROLES = {
128 IAM_ROLES = {
129 'ephemeral-ec2-role-1': {
129 'ephemeral-ec2-role-1': {
130 'description': 'Mercurial temporary EC2 instances',
130 'description': 'Mercurial temporary EC2 instances',
131 'policy_arns': [
131 'policy_arns': [
132 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM',
132 'arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM',
133 ],
133 ],
134 },
134 },
135 }
135 }
136
136
137
137
138 ASSUME_ROLE_POLICY_DOCUMENT = '''
138 ASSUME_ROLE_POLICY_DOCUMENT = '''
139 {
139 {
140 "Version": "2012-10-17",
140 "Version": "2012-10-17",
141 "Statement": [
141 "Statement": [
142 {
142 {
143 "Effect": "Allow",
143 "Effect": "Allow",
144 "Principal": {
144 "Principal": {
145 "Service": "ec2.amazonaws.com"
145 "Service": "ec2.amazonaws.com"
146 },
146 },
147 "Action": "sts:AssumeRole"
147 "Action": "sts:AssumeRole"
148 }
148 }
149 ]
149 ]
150 }
150 }
151 '''.strip()
151 '''.strip()
152
152
153
153
154 IAM_INSTANCE_PROFILES = {
154 IAM_INSTANCE_PROFILES = {
155 'ephemeral-ec2-1': {
155 'ephemeral-ec2-1': {
156 'roles': [
156 'roles': [
157 'ephemeral-ec2-role-1',
157 'ephemeral-ec2-role-1',
158 ],
158 ],
159 }
159 }
160 }
160 }
161
161
162
162
163 # User Data for Windows EC2 instance. Mainly used to set the password
163 # User Data for Windows EC2 instance. Mainly used to set the password
164 # and configure WinRM.
164 # and configure WinRM.
165 # Inspired by the User Data script used by Packer
165 # Inspired by the User Data script used by Packer
166 # (from https://www.packer.io/intro/getting-started/build-image.html).
166 # (from https://www.packer.io/intro/getting-started/build-image.html).
167 WINDOWS_USER_DATA = r'''
167 WINDOWS_USER_DATA = r'''
168 <powershell>
168 <powershell>
169
169
170 # TODO enable this once we figure out what is failing.
170 # TODO enable this once we figure out what is failing.
171 #$ErrorActionPreference = "stop"
171 #$ErrorActionPreference = "stop"
172
172
173 # Set administrator password
173 # Set administrator password
174 net user Administrator "%s"
174 net user Administrator "%s"
175 wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
175 wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
176
176
177 # And set it via EC2Launch so it persists across reboots.
178 $config = & $env:ProgramFiles\Amazon\EC2Launch\EC2Launch.exe get-agent-config --format json | ConvertFrom-Json
179 $config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml
180 $setAdminAccount = @"
181 {
182 "task": "setAdminAccount",
183 "inputs": {
184 "password": {
185 "type": "static",
186 "data": "%s"
187 }
188 }
189 }
190 "@
191 $config.config | %%{if($_.stage -eq 'preReady'){$_.tasks += (ConvertFrom-Json -InputObject $setAdminAccount)}}
192 $config | ConvertTo-Json -Depth 6 | Out-File -encoding UTF8 $env:ProgramData/Amazon/EC2Launch/config/agent-config.yml
193
177 # First, make sure WinRM can't be connected to
194 # First, make sure WinRM can't be connected to
178 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
195 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new enable=yes action=block
179
196
180 # Delete any existing WinRM listeners
197 # Delete any existing WinRM listeners
181 winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null
198 winrm delete winrm/config/listener?Address=*+Transport=HTTP 2>$Null
182 winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null
199 winrm delete winrm/config/listener?Address=*+Transport=HTTPS 2>$Null
183
200
184 # Create a new WinRM listener and configure
201 # Create a new WinRM listener and configure
185 winrm create winrm/config/listener?Address=*+Transport=HTTP
202 winrm create winrm/config/listener?Address=*+Transport=HTTP
186 winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}'
203 winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="0"}'
187 winrm set winrm/config '@{MaxTimeoutms="7200000"}'
204 winrm set winrm/config '@{MaxTimeoutms="7200000"}'
188 winrm set winrm/config/service '@{AllowUnencrypted="true"}'
205 winrm set winrm/config/service '@{AllowUnencrypted="true"}'
189 winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}'
206 winrm set winrm/config/service '@{MaxConcurrentOperationsPerUser="12000"}'
190 winrm set winrm/config/service/auth '@{Basic="true"}'
207 winrm set winrm/config/service/auth '@{Basic="true"}'
191 winrm set winrm/config/client/auth '@{Basic="true"}'
208 winrm set winrm/config/client/auth '@{Basic="true"}'
192
209
193 # Configure UAC to allow privilege elevation in remote shells
210 # Configure UAC to allow privilege elevation in remote shells
194 $Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
211 $Key = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System'
195 $Setting = 'LocalAccountTokenFilterPolicy'
212 $Setting = 'LocalAccountTokenFilterPolicy'
196 Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force
213 Set-ItemProperty -Path $Key -Name $Setting -Value 1 -Force
197
214
198 # Avoid long usernames in the temp directory path because the '~' causes extra quoting in ssh output
215 # Avoid long usernames in the temp directory path because the '~' causes extra quoting in ssh output
199 [System.Environment]::SetEnvironmentVariable('TMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User)
216 [System.Environment]::SetEnvironmentVariable('TMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User)
200 [System.Environment]::SetEnvironmentVariable('TEMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User)
217 [System.Environment]::SetEnvironmentVariable('TEMP', 'C:\Temp', [System.EnvironmentVariableTarget]::User)
201
218
202 # Configure and restart the WinRM Service; Enable the required firewall exception
219 # Configure and restart the WinRM Service; Enable the required firewall exception
203 Stop-Service -Name WinRM
220 Stop-Service -Name WinRM
204 Set-Service -Name WinRM -StartupType Automatic
221 Set-Service -Name WinRM -StartupType Automatic
205 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any
222 netsh advfirewall firewall set rule name="Windows Remote Management (HTTP-In)" new action=allow localip=any remoteip=any
206 Start-Service -Name WinRM
223 Start-Service -Name WinRM
207
224
208 # Disable firewall on private network interfaces so prompts don't appear.
225 # Disable firewall on private network interfaces so prompts don't appear.
209 Set-NetFirewallProfile -Name private -Enabled false
226 Set-NetFirewallProfile -Name private -Enabled false
210 </powershell>
227 </powershell>
211 '''.lstrip()
228 '''.lstrip()
212
229
213
230
214 WINDOWS_BOOTSTRAP_POWERSHELL = '''
231 WINDOWS_BOOTSTRAP_POWERSHELL = '''
215 Write-Output "installing PowerShell dependencies"
232 Write-Output "installing PowerShell dependencies"
216 Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
233 Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
217 Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
234 Set-PSRepository -Name PSGallery -InstallationPolicy Trusted
218 Install-Module -Name OpenSSHUtils -RequiredVersion 0.0.2.0
235 Install-Module -Name OpenSSHUtils -RequiredVersion 0.0.2.0
219
236
220 Write-Output "installing OpenSSL server"
237 Write-Output "installing OpenSSL server"
221 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
238 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
222 # Various tools will attempt to use older versions of .NET. So we enable
239 # Various tools will attempt to use older versions of .NET. So we enable
223 # the feature that provides them so it doesn't have to be auto-enabled
240 # the feature that provides them so it doesn't have to be auto-enabled
224 # later.
241 # later.
225 Write-Output "enabling .NET Framework feature"
242 Write-Output "enabling .NET Framework feature"
226 Install-WindowsFeature -Name Net-Framework-Core
243 Install-WindowsFeature -Name Net-Framework-Core
227 '''
244 '''
228
245
229
246
230 class AWSConnection:
247 class AWSConnection:
231 """Manages the state of a connection with AWS."""
248 """Manages the state of a connection with AWS."""
232
249
233 def __init__(self, automation, region: str, ensure_ec2_state: bool = True):
250 def __init__(self, automation, region: str, ensure_ec2_state: bool = True):
234 self.automation = automation
251 self.automation = automation
235 self.local_state_path = automation.state_path
252 self.local_state_path = automation.state_path
236
253
237 self.prefix = 'hg-'
254 self.prefix = 'hg-'
238
255
239 self.session = boto3.session.Session(region_name=region)
256 self.session = boto3.session.Session(region_name=region)
240 self.ec2client = self.session.client('ec2')
257 self.ec2client = self.session.client('ec2')
241 self.ec2resource = self.session.resource('ec2')
258 self.ec2resource = self.session.resource('ec2')
242 self.iamclient = self.session.client('iam')
259 self.iamclient = self.session.client('iam')
243 self.iamresource = self.session.resource('iam')
260 self.iamresource = self.session.resource('iam')
244 self.security_groups = {}
261 self.security_groups = {}
245
262
246 if ensure_ec2_state:
263 if ensure_ec2_state:
247 ensure_key_pairs(automation.state_path, self.ec2resource)
264 ensure_key_pairs(automation.state_path, self.ec2resource)
248 self.security_groups = ensure_security_groups(self.ec2resource)
265 self.security_groups = ensure_security_groups(self.ec2resource)
249 ensure_iam_state(self.iamclient, self.iamresource)
266 ensure_iam_state(self.iamclient, self.iamresource)
250
267
251 def key_pair_path_private(self, name):
268 def key_pair_path_private(self, name):
252 """Path to a key pair private key file."""
269 """Path to a key pair private key file."""
253 return self.local_state_path / 'keys' / ('keypair-%s' % name)
270 return self.local_state_path / 'keys' / ('keypair-%s' % name)
254
271
255 def key_pair_path_public(self, name):
272 def key_pair_path_public(self, name):
256 return self.local_state_path / 'keys' / ('keypair-%s.pub' % name)
273 return self.local_state_path / 'keys' / ('keypair-%s.pub' % name)
257
274
258
275
259 def rsa_key_fingerprint(p: pathlib.Path):
276 def rsa_key_fingerprint(p: pathlib.Path):
260 """Compute the fingerprint of an RSA private key."""
277 """Compute the fingerprint of an RSA private key."""
261
278
262 # TODO use rsa package.
279 # TODO use rsa package.
263 res = subprocess.run(
280 res = subprocess.run(
264 [
281 [
265 'openssl',
282 'openssl',
266 'pkcs8',
283 'pkcs8',
267 '-in',
284 '-in',
268 str(p),
285 str(p),
269 '-nocrypt',
286 '-nocrypt',
270 '-topk8',
287 '-topk8',
271 '-outform',
288 '-outform',
272 'DER',
289 'DER',
273 ],
290 ],
274 capture_output=True,
291 capture_output=True,
275 check=True,
292 check=True,
276 )
293 )
277
294
278 sha1 = hashlib.sha1(res.stdout).hexdigest()
295 sha1 = hashlib.sha1(res.stdout).hexdigest()
279 return ':'.join(a + b for a, b in zip(sha1[::2], sha1[1::2]))
296 return ':'.join(a + b for a, b in zip(sha1[::2], sha1[1::2]))
280
297
281
298
282 def ensure_key_pairs(state_path: pathlib.Path, ec2resource, prefix='hg-'):
299 def ensure_key_pairs(state_path: pathlib.Path, ec2resource, prefix='hg-'):
283 remote_existing = {}
300 remote_existing = {}
284
301
285 for kpi in ec2resource.key_pairs.all():
302 for kpi in ec2resource.key_pairs.all():
286 if kpi.name.startswith(prefix):
303 if kpi.name.startswith(prefix):
287 remote_existing[kpi.name[len(prefix) :]] = kpi.key_fingerprint
304 remote_existing[kpi.name[len(prefix) :]] = kpi.key_fingerprint
288
305
289 # Validate that we have these keys locally.
306 # Validate that we have these keys locally.
290 key_path = state_path / 'keys'
307 key_path = state_path / 'keys'
291 key_path.mkdir(exist_ok=True, mode=0o700)
308 key_path.mkdir(exist_ok=True, mode=0o700)
292
309
293 def remove_remote(name):
310 def remove_remote(name):
294 print('deleting key pair %s' % name)
311 print('deleting key pair %s' % name)
295 key = ec2resource.KeyPair(name)
312 key = ec2resource.KeyPair(name)
296 key.delete()
313 key.delete()
297
314
298 def remove_local(name):
315 def remove_local(name):
299 pub_full = key_path / ('keypair-%s.pub' % name)
316 pub_full = key_path / ('keypair-%s.pub' % name)
300 priv_full = key_path / ('keypair-%s' % name)
317 priv_full = key_path / ('keypair-%s' % name)
301
318
302 print('removing %s' % pub_full)
319 print('removing %s' % pub_full)
303 pub_full.unlink()
320 pub_full.unlink()
304 print('removing %s' % priv_full)
321 print('removing %s' % priv_full)
305 priv_full.unlink()
322 priv_full.unlink()
306
323
307 local_existing = {}
324 local_existing = {}
308
325
309 for f in sorted(os.listdir(key_path)):
326 for f in sorted(os.listdir(key_path)):
310 if not f.startswith('keypair-') or not f.endswith('.pub'):
327 if not f.startswith('keypair-') or not f.endswith('.pub'):
311 continue
328 continue
312
329
313 name = f[len('keypair-') : -len('.pub')]
330 name = f[len('keypair-') : -len('.pub')]
314
331
315 pub_full = key_path / f
332 pub_full = key_path / f
316 priv_full = key_path / ('keypair-%s' % name)
333 priv_full = key_path / ('keypair-%s' % name)
317
334
318 with open(pub_full, 'r', encoding='ascii') as fh:
335 with open(pub_full, 'r', encoding='ascii') as fh:
319 data = fh.read()
336 data = fh.read()
320
337
321 if not data.startswith('ssh-rsa '):
338 if not data.startswith('ssh-rsa '):
322 print(
339 print(
323 'unexpected format for key pair file: %s; removing' % pub_full
340 'unexpected format for key pair file: %s; removing' % pub_full
324 )
341 )
325 pub_full.unlink()
342 pub_full.unlink()
326 priv_full.unlink()
343 priv_full.unlink()
327 continue
344 continue
328
345
329 local_existing[name] = rsa_key_fingerprint(priv_full)
346 local_existing[name] = rsa_key_fingerprint(priv_full)
330
347
331 for name in sorted(set(remote_existing) | set(local_existing)):
348 for name in sorted(set(remote_existing) | set(local_existing)):
332 if name not in local_existing:
349 if name not in local_existing:
333 actual = '%s%s' % (prefix, name)
350 actual = '%s%s' % (prefix, name)
334 print('remote key %s does not exist locally' % name)
351 print('remote key %s does not exist locally' % name)
335 remove_remote(actual)
352 remove_remote(actual)
336 del remote_existing[name]
353 del remote_existing[name]
337
354
338 elif name not in remote_existing:
355 elif name not in remote_existing:
339 print('local key %s does not exist remotely' % name)
356 print('local key %s does not exist remotely' % name)
340 remove_local(name)
357 remove_local(name)
341 del local_existing[name]
358 del local_existing[name]
342
359
343 elif remote_existing[name] != local_existing[name]:
360 elif remote_existing[name] != local_existing[name]:
344 print(
361 print(
345 'key fingerprint mismatch for %s; '
362 'key fingerprint mismatch for %s; '
346 'removing from local and remote' % name
363 'removing from local and remote' % name
347 )
364 )
348 remove_local(name)
365 remove_local(name)
349 remove_remote('%s%s' % (prefix, name))
366 remove_remote('%s%s' % (prefix, name))
350 del local_existing[name]
367 del local_existing[name]
351 del remote_existing[name]
368 del remote_existing[name]
352
369
353 missing = KEY_PAIRS - set(remote_existing)
370 missing = KEY_PAIRS - set(remote_existing)
354
371
355 for name in sorted(missing):
372 for name in sorted(missing):
356 actual = '%s%s' % (prefix, name)
373 actual = '%s%s' % (prefix, name)
357 print('creating key pair %s' % actual)
374 print('creating key pair %s' % actual)
358
375
359 priv_full = key_path / ('keypair-%s' % name)
376 priv_full = key_path / ('keypair-%s' % name)
360 pub_full = key_path / ('keypair-%s.pub' % name)
377 pub_full = key_path / ('keypair-%s.pub' % name)
361
378
362 kp = ec2resource.create_key_pair(KeyName=actual)
379 kp = ec2resource.create_key_pair(KeyName=actual)
363
380
364 with priv_full.open('w', encoding='ascii') as fh:
381 with priv_full.open('w', encoding='ascii') as fh:
365 fh.write(kp.key_material)
382 fh.write(kp.key_material)
366 fh.write('\n')
383 fh.write('\n')
367
384
368 priv_full.chmod(0o0600)
385 priv_full.chmod(0o0600)
369
386
370 # SSH public key can be extracted via `ssh-keygen`.
387 # SSH public key can be extracted via `ssh-keygen`.
371 with pub_full.open('w', encoding='ascii') as fh:
388 with pub_full.open('w', encoding='ascii') as fh:
372 subprocess.run(
389 subprocess.run(
373 ['ssh-keygen', '-y', '-f', str(priv_full)],
390 ['ssh-keygen', '-y', '-f', str(priv_full)],
374 stdout=fh,
391 stdout=fh,
375 check=True,
392 check=True,
376 )
393 )
377
394
378 pub_full.chmod(0o0600)
395 pub_full.chmod(0o0600)
379
396
380
397
381 def delete_instance_profile(profile):
398 def delete_instance_profile(profile):
382 for role in profile.roles:
399 for role in profile.roles:
383 print(
400 print(
384 'removing role %s from instance profile %s'
401 'removing role %s from instance profile %s'
385 % (role.name, profile.name)
402 % (role.name, profile.name)
386 )
403 )
387 profile.remove_role(RoleName=role.name)
404 profile.remove_role(RoleName=role.name)
388
405
389 print('deleting instance profile %s' % profile.name)
406 print('deleting instance profile %s' % profile.name)
390 profile.delete()
407 profile.delete()
391
408
392
409
393 def ensure_iam_state(iamclient, iamresource, prefix='hg-'):
410 def ensure_iam_state(iamclient, iamresource, prefix='hg-'):
394 """Ensure IAM state is in sync with our canonical definition."""
411 """Ensure IAM state is in sync with our canonical definition."""
395
412
396 remote_profiles = {}
413 remote_profiles = {}
397
414
398 for profile in iamresource.instance_profiles.all():
415 for profile in iamresource.instance_profiles.all():
399 if profile.name.startswith(prefix):
416 if profile.name.startswith(prefix):
400 remote_profiles[profile.name[len(prefix) :]] = profile
417 remote_profiles[profile.name[len(prefix) :]] = profile
401
418
402 for name in sorted(set(remote_profiles) - set(IAM_INSTANCE_PROFILES)):
419 for name in sorted(set(remote_profiles) - set(IAM_INSTANCE_PROFILES)):
403 delete_instance_profile(remote_profiles[name])
420 delete_instance_profile(remote_profiles[name])
404 del remote_profiles[name]
421 del remote_profiles[name]
405
422
406 remote_roles = {}
423 remote_roles = {}
407
424
408 for role in iamresource.roles.all():
425 for role in iamresource.roles.all():
409 if role.name.startswith(prefix):
426 if role.name.startswith(prefix):
410 remote_roles[role.name[len(prefix) :]] = role
427 remote_roles[role.name[len(prefix) :]] = role
411
428
412 for name in sorted(set(remote_roles) - set(IAM_ROLES)):
429 for name in sorted(set(remote_roles) - set(IAM_ROLES)):
413 role = remote_roles[name]
430 role = remote_roles[name]
414
431
415 print('removing role %s' % role.name)
432 print('removing role %s' % role.name)
416 role.delete()
433 role.delete()
417 del remote_roles[name]
434 del remote_roles[name]
418
435
419 # We've purged remote state that doesn't belong. Create missing
436 # We've purged remote state that doesn't belong. Create missing
420 # instance profiles and roles.
437 # instance profiles and roles.
421 for name in sorted(set(IAM_INSTANCE_PROFILES) - set(remote_profiles)):
438 for name in sorted(set(IAM_INSTANCE_PROFILES) - set(remote_profiles)):
422 actual = '%s%s' % (prefix, name)
439 actual = '%s%s' % (prefix, name)
423 print('creating IAM instance profile %s' % actual)
440 print('creating IAM instance profile %s' % actual)
424
441
425 profile = iamresource.create_instance_profile(
442 profile = iamresource.create_instance_profile(
426 InstanceProfileName=actual
443 InstanceProfileName=actual
427 )
444 )
428 remote_profiles[name] = profile
445 remote_profiles[name] = profile
429
446
430 waiter = iamclient.get_waiter('instance_profile_exists')
447 waiter = iamclient.get_waiter('instance_profile_exists')
431 waiter.wait(InstanceProfileName=actual)
448 waiter.wait(InstanceProfileName=actual)
432 print('IAM instance profile %s is available' % actual)
449 print('IAM instance profile %s is available' % actual)
433
450
434 for name in sorted(set(IAM_ROLES) - set(remote_roles)):
451 for name in sorted(set(IAM_ROLES) - set(remote_roles)):
435 entry = IAM_ROLES[name]
452 entry = IAM_ROLES[name]
436
453
437 actual = '%s%s' % (prefix, name)
454 actual = '%s%s' % (prefix, name)
438 print('creating IAM role %s' % actual)
455 print('creating IAM role %s' % actual)
439
456
440 role = iamresource.create_role(
457 role = iamresource.create_role(
441 RoleName=actual,
458 RoleName=actual,
442 Description=entry['description'],
459 Description=entry['description'],
443 AssumeRolePolicyDocument=ASSUME_ROLE_POLICY_DOCUMENT,
460 AssumeRolePolicyDocument=ASSUME_ROLE_POLICY_DOCUMENT,
444 )
461 )
445
462
446 waiter = iamclient.get_waiter('role_exists')
463 waiter = iamclient.get_waiter('role_exists')
447 waiter.wait(RoleName=actual)
464 waiter.wait(RoleName=actual)
448 print('IAM role %s is available' % actual)
465 print('IAM role %s is available' % actual)
449
466
450 remote_roles[name] = role
467 remote_roles[name] = role
451
468
452 for arn in entry['policy_arns']:
469 for arn in entry['policy_arns']:
453 print('attaching policy %s to %s' % (arn, role.name))
470 print('attaching policy %s to %s' % (arn, role.name))
454 role.attach_policy(PolicyArn=arn)
471 role.attach_policy(PolicyArn=arn)
455
472
456 # Now reconcile state of profiles.
473 # Now reconcile state of profiles.
457 for name, meta in sorted(IAM_INSTANCE_PROFILES.items()):
474 for name, meta in sorted(IAM_INSTANCE_PROFILES.items()):
458 profile = remote_profiles[name]
475 profile = remote_profiles[name]
459 wanted = {'%s%s' % (prefix, role) for role in meta['roles']}
476 wanted = {'%s%s' % (prefix, role) for role in meta['roles']}
460 have = {role.name for role in profile.roles}
477 have = {role.name for role in profile.roles}
461
478
462 for role in sorted(have - wanted):
479 for role in sorted(have - wanted):
463 print('removing role %s from %s' % (role, profile.name))
480 print('removing role %s from %s' % (role, profile.name))
464 profile.remove_role(RoleName=role)
481 profile.remove_role(RoleName=role)
465
482
466 for role in sorted(wanted - have):
483 for role in sorted(wanted - have):
467 print('adding role %s to %s' % (role, profile.name))
484 print('adding role %s to %s' % (role, profile.name))
468 profile.add_role(RoleName=role)
485 profile.add_role(RoleName=role)
469
486
470
487
471 def find_image(ec2resource, owner_id, name, reverse_sort_field=None):
488 def find_image(ec2resource, owner_id, name, reverse_sort_field=None):
472 """Find an AMI by its owner ID and name."""
489 """Find an AMI by its owner ID and name."""
473
490
474 images = ec2resource.images.filter(
491 images = ec2resource.images.filter(
475 Filters=[
492 Filters=[
476 {
493 {
477 'Name': 'owner-id',
494 'Name': 'owner-id',
478 'Values': [owner_id],
495 'Values': [owner_id],
479 },
496 },
480 {
497 {
481 'Name': 'state',
498 'Name': 'state',
482 'Values': ['available'],
499 'Values': ['available'],
483 },
500 },
484 {
501 {
485 'Name': 'image-type',
502 'Name': 'image-type',
486 'Values': ['machine'],
503 'Values': ['machine'],
487 },
504 },
488 {
505 {
489 'Name': 'name',
506 'Name': 'name',
490 'Values': [name],
507 'Values': [name],
491 },
508 },
492 ]
509 ]
493 )
510 )
494
511
495 if reverse_sort_field:
512 if reverse_sort_field:
496 images = sorted(
513 images = sorted(
497 images,
514 images,
498 key=lambda image: getattr(image, reverse_sort_field),
515 key=lambda image: getattr(image, reverse_sort_field),
499 reverse=True,
516 reverse=True,
500 )
517 )
501
518
502 for image in images:
519 for image in images:
503 return image
520 return image
504
521
505 raise Exception('unable to find image for %s' % name)
522 raise Exception('unable to find image for %s' % name)
506
523
507
524
508 def ensure_security_groups(ec2resource, prefix='hg-'):
525 def ensure_security_groups(ec2resource, prefix='hg-'):
509 """Ensure all necessary Mercurial security groups are present.
526 """Ensure all necessary Mercurial security groups are present.
510
527
511 All security groups are prefixed with ``hg-`` by default. Any security
528 All security groups are prefixed with ``hg-`` by default. Any security
512 groups having this prefix but aren't in our list are deleted.
529 groups having this prefix but aren't in our list are deleted.
513 """
530 """
514 existing = {}
531 existing = {}
515
532
516 for group in ec2resource.security_groups.all():
533 for group in ec2resource.security_groups.all():
517 if group.group_name.startswith(prefix):
534 if group.group_name.startswith(prefix):
518 existing[group.group_name[len(prefix) :]] = group
535 existing[group.group_name[len(prefix) :]] = group
519
536
520 purge = set(existing) - set(SECURITY_GROUPS)
537 purge = set(existing) - set(SECURITY_GROUPS)
521
538
522 for name in sorted(purge):
539 for name in sorted(purge):
523 group = existing[name]
540 group = existing[name]
524 print('removing legacy security group: %s' % group.group_name)
541 print('removing legacy security group: %s' % group.group_name)
525 group.delete()
542 group.delete()
526
543
527 security_groups = {}
544 security_groups = {}
528
545
529 for name, group in sorted(SECURITY_GROUPS.items()):
546 for name, group in sorted(SECURITY_GROUPS.items()):
530 if name in existing:
547 if name in existing:
531 security_groups[name] = existing[name]
548 security_groups[name] = existing[name]
532 continue
549 continue
533
550
534 actual = '%s%s' % (prefix, name)
551 actual = '%s%s' % (prefix, name)
535 print('adding security group %s' % actual)
552 print('adding security group %s' % actual)
536
553
537 group_res = ec2resource.create_security_group(
554 group_res = ec2resource.create_security_group(
538 Description=group['description'],
555 Description=group['description'],
539 GroupName=actual,
556 GroupName=actual,
540 )
557 )
541
558
542 group_res.authorize_ingress(
559 group_res.authorize_ingress(
543 IpPermissions=group['ingress'],
560 IpPermissions=group['ingress'],
544 )
561 )
545
562
546 security_groups[name] = group_res
563 security_groups[name] = group_res
547
564
548 return security_groups
565 return security_groups
549
566
550
567
551 def terminate_ec2_instances(ec2resource, prefix='hg-'):
568 def terminate_ec2_instances(ec2resource, prefix='hg-'):
552 """Terminate all EC2 instances managed by us."""
569 """Terminate all EC2 instances managed by us."""
553 waiting = []
570 waiting = []
554
571
555 for instance in ec2resource.instances.all():
572 for instance in ec2resource.instances.all():
556 if instance.state['Name'] == 'terminated':
573 if instance.state['Name'] == 'terminated':
557 continue
574 continue
558
575
559 for tag in instance.tags or []:
576 for tag in instance.tags or []:
560 if tag['Key'] == 'Name' and tag['Value'].startswith(prefix):
577 if tag['Key'] == 'Name' and tag['Value'].startswith(prefix):
561 print('terminating %s' % instance.id)
578 print('terminating %s' % instance.id)
562 instance.terminate()
579 instance.terminate()
563 waiting.append(instance)
580 waiting.append(instance)
564
581
565 for instance in waiting:
582 for instance in waiting:
566 instance.wait_until_terminated()
583 instance.wait_until_terminated()
567
584
568
585
569 def remove_resources(c, prefix='hg-'):
586 def remove_resources(c, prefix='hg-'):
570 """Purge all of our resources in this EC2 region."""
587 """Purge all of our resources in this EC2 region."""
571 ec2resource = c.ec2resource
588 ec2resource = c.ec2resource
572 iamresource = c.iamresource
589 iamresource = c.iamresource
573
590
574 terminate_ec2_instances(ec2resource, prefix=prefix)
591 terminate_ec2_instances(ec2resource, prefix=prefix)
575
592
576 for image in ec2resource.images.filter(Owners=['self']):
593 for image in ec2resource.images.filter(Owners=['self']):
577 if image.name.startswith(prefix):
594 if image.name.startswith(prefix):
578 remove_ami(ec2resource, image)
595 remove_ami(ec2resource, image)
579
596
580 for group in ec2resource.security_groups.all():
597 for group in ec2resource.security_groups.all():
581 if group.group_name.startswith(prefix):
598 if group.group_name.startswith(prefix):
582 print('removing security group %s' % group.group_name)
599 print('removing security group %s' % group.group_name)
583 group.delete()
600 group.delete()
584
601
585 for profile in iamresource.instance_profiles.all():
602 for profile in iamresource.instance_profiles.all():
586 if profile.name.startswith(prefix):
603 if profile.name.startswith(prefix):
587 delete_instance_profile(profile)
604 delete_instance_profile(profile)
588
605
589 for role in iamresource.roles.all():
606 for role in iamresource.roles.all():
590 if role.name.startswith(prefix):
607 if role.name.startswith(prefix):
591 for p in role.attached_policies.all():
608 for p in role.attached_policies.all():
592 print('detaching policy %s from %s' % (p.arn, role.name))
609 print('detaching policy %s from %s' % (p.arn, role.name))
593 role.detach_policy(PolicyArn=p.arn)
610 role.detach_policy(PolicyArn=p.arn)
594
611
595 print('removing role %s' % role.name)
612 print('removing role %s' % role.name)
596 role.delete()
613 role.delete()
597
614
598
615
599 def wait_for_ip_addresses(instances):
616 def wait_for_ip_addresses(instances):
600 """Wait for the public IP addresses of an iterable of instances."""
617 """Wait for the public IP addresses of an iterable of instances."""
601 for instance in instances:
618 for instance in instances:
602 while True:
619 while True:
603 if not instance.public_ip_address:
620 if not instance.public_ip_address:
604 time.sleep(2)
621 time.sleep(2)
605 instance.reload()
622 instance.reload()
606 continue
623 continue
607
624
608 print(
625 print(
609 'public IP address for %s: %s'
626 'public IP address for %s: %s'
610 % (instance.id, instance.public_ip_address)
627 % (instance.id, instance.public_ip_address)
611 )
628 )
612 break
629 break
613
630
614
631
615 def remove_ami(ec2resource, image):
632 def remove_ami(ec2resource, image):
616 """Remove an AMI and its underlying snapshots."""
633 """Remove an AMI and its underlying snapshots."""
617 snapshots = []
634 snapshots = []
618
635
619 for device in image.block_device_mappings:
636 for device in image.block_device_mappings:
620 if 'Ebs' in device:
637 if 'Ebs' in device:
621 snapshots.append(ec2resource.Snapshot(device['Ebs']['SnapshotId']))
638 snapshots.append(ec2resource.Snapshot(device['Ebs']['SnapshotId']))
622
639
623 print('deregistering %s' % image.id)
640 print('deregistering %s' % image.id)
624 image.deregister()
641 image.deregister()
625
642
626 for snapshot in snapshots:
643 for snapshot in snapshots:
627 print('deleting snapshot %s' % snapshot.id)
644 print('deleting snapshot %s' % snapshot.id)
628 snapshot.delete()
645 snapshot.delete()
629
646
630
647
631 def wait_for_ssm(ssmclient, instances):
648 def wait_for_ssm(ssmclient, instances):
632 """Wait for SSM to come online for an iterable of instance IDs."""
649 """Wait for SSM to come online for an iterable of instance IDs."""
633 while True:
650 while True:
634 res = ssmclient.describe_instance_information(
651 res = ssmclient.describe_instance_information(
635 Filters=[
652 Filters=[
636 {
653 {
637 'Key': 'InstanceIds',
654 'Key': 'InstanceIds',
638 'Values': [i.id for i in instances],
655 'Values': [i.id for i in instances],
639 },
656 },
640 ],
657 ],
641 )
658 )
642
659
643 available = len(res['InstanceInformationList'])
660 available = len(res['InstanceInformationList'])
644 wanted = len(instances)
661 wanted = len(instances)
645
662
646 print('%d/%d instances available in SSM' % (available, wanted))
663 print('%d/%d instances available in SSM' % (available, wanted))
647
664
648 if available == wanted:
665 if available == wanted:
649 return
666 return
650
667
651 time.sleep(2)
668 time.sleep(2)
652
669
653
670
654 def run_ssm_command(ssmclient, instances, document_name, parameters):
671 def run_ssm_command(ssmclient, instances, document_name, parameters):
655 """Run a PowerShell script on an EC2 instance."""
672 """Run a PowerShell script on an EC2 instance."""
656
673
657 res = ssmclient.send_command(
674 res = ssmclient.send_command(
658 InstanceIds=[i.id for i in instances],
675 InstanceIds=[i.id for i in instances],
659 DocumentName=document_name,
676 DocumentName=document_name,
660 Parameters=parameters,
677 Parameters=parameters,
661 CloudWatchOutputConfig={
678 CloudWatchOutputConfig={
662 'CloudWatchOutputEnabled': True,
679 'CloudWatchOutputEnabled': True,
663 },
680 },
664 )
681 )
665
682
666 command_id = res['Command']['CommandId']
683 command_id = res['Command']['CommandId']
667
684
668 for instance in instances:
685 for instance in instances:
669 while True:
686 while True:
670 try:
687 try:
671 res = ssmclient.get_command_invocation(
688 res = ssmclient.get_command_invocation(
672 CommandId=command_id,
689 CommandId=command_id,
673 InstanceId=instance.id,
690 InstanceId=instance.id,
674 )
691 )
675 except botocore.exceptions.ClientError as e:
692 except botocore.exceptions.ClientError as e:
676 if e.response['Error']['Code'] == 'InvocationDoesNotExist':
693 if e.response['Error']['Code'] == 'InvocationDoesNotExist':
677 print('could not find SSM command invocation; waiting')
694 print('could not find SSM command invocation; waiting')
678 time.sleep(1)
695 time.sleep(1)
679 continue
696 continue
680 else:
697 else:
681 raise
698 raise
682
699
683 if res['Status'] == 'Success':
700 if res['Status'] == 'Success':
684 break
701 break
685 elif res['Status'] in ('Pending', 'InProgress', 'Delayed'):
702 elif res['Status'] in ('Pending', 'InProgress', 'Delayed'):
686 time.sleep(2)
703 time.sleep(2)
687 else:
704 else:
688 raise Exception(
705 raise Exception(
689 'command failed on %s: %s' % (instance.id, res['Status'])
706 'command failed on %s: %s' % (instance.id, res['Status'])
690 )
707 )
691
708
692
709
693 @contextlib.contextmanager
710 @contextlib.contextmanager
694 def temporary_ec2_instances(ec2resource, config):
711 def temporary_ec2_instances(ec2resource, config):
695 """Create temporary EC2 instances.
712 """Create temporary EC2 instances.
696
713
697 This is a proxy to ``ec2client.run_instances(**config)`` that takes care of
714 This is a proxy to ``ec2client.run_instances(**config)`` that takes care of
698 managing the lifecycle of the instances.
715 managing the lifecycle of the instances.
699
716
700 When the context manager exits, the instances are terminated.
717 When the context manager exits, the instances are terminated.
701
718
702 The context manager evaluates to the list of data structures
719 The context manager evaluates to the list of data structures
703 describing each created instance. The instances may not be available
720 describing each created instance. The instances may not be available
704 for work immediately: it is up to the caller to wait for the instance
721 for work immediately: it is up to the caller to wait for the instance
705 to start responding.
722 to start responding.
706 """
723 """
707
724
708 ids = None
725 ids = None
709
726
710 try:
727 try:
711 res = ec2resource.create_instances(**config)
728 res = ec2resource.create_instances(**config)
712
729
713 ids = [i.id for i in res]
730 ids = [i.id for i in res]
714 print('started instances: %s' % ' '.join(ids))
731 print('started instances: %s' % ' '.join(ids))
715
732
716 yield res
733 yield res
717 finally:
734 finally:
718 if ids:
735 if ids:
719 print('terminating instances: %s' % ' '.join(ids))
736 print('terminating instances: %s' % ' '.join(ids))
720 for instance in res:
737 for instance in res:
721 instance.terminate()
738 instance.terminate()
722 print('terminated %d instances' % len(ids))
739 print('terminated %d instances' % len(ids))
723
740
724
741
725 @contextlib.contextmanager
742 @contextlib.contextmanager
726 def create_temp_windows_ec2_instances(
743 def create_temp_windows_ec2_instances(
727 c: AWSConnection, config, bootstrap: bool = False
744 c: AWSConnection, config, bootstrap: bool = False
728 ):
745 ):
729 """Create temporary Windows EC2 instances.
746 """Create temporary Windows EC2 instances.
730
747
731 This is a higher-level wrapper around ``create_temp_ec2_instances()`` that
748 This is a higher-level wrapper around ``create_temp_ec2_instances()`` that
732 configures the Windows instance for Windows Remote Management. The emitted
749 configures the Windows instance for Windows Remote Management. The emitted
733 instances will have a ``winrm_client`` attribute containing a
750 instances will have a ``winrm_client`` attribute containing a
734 ``pypsrp.client.Client`` instance bound to the instance.
751 ``pypsrp.client.Client`` instance bound to the instance.
735 """
752 """
736 if 'IamInstanceProfile' in config:
753 if 'IamInstanceProfile' in config:
737 raise ValueError('IamInstanceProfile cannot be provided in config')
754 raise ValueError('IamInstanceProfile cannot be provided in config')
738 if 'UserData' in config:
755 if 'UserData' in config:
739 raise ValueError('UserData cannot be provided in config')
756 raise ValueError('UserData cannot be provided in config')
740
757
741 password = c.automation.default_password()
758 password = c.automation.default_password()
742
759
743 config = copy.deepcopy(config)
760 config = copy.deepcopy(config)
744 config['IamInstanceProfile'] = {
761 config['IamInstanceProfile'] = {
745 'Name': 'hg-ephemeral-ec2-1',
762 'Name': 'hg-ephemeral-ec2-1',
746 }
763 }
747 config.setdefault('TagSpecifications', []).append(
764 config.setdefault('TagSpecifications', []).append(
748 {
765 {
749 'ResourceType': 'instance',
766 'ResourceType': 'instance',
750 'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}],
767 'Tags': [{'Key': 'Name', 'Value': 'hg-temp-windows'}],
751 }
768 }
752 )
769 )
753
770
754 if bootstrap:
771 if bootstrap:
755 config['UserData'] = WINDOWS_USER_DATA % password
772 config['UserData'] = WINDOWS_USER_DATA % (password, password)
756
773
757 with temporary_ec2_instances(c.ec2resource, config) as instances:
774 with temporary_ec2_instances(c.ec2resource, config) as instances:
758 wait_for_ip_addresses(instances)
775 wait_for_ip_addresses(instances)
759
776
760 print('waiting for Windows Remote Management service...')
777 print('waiting for Windows Remote Management service...')
761
778
762 for instance in instances:
779 for instance in instances:
763 client = wait_for_winrm(
780 client = wait_for_winrm(
764 instance.public_ip_address, 'Administrator', password
781 instance.public_ip_address, 'Administrator', password
765 )
782 )
766 print('established WinRM connection to %s' % instance.id)
783 print('established WinRM connection to %s' % instance.id)
767 instance.winrm_client = client
784 instance.winrm_client = client
768
785
769 yield instances
786 yield instances
770
787
771
788
772 def resolve_fingerprint(fingerprint):
789 def resolve_fingerprint(fingerprint):
773 fingerprint = json.dumps(fingerprint, sort_keys=True)
790 fingerprint = json.dumps(fingerprint, sort_keys=True)
774 return hashlib.sha256(fingerprint.encode('utf-8')).hexdigest()
791 return hashlib.sha256(fingerprint.encode('utf-8')).hexdigest()
775
792
776
793
777 def find_and_reconcile_image(ec2resource, name, fingerprint):
794 def find_and_reconcile_image(ec2resource, name, fingerprint):
778 """Attempt to find an existing EC2 AMI with a name and fingerprint.
795 """Attempt to find an existing EC2 AMI with a name and fingerprint.
779
796
780 If an image with the specified fingerprint is found, it is returned.
797 If an image with the specified fingerprint is found, it is returned.
781 Otherwise None is returned.
798 Otherwise None is returned.
782
799
783 Existing images for the specified name that don't have the specified
800 Existing images for the specified name that don't have the specified
784 fingerprint or are missing required metadata or deleted.
801 fingerprint or are missing required metadata or deleted.
785 """
802 """
786 # Find existing AMIs with this name and delete the ones that are invalid.
803 # Find existing AMIs with this name and delete the ones that are invalid.
787 # Store a reference to a good image so it can be returned one the
804 # Store a reference to a good image so it can be returned one the
788 # image state is reconciled.
805 # image state is reconciled.
789 images = ec2resource.images.filter(
806 images = ec2resource.images.filter(
790 Filters=[{'Name': 'name', 'Values': [name]}]
807 Filters=[{'Name': 'name', 'Values': [name]}]
791 )
808 )
792
809
793 existing_image = None
810 existing_image = None
794
811
795 for image in images:
812 for image in images:
796 if image.tags is None:
813 if image.tags is None:
797 print(
814 print(
798 'image %s for %s lacks required tags; removing'
815 'image %s for %s lacks required tags; removing'
799 % (image.id, image.name)
816 % (image.id, image.name)
800 )
817 )
801 remove_ami(ec2resource, image)
818 remove_ami(ec2resource, image)
802 else:
819 else:
803 tags = {t['Key']: t['Value'] for t in image.tags}
820 tags = {t['Key']: t['Value'] for t in image.tags}
804
821
805 if tags.get('HGIMAGEFINGERPRINT') == fingerprint:
822 if tags.get('HGIMAGEFINGERPRINT') == fingerprint:
806 existing_image = image
823 existing_image = image
807 else:
824 else:
808 print(
825 print(
809 'image %s for %s has wrong fingerprint; removing'
826 'image %s for %s has wrong fingerprint; removing'
810 % (image.id, image.name)
827 % (image.id, image.name)
811 )
828 )
812 remove_ami(ec2resource, image)
829 remove_ami(ec2resource, image)
813
830
814 return existing_image
831 return existing_image
815
832
816
833
817 def create_ami_from_instance(
834 def create_ami_from_instance(
818 ec2client, instance, name, description, fingerprint
835 ec2client, instance, name, description, fingerprint
819 ):
836 ):
820 """Create an AMI from a running instance.
837 """Create an AMI from a running instance.
821
838
822 Returns the ``ec2resource.Image`` representing the created AMI.
839 Returns the ``ec2resource.Image`` representing the created AMI.
823 """
840 """
824 instance.stop()
841 instance.stop()
825
842
826 ec2client.get_waiter('instance_stopped').wait(
843 ec2client.get_waiter('instance_stopped').wait(
827 InstanceIds=[instance.id],
844 InstanceIds=[instance.id],
828 WaiterConfig={
845 WaiterConfig={
829 'Delay': 5,
846 'Delay': 5,
830 },
847 },
831 )
848 )
832 print('%s is stopped' % instance.id)
849 print('%s is stopped' % instance.id)
833
850
834 image = instance.create_image(
851 image = instance.create_image(
835 Name=name,
852 Name=name,
836 Description=description,
853 Description=description,
837 )
854 )
838
855
839 image.create_tags(
856 image.create_tags(
840 Tags=[
857 Tags=[
841 {
858 {
842 'Key': 'HGIMAGEFINGERPRINT',
859 'Key': 'HGIMAGEFINGERPRINT',
843 'Value': fingerprint,
860 'Value': fingerprint,
844 },
861 },
845 ]
862 ]
846 )
863 )
847
864
848 print('waiting for image %s' % image.id)
865 print('waiting for image %s' % image.id)
849
866
850 ec2client.get_waiter('image_available').wait(
867 ec2client.get_waiter('image_available').wait(
851 ImageIds=[image.id],
868 ImageIds=[image.id],
852 )
869 )
853
870
854 print('image %s available as %s' % (image.id, image.name))
871 print('image %s available as %s' % (image.id, image.name))
855
872
856 return image
873 return image
857
874
858
875
859 def ensure_linux_dev_ami(c: AWSConnection, distro='debian10', prefix='hg-'):
876 def ensure_linux_dev_ami(c: AWSConnection, distro='debian10', prefix='hg-'):
860 """Ensures a Linux development AMI is available and up-to-date.
877 """Ensures a Linux development AMI is available and up-to-date.
861
878
862 Returns an ``ec2.Image`` of either an existing AMI or a newly-built one.
879 Returns an ``ec2.Image`` of either an existing AMI or a newly-built one.
863 """
880 """
864 ec2client = c.ec2client
881 ec2client = c.ec2client
865 ec2resource = c.ec2resource
882 ec2resource = c.ec2resource
866
883
867 name = '%s%s-%s' % (prefix, 'linux-dev', distro)
884 name = '%s%s-%s' % (prefix, 'linux-dev', distro)
868
885
869 if distro == 'debian9':
886 if distro == 'debian9':
870 image = find_image(
887 image = find_image(
871 ec2resource,
888 ec2resource,
872 DEBIAN_ACCOUNT_ID,
889 DEBIAN_ACCOUNT_ID,
873 'debian-stretch-hvm-x86_64-gp2-2019-09-08-17994',
890 'debian-stretch-hvm-x86_64-gp2-2019-09-08-17994',
874 )
891 )
875 ssh_username = 'admin'
892 ssh_username = 'admin'
876 elif distro == 'debian10':
893 elif distro == 'debian10':
877 image = find_image(
894 image = find_image(
878 ec2resource,
895 ec2resource,
879 DEBIAN_ACCOUNT_ID_2,
896 DEBIAN_ACCOUNT_ID_2,
880 'debian-10-amd64-20190909-10',
897 'debian-10-amd64-20190909-10',
881 )
898 )
882 ssh_username = 'admin'
899 ssh_username = 'admin'
883 elif distro == 'ubuntu18.04':
900 elif distro == 'ubuntu18.04':
884 image = find_image(
901 image = find_image(
885 ec2resource,
902 ec2resource,
886 UBUNTU_ACCOUNT_ID,
903 UBUNTU_ACCOUNT_ID,
887 'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20190918',
904 'ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20190918',
888 )
905 )
889 ssh_username = 'ubuntu'
906 ssh_username = 'ubuntu'
890 elif distro == 'ubuntu19.04':
907 elif distro == 'ubuntu19.04':
891 image = find_image(
908 image = find_image(
892 ec2resource,
909 ec2resource,
893 UBUNTU_ACCOUNT_ID,
910 UBUNTU_ACCOUNT_ID,
894 'ubuntu/images/hvm-ssd/ubuntu-disco-19.04-amd64-server-20190918',
911 'ubuntu/images/hvm-ssd/ubuntu-disco-19.04-amd64-server-20190918',
895 )
912 )
896 ssh_username = 'ubuntu'
913 ssh_username = 'ubuntu'
897 else:
914 else:
898 raise ValueError('unsupported Linux distro: %s' % distro)
915 raise ValueError('unsupported Linux distro: %s' % distro)
899
916
900 config = {
917 config = {
901 'BlockDeviceMappings': [
918 'BlockDeviceMappings': [
902 {
919 {
903 'DeviceName': image.block_device_mappings[0]['DeviceName'],
920 'DeviceName': image.block_device_mappings[0]['DeviceName'],
904 'Ebs': {
921 'Ebs': {
905 'DeleteOnTermination': True,
922 'DeleteOnTermination': True,
906 'VolumeSize': 10,
923 'VolumeSize': 10,
907 'VolumeType': 'gp3',
924 'VolumeType': 'gp3',
908 },
925 },
909 },
926 },
910 ],
927 ],
911 'EbsOptimized': True,
928 'EbsOptimized': True,
912 'ImageId': image.id,
929 'ImageId': image.id,
913 'InstanceInitiatedShutdownBehavior': 'stop',
930 'InstanceInitiatedShutdownBehavior': 'stop',
914 # 8 VCPUs for compiling Python.
931 # 8 VCPUs for compiling Python.
915 'InstanceType': 't3.2xlarge',
932 'InstanceType': 't3.2xlarge',
916 'KeyName': '%sautomation' % prefix,
933 'KeyName': '%sautomation' % prefix,
917 'MaxCount': 1,
934 'MaxCount': 1,
918 'MinCount': 1,
935 'MinCount': 1,
919 'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
936 'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
920 }
937 }
921
938
922 requirements3_path = (
939 requirements3_path = (
923 pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.txt'
940 pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.txt'
924 )
941 )
925 requirements35_path = (
942 requirements35_path = (
926 pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.5.txt'
943 pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.5.txt'
927 )
944 )
928 with requirements3_path.open('r', encoding='utf-8') as fh:
945 with requirements3_path.open('r', encoding='utf-8') as fh:
929 requirements3 = fh.read()
946 requirements3 = fh.read()
930 with requirements35_path.open('r', encoding='utf-8') as fh:
947 with requirements35_path.open('r', encoding='utf-8') as fh:
931 requirements35 = fh.read()
948 requirements35 = fh.read()
932
949
933 # Compute a deterministic fingerprint to determine whether image needs to
950 # Compute a deterministic fingerprint to determine whether image needs to
934 # be regenerated.
951 # be regenerated.
935 fingerprint = resolve_fingerprint(
952 fingerprint = resolve_fingerprint(
936 {
953 {
937 'instance_config': config,
954 'instance_config': config,
938 'bootstrap_script': BOOTSTRAP_DEBIAN,
955 'bootstrap_script': BOOTSTRAP_DEBIAN,
939 'requirements_py3': requirements3,
956 'requirements_py3': requirements3,
940 'requirements_py35': requirements35,
957 'requirements_py35': requirements35,
941 }
958 }
942 )
959 )
943
960
944 existing_image = find_and_reconcile_image(ec2resource, name, fingerprint)
961 existing_image = find_and_reconcile_image(ec2resource, name, fingerprint)
945
962
946 if existing_image:
963 if existing_image:
947 return existing_image
964 return existing_image
948
965
949 print('no suitable %s image found; creating one...' % name)
966 print('no suitable %s image found; creating one...' % name)
950
967
951 with temporary_ec2_instances(ec2resource, config) as instances:
968 with temporary_ec2_instances(ec2resource, config) as instances:
952 wait_for_ip_addresses(instances)
969 wait_for_ip_addresses(instances)
953
970
954 instance = instances[0]
971 instance = instances[0]
955
972
956 client = wait_for_ssh(
973 client = wait_for_ssh(
957 instance.public_ip_address,
974 instance.public_ip_address,
958 22,
975 22,
959 username=ssh_username,
976 username=ssh_username,
960 key_filename=str(c.key_pair_path_private('automation')),
977 key_filename=str(c.key_pair_path_private('automation')),
961 )
978 )
962
979
963 home = '/home/%s' % ssh_username
980 home = '/home/%s' % ssh_username
964
981
965 with client:
982 with client:
966 print('connecting to SSH server')
983 print('connecting to SSH server')
967 sftp = client.open_sftp()
984 sftp = client.open_sftp()
968
985
969 print('uploading bootstrap files')
986 print('uploading bootstrap files')
970 with sftp.open('%s/bootstrap' % home, 'wb') as fh:
987 with sftp.open('%s/bootstrap' % home, 'wb') as fh:
971 fh.write(BOOTSTRAP_DEBIAN)
988 fh.write(BOOTSTRAP_DEBIAN)
972 fh.chmod(0o0700)
989 fh.chmod(0o0700)
973
990
974 with sftp.open('%s/requirements-py3.txt' % home, 'wb') as fh:
991 with sftp.open('%s/requirements-py3.txt' % home, 'wb') as fh:
975 fh.write(requirements3)
992 fh.write(requirements3)
976 fh.chmod(0o0700)
993 fh.chmod(0o0700)
977
994
978 with sftp.open('%s/requirements-py3.5.txt' % home, 'wb') as fh:
995 with sftp.open('%s/requirements-py3.5.txt' % home, 'wb') as fh:
979 fh.write(requirements35)
996 fh.write(requirements35)
980 fh.chmod(0o0700)
997 fh.chmod(0o0700)
981
998
982 print('executing bootstrap')
999 print('executing bootstrap')
983 chan, stdin, stdout = ssh_exec_command(
1000 chan, stdin, stdout = ssh_exec_command(
984 client, '%s/bootstrap' % home
1001 client, '%s/bootstrap' % home
985 )
1002 )
986 stdin.close()
1003 stdin.close()
987
1004
988 for line in stdout:
1005 for line in stdout:
989 print(line, end='')
1006 print(line, end='')
990
1007
991 res = chan.recv_exit_status()
1008 res = chan.recv_exit_status()
992 if res:
1009 if res:
993 raise Exception('non-0 exit from bootstrap: %d' % res)
1010 raise Exception('non-0 exit from bootstrap: %d' % res)
994
1011
995 print(
1012 print(
996 'bootstrap completed; stopping %s to create %s'
1013 'bootstrap completed; stopping %s to create %s'
997 % (instance.id, name)
1014 % (instance.id, name)
998 )
1015 )
999
1016
1000 return create_ami_from_instance(
1017 return create_ami_from_instance(
1001 ec2client,
1018 ec2client,
1002 instance,
1019 instance,
1003 name,
1020 name,
1004 'Mercurial Linux development environment',
1021 'Mercurial Linux development environment',
1005 fingerprint,
1022 fingerprint,
1006 )
1023 )
1007
1024
1008
1025
1009 @contextlib.contextmanager
1026 @contextlib.contextmanager
1010 def temporary_linux_dev_instances(
1027 def temporary_linux_dev_instances(
1011 c: AWSConnection,
1028 c: AWSConnection,
1012 image,
1029 image,
1013 instance_type,
1030 instance_type,
1014 prefix='hg-',
1031 prefix='hg-',
1015 ensure_extra_volume=False,
1032 ensure_extra_volume=False,
1016 ):
1033 ):
1017 """Create temporary Linux development EC2 instances.
1034 """Create temporary Linux development EC2 instances.
1018
1035
1019 Context manager resolves to a list of ``ec2.Instance`` that were created
1036 Context manager resolves to a list of ``ec2.Instance`` that were created
1020 and are running.
1037 and are running.
1021
1038
1022 ``ensure_extra_volume`` can be set to ``True`` to require that instances
1039 ``ensure_extra_volume`` can be set to ``True`` to require that instances
1023 have a 2nd storage volume available other than the primary AMI volume.
1040 have a 2nd storage volume available other than the primary AMI volume.
1024 For instance types with instance storage, this does nothing special.
1041 For instance types with instance storage, this does nothing special.
1025 But for instance types without instance storage, an additional EBS volume
1042 But for instance types without instance storage, an additional EBS volume
1026 will be added to the instance.
1043 will be added to the instance.
1027
1044
1028 Instances have an ``ssh_client`` attribute containing a paramiko SSHClient
1045 Instances have an ``ssh_client`` attribute containing a paramiko SSHClient
1029 instance bound to the instance.
1046 instance bound to the instance.
1030
1047
1031 Instances have an ``ssh_private_key_path`` attributing containing the
1048 Instances have an ``ssh_private_key_path`` attributing containing the
1032 str path to the SSH private key to connect to the instance.
1049 str path to the SSH private key to connect to the instance.
1033 """
1050 """
1034
1051
1035 block_device_mappings = [
1052 block_device_mappings = [
1036 {
1053 {
1037 'DeviceName': image.block_device_mappings[0]['DeviceName'],
1054 'DeviceName': image.block_device_mappings[0]['DeviceName'],
1038 'Ebs': {
1055 'Ebs': {
1039 'DeleteOnTermination': True,
1056 'DeleteOnTermination': True,
1040 'VolumeSize': 12,
1057 'VolumeSize': 12,
1041 'VolumeType': 'gp3',
1058 'VolumeType': 'gp3',
1042 },
1059 },
1043 }
1060 }
1044 ]
1061 ]
1045
1062
1046 # This is not an exhaustive list of instance types having instance storage.
1063 # This is not an exhaustive list of instance types having instance storage.
1047 # But
1064 # But
1048 if ensure_extra_volume and not instance_type.startswith(
1065 if ensure_extra_volume and not instance_type.startswith(
1049 tuple(INSTANCE_TYPES_WITH_STORAGE)
1066 tuple(INSTANCE_TYPES_WITH_STORAGE)
1050 ):
1067 ):
1051 main_device = block_device_mappings[0]['DeviceName']
1068 main_device = block_device_mappings[0]['DeviceName']
1052
1069
1053 if main_device == 'xvda':
1070 if main_device == 'xvda':
1054 second_device = 'xvdb'
1071 second_device = 'xvdb'
1055 elif main_device == '/dev/sda1':
1072 elif main_device == '/dev/sda1':
1056 second_device = '/dev/sdb'
1073 second_device = '/dev/sdb'
1057 else:
1074 else:
1058 raise ValueError(
1075 raise ValueError(
1059 'unhandled primary EBS device name: %s' % main_device
1076 'unhandled primary EBS device name: %s' % main_device
1060 )
1077 )
1061
1078
1062 block_device_mappings.append(
1079 block_device_mappings.append(
1063 {
1080 {
1064 'DeviceName': second_device,
1081 'DeviceName': second_device,
1065 'Ebs': {
1082 'Ebs': {
1066 'DeleteOnTermination': True,
1083 'DeleteOnTermination': True,
1067 'VolumeSize': 8,
1084 'VolumeSize': 8,
1068 'VolumeType': 'gp3',
1085 'VolumeType': 'gp3',
1069 },
1086 },
1070 }
1087 }
1071 )
1088 )
1072
1089
1073 config = {
1090 config = {
1074 'BlockDeviceMappings': block_device_mappings,
1091 'BlockDeviceMappings': block_device_mappings,
1075 'EbsOptimized': True,
1092 'EbsOptimized': True,
1076 'ImageId': image.id,
1093 'ImageId': image.id,
1077 'InstanceInitiatedShutdownBehavior': 'terminate',
1094 'InstanceInitiatedShutdownBehavior': 'terminate',
1078 'InstanceType': instance_type,
1095 'InstanceType': instance_type,
1079 'KeyName': '%sautomation' % prefix,
1096 'KeyName': '%sautomation' % prefix,
1080 'MaxCount': 1,
1097 'MaxCount': 1,
1081 'MinCount': 1,
1098 'MinCount': 1,
1082 'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
1099 'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
1083 }
1100 }
1084
1101
1085 with temporary_ec2_instances(c.ec2resource, config) as instances:
1102 with temporary_ec2_instances(c.ec2resource, config) as instances:
1086 wait_for_ip_addresses(instances)
1103 wait_for_ip_addresses(instances)
1087
1104
1088 ssh_private_key_path = str(c.key_pair_path_private('automation'))
1105 ssh_private_key_path = str(c.key_pair_path_private('automation'))
1089
1106
1090 for instance in instances:
1107 for instance in instances:
1091 client = wait_for_ssh(
1108 client = wait_for_ssh(
1092 instance.public_ip_address,
1109 instance.public_ip_address,
1093 22,
1110 22,
1094 username='hg',
1111 username='hg',
1095 key_filename=ssh_private_key_path,
1112 key_filename=ssh_private_key_path,
1096 )
1113 )
1097
1114
1098 instance.ssh_client = client
1115 instance.ssh_client = client
1099 instance.ssh_private_key_path = ssh_private_key_path
1116 instance.ssh_private_key_path = ssh_private_key_path
1100
1117
1101 try:
1118 try:
1102 yield instances
1119 yield instances
1103 finally:
1120 finally:
1104 for instance in instances:
1121 for instance in instances:
1105 instance.ssh_client.close()
1122 instance.ssh_client.close()
1106
1123
1107
1124
1108 def ensure_windows_dev_ami(
1125 def ensure_windows_dev_ami(
1109 c: AWSConnection,
1126 c: AWSConnection,
1110 prefix='hg-',
1127 prefix='hg-',
1111 base_image_name=WINDOWS_BASE_IMAGE_NAME,
1128 base_image_name=WINDOWS_BASE_IMAGE_NAME,
1112 ):
1129 ):
1113 """Ensure Windows Development AMI is available and up-to-date.
1130 """Ensure Windows Development AMI is available and up-to-date.
1114
1131
1115 If necessary, a modern AMI will be built by starting a temporary EC2
1132 If necessary, a modern AMI will be built by starting a temporary EC2
1116 instance and bootstrapping it.
1133 instance and bootstrapping it.
1117
1134
1118 Obsolete AMIs will be deleted so there is only a single AMI having the
1135 Obsolete AMIs will be deleted so there is only a single AMI having the
1119 desired name.
1136 desired name.
1120
1137
1121 Returns an ``ec2.Image`` of either an existing AMI or a newly-built
1138 Returns an ``ec2.Image`` of either an existing AMI or a newly-built
1122 one.
1139 one.
1123 """
1140 """
1124 ec2client = c.ec2client
1141 ec2client = c.ec2client
1125 ec2resource = c.ec2resource
1142 ec2resource = c.ec2resource
1126 ssmclient = c.session.client('ssm')
1143 ssmclient = c.session.client('ssm')
1127
1144
1128 name = '%s%s' % (prefix, 'windows-dev')
1145 name = '%s%s' % (prefix, 'windows-dev')
1129
1146
1130 image = find_image(
1147 image = find_image(
1131 ec2resource,
1148 ec2resource,
1132 AMAZON_ACCOUNT_ID,
1149 AMAZON_ACCOUNT_ID,
1133 base_image_name,
1150 base_image_name,
1134 reverse_sort_field="name",
1151 reverse_sort_field="name",
1135 )
1152 )
1136
1153
1137 config = {
1154 config = {
1138 'BlockDeviceMappings': [
1155 'BlockDeviceMappings': [
1139 {
1156 {
1140 'DeviceName': '/dev/sda1',
1157 'DeviceName': '/dev/sda1',
1141 'Ebs': {
1158 'Ebs': {
1142 'DeleteOnTermination': True,
1159 'DeleteOnTermination': True,
1143 'VolumeSize': 32,
1160 'VolumeSize': 32,
1144 'VolumeType': 'gp3',
1161 'VolumeType': 'gp3',
1145 },
1162 },
1146 }
1163 }
1147 ],
1164 ],
1148 'ImageId': image.id,
1165 'ImageId': image.id,
1149 'InstanceInitiatedShutdownBehavior': 'stop',
1166 'InstanceInitiatedShutdownBehavior': 'stop',
1150 'InstanceType': 'm6i.large',
1167 'InstanceType': 'm6i.large',
1151 'KeyName': '%sautomation' % prefix,
1168 'KeyName': '%sautomation' % prefix,
1152 'MaxCount': 1,
1169 'MaxCount': 1,
1153 'MinCount': 1,
1170 'MinCount': 1,
1154 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id],
1171 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id],
1155 }
1172 }
1156
1173
1157 commands = [
1174 commands = [
1158 # Need to start the service so sshd_config is generated.
1175 # Need to start the service so sshd_config is generated.
1159 'Start-Service sshd',
1176 'Start-Service sshd',
1160 'Write-Output "modifying sshd_config"',
1177 'Write-Output "modifying sshd_config"',
1161 r'$content = Get-Content C:\ProgramData\ssh\sshd_config',
1178 r'$content = Get-Content C:\ProgramData\ssh\sshd_config',
1162 '$content = $content -replace "Match Group administrators","" -replace "AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys",""',
1179 '$content = $content -replace "Match Group administrators","" -replace "AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys",""',
1163 r'$content | Set-Content C:\ProgramData\ssh\sshd_config',
1180 r'$content | Set-Content C:\ProgramData\ssh\sshd_config',
1164 'Import-Module OpenSSHUtils',
1181 'Import-Module OpenSSHUtils',
1165 r'Repair-SshdConfigPermission C:\ProgramData\ssh\sshd_config -Confirm:$false',
1182 r'Repair-SshdConfigPermission C:\ProgramData\ssh\sshd_config -Confirm:$false',
1166 'Restart-Service sshd',
1183 'Restart-Service sshd',
1167 'Write-Output "installing OpenSSL client"',
1184 'Write-Output "installing OpenSSL client"',
1168 'Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0',
1185 'Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0',
1169 'Set-Service -Name sshd -StartupType "Automatic"',
1186 'Set-Service -Name sshd -StartupType "Automatic"',
1170 'Write-Output "OpenSSH server running"',
1187 'Write-Output "OpenSSH server running"',
1171 ]
1188 ]
1172
1189
1173 with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh:
1190 with INSTALL_WINDOWS_DEPENDENCIES.open('r', encoding='utf-8') as fh:
1174 commands.extend(l.rstrip() for l in fh)
1191 commands.extend(l.rstrip() for l in fh)
1175
1192
1176 # Schedule run of EC2Launch on next boot. This ensures that UserData
1177 # is executed.
1178 # We disable setComputerName because it forces a reboot.
1179 # We set an explicit admin password because this causes UserData to run
1180 # as Administrator instead of System.
1181 commands.extend(
1182 [
1183 r'''Set-Content -Path C:\ProgramData\Amazon\EC2-Windows\Launch\Config\LaunchConfig.json '''
1184 r'''-Value '{"setComputerName": false, "setWallpaper": true, "addDnsSuffixList": true, '''
1185 r'''"extendBootVolumeSize": true, "handleUserData": true, '''
1186 r'''"adminPasswordType": "Specify", "adminPassword": "%s"}' '''
1187 % c.automation.default_password(),
1188 r'C:\ProgramData\Amazon\EC2-Windows\Launch\Scripts\InitializeInstance.ps1 '
1189 r'–Schedule',
1190 ]
1191 )
1192
1193 # Disable Windows Defender when bootstrapping because it just slows
1193 # Disable Windows Defender when bootstrapping because it just slows
1194 # things down.
1194 # things down.
1195 commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true')
1195 commands.insert(0, 'Set-MpPreference -DisableRealtimeMonitoring $true')
1196 commands.append('Set-MpPreference -DisableRealtimeMonitoring $false')
1196 commands.append('Set-MpPreference -DisableRealtimeMonitoring $false')
1197
1197
1198 # Trigger shutdown to prepare for imaging.
1199 commands.append(
1200 'Stop-Computer -ComputerName localhost',
1201 )
1202
1198 # Compute a deterministic fingerprint to determine whether image needs
1203 # Compute a deterministic fingerprint to determine whether image needs
1199 # to be regenerated.
1204 # to be regenerated.
1200 fingerprint = resolve_fingerprint(
1205 fingerprint = resolve_fingerprint(
1201 {
1206 {
1202 'instance_config': config,
1207 'instance_config': config,
1203 'user_data': WINDOWS_USER_DATA,
1208 'user_data': WINDOWS_USER_DATA,
1204 'initial_bootstrap': WINDOWS_BOOTSTRAP_POWERSHELL,
1209 'initial_bootstrap': WINDOWS_BOOTSTRAP_POWERSHELL,
1205 'bootstrap_commands': commands,
1210 'bootstrap_commands': commands,
1206 'base_image_name': base_image_name,
1211 'base_image_name': base_image_name,
1207 }
1212 }
1208 )
1213 )
1209
1214
1210 existing_image = find_and_reconcile_image(ec2resource, name, fingerprint)
1215 existing_image = find_and_reconcile_image(ec2resource, name, fingerprint)
1211
1216
1212 if existing_image:
1217 if existing_image:
1213 return existing_image
1218 return existing_image
1214
1219
1215 print('no suitable Windows development image found; creating one...')
1220 print('no suitable Windows development image found; creating one...')
1216
1221
1217 with create_temp_windows_ec2_instances(
1222 with create_temp_windows_ec2_instances(
1218 c, config, bootstrap=True
1223 c, config, bootstrap=True
1219 ) as instances:
1224 ) as instances:
1220 assert len(instances) == 1
1225 assert len(instances) == 1
1221 instance = instances[0]
1226 instance = instances[0]
1222
1227
1223 wait_for_ssm(ssmclient, [instance])
1228 wait_for_ssm(ssmclient, [instance])
1224
1229
1225 # On first boot, install various Windows updates.
1230 # On first boot, install various Windows updates.
1226 # We would ideally use PowerShell Remoting for this. However, there are
1231 # We would ideally use PowerShell Remoting for this. However, there are
1227 # trust issues that make it difficult to invoke Windows Update
1232 # trust issues that make it difficult to invoke Windows Update
1228 # remotely. So we use SSM, which has a mechanism for running Windows
1233 # remotely. So we use SSM, which has a mechanism for running Windows
1229 # Update.
1234 # Update.
1230 print('installing Windows features...')
1235 print('installing Windows features...')
1231 run_ssm_command(
1236 run_ssm_command(
1232 ssmclient,
1237 ssmclient,
1233 [instance],
1238 [instance],
1234 'AWS-RunPowerShellScript',
1239 'AWS-RunPowerShellScript',
1235 {
1240 {
1236 'commands': WINDOWS_BOOTSTRAP_POWERSHELL.split('\n'),
1241 'commands': WINDOWS_BOOTSTRAP_POWERSHELL.split('\n'),
1237 },
1242 },
1238 )
1243 )
1239
1244
1240 # Reboot so all updates are fully applied.
1245 # Reboot so all updates are fully applied.
1241 #
1246 #
1242 # We don't use instance.reboot() here because it is asynchronous and
1247 # We don't use instance.reboot() here because it is asynchronous and
1243 # we don't know when exactly the instance has rebooted. It could take
1248 # we don't know when exactly the instance has rebooted. It could take
1244 # a while to stop and we may start trying to interact with the instance
1249 # a while to stop and we may start trying to interact with the instance
1245 # before it has rebooted.
1250 # before it has rebooted.
1246 print('rebooting instance %s' % instance.id)
1251 print('rebooting instance %s' % instance.id)
1247 instance.stop()
1252 instance.stop()
1248 ec2client.get_waiter('instance_stopped').wait(
1253 ec2client.get_waiter('instance_stopped').wait(
1249 InstanceIds=[instance.id],
1254 InstanceIds=[instance.id],
1250 WaiterConfig={
1255 WaiterConfig={
1251 'Delay': 5,
1256 'Delay': 5,
1252 },
1257 },
1253 )
1258 )
1254
1259
1255 instance.start()
1260 instance.start()
1256 wait_for_ip_addresses([instance])
1261 wait_for_ip_addresses([instance])
1257
1262
1258 # There is a race condition here between the User Data PS script running
1263 # There is a race condition here between the User Data PS script running
1259 # and us connecting to WinRM. This can manifest as
1264 # and us connecting to WinRM. This can manifest as
1260 # "AuthorizationManager check failed" failures during run_powershell().
1265 # "AuthorizationManager check failed" failures during run_powershell().
1261 # TODO figure out a workaround.
1266 # TODO figure out a workaround.
1262
1267
1263 print('waiting for Windows Remote Management to come back...')
1268 print('waiting for Windows Remote Management to come back...')
1264 client = wait_for_winrm(
1269 client = wait_for_winrm(
1265 instance.public_ip_address,
1270 instance.public_ip_address,
1266 'Administrator',
1271 'Administrator',
1267 c.automation.default_password(),
1272 c.automation.default_password(),
1268 )
1273 )
1269 print('established WinRM connection to %s' % instance.id)
1274 print('established WinRM connection to %s' % instance.id)
1270 instance.winrm_client = client
1275 instance.winrm_client = client
1271
1276
1272 print('bootstrapping instance...')
1277 print('bootstrapping instance...')
1273 run_powershell(instance.winrm_client, '\n'.join(commands))
1278 run_powershell(instance.winrm_client, '\n'.join(commands))
1274
1279
1275 print('bootstrap completed; stopping %s to create image' % instance.id)
1280 print('bootstrap completed; stopping %s to create image' % instance.id)
1276 return create_ami_from_instance(
1281 return create_ami_from_instance(
1277 ec2client,
1282 ec2client,
1278 instance,
1283 instance,
1279 name,
1284 name,
1280 'Mercurial Windows development environment',
1285 'Mercurial Windows development environment',
1281 fingerprint,
1286 fingerprint,
1282 )
1287 )
1283
1288
1284
1289
1285 @contextlib.contextmanager
1290 @contextlib.contextmanager
1286 def temporary_windows_dev_instances(
1291 def temporary_windows_dev_instances(
1287 c: AWSConnection,
1292 c: AWSConnection,
1288 image,
1293 image,
1289 instance_type,
1294 instance_type,
1290 prefix='hg-',
1295 prefix='hg-',
1291 disable_antivirus=False,
1296 disable_antivirus=False,
1292 ):
1297 ):
1293 """Create a temporary Windows development EC2 instance.
1298 """Create a temporary Windows development EC2 instance.
1294
1299
1295 Context manager resolves to the list of ``EC2.Instance`` that were created.
1300 Context manager resolves to the list of ``EC2.Instance`` that were created.
1296 """
1301 """
1297 config = {
1302 config = {
1298 'BlockDeviceMappings': [
1303 'BlockDeviceMappings': [
1299 {
1304 {
1300 'DeviceName': '/dev/sda1',
1305 'DeviceName': '/dev/sda1',
1301 'Ebs': {
1306 'Ebs': {
1302 'DeleteOnTermination': True,
1307 'DeleteOnTermination': True,
1303 'VolumeSize': 32,
1308 'VolumeSize': 32,
1304 'VolumeType': 'gp3',
1309 'VolumeType': 'gp3',
1305 },
1310 },
1306 }
1311 }
1307 ],
1312 ],
1308 'ImageId': image.id,
1313 'ImageId': image.id,
1309 'InstanceInitiatedShutdownBehavior': 'stop',
1314 'InstanceInitiatedShutdownBehavior': 'stop',
1310 'InstanceType': instance_type,
1315 'InstanceType': instance_type,
1311 'KeyName': '%sautomation' % prefix,
1316 'KeyName': '%sautomation' % prefix,
1312 'MaxCount': 1,
1317 'MaxCount': 1,
1313 'MinCount': 1,
1318 'MinCount': 1,
1314 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id],
1319 'SecurityGroupIds': [c.security_groups['windows-dev-1'].id],
1315 }
1320 }
1316
1321
1317 with create_temp_windows_ec2_instances(c, config) as instances:
1322 with create_temp_windows_ec2_instances(c, config) as instances:
1318 if disable_antivirus:
1323 if disable_antivirus:
1319 for instance in instances:
1324 for instance in instances:
1320 run_powershell(
1325 run_powershell(
1321 instance.winrm_client,
1326 instance.winrm_client,
1322 'Set-MpPreference -DisableRealtimeMonitoring $true',
1327 'Set-MpPreference -DisableRealtimeMonitoring $true',
1323 )
1328 )
1324
1329
1325 yield instances
1330 yield instances
@@ -1,539 +1,542 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 HG_PURGE = r'''
22 HG_PURGE = r'''
23 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
23 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
24 Set-Location C:\hgdev\src
24 Set-Location C:\hgdev\src
25 hg.exe --config extensions.purge= purge --all
25 hg.exe --config extensions.purge= purge --all
26 if ($LASTEXITCODE -ne 0) {
26 if ($LASTEXITCODE -ne 0) {
27 throw "process exited non-0: $LASTEXITCODE"
27 throw "process exited non-0: $LASTEXITCODE"
28 }
28 }
29 Write-Output "purged Mercurial repo"
29 Write-Output "purged Mercurial repo"
30 '''
30 '''
31
31
32 HG_UPDATE_CLEAN = r'''
32 HG_UPDATE_CLEAN = r'''
33 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
33 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
34 Set-Location C:\hgdev\src
34 Set-Location C:\hgdev\src
35 hg.exe --config extensions.purge= purge --all
35 hg.exe --config extensions.purge= purge --all
36 if ($LASTEXITCODE -ne 0) {{
36 if ($LASTEXITCODE -ne 0) {{
37 throw "process exited non-0: $LASTEXITCODE"
37 throw "process exited non-0: $LASTEXITCODE"
38 }}
38 }}
39 hg.exe update -C {revision}
39 hg.exe update -C {revision}
40 if ($LASTEXITCODE -ne 0) {{
40 if ($LASTEXITCODE -ne 0) {{
41 throw "process exited non-0: $LASTEXITCODE"
41 throw "process exited non-0: $LASTEXITCODE"
42 }}
42 }}
43 hg.exe log -r .
43 hg.exe log -r .
44 Write-Output "updated Mercurial working directory to {revision}"
44 Write-Output "updated Mercurial working directory to {revision}"
45 '''.lstrip()
45 '''.lstrip()
46
46
47 BUILD_INNO_PYTHON3 = r'''
47 BUILD_INNO_PYTHON3 = r'''
48 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
48 $Env:RUSTUP_HOME = "C:\hgdev\rustup"
49 $Env:RUSTUP_HOME = "C:\hgdev\rustup"
49 $Env:CARGO_HOME = "C:\hgdev\cargo"
50 $Env:CARGO_HOME = "C:\hgdev\cargo"
50 Set-Location C:\hgdev\src
51 Set-Location C:\hgdev\src
51 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --pyoxidizer-target {pyoxidizer_target} --version {version}
52 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --pyoxidizer-target {pyoxidizer_target} --version {version}
52 if ($LASTEXITCODE -ne 0) {{
53 if ($LASTEXITCODE -ne 0) {{
53 throw "process exited non-0: $LASTEXITCODE"
54 throw "process exited non-0: $LASTEXITCODE"
54 }}
55 }}
55 '''
56 '''
56
57
57
58
58 BUILD_WHEEL = r'''
59 BUILD_WHEEL = r'''
60 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
59 Set-Location C:\hgdev\src
61 Set-Location C:\hgdev\src
60 C:\hgdev\python{python_version}-{arch}\python.exe -m pip wheel --wheel-dir dist .
62 C:\hgdev\python{python_version}-{arch}\python.exe -m pip wheel --wheel-dir dist .
61 if ($LASTEXITCODE -ne 0) {{
63 if ($LASTEXITCODE -ne 0) {{
62 throw "process exited non-0: $LASTEXITCODE"
64 throw "process exited non-0: $LASTEXITCODE"
63 }}
65 }}
64 '''
66 '''
65
67
66 BUILD_WIX_PYTHON3 = r'''
68 BUILD_WIX_PYTHON3 = r'''
69 $Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
67 $Env:RUSTUP_HOME = "C:\hgdev\rustup"
70 $Env:RUSTUP_HOME = "C:\hgdev\rustup"
68 $Env:CARGO_HOME = "C:\hgdev\cargo"
71 $Env:CARGO_HOME = "C:\hgdev\cargo"
69 Set-Location C:\hgdev\src
72 Set-Location C:\hgdev\src
70 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --pyoxidizer-target {pyoxidizer_target} --version {version}
73 C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --pyoxidizer-target {pyoxidizer_target} --version {version}
71 if ($LASTEXITCODE -ne 0) {{
74 if ($LASTEXITCODE -ne 0) {{
72 throw "process exited non-0: $LASTEXITCODE"
75 throw "process exited non-0: $LASTEXITCODE"
73 }}
76 }}
74 '''
77 '''
75
78
76
79
77 RUN_TESTS = r'''
80 RUN_TESTS = r'''
78 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}"
81 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}"
79 if ($LASTEXITCODE -ne 0) {{
82 if ($LASTEXITCODE -ne 0) {{
80 throw "process exited non-0: $LASTEXITCODE"
83 throw "process exited non-0: $LASTEXITCODE"
81 }}
84 }}
82 '''
85 '''
83
86
84
87
85 WHEEL_FILENAME_PYTHON37_X86 = 'mercurial-{version}-cp37-cp37m-win32.whl'
88 WHEEL_FILENAME_PYTHON37_X86 = 'mercurial-{version}-cp37-cp37m-win32.whl'
86 WHEEL_FILENAME_PYTHON37_X64 = 'mercurial-{version}-cp37-cp37m-win_amd64.whl'
89 WHEEL_FILENAME_PYTHON37_X64 = 'mercurial-{version}-cp37-cp37m-win_amd64.whl'
87 WHEEL_FILENAME_PYTHON38_X86 = 'mercurial-{version}-cp38-cp38-win32.whl'
90 WHEEL_FILENAME_PYTHON38_X86 = 'mercurial-{version}-cp38-cp38-win32.whl'
88 WHEEL_FILENAME_PYTHON38_X64 = 'mercurial-{version}-cp38-cp38-win_amd64.whl'
91 WHEEL_FILENAME_PYTHON38_X64 = 'mercurial-{version}-cp38-cp38-win_amd64.whl'
89 WHEEL_FILENAME_PYTHON39_X86 = 'mercurial-{version}-cp39-cp39-win32.whl'
92 WHEEL_FILENAME_PYTHON39_X86 = 'mercurial-{version}-cp39-cp39-win32.whl'
90 WHEEL_FILENAME_PYTHON39_X64 = 'mercurial-{version}-cp39-cp39-win_amd64.whl'
93 WHEEL_FILENAME_PYTHON39_X64 = 'mercurial-{version}-cp39-cp39-win_amd64.whl'
91 WHEEL_FILENAME_PYTHON310_X86 = 'mercurial-{version}-cp310-cp310-win32.whl'
94 WHEEL_FILENAME_PYTHON310_X86 = 'mercurial-{version}-cp310-cp310-win32.whl'
92 WHEEL_FILENAME_PYTHON310_X64 = 'mercurial-{version}-cp310-cp310-win_amd64.whl'
95 WHEEL_FILENAME_PYTHON310_X64 = 'mercurial-{version}-cp310-cp310-win_amd64.whl'
93
96
94 EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe'
97 EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe'
95 EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe'
98 EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe'
96
99
97 MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi'
100 MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi'
98 MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi'
101 MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi'
99
102
100 MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows'
103 MERCURIAL_SCM_BASE_URL = 'https://mercurial-scm.org/release/windows'
101
104
102 X86_USER_AGENT_PATTERN = '.*Windows.*'
105 X86_USER_AGENT_PATTERN = '.*Windows.*'
103 X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*'
106 X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*'
104
107
105 # TODO remove Python version once Python 2 is dropped.
108 # TODO remove Python version once Python 2 is dropped.
106 EXE_PYTHON3_X86_DESCRIPTION = (
109 EXE_PYTHON3_X86_DESCRIPTION = (
107 'Mercurial {version} Inno Setup installer - x86 Windows (Python 3) '
110 'Mercurial {version} Inno Setup installer - x86 Windows (Python 3) '
108 '- does not require admin rights'
111 '- does not require admin rights'
109 )
112 )
110 EXE_PYTHON3_X64_DESCRIPTION = (
113 EXE_PYTHON3_X64_DESCRIPTION = (
111 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) '
114 'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) '
112 '- does not require admin rights'
115 '- does not require admin rights'
113 )
116 )
114 MSI_PYTHON3_X86_DESCRIPTION = (
117 MSI_PYTHON3_X86_DESCRIPTION = (
115 'Mercurial {version} MSI installer - x86 Windows (Python 3) '
118 'Mercurial {version} MSI installer - x86 Windows (Python 3) '
116 '- requires admin rights'
119 '- requires admin rights'
117 )
120 )
118 MSI_PYTHON3_X64_DESCRIPTION = (
121 MSI_PYTHON3_X64_DESCRIPTION = (
119 'Mercurial {version} MSI installer - x64 Windows (Python 3) '
122 'Mercurial {version} MSI installer - x64 Windows (Python 3) '
120 '- requires admin rights'
123 '- requires admin rights'
121 )
124 )
122
125
123
126
124 def fix_authorized_keys_permissions(winrm_client, path):
127 def fix_authorized_keys_permissions(winrm_client, path):
125 commands = [
128 commands = [
126 '$ErrorActionPreference = "Stop"',
129 '$ErrorActionPreference = "Stop"',
127 'Repair-AuthorizedKeyPermission -FilePath %s -Confirm:$false' % path,
130 'Repair-AuthorizedKeyPermission -FilePath %s -Confirm:$false' % path,
128 r'icacls %s /remove:g "NT Service\sshd"' % path,
131 r'icacls %s /remove:g "NT Service\sshd"' % path,
129 ]
132 ]
130
133
131 run_powershell(winrm_client, '\n'.join(commands))
134 run_powershell(winrm_client, '\n'.join(commands))
132
135
133
136
134 def synchronize_hg(hg_repo: pathlib.Path, revision: str, ec2_instance):
137 def synchronize_hg(hg_repo: pathlib.Path, revision: str, ec2_instance):
135 """Synchronize local Mercurial repo to remote EC2 instance."""
138 """Synchronize local Mercurial repo to remote EC2 instance."""
136
139
137 winrm_client = ec2_instance.winrm_client
140 winrm_client = ec2_instance.winrm_client
138
141
139 with tempfile.TemporaryDirectory() as temp_dir:
142 with tempfile.TemporaryDirectory() as temp_dir:
140 temp_dir = pathlib.Path(temp_dir)
143 temp_dir = pathlib.Path(temp_dir)
141
144
142 ssh_dir = temp_dir / '.ssh'
145 ssh_dir = temp_dir / '.ssh'
143 ssh_dir.mkdir()
146 ssh_dir.mkdir()
144 ssh_dir.chmod(0o0700)
147 ssh_dir.chmod(0o0700)
145
148
146 # Generate SSH key to use for communication.
149 # Generate SSH key to use for communication.
147 subprocess.run(
150 subprocess.run(
148 [
151 [
149 'ssh-keygen',
152 'ssh-keygen',
150 '-t',
153 '-t',
151 'rsa',
154 'rsa',
152 '-b',
155 '-b',
153 '4096',
156 '4096',
154 '-N',
157 '-N',
155 '',
158 '',
156 '-f',
159 '-f',
157 str(ssh_dir / 'id_rsa'),
160 str(ssh_dir / 'id_rsa'),
158 ],
161 ],
159 check=True,
162 check=True,
160 capture_output=True,
163 capture_output=True,
161 )
164 )
162
165
163 # Add it to ~/.ssh/authorized_keys on remote.
166 # Add it to ~/.ssh/authorized_keys on remote.
164 # This assumes the file doesn't already exist.
167 # This assumes the file doesn't already exist.
165 authorized_keys = r'c:\Users\Administrator\.ssh\authorized_keys'
168 authorized_keys = r'c:\Users\Administrator\.ssh\authorized_keys'
166 winrm_client.execute_cmd(r'mkdir c:\Users\Administrator\.ssh')
169 winrm_client.execute_cmd(r'mkdir c:\Users\Administrator\.ssh')
167 winrm_client.copy(str(ssh_dir / 'id_rsa.pub'), authorized_keys)
170 winrm_client.copy(str(ssh_dir / 'id_rsa.pub'), authorized_keys)
168 fix_authorized_keys_permissions(winrm_client, authorized_keys)
171 fix_authorized_keys_permissions(winrm_client, authorized_keys)
169
172
170 public_ip = ec2_instance.public_ip_address
173 public_ip = ec2_instance.public_ip_address
171
174
172 ssh_config = temp_dir / '.ssh' / 'config'
175 ssh_config = temp_dir / '.ssh' / 'config'
173
176
174 with open(ssh_config, 'w', encoding='utf-8') as fh:
177 with open(ssh_config, 'w', encoding='utf-8') as fh:
175 fh.write('Host %s\n' % public_ip)
178 fh.write('Host %s\n' % public_ip)
176 fh.write(' User Administrator\n')
179 fh.write(' User Administrator\n')
177 fh.write(' StrictHostKeyChecking no\n')
180 fh.write(' StrictHostKeyChecking no\n')
178 fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts'))
181 fh.write(' UserKnownHostsFile %s\n' % (ssh_dir / 'known_hosts'))
179 fh.write(' IdentityFile %s\n' % (ssh_dir / 'id_rsa'))
182 fh.write(' IdentityFile %s\n' % (ssh_dir / 'id_rsa'))
180
183
181 if not (hg_repo / '.hg').is_dir():
184 if not (hg_repo / '.hg').is_dir():
182 raise Exception(
185 raise Exception(
183 '%s is not a Mercurial repository; '
186 '%s is not a Mercurial repository; '
184 'synchronization not yet supported' % hg_repo
187 'synchronization not yet supported' % hg_repo
185 )
188 )
186
189
187 env = dict(os.environ)
190 env = dict(os.environ)
188 env['HGPLAIN'] = '1'
191 env['HGPLAIN'] = '1'
189 env['HGENCODING'] = 'utf-8'
192 env['HGENCODING'] = 'utf-8'
190
193
191 hg_bin = hg_repo / 'hg'
194 hg_bin = hg_repo / 'hg'
192
195
193 res = subprocess.run(
196 res = subprocess.run(
194 ['python3', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
197 ['python3', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
195 cwd=str(hg_repo),
198 cwd=str(hg_repo),
196 env=env,
199 env=env,
197 check=True,
200 check=True,
198 capture_output=True,
201 capture_output=True,
199 )
202 )
200
203
201 full_revision = res.stdout.decode('ascii')
204 full_revision = res.stdout.decode('ascii')
202
205
203 args = [
206 args = [
204 'python3',
207 'python3',
205 hg_bin,
208 hg_bin,
206 '--config',
209 '--config',
207 'ui.ssh=ssh -F %s' % ssh_config,
210 'ui.ssh=ssh -F %s' % ssh_config,
208 '--config',
211 '--config',
209 'ui.remotecmd=c:/hgdev/venv-bootstrap/Scripts/hg.exe',
212 'ui.remotecmd=c:/hgdev/venv-bootstrap/Scripts/hg.exe',
210 # Also ensure .hgtags changes are present so auto version
213 # Also ensure .hgtags changes are present so auto version
211 # calculation works.
214 # calculation works.
212 'push',
215 'push',
213 '-f',
216 '-f',
214 '-r',
217 '-r',
215 full_revision,
218 full_revision,
216 '-r',
219 '-r',
217 'file(.hgtags)',
220 'file(.hgtags)',
218 'ssh://%s/c:/hgdev/src' % public_ip,
221 'ssh://%s/c:/hgdev/src' % public_ip,
219 ]
222 ]
220
223
221 res = subprocess.run(args, cwd=str(hg_repo), env=env)
224 res = subprocess.run(args, cwd=str(hg_repo), env=env)
222
225
223 # Allow 1 (no-op) to not trigger error.
226 # Allow 1 (no-op) to not trigger error.
224 if res.returncode not in (0, 1):
227 if res.returncode not in (0, 1):
225 res.check_returncode()
228 res.check_returncode()
226
229
227 run_powershell(
230 run_powershell(
228 winrm_client, HG_UPDATE_CLEAN.format(revision=full_revision)
231 winrm_client, HG_UPDATE_CLEAN.format(revision=full_revision)
229 )
232 )
230
233
231 # TODO detect dirty local working directory and synchronize accordingly.
234 # TODO detect dirty local working directory and synchronize accordingly.
232
235
233
236
234 def purge_hg(winrm_client):
237 def purge_hg(winrm_client):
235 """Purge the Mercurial source repository on an EC2 instance."""
238 """Purge the Mercurial source repository on an EC2 instance."""
236 run_powershell(winrm_client, HG_PURGE)
239 run_powershell(winrm_client, HG_PURGE)
237
240
238
241
239 def find_latest_dist(winrm_client, pattern):
242 def find_latest_dist(winrm_client, pattern):
240 """Find path to newest file in dist/ directory matching a pattern."""
243 """Find path to newest file in dist/ directory matching a pattern."""
241
244
242 res = winrm_client.execute_ps(
245 res = winrm_client.execute_ps(
243 r'$v = Get-ChildItem -Path C:\hgdev\src\dist -Filter "%s" '
246 r'$v = Get-ChildItem -Path C:\hgdev\src\dist -Filter "%s" '
244 '| Sort-Object LastWriteTime -Descending '
247 '| Sort-Object LastWriteTime -Descending '
245 '| Select-Object -First 1\n'
248 '| Select-Object -First 1\n'
246 '$v.name' % pattern
249 '$v.name' % pattern
247 )
250 )
248 return res[0]
251 return res[0]
249
252
250
253
251 def copy_latest_dist(winrm_client, pattern, dest_path):
254 def copy_latest_dist(winrm_client, pattern, dest_path):
252 """Copy latest file matching pattern in dist/ directory.
255 """Copy latest file matching pattern in dist/ directory.
253
256
254 Given a WinRM client and a file pattern, find the latest file on the remote
257 Given a WinRM client and a file pattern, find the latest file on the remote
255 matching that pattern and copy it to the ``dest_path`` directory on the
258 matching that pattern and copy it to the ``dest_path`` directory on the
256 local machine.
259 local machine.
257 """
260 """
258 latest = find_latest_dist(winrm_client, pattern)
261 latest = find_latest_dist(winrm_client, pattern)
259 source = r'C:\hgdev\src\dist\%s' % latest
262 source = r'C:\hgdev\src\dist\%s' % latest
260 dest = dest_path / latest
263 dest = dest_path / latest
261 print('copying %s to %s' % (source, dest))
264 print('copying %s to %s' % (source, dest))
262 winrm_client.fetch(source, str(dest))
265 winrm_client.fetch(source, str(dest))
263
266
264
267
265 def build_inno_installer(
268 def build_inno_installer(
266 winrm_client,
269 winrm_client,
267 arch: str,
270 arch: str,
268 dest_path: pathlib.Path,
271 dest_path: pathlib.Path,
269 version=None,
272 version=None,
270 ):
273 ):
271 """Build the Inno Setup installer on a remote machine.
274 """Build the Inno Setup installer on a remote machine.
272
275
273 Using a WinRM client, remote commands are executed to build
276 Using a WinRM client, remote commands are executed to build
274 a Mercurial Inno Setup installer.
277 a Mercurial Inno Setup installer.
275 """
278 """
276 print('building Inno Setup installer for %s' % arch)
279 print('building Inno Setup installer for %s' % arch)
277
280
278 # TODO fix this limitation in packaging code
281 # TODO fix this limitation in packaging code
279 if not version:
282 if not version:
280 raise Exception("version string is required when building for Python 3")
283 raise Exception("version string is required when building for Python 3")
281
284
282 if arch == "x86":
285 if arch == "x86":
283 target_triple = "i686-pc-windows-msvc"
286 target_triple = "i686-pc-windows-msvc"
284 elif arch == "x64":
287 elif arch == "x64":
285 target_triple = "x86_64-pc-windows-msvc"
288 target_triple = "x86_64-pc-windows-msvc"
286 else:
289 else:
287 raise Exception("unhandled arch: %s" % arch)
290 raise Exception("unhandled arch: %s" % arch)
288
291
289 ps = BUILD_INNO_PYTHON3.format(
292 ps = BUILD_INNO_PYTHON3.format(
290 pyoxidizer_target=target_triple,
293 pyoxidizer_target=target_triple,
291 version=version,
294 version=version,
292 )
295 )
293
296
294 run_powershell(winrm_client, ps)
297 run_powershell(winrm_client, ps)
295 copy_latest_dist(winrm_client, '*.exe', dest_path)
298 copy_latest_dist(winrm_client, '*.exe', dest_path)
296
299
297
300
298 def build_wheel(
301 def build_wheel(
299 winrm_client, python_version: str, arch: str, dest_path: pathlib.Path
302 winrm_client, python_version: str, arch: str, dest_path: pathlib.Path
300 ):
303 ):
301 """Build Python wheels on a remote machine.
304 """Build Python wheels on a remote machine.
302
305
303 Using a WinRM client, remote commands are executed to build a Python wheel
306 Using a WinRM client, remote commands are executed to build a Python wheel
304 for Mercurial.
307 for Mercurial.
305 """
308 """
306 print('Building Windows wheel for Python %s %s' % (python_version, arch))
309 print('Building Windows wheel for Python %s %s' % (python_version, arch))
307
310
308 ps = BUILD_WHEEL.format(
311 ps = BUILD_WHEEL.format(
309 python_version=python_version.replace(".", ""), arch=arch
312 python_version=python_version.replace(".", ""), arch=arch
310 )
313 )
311
314
312 run_powershell(winrm_client, ps)
315 run_powershell(winrm_client, ps)
313 copy_latest_dist(winrm_client, '*.whl', dest_path)
316 copy_latest_dist(winrm_client, '*.whl', dest_path)
314
317
315
318
316 def build_wix_installer(
319 def build_wix_installer(
317 winrm_client,
320 winrm_client,
318 arch: str,
321 arch: str,
319 dest_path: pathlib.Path,
322 dest_path: pathlib.Path,
320 version=None,
323 version=None,
321 ):
324 ):
322 """Build the WiX installer on a remote machine.
325 """Build the WiX installer on a remote machine.
323
326
324 Using a WinRM client, remote commands are executed to build a WiX installer.
327 Using a WinRM client, remote commands are executed to build a WiX installer.
325 """
328 """
326 print('Building WiX installer for %s' % arch)
329 print('Building WiX installer for %s' % arch)
327
330
328 # TODO fix this limitation in packaging code
331 # TODO fix this limitation in packaging code
329 if not version:
332 if not version:
330 raise Exception("version string is required when building for Python 3")
333 raise Exception("version string is required when building for Python 3")
331
334
332 if arch == "x86":
335 if arch == "x86":
333 target_triple = "i686-pc-windows-msvc"
336 target_triple = "i686-pc-windows-msvc"
334 elif arch == "x64":
337 elif arch == "x64":
335 target_triple = "x86_64-pc-windows-msvc"
338 target_triple = "x86_64-pc-windows-msvc"
336 else:
339 else:
337 raise Exception("unhandled arch: %s" % arch)
340 raise Exception("unhandled arch: %s" % arch)
338
341
339 ps = BUILD_WIX_PYTHON3.format(
342 ps = BUILD_WIX_PYTHON3.format(
340 pyoxidizer_target=target_triple,
343 pyoxidizer_target=target_triple,
341 version=version,
344 version=version,
342 )
345 )
343
346
344 run_powershell(winrm_client, ps)
347 run_powershell(winrm_client, ps)
345 copy_latest_dist(winrm_client, '*.msi', dest_path)
348 copy_latest_dist(winrm_client, '*.msi', dest_path)
346
349
347
350
348 def run_tests(winrm_client, python_version, arch, test_flags=''):
351 def run_tests(winrm_client, python_version, arch, test_flags=''):
349 """Run tests on a remote Windows machine.
352 """Run tests on a remote Windows machine.
350
353
351 ``python_version`` is a ``X.Y`` string like ``2.7`` or ``3.7``.
354 ``python_version`` is a ``X.Y`` string like ``2.7`` or ``3.7``.
352 ``arch`` is ``x86`` or ``x64``.
355 ``arch`` is ``x86`` or ``x64``.
353 ``test_flags`` is a str representing extra arguments to pass to
356 ``test_flags`` is a str representing extra arguments to pass to
354 ``run-tests.py``.
357 ``run-tests.py``.
355 """
358 """
356 if not re.match(r'\d\.\d', python_version):
359 if not re.match(r'\d\.\d', python_version):
357 raise ValueError(
360 raise ValueError(
358 r'python_version must be \d.\d; got %s' % python_version
361 r'python_version must be \d.\d; got %s' % python_version
359 )
362 )
360
363
361 if arch not in ('x86', 'x64'):
364 if arch not in ('x86', 'x64'):
362 raise ValueError('arch must be x86 or x64; got %s' % arch)
365 raise ValueError('arch must be x86 or x64; got %s' % arch)
363
366
364 python_path = 'python%s-%s' % (python_version.replace('.', ''), arch)
367 python_path = 'python%s-%s' % (python_version.replace('.', ''), arch)
365
368
366 ps = RUN_TESTS.format(
369 ps = RUN_TESTS.format(
367 python_path=python_path,
370 python_path=python_path,
368 test_flags=test_flags or '',
371 test_flags=test_flags or '',
369 )
372 )
370
373
371 run_powershell(winrm_client, ps)
374 run_powershell(winrm_client, ps)
372
375
373
376
374 def resolve_wheel_artifacts(dist_path: pathlib.Path, version: str):
377 def resolve_wheel_artifacts(dist_path: pathlib.Path, version: str):
375 return (
378 return (
376 dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version),
379 dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version),
377 dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version),
380 dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version),
378 dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version),
381 dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version),
379 dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version),
382 dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version),
380 dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version),
383 dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version),
381 dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version),
384 dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version),
382 dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version),
385 dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version),
383 dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version),
386 dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version),
384 )
387 )
385
388
386
389
387 def resolve_all_artifacts(dist_path: pathlib.Path, version: str):
390 def resolve_all_artifacts(dist_path: pathlib.Path, version: str):
388 return (
391 return (
389 dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version),
392 dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version),
390 dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version),
393 dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version),
391 dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version),
394 dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version),
392 dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version),
395 dist_path / WHEEL_FILENAME_PYTHON38_X64.format(version=version),
393 dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version),
396 dist_path / WHEEL_FILENAME_PYTHON39_X86.format(version=version),
394 dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version),
397 dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version),
395 dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version),
398 dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version),
396 dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version),
399 dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version),
397 dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version),
400 dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version),
398 dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version),
401 dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version),
399 dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version),
402 dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version),
400 dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version),
403 dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version),
401 )
404 )
402
405
403
406
404 def generate_latest_dat(version: str):
407 def generate_latest_dat(version: str):
405 python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version)
408 python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version)
406 python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version)
409 python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version)
407 python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version)
410 python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version)
408 python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version)
411 python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version)
409
412
410 entries = (
413 entries = (
411 (
414 (
412 '10',
415 '10',
413 version,
416 version,
414 X86_USER_AGENT_PATTERN,
417 X86_USER_AGENT_PATTERN,
415 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_exe_filename),
418 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_exe_filename),
416 EXE_PYTHON3_X86_DESCRIPTION.format(version=version),
419 EXE_PYTHON3_X86_DESCRIPTION.format(version=version),
417 ),
420 ),
418 (
421 (
419 '10',
422 '10',
420 version,
423 version,
421 X64_USER_AGENT_PATTERN,
424 X64_USER_AGENT_PATTERN,
422 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_exe_filename),
425 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_exe_filename),
423 EXE_PYTHON3_X64_DESCRIPTION.format(version=version),
426 EXE_PYTHON3_X64_DESCRIPTION.format(version=version),
424 ),
427 ),
425 (
428 (
426 '10',
429 '10',
427 version,
430 version,
428 X86_USER_AGENT_PATTERN,
431 X86_USER_AGENT_PATTERN,
429 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_msi_filename),
432 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x86_msi_filename),
430 MSI_PYTHON3_X86_DESCRIPTION.format(version=version),
433 MSI_PYTHON3_X86_DESCRIPTION.format(version=version),
431 ),
434 ),
432 (
435 (
433 '10',
436 '10',
434 version,
437 version,
435 X64_USER_AGENT_PATTERN,
438 X64_USER_AGENT_PATTERN,
436 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename),
439 '%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename),
437 MSI_PYTHON3_X64_DESCRIPTION.format(version=version),
440 MSI_PYTHON3_X64_DESCRIPTION.format(version=version),
438 ),
441 ),
439 )
442 )
440
443
441 lines = ['\t'.join(e) for e in entries]
444 lines = ['\t'.join(e) for e in entries]
442
445
443 return '\n'.join(lines) + '\n'
446 return '\n'.join(lines) + '\n'
444
447
445
448
446 def publish_artifacts_pypi(dist_path: pathlib.Path, version: str):
449 def publish_artifacts_pypi(dist_path: pathlib.Path, version: str):
447 """Publish Windows release artifacts to PyPI."""
450 """Publish Windows release artifacts to PyPI."""
448
451
449 wheel_paths = resolve_wheel_artifacts(dist_path, version)
452 wheel_paths = resolve_wheel_artifacts(dist_path, version)
450
453
451 for p in wheel_paths:
454 for p in wheel_paths:
452 if not p.exists():
455 if not p.exists():
453 raise Exception('%s not found' % p)
456 raise Exception('%s not found' % p)
454
457
455 print('uploading wheels to PyPI (you may be prompted for credentials)')
458 print('uploading wheels to PyPI (you may be prompted for credentials)')
456 pypi_upload(wheel_paths)
459 pypi_upload(wheel_paths)
457
460
458
461
459 def publish_artifacts_mercurial_scm_org(
462 def publish_artifacts_mercurial_scm_org(
460 dist_path: pathlib.Path, version: str, ssh_username=None
463 dist_path: pathlib.Path, version: str, ssh_username=None
461 ):
464 ):
462 """Publish Windows release artifacts to mercurial-scm.org."""
465 """Publish Windows release artifacts to mercurial-scm.org."""
463 all_paths = resolve_all_artifacts(dist_path, version)
466 all_paths = resolve_all_artifacts(dist_path, version)
464
467
465 for p in all_paths:
468 for p in all_paths:
466 if not p.exists():
469 if not p.exists():
467 raise Exception('%s not found' % p)
470 raise Exception('%s not found' % p)
468
471
469 client = paramiko.SSHClient()
472 client = paramiko.SSHClient()
470 client.load_system_host_keys()
473 client.load_system_host_keys()
471 # We assume the system SSH configuration knows how to connect.
474 # We assume the system SSH configuration knows how to connect.
472 print('connecting to mercurial-scm.org via ssh...')
475 print('connecting to mercurial-scm.org via ssh...')
473 try:
476 try:
474 client.connect('mercurial-scm.org', username=ssh_username)
477 client.connect('mercurial-scm.org', username=ssh_username)
475 except paramiko.AuthenticationException:
478 except paramiko.AuthenticationException:
476 print('error authenticating; is an SSH key available in an SSH agent?')
479 print('error authenticating; is an SSH key available in an SSH agent?')
477 raise
480 raise
478
481
479 print('SSH connection established')
482 print('SSH connection established')
480
483
481 print('opening SFTP client...')
484 print('opening SFTP client...')
482 sftp = client.open_sftp()
485 sftp = client.open_sftp()
483 print('SFTP client obtained')
486 print('SFTP client obtained')
484
487
485 for p in all_paths:
488 for p in all_paths:
486 dest_path = '/var/www/release/windows/%s' % p.name
489 dest_path = '/var/www/release/windows/%s' % p.name
487 print('uploading %s to %s' % (p, dest_path))
490 print('uploading %s to %s' % (p, dest_path))
488
491
489 with p.open('rb') as fh:
492 with p.open('rb') as fh:
490 data = fh.read()
493 data = fh.read()
491
494
492 with sftp.open(dest_path, 'wb') as fh:
495 with sftp.open(dest_path, 'wb') as fh:
493 fh.write(data)
496 fh.write(data)
494 fh.chmod(0o0664)
497 fh.chmod(0o0664)
495
498
496 latest_dat_path = '/var/www/release/windows/latest.dat'
499 latest_dat_path = '/var/www/release/windows/latest.dat'
497
500
498 now = datetime.datetime.utcnow()
501 now = datetime.datetime.utcnow()
499 backup_path = dist_path / (
502 backup_path = dist_path / (
500 'latest-windows-%s.dat' % now.strftime('%Y%m%dT%H%M%S')
503 'latest-windows-%s.dat' % now.strftime('%Y%m%dT%H%M%S')
501 )
504 )
502 print('backing up %s to %s' % (latest_dat_path, backup_path))
505 print('backing up %s to %s' % (latest_dat_path, backup_path))
503
506
504 with sftp.open(latest_dat_path, 'rb') as fh:
507 with sftp.open(latest_dat_path, 'rb') as fh:
505 latest_dat_old = fh.read()
508 latest_dat_old = fh.read()
506
509
507 with backup_path.open('wb') as fh:
510 with backup_path.open('wb') as fh:
508 fh.write(latest_dat_old)
511 fh.write(latest_dat_old)
509
512
510 print('writing %s with content:' % latest_dat_path)
513 print('writing %s with content:' % latest_dat_path)
511 latest_dat_content = generate_latest_dat(version)
514 latest_dat_content = generate_latest_dat(version)
512 print(latest_dat_content)
515 print(latest_dat_content)
513
516
514 with sftp.open(latest_dat_path, 'wb') as fh:
517 with sftp.open(latest_dat_path, 'wb') as fh:
515 fh.write(latest_dat_content.encode('ascii'))
518 fh.write(latest_dat_content.encode('ascii'))
516
519
517
520
518 def publish_artifacts(
521 def publish_artifacts(
519 dist_path: pathlib.Path,
522 dist_path: pathlib.Path,
520 version: str,
523 version: str,
521 pypi=True,
524 pypi=True,
522 mercurial_scm_org=True,
525 mercurial_scm_org=True,
523 ssh_username=None,
526 ssh_username=None,
524 ):
527 ):
525 """Publish Windows release artifacts.
528 """Publish Windows release artifacts.
526
529
527 Files are found in `dist_path`. We will look for files with version string
530 Files are found in `dist_path`. We will look for files with version string
528 `version`.
531 `version`.
529
532
530 `pypi` controls whether we upload to PyPI.
533 `pypi` controls whether we upload to PyPI.
531 `mercurial_scm_org` controls whether we upload to mercurial-scm.org.
534 `mercurial_scm_org` controls whether we upload to mercurial-scm.org.
532 """
535 """
533 if pypi:
536 if pypi:
534 publish_artifacts_pypi(dist_path, version)
537 publish_artifacts_pypi(dist_path, version)
535
538
536 if mercurial_scm_org:
539 if mercurial_scm_org:
537 publish_artifacts_mercurial_scm_org(
540 publish_artifacts_mercurial_scm_org(
538 dist_path, version, ssh_username=ssh_username
541 dist_path, version, ssh_username=ssh_username
539 )
542 )
@@ -1,193 +1,267 b''
1 #
1 #
2 # This file is autogenerated by pip-compile
2 # This file is autogenerated by pip-compile with python 3.10
3 # To update, run:
3 # To update, run:
4 #
4 #
5 # pip-compile --generate-hashes --output-file=contrib/automation/requirements.txt contrib/automation/requirements.txt.in
5 # pip-compile --generate-hashes --output-file=contrib/automation/requirements.txt contrib/automation/requirements.txt.in
6 #
6 #
7 asn1crypto==1.0.1 \
7 bcrypt==3.2.2 \
8 --hash=sha256:0b199f211ae690df3db4fd6c1c4ff976497fb1da689193e368eedbadc53d9292 \
8 --hash=sha256:2b02d6bfc6336d1094276f3f588aa1225a598e27f8e3388f4db9948cb707b521 \
9 --hash=sha256:bca90060bd995c3f62c4433168eab407e44bdbdb567b3f3a396a676c1a4c4a3f \
9 --hash=sha256:433c410c2177057705da2a9f2cd01dd157493b2a7ac14c8593a16b3dab6b6bfb \
10 # via cryptography
10 --hash=sha256:4e029cef560967fb0cf4a802bcf4d562d3d6b4b1bf81de5ec1abbe0f1adb027e \
11 bcrypt==3.1.7 \
11 --hash=sha256:61bae49580dce88095d669226d5076d0b9d927754cedbdf76c6c9f5099ad6f26 \
12 --hash=sha256:0258f143f3de96b7c14f762c770f5fc56ccd72f8a1857a451c1cd9a655d9ac89 \
12 --hash=sha256:6d2cb9d969bfca5bc08e45864137276e4c3d3d7de2b162171def3d188bf9d34a \
13 --hash=sha256:0b0069c752ec14172c5f78208f1863d7ad6755a6fae6fe76ec2c80d13be41e42 \
13 --hash=sha256:7180d98a96f00b1050e93f5b0f556e658605dd9f524d0b0e68ae7944673f525e \
14 --hash=sha256:19a4b72a6ae5bb467fea018b825f0a7d917789bcfe893e53f15c92805d187294 \
14 --hash=sha256:7d9ba2e41e330d2af4af6b1b6ec9e6128e91343d0b4afb9282e54e5508f31baa \
15 --hash=sha256:5432dd7b34107ae8ed6c10a71b4397f1c853bd39a4d6ffa7e35f40584cffd161 \
15 --hash=sha256:7ff2069240c6bbe49109fe84ca80508773a904f5a8cb960e02a977f7f519b129 \
16 --hash=sha256:69361315039878c0680be456640f8705d76cb4a3a3fe1e057e0f261b74be4b31 \
16 --hash=sha256:88273d806ab3a50d06bc6a2fc7c87d737dd669b76ad955f449c43095389bc8fb \
17 --hash=sha256:6fe49a60b25b584e2f4ef175b29d3a83ba63b3a4df1b4c0605b826668d1b6be5 \
17 --hash=sha256:a2c46100e315c3a5b90fdc53e429c006c5f962529bc27e1dfd656292c20ccc40 \
18 --hash=sha256:74a015102e877d0ccd02cdeaa18b32aa7273746914a6c5d0456dd442cb65b99c \
18 --hash=sha256:cd43303d6b8a165c29ec6756afd169faba9396a9472cdff753fe9f19b96ce2fa
19 --hash=sha256:763669a367869786bb4c8fcf731f4175775a5b43f070f50f46f0b59da45375d0 \
20 --hash=sha256:8b10acde4e1919d6015e1df86d4c217d3b5b01bb7744c36113ea43d529e1c3de \
21 --hash=sha256:9fe92406c857409b70a38729dbdf6578caf9228de0aef5bc44f859ffe971a39e \
22 --hash=sha256:a190f2a5dbbdbff4b74e3103cef44344bc30e61255beb27310e2aec407766052 \
23 --hash=sha256:a595c12c618119255c90deb4b046e1ca3bcfad64667c43d1166f2b04bc72db09 \
24 --hash=sha256:c9457fa5c121e94a58d6505cadca8bed1c64444b83b3204928a866ca2e599105 \
25 --hash=sha256:cb93f6b2ab0f6853550b74e051d297c27a638719753eb9ff66d1e4072be67133 \
26 --hash=sha256:d7bdc26475679dd073ba0ed2766445bb5b20ca4793ca0db32b399dccc6bc84b7 \
27 --hash=sha256:ff032765bb8716d9387fd5376d987a937254b0619eff0972779515b5c98820bc \
28 # via paramiko
19 # via paramiko
29 bleach==3.1.0 \
20 bleach==5.0.0 \
30 --hash=sha256:213336e49e102af26d9cde77dd2d0397afabc5a6bf2fed985dc35b5d1e285a16 \
21 --hash=sha256:08a1fe86d253b5c88c92cc3d810fd8048a16d15762e1e5b74d502256e5926aa1 \
31 --hash=sha256:3fdf7f77adcf649c9911387df51254b813185e32b2c6619f690b593a617e19fa \
22 --hash=sha256:c6d6cc054bdc9c83b48b8083e236e5f00f238428666d2ce2e083eaa5fd568565
32 # via readme-renderer
23 # via readme-renderer
33 boto3==1.9.243 \
24 boto3==1.22.7 \
34 --hash=sha256:404acbecef8f4912f18312fcfaffe7eba7f10b3b7adf7853bdba59cdf2275ebb \
25 --hash=sha256:4dc0df36c3465ff0d586017da68b0152123695f38f30ad98fed7185e59298d2c \
35 --hash=sha256:c6e5a7e4548ce7586c354ff633f2a66ba3c471d15a8ae6a30f873122ab04e1cf
26 --hash=sha256:de4fa49ca1cbc93313144e93e6d0997cbb61c8cca91f3418b4e3646dc215f441
36 botocore==1.12.243 \
27 # via -r contrib/automation/requirements.txt.in
37 --hash=sha256:397585a7881230274afb8d1877ef69a661b0a311745cd324f14a052fb2a2863a \
28 botocore==1.25.7 \
38 --hash=sha256:4496f8da89cb496462a831897ad248e13e431d9fa7e41e06d426fd6658ab6e59 \
29 --hash=sha256:190361776d96323ff401b976175f76172acf7ebbe3efbb19c4c6f9800a9ad6b6 \
39 # via boto3, s3transfer
30 --hash=sha256:83da857c12fff5cf4c1a64afaa72a28ff5bef929a2834ec4ed5b0b674f88fd0e
40 certifi==2021.5.30 \
31 # via
41 --hash=sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee \
32 # boto3
42 --hash=sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8 \
33 # s3transfer
34 certifi==2021.10.8 \
35 --hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \
36 --hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
43 # via requests
37 # via requests
44 cffi==1.12.3 \
38 cffi==1.15.0 \
45 --hash=sha256:041c81822e9f84b1d9c401182e174996f0bae9991f33725d059b771744290774 \
39 --hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \
46 --hash=sha256:046ef9a22f5d3eed06334d01b1e836977eeef500d9b78e9ef693f9380ad0b83d \
40 --hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \
47 --hash=sha256:066bc4c7895c91812eff46f4b1c285220947d4aa46fa0a2651ff85f2afae9c90 \
41 --hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \
48 --hash=sha256:066c7ff148ae33040c01058662d6752fd73fbc8e64787229ea8498c7d7f4041b \
42 --hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \
49 --hash=sha256:2444d0c61f03dcd26dbf7600cf64354376ee579acad77aef459e34efcb438c63 \
43 --hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \
50 --hash=sha256:300832850b8f7967e278870c5d51e3819b9aad8f0a2c8dbe39ab11f119237f45 \
44 --hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \
51 --hash=sha256:34c77afe85b6b9e967bd8154e3855e847b70ca42043db6ad17f26899a3df1b25 \
45 --hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \
52 --hash=sha256:46de5fa00f7ac09f020729148ff632819649b3e05a007d286242c4882f7b1dc3 \
46 --hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \
53 --hash=sha256:4aa8ee7ba27c472d429b980c51e714a24f47ca296d53f4d7868075b175866f4b \
47 --hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \
54 --hash=sha256:4d0004eb4351e35ed950c14c11e734182591465a33e960a4ab5e8d4f04d72647 \
48 --hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \
55 --hash=sha256:4e3d3f31a1e202b0f5a35ba3bc4eb41e2fc2b11c1eff38b362de710bcffb5016 \
49 --hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \
56 --hash=sha256:50bec6d35e6b1aaeb17f7c4e2b9374ebf95a8975d57863546fa83e8d31bdb8c4 \
50 --hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \
57 --hash=sha256:55cad9a6df1e2a1d62063f79d0881a414a906a6962bc160ac968cc03ed3efcfb \
51 --hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \
58 --hash=sha256:5662ad4e4e84f1eaa8efce5da695c5d2e229c563f9d5ce5b0113f71321bcf753 \
52 --hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \
59 --hash=sha256:59b4dc008f98fc6ee2bb4fd7fc786a8d70000d058c2bbe2698275bc53a8d3fa7 \
53 --hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \
60 --hash=sha256:73e1ffefe05e4ccd7bcea61af76f36077b914f92b76f95ccf00b0c1b9186f3f9 \
54 --hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \
61 --hash=sha256:a1f0fd46eba2d71ce1589f7e50a9e2ffaeb739fb2c11e8192aa2b45d5f6cc41f \
55 --hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \
62 --hash=sha256:a2e85dc204556657661051ff4bab75a84e968669765c8a2cd425918699c3d0e8 \
56 --hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \
63 --hash=sha256:a5457d47dfff24882a21492e5815f891c0ca35fefae8aa742c6c263dac16ef1f \
57 --hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \
64 --hash=sha256:a8dccd61d52a8dae4a825cdbb7735da530179fea472903eb871a5513b5abbfdc \
58 --hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \
65 --hash=sha256:ae61af521ed676cf16ae94f30fe202781a38d7178b6b4ab622e4eec8cefaff42 \
59 --hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \
66 --hash=sha256:b012a5edb48288f77a63dba0840c92d0504aa215612da4541b7b42d849bc83a3 \
60 --hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \
67 --hash=sha256:d2c5cfa536227f57f97c92ac30c8109688ace8fa4ac086d19d0af47d134e2909 \
61 --hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \
68 --hash=sha256:d42b5796e20aacc9d15e66befb7a345454eef794fdb0737d1af593447c6c8f45 \
62 --hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \
69 --hash=sha256:dee54f5d30d775f525894d67b1495625dd9322945e7fee00731952e0368ff42d \
63 --hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \
70 --hash=sha256:e070535507bd6aa07124258171be2ee8dfc19119c28ca94c9dfb7efd23564512 \
64 --hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \
71 --hash=sha256:e1ff2748c84d97b065cc95429814cdba39bcbd77c9c85c89344b317dc0d9cbff \
65 --hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \
72 --hash=sha256:ed851c75d1e0e043cbf5ca9a8e1b13c4c90f3fbd863dacb01c0808e2b5204201 \
66 --hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \
73 # via bcrypt, cryptography, pynacl
67 --hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \
74 chardet==3.0.4 \
68 --hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \
75 --hash=sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae \
69 --hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \
76 --hash=sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691 \
70 --hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \
71 --hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \
72 --hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \
73 --hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \
74 --hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \
75 --hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \
76 --hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \
77 --hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \
78 --hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \
79 --hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \
80 --hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \
81 --hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \
82 --hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \
83 --hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \
84 --hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \
85 --hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \
86 --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \
87 --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \
88 --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796
89 # via
90 # bcrypt
91 # cryptography
92 # pynacl
93 charset-normalizer==2.0.12 \
94 --hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \
95 --hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df
77 # via requests
96 # via requests
78 cryptography==2.7 \
97 commonmark==0.9.1 \
79 --hash=sha256:24b61e5fcb506424d3ec4e18bca995833839bf13c59fc43e530e488f28d46b8c \
98 --hash=sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60 \
80 --hash=sha256:25dd1581a183e9e7a806fe0543f485103232f940fcfc301db65e630512cce643 \
99 --hash=sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9
81 --hash=sha256:3452bba7c21c69f2df772762be0066c7ed5dc65df494a1d53a58b683a83e1216 \
100 # via rich
82 --hash=sha256:41a0be220dd1ed9e998f5891948306eb8c812b512dc398e5a01846d855050799 \
101 cryptography==37.0.2 \
83 --hash=sha256:5751d8a11b956fbfa314f6553d186b94aa70fdb03d8a4d4f1c82dcacf0cbe28a \
102 --hash=sha256:093cb351031656d3ee2f4fa1be579a8c69c754cf874206be1d4cf3b542042804 \
84 --hash=sha256:5f61c7d749048fa6e3322258b4263463bfccefecb0dd731b6561cb617a1d9bb9 \
103 --hash=sha256:0cc20f655157d4cfc7bada909dc5cc228211b075ba8407c46467f63597c78178 \
85 --hash=sha256:72e24c521fa2106f19623a3851e9f89ddfdeb9ac63871c7643790f872a305dfc \
104 --hash=sha256:1b9362d34363f2c71b7853f6251219298124aa4cc2075ae2932e64c91a3e2717 \
86 --hash=sha256:7b97ae6ef5cba2e3bb14256625423413d5ce8d1abb91d4f29b6d1a081da765f8 \
105 --hash=sha256:1f3bfbd611db5cb58ca82f3deb35e83af34bb8cf06043fa61500157d50a70982 \
87 --hash=sha256:961e886d8a3590fd2c723cf07be14e2a91cf53c25f02435c04d39e90780e3b53 \
106 --hash=sha256:2bd1096476aaac820426239ab534b636c77d71af66c547b9ddcd76eb9c79e004 \
88 --hash=sha256:96d8473848e984184b6728e2c9d391482008646276c3ff084a1bd89e15ff53a1 \
107 --hash=sha256:31fe38d14d2e5f787e0aecef831457da6cec68e0bb09a35835b0b44ae8b988fe \
89 --hash=sha256:ae536da50c7ad1e002c3eee101871d93abdc90d9c5f651818450a0d3af718609 \
108 --hash=sha256:3b8398b3d0efc420e777c40c16764d6870bcef2eb383df9c6dbb9ffe12c64452 \
90 --hash=sha256:b0db0cecf396033abb4a93c95d1602f268b3a68bb0a9cc06a7cff587bb9a7292 \
109 --hash=sha256:3c81599befb4d4f3d7648ed3217e00d21a9341a9a688ecdd615ff72ffbed7336 \
91 --hash=sha256:cfee9164954c186b191b91d4193989ca994703b2fff406f71cf454a2d3c7327e \
110 --hash=sha256:419c57d7b63f5ec38b1199a9521d77d7d1754eb97827bbb773162073ccd8c8d4 \
92 --hash=sha256:e6347742ac8f35ded4a46ff835c60e68c22a536a8ae5c4422966d06946b6d4c6 \
111 --hash=sha256:46f4c544f6557a2fefa7ac8ac7d1b17bf9b647bd20b16decc8fbcab7117fbc15 \
93 --hash=sha256:f27d93f0139a3c056172ebb5d4f9056e770fdf0206c2f422ff2ebbad142e09ed \
112 --hash=sha256:471e0d70201c069f74c837983189949aa0d24bb2d751b57e26e3761f2f782b8d \
94 --hash=sha256:f57b76e46a58b63d1c6375017f4564a28f19a5ca912691fd2e4261b3414b618d \
113 --hash=sha256:59b281eab51e1b6b6afa525af2bd93c16d49358404f814fe2c2410058623928c \
95 # via paramiko, pypsrp
114 --hash=sha256:731c8abd27693323b348518ed0e0705713a36d79fdbd969ad968fbef0979a7e0 \
96 docutils==0.15.2 \
115 --hash=sha256:95e590dd70642eb2079d280420a888190aa040ad20f19ec8c6e097e38aa29e06 \
97 --hash=sha256:6c4f696463b79f1fb8ba0c594b63840ebd41f059e92b31957c46b74a4599b6d0 \
116 --hash=sha256:a68254dd88021f24a68b613d8c51d5c5e74d735878b9e32cc0adf19d1f10aaf9 \
98 --hash=sha256:9e4d7ecfc600058e07ba661411a2b7de2fd0fafa17d1a7f7361cd47b1175c827 \
117 --hash=sha256:a7d5137e556cc0ea418dca6186deabe9129cee318618eb1ffecbd35bee55ddc1 \
99 --hash=sha256:a2aeea129088da402665e92e0b25b04b073c04b2dce4ab65caaa38b7ce2e1a99 \
118 --hash=sha256:aeaba7b5e756ea52c8861c133c596afe93dd716cbcacae23b80bc238202dc023 \
100 # via botocore, readme-renderer
119 --hash=sha256:dc26bb134452081859aa21d4990474ddb7e863aa39e60d1592800a8865a702de \
101 idna==2.8 \
120 --hash=sha256:e53258e69874a306fcecb88b7534d61820db8a98655662a3dd2ec7f1afd9132f \
102 --hash=sha256:c357b3f628cf53ae2c4c05627ecc484553142ca23264e593d327bcde5e9c3407 \
121 --hash=sha256:ef15c2df7656763b4ff20a9bc4381d8352e6640cfeb95c2972c38ef508e75181 \
103 --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
122 --hash=sha256:f224ad253cc9cea7568f49077007d2263efa57396a2f2f78114066fd54b5c68e \
123 --hash=sha256:f8ec91983e638a9bcd75b39f1396e5c0dc2330cbd9ce4accefe68717e6779e0a
124 # via
125 # paramiko
126 # pypsrp
127 # pyspnego
128 # secretstorage
129 docutils==0.18.1 \
130 --hash=sha256:23010f129180089fbcd3bc08cfefccb3b890b0050e1ca00c867036e9d161b98c \
131 --hash=sha256:679987caf361a7539d76e584cbeddc311e3aee937877c87346f31debc63e9d06
132 # via readme-renderer
133 idna==3.3 \
134 --hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
135 --hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
104 # via requests
136 # via requests
105 jmespath==0.9.4 \
137 importlib-metadata==4.11.3 \
106 --hash=sha256:3720a4b1bd659dd2eecad0666459b9788813e032b83e7ba58578e48254e0a0e6 \
138 --hash=sha256:1208431ca90a8cca1a6b8af391bb53c1a2db74e5d1cef6ddced95d4b2062edc6 \
107 --hash=sha256:bde2aef6f44302dfb30320115b17d030798de8c4110e28d5cf6cf91a7a31074c \
139 --hash=sha256:ea4c597ebf37142f827b8f39299579e31685c31d3a438b59f469406afd0f2539
108 # via boto3, botocore
140 # via
109 ntlm-auth==1.4.0 \
141 # keyring
110 --hash=sha256:11f7a3cec38155b7cecdd9bbc8c37cd738d8012f0523b3f98d8caefe394feb97 \
142 # twine
111 --hash=sha256:350f2389c8ee5517f47db55a36ac2f8efc9742a60a678d6e2caa92385bdcaa9a \
143 jeepney==0.8.0 \
144 --hash=sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806 \
145 --hash=sha256:c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755
146 # via
147 # keyring
148 # secretstorage
149 jmespath==1.0.0 \
150 --hash=sha256:a490e280edd1f57d6de88636992d05b71e97d69a26a19f058ecf7d304474bf5e \
151 --hash=sha256:e8dcd576ed616f14ec02eed0005c85973b5890083313860136657e24784e4c04
152 # via
153 # boto3
154 # botocore
155 keyring==23.5.0 \
156 --hash=sha256:9012508e141a80bd1c0b6778d5c610dd9f8c464d75ac6774248500503f972fb9 \
157 --hash=sha256:b0d28928ac3ec8e42ef4cc227822647a19f1d544f21f96457965dc01cf555261
158 # via twine
159 paramiko==2.10.4 \
160 --hash=sha256:3c9ed6084f4b671ab66dc3c729092d32d96c3258f1426071301cb33654b09027 \
161 --hash=sha256:3d2e650b6812ce6d160abff701d6ef4434ec97934b13e95cf1ad3da70ffb5c58
162 # via -r contrib/automation/requirements.txt.in
163 pkginfo==1.8.2 \
164 --hash=sha256:542e0d0b6750e2e21c20179803e40ab50598d8066d51097a0e382cba9eb02bff \
165 --hash=sha256:c24c487c6a7f72c66e816ab1796b96ac6c3d14d49338293d2141664330b55ffc
166 # via twine
167 pycparser==2.21 \
168 --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
169 --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
170 # via cffi
171 pygments==2.12.0 \
172 --hash=sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb \
173 --hash=sha256:dc9c10fb40944260f6ed4c688ece0cd2048414940f1cea51b8b226318411c519
174 # via
175 # readme-renderer
176 # rich
177 pynacl==1.5.0 \
178 --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \
179 --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \
180 --hash=sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93 \
181 --hash=sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1 \
182 --hash=sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92 \
183 --hash=sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff \
184 --hash=sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba \
185 --hash=sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394 \
186 --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \
187 --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543
188 # via paramiko
189 pypsrp==0.8.1 \
190 --hash=sha256:0101345ceb415896fed9b056e7b77d65312089ddc73c4286247ccf1859d4bc4d \
191 --hash=sha256:f5500acd11dfe742d51b7fbb61321ba721038a300d67763dc52babe709db65e7
192 # via -r contrib/automation/requirements.txt.in
193 pyspnego==0.5.2 \
194 --hash=sha256:1fed228edc4b1730844da8237b90489be28c55681cf3934cd04fceb2253e55bf \
195 --hash=sha256:25fbc90fc6bd16881480316739bab820cc91364765e46340da17f861f89691f1 \
196 --hash=sha256:274b3a2d37e45ad4567bc5754be04b5fefad3f7cdea7d205f739d8a26b5a9189 \
197 --hash=sha256:36db7ec38023a23a545114dfd23825639571f135c72fb4b13a1ed559a0a4d93c \
198 --hash=sha256:3b1ff3c1d5588b66f8e4ebafa3079a7bf0bdcc6fb144b944c5a101e688a5a280 \
199 --hash=sha256:4b9bda51bd964f40322aa1b33dcfc5d68f23b0680b4b5158175f2e9a04119aa9 \
200 --hash=sha256:5d6d91e35ee63a5de30eb70716bf25274bf16c2c472b046dd21fad60fe63b0b6 \
201 --hash=sha256:7562bc640bf402bb2849f325b0bb41260bd2c0cb06e38b9a8c6f7021b452c873 \
202 --hash=sha256:9c5bdb9f0207e2ce9e5410ee2205bf016755712018534c711ae6c1daff7fa7db \
203 --hash=sha256:a5c135d20819db3c48f65054d648317f369a61b7b22dc17b9e5ec9c0169541a0 \
204 --hash=sha256:bd95633e7dce69e267579bdbe992fc081a14310236b4e84c3d179b1cf6439ca5 \
205 --hash=sha256:eb41b970dbda0dfe07b1da6fc83fe9f534a66d8dea38c06c0155377697407d9a
112 # via pypsrp
206 # via pypsrp
113 paramiko==2.6.0 \
207 python-dateutil==2.8.2 \
114 --hash=sha256:99f0179bdc176281d21961a003ffdb2ec369daac1a1007241f53374e376576cf \
208 --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \
115 --hash=sha256:f4b2edfa0d226b70bd4ca31ea7e389325990283da23465d572ed1f70a7583041
209 --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9
116 pkginfo==1.5.0.1 \
210 # via botocore
117 --hash=sha256:7424f2c8511c186cd5424bbf31045b77435b37a8d604990b79d4e70d741148bb \
211 readme-renderer==35.0 \
118 --hash=sha256:a6d9e40ca61ad3ebd0b72fbadd4fba16e4c0e4df0428c041e01e06eb6ee71f32 \
212 --hash=sha256:73b84905d091c31f36e50b4ae05ae2acead661f6a09a9abb4df7d2ddcdb6a698 \
213 --hash=sha256:a727999acfc222fc21d82a12ed48c957c4989785e5865807c65a487d21677497
119 # via twine
214 # via twine
120 pycparser==2.19 \
215 requests==2.27.1 \
121 --hash=sha256:a988718abfad80b6b157acce7bf130a30876d27603738ac39f140993246b25b3 \
216 --hash=sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61 \
122 # via cffi
217 --hash=sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d
123 pygments==2.4.2 \
218 # via
124 --hash=sha256:71e430bc85c88a430f000ac1d9b331d2407f681d6f6aec95e8bcfbc3df5b0127 \
219 # pypsrp
125 --hash=sha256:881c4c157e45f30af185c1ffe8d549d48ac9127433f2c380c24b84572ad66297 \
220 # requests-toolbelt
126 # via readme-renderer
221 # twine
127 pynacl==1.3.0 \
128 --hash=sha256:05c26f93964373fc0abe332676cb6735f0ecad27711035b9472751faa8521255 \
129 --hash=sha256:0c6100edd16fefd1557da078c7a31e7b7d7a52ce39fdca2bec29d4f7b6e7600c \
130 --hash=sha256:0d0a8171a68edf51add1e73d2159c4bc19fc0718e79dec51166e940856c2f28e \
131 --hash=sha256:1c780712b206317a746ace34c209b8c29dbfd841dfbc02aa27f2084dd3db77ae \
132 --hash=sha256:2424c8b9f41aa65bbdbd7a64e73a7450ebb4aa9ddedc6a081e7afcc4c97f7621 \
133 --hash=sha256:2d23c04e8d709444220557ae48ed01f3f1086439f12dbf11976e849a4926db56 \
134 --hash=sha256:30f36a9c70450c7878053fa1344aca0145fd47d845270b43a7ee9192a051bf39 \
135 --hash=sha256:37aa336a317209f1bb099ad177fef0da45be36a2aa664507c5d72015f956c310 \
136 --hash=sha256:4943decfc5b905748f0756fdd99d4f9498d7064815c4cf3643820c9028b711d1 \
137 --hash=sha256:57ef38a65056e7800859e5ba9e6091053cd06e1038983016effaffe0efcd594a \
138 --hash=sha256:5bd61e9b44c543016ce1f6aef48606280e45f892a928ca7068fba30021e9b786 \
139 --hash=sha256:6482d3017a0c0327a49dddc8bd1074cc730d45db2ccb09c3bac1f8f32d1eb61b \
140 --hash=sha256:7d3ce02c0784b7cbcc771a2da6ea51f87e8716004512493a2b69016326301c3b \
141 --hash=sha256:a14e499c0f5955dcc3991f785f3f8e2130ed504fa3a7f44009ff458ad6bdd17f \
142 --hash=sha256:a39f54ccbcd2757d1d63b0ec00a00980c0b382c62865b61a505163943624ab20 \
143 --hash=sha256:aabb0c5232910a20eec8563503c153a8e78bbf5459490c49ab31f6adf3f3a415 \
144 --hash=sha256:bd4ecb473a96ad0f90c20acba4f0bf0df91a4e03a1f4dd6a4bdc9ca75aa3a715 \
145 --hash=sha256:e2da3c13307eac601f3de04887624939aca8ee3c9488a0bb0eca4fb9401fc6b1 \
146 --hash=sha256:f67814c38162f4deb31f68d590771a29d5ae3b1bd64b75cf232308e5c74777e0 \
147 # via paramiko
148 pypsrp==0.4.0 \
149 --hash=sha256:64b5bdd725a9744c821483b05ecd266f6417f4c6e90ee961a08838480f7d025e \
150 --hash=sha256:f42919247fb80f7dc24c552560d7c24e754d15326030c9e3b7b94f51cfa4dc69
151 python-dateutil==2.8.0 \
152 --hash=sha256:7e6584c74aeed623791615e26efd690f29817a27c73085b78e4bad02493df2fb \
153 --hash=sha256:c89805f6f4d64db21ed966fda138f8a5ed7a4fdbc1a8ee329ce1b74e3c74da9e \
154 # via botocore
155 readme-renderer==24.0 \
156 --hash=sha256:bb16f55b259f27f75f640acf5e00cf897845a8b3e4731b5c1a436e4b8529202f \
157 --hash=sha256:c8532b79afc0375a85f10433eca157d6b50f7d6990f337fa498c96cd4bfc203d \
158 # via twine
159 requests-toolbelt==0.9.1 \
222 requests-toolbelt==0.9.1 \
160 --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \
223 --hash=sha256:380606e1d10dc85c3bd47bf5a6095f815ec007be7a8b69c878507068df059e6f \
161 --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0 \
224 --hash=sha256:968089d4584ad4ad7c171454f0a5c6dac23971e9472521ea3b6d49d610aa6fc0
225 # via twine
226 rfc3986==2.0.0 \
227 --hash=sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd \
228 --hash=sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c
162 # via twine
229 # via twine
163 requests==2.22.0 \
230 rich==12.3.0 \
164 --hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \
231 --hash=sha256:0eb63013630c6ee1237e0e395d51cb23513de6b5531235e33889e8842bdf3a6f \
165 --hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31 \
232 --hash=sha256:7e8700cda776337036a712ff0495b04052fb5f957c7dfb8df997f88350044b64
166 # via pypsrp, requests-toolbelt, twine
233 # via twine
167 s3transfer==0.2.1 \
234 s3transfer==0.5.2 \
168 --hash=sha256:6efc926738a3cd576c2a79725fed9afde92378aa5c6a957e3af010cb019fac9d \
235 --hash=sha256:7a6f4c4d1fdb9a2b640244008e142cbc2cd3ae34b386584ef044dd0f27101971 \
169 --hash=sha256:b780f2411b824cb541dbcd2c713d0cb61c7d1bcadae204cdddda2b35cef493ba \
236 --hash=sha256:95c58c194ce657a5f4fb0b9e60a84968c808888aed628cd98ab8771fe1db98ed
170 # via boto3
237 # via boto3
171 six==1.12.0 \
238 secretstorage==3.3.2 \
172 --hash=sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c \
239 --hash=sha256:0a8eb9645b320881c222e827c26f4cfcf55363e8b374a021981ef886657a912f \
173 --hash=sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73 \
240 --hash=sha256:755dc845b6ad76dcbcbc07ea3da75ae54bb1ea529eb72d15f83d26499a5df319
174 # via bcrypt, bleach, cryptography, pynacl, pypsrp, python-dateutil, readme-renderer
241 # via keyring
175 tqdm==4.36.1 \
242 six==1.16.0 \
176 --hash=sha256:abc25d0ce2397d070ef07d8c7e706aede7920da163c64997585d42d3537ece3d \
243 --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
177 --hash=sha256:dd3fcca8488bb1d416aa7469d2f277902f26260c45aa86b667b074cd44b3b115 \
244 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
178 # via twine
245 # via
179 twine==2.0.0 \
246 # bleach
180 --hash=sha256:5319dd3e02ac73fcddcd94f035b9631589ab5d23e1f4699d57365199d85261e1 \
247 # paramiko
181 --hash=sha256:9fe7091715c7576df166df8ef6654e61bada39571783f2fd415bdcba867c6993
248 # python-dateutil
182 urllib3==1.25.6 \
249 twine==4.0.0 \
183 --hash=sha256:3de946ffbed6e6746608990594d08faac602528ac7015ac28d33cee6a45b7398 \
250 --hash=sha256:6f7496cf14a3a8903474552d5271c79c71916519edb42554f23f42a8563498a9 \
184 --hash=sha256:9a107b99a5393caf59c7aa3c1249c16e6879447533d0887f4336dde834c7be86 \
251 --hash=sha256:817aa0c0bdc02a5ebe32051e168e23c71a0608334e624c793011f120dbbc05b7
185 # via botocore, requests
252 # via -r contrib/automation/requirements.txt.in
253 urllib3==1.26.9 \
254 --hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \
255 --hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e
256 # via
257 # botocore
258 # requests
259 # twine
186 webencodings==0.5.1 \
260 webencodings==0.5.1 \
187 --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
261 --hash=sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78 \
188 --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923 \
262 --hash=sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923
189 # via bleach
263 # via bleach
190
264 zipp==3.8.0 \
191 # WARNING: The following packages were not pinned, but pip requires them to be
265 --hash=sha256:56bf8aadb83c24db6c4b577e13de374ccfb67da2078beba1d037c17980bf43ad \
192 # pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
266 --hash=sha256:c4f6e5bbf48e74f7a38e7cc5b0480ff42b0ae5178957d564d18932525d5cf099
193 # setuptools==41.2.0 # via twine
267 # via importlib-metadata
@@ -1,204 +1,204 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 $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe"
22 $PYTHON37_x86_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9.exe"
23 $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220"
23 $PYTHON37_x86_SHA256 = "769bb7c74ad1df6d7d74071cc16a984ff6182e4016e11b8949b93db487977220"
24 $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe"
24 $PYTHON37_X64_URL = "https://www.python.org/ftp/python/3.7.9/python-3.7.9-amd64.exe"
25 $PYTHON37_x64_SHA256 = "e69ed52afb5a722e5c56f6c21d594e85c17cb29f12f18bb69751cf1714e0f987"
25 $PYTHON37_x64_SHA256 = "e69ed52afb5a722e5c56f6c21d594e85c17cb29f12f18bb69751cf1714e0f987"
26
26
27 $PYTHON38_x86_URL = "https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"
27 $PYTHON38_x86_URL = "https://www.python.org/ftp/python/3.8.10/python-3.8.10.exe"
28 $PYTHON38_x86_SHA256 = "ad07633a1f0cd795f3bf9da33729f662281df196b4567fa795829f3bb38a30ac"
28 $PYTHON38_x86_SHA256 = "ad07633a1f0cd795f3bf9da33729f662281df196b4567fa795829f3bb38a30ac"
29 $PYTHON38_x64_URL = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe"
29 $PYTHON38_x64_URL = "https://www.python.org/ftp/python/3.8.10/python-3.8.10-amd64.exe"
30 $PYTHON38_x64_SHA256 = "7628244cb53408b50639d2c1287c659f4e29d3dfdb9084b11aed5870c0c6a48a"
30 $PYTHON38_x64_SHA256 = "7628244cb53408b50639d2c1287c659f4e29d3dfdb9084b11aed5870c0c6a48a"
31
31
32 $PYTHON39_x86_URL = "https://www.python.org/ftp/python/3.9.12/python-3.9.12.exe"
32 $PYTHON39_x86_URL = "https://www.python.org/ftp/python/3.9.12/python-3.9.12.exe"
33 $PYTHON39_x86_SHA256 = "3d883326f30ac231c06b33f2a8ea700a185c20bf98d01da118079e9134d5fd20"
33 $PYTHON39_x86_SHA256 = "3d883326f30ac231c06b33f2a8ea700a185c20bf98d01da118079e9134d5fd20"
34 $PYTHON39_X64_URL = "https://www.python.org/ftp/python/3.9.12/python-3.9.12-amd64.exe"
34 $PYTHON39_X64_URL = "https://www.python.org/ftp/python/3.9.12/python-3.9.12-amd64.exe"
35 $PYTHON39_x64_SHA256 = "2ba57ab2281094f78fc0227a27f4d47c90d94094e7cca35ce78419e616b3cb63"
35 $PYTHON39_x64_SHA256 = "2ba57ab2281094f78fc0227a27f4d47c90d94094e7cca35ce78419e616b3cb63"
36
36
37 $PYTHON310_x86_URL = "https://www.python.org/ftp/python/3.10.4/python-3.10.4.exe"
37 $PYTHON310_x86_URL = "https://www.python.org/ftp/python/3.10.4/python-3.10.4.exe"
38 $PYTHON310_x86_SHA256 = "97c37c53c7a826f5b00e185754ab2a324a919f7afc469b20764b71715c80041d"
38 $PYTHON310_x86_SHA256 = "97c37c53c7a826f5b00e185754ab2a324a919f7afc469b20764b71715c80041d"
39 $PYTHON310_X64_URL = "https://www.python.org/ftp/python/3.10.4/python-3.10.4-amd64.exe"
39 $PYTHON310_X64_URL = "https://www.python.org/ftp/python/3.10.4/python-3.10.4-amd64.exe"
40 $PYTHON310_x64_SHA256 = "a81fc4180f34e5733c3f15526c668ff55de096366f9006d8a44c0336704e50f1"
40 $PYTHON310_x64_SHA256 = "a81fc4180f34e5733c3f15526c668ff55de096366f9006d8a44c0336704e50f1"
41
41
42 # PIP 22.0.4.
42 # PIP 22.0.4.
43 $PIP_URL = "https://github.com/pypa/get-pip/raw/38e54e5de07c66e875c11a1ebbdb938854625dd8/public/get-pip.py"
43 $PIP_URL = "https://github.com/pypa/get-pip/raw/38e54e5de07c66e875c11a1ebbdb938854625dd8/public/get-pip.py"
44 $PIP_SHA256 = "e235c437e5c7d7524fbce3880ca39b917a73dc565e0c813465b7a7a329bb279a"
44 $PIP_SHA256 = "e235c437e5c7d7524fbce3880ca39b917a73dc565e0c813465b7a7a329bb279a"
45
45
46 $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe"
46 $INNO_SETUP_URL = "http://files.jrsoftware.org/is/5/innosetup-5.6.1-unicode.exe"
47 $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538"
47 $INNO_SETUP_SHA256 = "27D49E9BC769E9D1B214C153011978DB90DC01C2ACD1DDCD9ED7B3FE3B96B538"
48
48
49 $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"
49 $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"
50 $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF"
50 $MINGW_BIN_SHA256 = "2AB8EFD7C7D1FC8EAF8B2FA4DA4EEF8F3E47768284C021599BC7435839A046DF"
51
51
52 $MERCURIAL_WHEEL_FILENAME = "mercurial-5.8.1-cp39-cp39-win_amd64.whl"
52 $MERCURIAL_WHEEL_FILENAME = "mercurial-6.1.4-cp39-cp39-win_amd64.whl"
53 $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/5c/b5/a5fa664761eef29b6c90eb24cb09ab8fe2c9b4b86af41d42c17476aff29b/$MERCURIAL_WHEEL_FILENAME"
53 $MERCURIAL_WHEEL_URL = "https://files.pythonhosted.org/packages/82/86/fbcc4b552f6c1bdfdbbc5a68b0896a55ac3c6c0e8baf51394816bdc320bd/$MERCURIAL_WHEEL_FILENAME"
54 $MERCURIAL_WHEEL_SHA256 = "cbf3efa68fd7ebf94691bd00d2c86bbd47ca73620c8faa4f18b6c394bf5f82b0"
54 $MERCURIAL_WHEEL_SHA256 = "ab578daec7c21786c668b0da2e71282a290d18010255719f78d0e55145020d46"
55
55
56 $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe"
56 $RUSTUP_INIT_URL = "https://static.rust-lang.org/rustup/archive/1.21.1/x86_64-pc-windows-gnu/rustup-init.exe"
57 $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72"
57 $RUSTUP_INIT_SHA256 = "d17df34ba974b9b19cf5c75883a95475aa22ddc364591d75d174090d55711c72"
58
58
59 $PYOXIDIZER_URL = "https://github.com/indygreg/PyOxidizer/releases/download/pyoxidizer%2F0.17/PyOxidizer-0.17.0-x64.msi"
59 $PYOXIDIZER_URL = "https://github.com/indygreg/PyOxidizer/releases/download/pyoxidizer%2F0.17/PyOxidizer-0.17.0-x64.msi"
60 $PYOXIDIZER_SHA256 = "85c3bc21a18eb5e2db4dad87cca29accf725c7d59dd364a853ab5099c272024b"
60 $PYOXIDIZER_SHA256 = "85c3bc21a18eb5e2db4dad87cca29accf725c7d59dd364a853ab5099c272024b"
61
61
62 # Writing progress slows down downloads substantially. So disable it.
62 # Writing progress slows down downloads substantially. So disable it.
63 $progressPreference = 'silentlyContinue'
63 $progressPreference = 'silentlyContinue'
64
64
65 function Secure-Download($url, $path, $sha256) {
65 function Secure-Download($url, $path, $sha256) {
66 if (Test-Path -Path $path) {
66 if (Test-Path -Path $path) {
67 Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash
67 Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash
68
68
69 if ($hash.Hash -eq $sha256) {
69 if ($hash.Hash -eq $sha256) {
70 Write-Output "SHA256 of $path verified as $sha256"
70 Write-Output "SHA256 of $path verified as $sha256"
71 return
71 return
72 }
72 }
73
73
74 Write-Output "hash mismatch on $path; downloading again"
74 Write-Output "hash mismatch on $path; downloading again"
75 }
75 }
76
76
77 Write-Output "downloading $url to $path"
77 Write-Output "downloading $url to $path"
78 Invoke-WebRequest -Uri $url -OutFile $path
78 Invoke-WebRequest -Uri $url -OutFile $path
79 Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash
79 Get-FileHash -Path $path -Algorithm SHA256 -OutVariable hash
80
80
81 if ($hash.Hash -ne $sha256) {
81 if ($hash.Hash -ne $sha256) {
82 Remove-Item -Path $path
82 Remove-Item -Path $path
83 throw "hash mismatch when downloading $url; got $($hash.Hash), expected $sha256"
83 throw "hash mismatch when downloading $url; got $($hash.Hash), expected $sha256"
84 }
84 }
85 }
85 }
86
86
87 function Invoke-Process($path, $arguments) {
87 function Invoke-Process($path, $arguments) {
88 echo "$path $arguments"
88 echo "$path $arguments"
89
89
90 $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden
90 $p = Start-Process -FilePath $path -ArgumentList $arguments -Wait -PassThru -WindowStyle Hidden
91
91
92 if ($p.ExitCode -ne 0) {
92 if ($p.ExitCode -ne 0) {
93 # If the MSI is already installed, ignore the error
93 # If the MSI is already installed, ignore the error
94 if ($p.ExitCode -eq 1638) {
94 if ($p.ExitCode -eq 1638) {
95 Write-Output "program already installed; continuing..."
95 Write-Output "program already installed; continuing..."
96 }
96 }
97 else {
97 else {
98 throw "process exited non-0: $($p.ExitCode)"
98 throw "process exited non-0: $($p.ExitCode)"
99 }
99 }
100 }
100 }
101 }
101 }
102
102
103 function Install-Python3($name, $installer, $dest, $pip) {
103 function Install-Python3($name, $installer, $dest, $pip) {
104 Write-Output "installing $name"
104 Write-Output "installing $name"
105
105
106 # We hit this when running the script as part of Simple Systems Manager in
106 # We hit this when running the script as part of Simple Systems Manager in
107 # EC2. The Python 3 installer doesn't seem to like per-user installs
107 # EC2. The Python 3 installer doesn't seem to like per-user installs
108 # when running as the SYSTEM user. So enable global installs if executed in
108 # when running as the SYSTEM user. So enable global installs if executed in
109 # this mode.
109 # this mode.
110 if ($env:USERPROFILE -eq "C:\Windows\system32\config\systemprofile") {
110 if ($env:USERPROFILE -eq "C:\Windows\system32\config\systemprofile") {
111 Write-Output "running with SYSTEM account; installing for all users"
111 Write-Output "running with SYSTEM account; installing for all users"
112 $allusers = "1"
112 $allusers = "1"
113 }
113 }
114 else {
114 else {
115 $allusers = "0"
115 $allusers = "0"
116 }
116 }
117
117
118 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"
118 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"
119 Invoke-Process ${dest}\python.exe $pip
119 Invoke-Process ${dest}\python.exe $pip
120 }
120 }
121
121
122 function Install-Rust($prefix) {
122 function Install-Rust($prefix) {
123 Write-Output "installing Rust"
123 Write-Output "installing Rust"
124 $Env:RUSTUP_HOME = "${prefix}\rustup"
124 $Env:RUSTUP_HOME = "${prefix}\rustup"
125 $Env:CARGO_HOME = "${prefix}\cargo"
125 $Env:CARGO_HOME = "${prefix}\cargo"
126
126
127 Invoke-Process "${prefix}\assets\rustup-init.exe" "-y --default-host x86_64-pc-windows-msvc"
127 Invoke-Process "${prefix}\assets\rustup-init.exe" "-y --default-host x86_64-pc-windows-msvc"
128 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "target add i686-pc-windows-msvc"
128 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "target add i686-pc-windows-msvc"
129 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "install 1.52.0"
129 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "install 1.52.0"
130 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "component add clippy"
130 Invoke-Process "${prefix}\cargo\bin\rustup.exe" "component add clippy"
131 }
131 }
132
132
133 function Install-Dependencies($prefix) {
133 function Install-Dependencies($prefix) {
134 if (!(Test-Path -Path $prefix\assets)) {
134 if (!(Test-Path -Path $prefix\assets)) {
135 New-Item -Path $prefix\assets -ItemType Directory
135 New-Item -Path $prefix\assets -ItemType Directory
136 }
136 }
137
137
138 $pip = "${prefix}\assets\get-pip.py"
138 $pip = "${prefix}\assets\get-pip.py"
139
139
140 Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256
140 Secure-Download $PYTHON37_x86_URL ${prefix}\assets\python37-x86.exe $PYTHON37_x86_SHA256
141 Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256
141 Secure-Download $PYTHON37_x64_URL ${prefix}\assets\python37-x64.exe $PYTHON37_x64_SHA256
142 Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256
142 Secure-Download $PYTHON38_x86_URL ${prefix}\assets\python38-x86.exe $PYTHON38_x86_SHA256
143 Secure-Download $PYTHON38_x64_URL ${prefix}\assets\python38-x64.exe $PYTHON38_x64_SHA256
143 Secure-Download $PYTHON38_x64_URL ${prefix}\assets\python38-x64.exe $PYTHON38_x64_SHA256
144 Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256
144 Secure-Download $PYTHON39_x86_URL ${prefix}\assets\python39-x86.exe $PYTHON39_x86_SHA256
145 Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256
145 Secure-Download $PYTHON39_x64_URL ${prefix}\assets\python39-x64.exe $PYTHON39_x64_SHA256
146 Secure-Download $PYTHON310_x86_URL ${prefix}\assets\python310-x86.exe $PYTHON310_x86_SHA256
146 Secure-Download $PYTHON310_x86_URL ${prefix}\assets\python310-x86.exe $PYTHON310_x86_SHA256
147 Secure-Download $PYTHON310_x64_URL ${prefix}\assets\python310-x64.exe $PYTHON310_x64_SHA256
147 Secure-Download $PYTHON310_x64_URL ${prefix}\assets\python310-x64.exe $PYTHON310_x64_SHA256
148 Secure-Download $PIP_URL ${pip} $PIP_SHA256
148 Secure-Download $PIP_URL ${pip} $PIP_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 Secure-Download $PYOXIDIZER_URL ${prefix}\assets\PyOxidizer.msi $PYOXIDIZER_SHA256
154 Secure-Download $PYOXIDIZER_URL ${prefix}\assets\PyOxidizer.msi $PYOXIDIZER_SHA256
155
155
156 Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip}
156 Install-Python3 "Python 3.7 32-bit" ${prefix}\assets\python37-x86.exe ${prefix}\python37-x86 ${pip}
157 Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip}
157 Install-Python3 "Python 3.7 64-bit" ${prefix}\assets\python37-x64.exe ${prefix}\python37-x64 ${pip}
158 Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip}
158 Install-Python3 "Python 3.8 32-bit" ${prefix}\assets\python38-x86.exe ${prefix}\python38-x86 ${pip}
159 Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip}
159 Install-Python3 "Python 3.8 64-bit" ${prefix}\assets\python38-x64.exe ${prefix}\python38-x64 ${pip}
160 Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip}
160 Install-Python3 "Python 3.9 32-bit" ${prefix}\assets\python39-x86.exe ${prefix}\python39-x86 ${pip}
161 Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip}
161 Install-Python3 "Python 3.9 64-bit" ${prefix}\assets\python39-x64.exe ${prefix}\python39-x64 ${pip}
162 Install-Python3 "Python 3.10 32-bit" ${prefix}\assets\python310-x86.exe ${prefix}\python310-x86 ${pip}
162 Install-Python3 "Python 3.10 32-bit" ${prefix}\assets\python310-x86.exe ${prefix}\python310-x86 ${pip}
163 Install-Python3 "Python 3.10 64-bit" ${prefix}\assets\python310-x64.exe ${prefix}\python310-x64 ${pip}
163 Install-Python3 "Python 3.10 64-bit" ${prefix}\assets\python310-x64.exe ${prefix}\python310-x64 ${pip}
164
164
165 Write-Output "installing Visual Studio 2017 Build Tools and SDKs"
165 Write-Output "installing Visual Studio 2017 Build Tools and SDKs"
166 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"
166 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"
167
167
168 Write-Output "installing PyOxidizer"
168 Write-Output "installing PyOxidizer"
169 Invoke-Process msiexec.exe "/i ${prefix}\assets\PyOxidizer.msi /l* ${prefix}\assets\PyOxidizer.log /quiet"
169 Invoke-Process msiexec.exe "/i ${prefix}\assets\PyOxidizer.msi /l* ${prefix}\assets\PyOxidizer.log /quiet"
170
170
171 Install-Rust ${prefix}
171 Install-Rust ${prefix}
172
172
173 Write-Output "installing Inno Setup"
173 Write-Output "installing Inno Setup"
174 Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES"
174 Invoke-Process ${prefix}\assets\InnoSetup.exe "/SP- /VERYSILENT /SUPPRESSMSGBOXES"
175
175
176 Write-Output "extracting MinGW base archive"
176 Write-Output "extracting MinGW base archive"
177 Expand-Archive -Path ${prefix}\assets\mingw-get-bin.zip -DestinationPath "${prefix}\MinGW" -Force
177 Expand-Archive -Path ${prefix}\assets\mingw-get-bin.zip -DestinationPath "${prefix}\MinGW" -Force
178
178
179 Write-Output "updating MinGW package catalogs"
179 Write-Output "updating MinGW package catalogs"
180 Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "update"
180 Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "update"
181
181
182 Write-Output "installing MinGW packages"
182 Write-Output "installing MinGW packages"
183 Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "install msys-base msys-coreutils msys-diffutils msys-unzip"
183 Invoke-Process ${prefix}\MinGW\bin\mingw-get.exe "install msys-base msys-coreutils msys-diffutils msys-unzip"
184
184
185 # Construct a virtualenv useful for bootstrapping. It conveniently contains a
185 # Construct a virtualenv useful for bootstrapping. It conveniently contains a
186 # Mercurial install.
186 # Mercurial install.
187 Write-Output "creating bootstrap virtualenv with Mercurial"
187 Write-Output "creating bootstrap virtualenv with Mercurial"
188 Invoke-Process "$prefix\python39-x64\python.exe" "-m venv ${prefix}\venv-bootstrap"
188 Invoke-Process "$prefix\python39-x64\python.exe" "-m venv ${prefix}\venv-bootstrap"
189 Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}"
189 Invoke-Process "${prefix}\venv-bootstrap\Scripts\pip.exe" "install ${prefix}\assets\${MERCURIAL_WHEEL_FILENAME}"
190 }
190 }
191
191
192 function Clone-Mercurial-Repo($prefix, $repo_url, $dest) {
192 function Clone-Mercurial-Repo($prefix, $repo_url, $dest) {
193 Write-Output "cloning $repo_url to $dest"
193 Write-Output "cloning $repo_url to $dest"
194 # TODO Figure out why CA verification isn't working in EC2 and remove
194 # TODO Figure out why CA verification isn't working in EC2 and remove
195 # --insecure.
195 # --insecure.
196 Invoke-Process "${prefix}\venv-bootstrap\Scripts\python.exe" "${prefix}\venv-bootstrap\Scripts\hg clone --insecure $repo_url $dest"
196 Invoke-Process "${prefix}\venv-bootstrap\Scripts\python.exe" "${prefix}\venv-bootstrap\Scripts\hg clone --insecure $repo_url $dest"
197
197
198 # Mark repo as non-publishing by default for convenience.
198 # Mark repo as non-publishing by default for convenience.
199 Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false"
199 Add-Content -Path "$dest\.hg\hgrc" -Value "`n[phases]`npublish = false"
200 }
200 }
201
201
202 $prefix = "c:\hgdev"
202 $prefix = "c:\hgdev"
203 Install-Dependencies $prefix
203 Install-Dependencies $prefix
204 Clone-Mercurial-Repo $prefix "https://www.mercurial-scm.org/repo/hg" $prefix\src
204 Clone-Mercurial-Repo $prefix "https://www.mercurial-scm.org/repo/hg" $prefix\src
@@ -1,328 +1,336 b''
1 #
1 #
2 # This file is autogenerated by pip-compile with python 3.7
2 # This file is autogenerated by pip-compile with python 3.7
3 # To update, run:
3 # To update, run:
4 #
4 #
5 # pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py3.txt contrib/packaging/requirements-windows.txt.in
5 # pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py3.txt contrib/packaging/requirements-windows.txt.in
6 #
6 #
7 atomicwrites==1.4.0 \
7 atomicwrites==1.4.0 \
8 --hash=sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197 \
8 --hash=sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197 \
9 --hash=sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a
9 --hash=sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a
10 # via pytest
10 # via pytest
11 attrs==21.2.0 \
11 attrs==21.2.0 \
12 --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \
12 --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \
13 --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb
13 --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb
14 # via pytest
14 # via pytest
15 cached-property==1.5.2 \
15 cached-property==1.5.2 \
16 --hash=sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130 \
16 --hash=sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130 \
17 --hash=sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0
17 --hash=sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0
18 # via pygit2
18 # via pygit2
19 certifi==2021.5.30 \
19 certifi==2021.5.30 \
20 --hash=sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee \
20 --hash=sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee \
21 --hash=sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8
21 --hash=sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8
22 # via dulwich
22 # via dulwich
23 cffi==1.15.0 \
23 cffi==1.15.0 \
24 --hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \
24 --hash=sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3 \
25 --hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \
25 --hash=sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2 \
26 --hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \
26 --hash=sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636 \
27 --hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \
27 --hash=sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20 \
28 --hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \
28 --hash=sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728 \
29 --hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \
29 --hash=sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27 \
30 --hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \
30 --hash=sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66 \
31 --hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \
31 --hash=sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443 \
32 --hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \
32 --hash=sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0 \
33 --hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \
33 --hash=sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7 \
34 --hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \
34 --hash=sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39 \
35 --hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \
35 --hash=sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605 \
36 --hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \
36 --hash=sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a \
37 --hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \
37 --hash=sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37 \
38 --hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \
38 --hash=sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029 \
39 --hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \
39 --hash=sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139 \
40 --hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \
40 --hash=sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc \
41 --hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \
41 --hash=sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df \
42 --hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \
42 --hash=sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14 \
43 --hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \
43 --hash=sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880 \
44 --hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \
44 --hash=sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2 \
45 --hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \
45 --hash=sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a \
46 --hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \
46 --hash=sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e \
47 --hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \
47 --hash=sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474 \
48 --hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \
48 --hash=sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024 \
49 --hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \
49 --hash=sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8 \
50 --hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \
50 --hash=sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0 \
51 --hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \
51 --hash=sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e \
52 --hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \
52 --hash=sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a \
53 --hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \
53 --hash=sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e \
54 --hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \
54 --hash=sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032 \
55 --hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \
55 --hash=sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6 \
56 --hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \
56 --hash=sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e \
57 --hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \
57 --hash=sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b \
58 --hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \
58 --hash=sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e \
59 --hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \
59 --hash=sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954 \
60 --hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \
60 --hash=sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962 \
61 --hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \
61 --hash=sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c \
62 --hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \
62 --hash=sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4 \
63 --hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \
63 --hash=sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55 \
64 --hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \
64 --hash=sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962 \
65 --hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \
65 --hash=sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023 \
66 --hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \
66 --hash=sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c \
67 --hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \
67 --hash=sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6 \
68 --hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \
68 --hash=sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8 \
69 --hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \
69 --hash=sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382 \
70 --hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \
70 --hash=sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7 \
71 --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \
71 --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \
72 --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \
72 --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \
73 --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796
73 --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796
74 # via pygit2
74 # via pygit2
75 colorama==0.4.4 \
75 colorama==0.4.4 \
76 --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b \
76 --hash=sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b \
77 --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2
77 --hash=sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2
78 # via pytest
78 # via pytest
79 docutils==0.16 \
79 docutils==0.16 \
80 --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
80 --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
81 --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc
81 --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc
82 # via -r contrib/packaging/requirements-windows.txt.in
82 # via -r contrib/packaging/requirements-windows.txt.in
83 dulwich==0.20.6 ; python_version >= "3" \
83 dulwich==0.20.45 \
84 --hash=sha256:1ccd55e38fa9f169290f93e027ab4508202f5bdd6ef534facac4edd3f6903f0d \
84 --hash=sha256:042bc206764968b17338e32c52bb6a116154eb87a63651971946917dfa37a359 \
85 --hash=sha256:2452a0379cc7bbbd7ab893ec104d18039f1ea98b0d6be6bca5646e5cf29e0ae9 \
85 --hash=sha256:22d433ba9c776f2b0e19b1186e01e25ca286175e20f4ac422141db94eeaac08b \
86 --hash=sha256:2f4aebc54ed2d37dcee737024421452375570a422eb682232e676aa7ebc9cb4b \
86 --hash=sha256:2d7cf5171034d9d61b928bd5f9c509000e895d1ba29bd6ea850b9e4f93fca0f7 \
87 --hash=sha256:304f52b10c49c3a6ddfbd73e2e93d8e979350225cfba9688e51110e74fa2f718 \
87 --hash=sha256:3136bcaf7508522a2aa63f856743f06129261bc5a03331aa6a0654fa6d04a4ae \
88 --hash=sha256:49e747c72d9099e873bf6196260346d5996c3f28af788294d47a8accdc524de7 \
88 --hash=sha256:35015e43207752cf7924860e85a3c2290c652c0c3ee81e7c95c52d34638f605d \
89 --hash=sha256:4fee359928c59b53af153a582a7ed7595259a5a825df400301a29e17fd78dfd3 \
89 --hash=sha256:3f2c137a0003e80e384d116e65b453f8a704c2d393c30a47b447764e7f9c05a1 \
90 --hash=sha256:50ef300a9fa4efd9f85009c2bd8b515266ec1529400f8834f85c04fa9f09b2c0 \
90 --hash=sha256:49852f12c1e1d50039f927e9fdee1bd00a9b428c31b078ba5ba9fc1cf88e9d3e \
91 --hash=sha256:5348310f21b2a23847342ce464461499b6652483fa42de03714d0f6421a99698 \
91 --hash=sha256:4abb1b0e1e50192ce7204c4e14f24c989c5920c56de908365f4e66c6e3458945 \
92 --hash=sha256:7e7b5dea5178b6493fdb83adccbe81de9ddff55f79880185ed594c0e3a97209b \
92 --hash=sha256:4e405ac9426288ca782c45e066f816d878b4a529acf4d4b0b2a5bb45a804dfec \
93 --hash=sha256:8f7a7f973be2beedfb10dd8d3eb6bdf9ec466c72ad555704897cbd6357fe5021 \
93 --hash=sha256:5e41044ac51a4b3454d67e5f691808540470deeb6a852d7c5c6ca44c48b4cdc3 \
94 --hash=sha256:bea6e6caffc6c73bfd1647714c5715ab96ac49deb8beb8b67511529afa25685a \
94 --hash=sha256:65334bd7a1d91054516a49f86343e9c2549740bbddebcbb4763c8aacf2aac48c \
95 --hash=sha256:e5871b86a079e9e290f52ab14559cea1b694a0b8ed2b9ebb898f6ced7f14a406 \
95 --hash=sha256:6e02babb44bdad17b6c9c50b4f9df42f6e511e3a51555ac07dd85ec904efe0b1 \
96 --hash=sha256:e593f514b8ac740b4ceeb047745b4719bfc9f334904245c6edcb3a9d002f577b
96 --hash=sha256:70710dd9ca2a442190c7e506892db074c318ac762e221f7529b8ce34802041b7 \
97 --hash=sha256:9b689b05bc7baa5cb20ebff54291085b598a9bdf7caeab23daf93b46421d96ff \
98 --hash=sha256:b3f64870f2f206dda3308cb73563f5f59fdc084179271651a0488d12ab4185b9 \
99 --hash=sha256:bb75268cec2f3ae6f6b7addbc0db50db2e9e42b2ad8364e74b9f5b17ab0053b5 \
100 --hash=sha256:c8c0fc7d2e3b0ad6a4faadf96f0626fa50935ababfd774b9b94edaa28f0668ec \
101 --hash=sha256:d89f53a739ac3394b5ef2f178480569b7d36d4fe7b4bb49678582914530ce35b \
102 --hash=sha256:d8b6aae7af8edbfac8038e1777ae820efac33c7c22a8025d3254bbd53ec725b5 \
103 --hash=sha256:eb4189d72a0e2f3070e2abdbd10a05c0e62355cd5496761d6e68f1e865ac6fad \
104 --hash=sha256:efe46167eb02ba85d9c2e993635e7543e1e04bb3261112e9d54daff2385ae5df
97 # via -r contrib/packaging/requirements-windows.txt.in
105 # via -r contrib/packaging/requirements-windows.txt.in
98 fuzzywuzzy==0.18.0 \
106 fuzzywuzzy==0.18.0 \
99 --hash=sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8
107 --hash=sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8
100 # via -r contrib/packaging/requirements-windows.txt.in
108 # via -r contrib/packaging/requirements-windows.txt.in
101 idna==3.2 \
109 idna==3.2 \
102 --hash=sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a \
110 --hash=sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a \
103 --hash=sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3
111 --hash=sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3
104 # via yarl
112 # via yarl
105 importlib-metadata==3.1.0 \
113 importlib-metadata==3.1.0 \
106 --hash=sha256:590690d61efdd716ff82c39ca9a9d4209252adfe288a4b5721181050acbd4175 \
114 --hash=sha256:590690d61efdd716ff82c39ca9a9d4209252adfe288a4b5721181050acbd4175 \
107 --hash=sha256:d9b8a46a0885337627a6430db287176970fff18ad421becec1d64cfc763c2099
115 --hash=sha256:d9b8a46a0885337627a6430db287176970fff18ad421becec1d64cfc763c2099
108 # via
116 # via
109 # keyring
117 # keyring
110 # pluggy
118 # pluggy
111 # pytest
119 # pytest
112 iniconfig==1.1.1 \
120 iniconfig==1.1.1 \
113 --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
121 --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
114 --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
122 --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
115 # via pytest
123 # via pytest
116 keyring==21.4.0 \
124 keyring==22.3.0 \
117 --hash=sha256:4e34ea2fdec90c1c43d6610b5a5fafa1b9097db1802948e90caf5763974b8f8d \
125 --hash=sha256:16927a444b2c73f983520a48dec79ddab49fe76429ea05b8d528d778c8339522 \
118 --hash=sha256:9aeadd006a852b78f4b4ef7c7556c2774d2432bbef8ee538a3e9089ac8b11466
126 --hash=sha256:2bc8363ebdd63886126a012057a85c8cb6e143877afa02619ac7dbc9f38a207b
119 # via -r contrib/packaging/requirements-windows.txt.in
127 # via -r contrib/packaging/requirements-windows.txt.in
120 multidict==5.1.0 \
128 multidict==5.1.0 \
121 --hash=sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a \
129 --hash=sha256:018132dbd8688c7a69ad89c4a3f39ea2f9f33302ebe567a879da8f4ca73f0d0a \
122 --hash=sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93 \
130 --hash=sha256:051012ccee979b2b06be928a6150d237aec75dd6bf2d1eeeb190baf2b05abc93 \
123 --hash=sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632 \
131 --hash=sha256:05c20b68e512166fddba59a918773ba002fdd77800cad9f55b59790030bab632 \
124 --hash=sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656 \
132 --hash=sha256:07b42215124aedecc6083f1ce6b7e5ec5b50047afa701f3442054373a6deb656 \
125 --hash=sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79 \
133 --hash=sha256:0e3c84e6c67eba89c2dbcee08504ba8644ab4284863452450520dad8f1e89b79 \
126 --hash=sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7 \
134 --hash=sha256:0e929169f9c090dae0646a011c8b058e5e5fb391466016b39d21745b48817fd7 \
127 --hash=sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d \
135 --hash=sha256:1ab820665e67373de5802acae069a6a05567ae234ddb129f31d290fc3d1aa56d \
128 --hash=sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5 \
136 --hash=sha256:25b4e5f22d3a37ddf3effc0710ba692cfc792c2b9edfb9c05aefe823256e84d5 \
129 --hash=sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224 \
137 --hash=sha256:2e68965192c4ea61fff1b81c14ff712fc7dc15d2bd120602e4a3494ea6584224 \
130 --hash=sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26 \
138 --hash=sha256:2f1a132f1c88724674271d636e6b7351477c27722f2ed789f719f9e3545a3d26 \
131 --hash=sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea \
139 --hash=sha256:37e5438e1c78931df5d3c0c78ae049092877e5e9c02dd1ff5abb9cf27a5914ea \
132 --hash=sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348 \
140 --hash=sha256:3a041b76d13706b7fff23b9fc83117c7b8fe8d5fe9e6be45eee72b9baa75f348 \
133 --hash=sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6 \
141 --hash=sha256:3a4f32116f8f72ecf2a29dabfb27b23ab7cdc0ba807e8459e59a93a9be9506f6 \
134 --hash=sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76 \
142 --hash=sha256:46c73e09ad374a6d876c599f2328161bcd95e280f84d2060cf57991dec5cfe76 \
135 --hash=sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1 \
143 --hash=sha256:46dd362c2f045095c920162e9307de5ffd0a1bfbba0a6e990b344366f55a30c1 \
136 --hash=sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f \
144 --hash=sha256:4b186eb7d6ae7c06eb4392411189469e6a820da81447f46c0072a41c748ab73f \
137 --hash=sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952 \
145 --hash=sha256:54fd1e83a184e19c598d5e70ba508196fd0bbdd676ce159feb412a4a6664f952 \
138 --hash=sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a \
146 --hash=sha256:585fd452dd7782130d112f7ddf3473ffdd521414674c33876187e101b588738a \
139 --hash=sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37 \
147 --hash=sha256:5cf3443199b83ed9e955f511b5b241fd3ae004e3cb81c58ec10f4fe47c7dce37 \
140 --hash=sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9 \
148 --hash=sha256:6a4d5ce640e37b0efcc8441caeea8f43a06addace2335bd11151bc02d2ee31f9 \
141 --hash=sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359 \
149 --hash=sha256:7df80d07818b385f3129180369079bd6934cf70469f99daaebfac89dca288359 \
142 --hash=sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8 \
150 --hash=sha256:806068d4f86cb06af37cd65821554f98240a19ce646d3cd24e1c33587f313eb8 \
143 --hash=sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da \
151 --hash=sha256:830f57206cc96ed0ccf68304141fec9481a096c4d2e2831f311bde1c404401da \
144 --hash=sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3 \
152 --hash=sha256:929006d3c2d923788ba153ad0de8ed2e5ed39fdbe8e7be21e2f22ed06c6783d3 \
145 --hash=sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d \
153 --hash=sha256:9436dc58c123f07b230383083855593550c4d301d2532045a17ccf6eca505f6d \
146 --hash=sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf \
154 --hash=sha256:9dd6e9b1a913d096ac95d0399bd737e00f2af1e1594a787e00f7975778c8b2bf \
147 --hash=sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841 \
155 --hash=sha256:ace010325c787c378afd7f7c1ac66b26313b3344628652eacd149bdd23c68841 \
148 --hash=sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d \
156 --hash=sha256:b47a43177a5e65b771b80db71e7be76c0ba23cc8aa73eeeb089ed5219cdbe27d \
149 --hash=sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93 \
157 --hash=sha256:b797515be8743b771aa868f83563f789bbd4b236659ba52243b735d80b29ed93 \
150 --hash=sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f \
158 --hash=sha256:b7993704f1a4b204e71debe6095150d43b2ee6150fa4f44d6d966ec356a8d61f \
151 --hash=sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647 \
159 --hash=sha256:d5c65bdf4484872c4af3150aeebe101ba560dcfb34488d9a8ff8dbcd21079647 \
152 --hash=sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635 \
160 --hash=sha256:d81eddcb12d608cc08081fa88d046c78afb1bf8107e6feab5d43503fea74a635 \
153 --hash=sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456 \
161 --hash=sha256:dc862056f76443a0db4509116c5cd480fe1b6a2d45512a653f9a855cc0517456 \
154 --hash=sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda \
162 --hash=sha256:ecc771ab628ea281517e24fd2c52e8f31c41e66652d07599ad8818abaad38cda \
155 --hash=sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5 \
163 --hash=sha256:f200755768dc19c6f4e2b672421e0ebb3dd54c38d5a4f262b872d8cfcc9e93b5 \
156 --hash=sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281 \
164 --hash=sha256:f21756997ad8ef815d8ef3d34edd98804ab5ea337feedcd62fb52d22bf531281 \
157 --hash=sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80
165 --hash=sha256:fc13a9524bc18b6fb6e0dbec3533ba0496bbed167c56d0aabefd965584557d80
158 # via yarl
166 # via yarl
159 packaging==21.0 \
167 packaging==21.0 \
160 --hash=sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7 \
168 --hash=sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7 \
161 --hash=sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14
169 --hash=sha256:c86254f9220d55e31cc94d69bade760f0847da8000def4dfe1c6b872fd14ff14
162 # via pytest
170 # via pytest
163 pluggy==0.13.1 \
171 pluggy==0.13.1 \
164 --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 \
172 --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 \
165 --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d
173 --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d
166 # via pytest
174 # via pytest
167 py==1.10.0 \
175 py==1.10.0 \
168 --hash=sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3 \
176 --hash=sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3 \
169 --hash=sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a
177 --hash=sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a
170 # via pytest
178 # via pytest
171 pycparser==2.21 \
179 pycparser==2.21 \
172 --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
180 --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \
173 --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
181 --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206
174 # via cffi
182 # via cffi
175 pygit2==1.7.1 ; python_version >= "3" \
183 pygit2==1.7.1 \
176 --hash=sha256:2c9e95efb86c0b32cc07c26be3d179e851ca4a7899c47fef63c4203963144f5e \
184 --hash=sha256:2c9e95efb86c0b32cc07c26be3d179e851ca4a7899c47fef63c4203963144f5e \
177 --hash=sha256:3ddacbf461652d3d4900382f821d9fbd5ae2dedecd7862b5245842419ad0ccba \
185 --hash=sha256:3ddacbf461652d3d4900382f821d9fbd5ae2dedecd7862b5245842419ad0ccba \
178 --hash=sha256:4cb0414df6089d0072ebe93ff2f34730737172dd5f0e72289567d06a6caf09c0 \
186 --hash=sha256:4cb0414df6089d0072ebe93ff2f34730737172dd5f0e72289567d06a6caf09c0 \
179 --hash=sha256:56e960dc74f4582bfa3ca17a1a9d542732fc93b5cf8f82574c235d06b2d61eae \
187 --hash=sha256:56e960dc74f4582bfa3ca17a1a9d542732fc93b5cf8f82574c235d06b2d61eae \
180 --hash=sha256:6b17ab922c2a2d99b30ab9222472b07732bf7261d9f9655a4ea23b4c700049d8 \
188 --hash=sha256:6b17ab922c2a2d99b30ab9222472b07732bf7261d9f9655a4ea23b4c700049d8 \
181 --hash=sha256:73a7b471f22cb59e8729016de1f447c472b3b2c1cc2b622194e5e3b48a7f5776 \
189 --hash=sha256:73a7b471f22cb59e8729016de1f447c472b3b2c1cc2b622194e5e3b48a7f5776 \
182 --hash=sha256:761a8850e33822796c1c24d411d5cc2460c04e1a74b04ae8560efd3596bbd6bd \
190 --hash=sha256:761a8850e33822796c1c24d411d5cc2460c04e1a74b04ae8560efd3596bbd6bd \
183 --hash=sha256:7c467e81158f5827b3bca6362e5cc9b92857eff9de65034d338c1f18524b09be \
191 --hash=sha256:7c467e81158f5827b3bca6362e5cc9b92857eff9de65034d338c1f18524b09be \
184 --hash=sha256:7c56e10592e62610a19bd3e2a633aafe3488c57b906c7c2fde0299937f0f0b2f \
192 --hash=sha256:7c56e10592e62610a19bd3e2a633aafe3488c57b906c7c2fde0299937f0f0b2f \
185 --hash=sha256:7cc2a8e29cc9598310a78cf58b70d9331277cf374802be8f97d97c4a9e5d8387 \
193 --hash=sha256:7cc2a8e29cc9598310a78cf58b70d9331277cf374802be8f97d97c4a9e5d8387 \
186 --hash=sha256:812670f7994f31778e873a9eced29d2bbfa91674e8be0ab1e974c8a4bda9cbab \
194 --hash=sha256:812670f7994f31778e873a9eced29d2bbfa91674e8be0ab1e974c8a4bda9cbab \
187 --hash=sha256:8cdb0b1d6c3d24b44f340fed143b16e64ba23fe2a449f1a5db87aaf9339a9dbe \
195 --hash=sha256:8cdb0b1d6c3d24b44f340fed143b16e64ba23fe2a449f1a5db87aaf9339a9dbe \
188 --hash=sha256:91b77a305d8d18b649396e66e832d654cd593a3d29b5728f753f254a04533812 \
196 --hash=sha256:91b77a305d8d18b649396e66e832d654cd593a3d29b5728f753f254a04533812 \
189 --hash=sha256:a75bcde32238c77eb0cf7d9698a5aa899408d7ad999a5920a29a7c4b80fdeaa7 \
197 --hash=sha256:a75bcde32238c77eb0cf7d9698a5aa899408d7ad999a5920a29a7c4b80fdeaa7 \
190 --hash=sha256:b060240cf3038e7a0706bbfc5436dd03b8d5ac797ac1d512b613f4d04b974c80 \
198 --hash=sha256:b060240cf3038e7a0706bbfc5436dd03b8d5ac797ac1d512b613f4d04b974c80 \
191 --hash=sha256:cdfa61c0428a8182e5a6a1161c017b824cd511574f080a40b10d6413774eb0ca \
199 --hash=sha256:cdfa61c0428a8182e5a6a1161c017b824cd511574f080a40b10d6413774eb0ca \
192 --hash=sha256:d7faa29558436decc2e78110f38d6677eb366b683ba5cdc2803d47195711165d \
200 --hash=sha256:d7faa29558436decc2e78110f38d6677eb366b683ba5cdc2803d47195711165d \
193 --hash=sha256:d831825ad9c3b3c28e6b3ef8a2401ad2d3fd4db5455427ff27175a7e254e2592 \
201 --hash=sha256:d831825ad9c3b3c28e6b3ef8a2401ad2d3fd4db5455427ff27175a7e254e2592 \
194 --hash=sha256:df4c477bdfac85d32a1e3180282cd829a0980aa69be9bd0f7cbd4db1778ca72b \
202 --hash=sha256:df4c477bdfac85d32a1e3180282cd829a0980aa69be9bd0f7cbd4db1778ca72b \
195 --hash=sha256:eced3529bafcaaac015d08dfaa743b3cbad37fcd5b13ae9d280b8b7f716ec5ce \
203 --hash=sha256:eced3529bafcaaac015d08dfaa743b3cbad37fcd5b13ae9d280b8b7f716ec5ce \
196 --hash=sha256:fec17e2da668e6bb192d777417aad9c7ca924a166d0a0b9a81a11e00362b1bc7
204 --hash=sha256:fec17e2da668e6bb192d777417aad9c7ca924a166d0a0b9a81a11e00362b1bc7
197 # via -r contrib/packaging/requirements-windows.txt.in
205 # via -r contrib/packaging/requirements-windows.txt.in
198 pygments==2.7.1 \
206 pygments==2.7.1 \
199 --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \
207 --hash=sha256:307543fe65c0947b126e83dd5a61bd8acbd84abec11f43caebaf5534cbc17998 \
200 --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7
208 --hash=sha256:926c3f319eda178d1bd90851e4317e6d8cdb5e292a3386aac9bd75eca29cf9c7
201 # via -r contrib/packaging/requirements-windows.txt.in
209 # via -r contrib/packaging/requirements-windows.txt.in
202 pyparsing==2.4.7 \
210 pyparsing==2.4.7 \
203 --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 \
211 --hash=sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1 \
204 --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b
212 --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b
205 # via packaging
213 # via packaging
206 pytest==6.2.4 \
214 pytest==6.2.4 \
207 --hash=sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b \
215 --hash=sha256:50bcad0a0b9c5a72c8e4e7c9855a3ad496ca6a881a3641b4260605450772c54b \
208 --hash=sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890
216 --hash=sha256:91ef2131a9bd6be8f76f1f08eac5c5317221d6ad1e143ae03894b862e8976890
209 # via pytest-vcr
217 # via pytest-vcr
210 pytest-vcr==1.0.2 \
218 pytest-vcr==1.0.2 \
211 --hash=sha256:23ee51b75abbcc43d926272773aae4f39f93aceb75ed56852d0bf618f92e1896
219 --hash=sha256:23ee51b75abbcc43d926272773aae4f39f93aceb75ed56852d0bf618f92e1896
212 # via -r contrib/packaging/requirements-windows.txt.in
220 # via -r contrib/packaging/requirements-windows.txt.in
213 pywin32-ctypes==0.2.0 \
221 pywin32-ctypes==0.2.0 \
214 --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \
222 --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \
215 --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98
223 --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98
216 # via
224 # via
217 # -r contrib/packaging/requirements-windows.txt.in
225 # -r contrib/packaging/requirements-windows.txt.in
218 # keyring
226 # keyring
219 pyyaml==5.4.1 \
227 pyyaml==5.4.1 \
220 --hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
228 --hash=sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf \
221 --hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
229 --hash=sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696 \
222 --hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \
230 --hash=sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393 \
223 --hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
231 --hash=sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77 \
224 --hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \
232 --hash=sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922 \
225 --hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
233 --hash=sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5 \
226 --hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \
234 --hash=sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8 \
227 --hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
235 --hash=sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10 \
228 --hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
236 --hash=sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc \
229 --hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
237 --hash=sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018 \
230 --hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e \
238 --hash=sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e \
231 --hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
239 --hash=sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253 \
232 --hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \
240 --hash=sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347 \
233 --hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
241 --hash=sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183 \
234 --hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \
242 --hash=sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541 \
235 --hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
243 --hash=sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb \
236 --hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
244 --hash=sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185 \
237 --hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \
245 --hash=sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc \
238 --hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
246 --hash=sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db \
239 --hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \
247 --hash=sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa \
240 --hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
248 --hash=sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46 \
241 --hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \
249 --hash=sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122 \
242 --hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
250 --hash=sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b \
243 --hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
251 --hash=sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63 \
244 --hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
252 --hash=sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df \
245 --hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
253 --hash=sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc \
246 --hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \
254 --hash=sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247 \
247 --hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \
255 --hash=sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6 \
248 --hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0
256 --hash=sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0
249 # via vcrpy
257 # via vcrpy
250 six==1.16.0 \
258 six==1.16.0 \
251 --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
259 --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
252 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
260 --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
253 # via vcrpy
261 # via vcrpy
254 toml==0.10.2 \
262 toml==0.10.2 \
255 --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
263 --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
256 --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
264 --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
257 # via pytest
265 # via pytest
258 typing-extensions==3.10.0.0 \
266 typing-extensions==3.10.0.0 \
259 --hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \
267 --hash=sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497 \
260 --hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342 \
268 --hash=sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342 \
261 --hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84
269 --hash=sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84
262 # via yarl
270 # via yarl
263 urllib3==1.25.11 \
271 urllib3==1.25.11 \
264 --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \
272 --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \
265 --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e
273 --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e
266 # via dulwich
274 # via dulwich
267 vcrpy==4.1.1 \
275 vcrpy==4.1.1 \
268 --hash=sha256:12c3fcdae7b88ecf11fc0d3e6d77586549d4575a2ceee18e82eee75c1f626162 \
276 --hash=sha256:12c3fcdae7b88ecf11fc0d3e6d77586549d4575a2ceee18e82eee75c1f626162 \
269 --hash=sha256:57095bf22fc0a2d99ee9674cdafebed0f3ba763018582450706f7d3a74fff599
277 --hash=sha256:57095bf22fc0a2d99ee9674cdafebed0f3ba763018582450706f7d3a74fff599
270 # via pytest-vcr
278 # via pytest-vcr
271 windows-curses==2.3.0 \
279 windows-curses==2.3.0 \
272 --hash=sha256:170c0d941c2e0cdf864e7f0441c1bdf0709232bf4aa7ce7f54d90fc76a4c0504 \
280 --hash=sha256:170c0d941c2e0cdf864e7f0441c1bdf0709232bf4aa7ce7f54d90fc76a4c0504 \
273 --hash=sha256:4d5fb991d1b90a41c2332f02241a1f84c8a1e6bc8f6e0d26f532d0da7a9f7b51 \
281 --hash=sha256:4d5fb991d1b90a41c2332f02241a1f84c8a1e6bc8f6e0d26f532d0da7a9f7b51 \
274 --hash=sha256:7a35eda4cb120b9e1a5ae795f3bc06c55b92c9d391baba6be1903285a05f3551 \
282 --hash=sha256:7a35eda4cb120b9e1a5ae795f3bc06c55b92c9d391baba6be1903285a05f3551 \
275 --hash=sha256:935be95cfdb9213f6f5d3d5bcd489960e3a8fbc9b574e7b2e8a3a3cc46efff49 \
283 --hash=sha256:935be95cfdb9213f6f5d3d5bcd489960e3a8fbc9b574e7b2e8a3a3cc46efff49 \
276 --hash=sha256:a3a63a0597729e10f923724c2cf972a23ea677b400d2387dee1d668cf7116177 \
284 --hash=sha256:a3a63a0597729e10f923724c2cf972a23ea677b400d2387dee1d668cf7116177 \
277 --hash=sha256:c860f596d28377e47f322b7382be4d3573fd76d1292234996bb7f72e0bc0ed0d \
285 --hash=sha256:c860f596d28377e47f322b7382be4d3573fd76d1292234996bb7f72e0bc0ed0d \
278 --hash=sha256:cc5fa913780d60f4a40824d374a4f8ca45b4e205546e83a2d85147315a57457e \
286 --hash=sha256:cc5fa913780d60f4a40824d374a4f8ca45b4e205546e83a2d85147315a57457e \
279 --hash=sha256:d5cde8ec6d582aa77af791eca54f60858339fb3f391945f9cad11b1ab71062e3 \
287 --hash=sha256:d5cde8ec6d582aa77af791eca54f60858339fb3f391945f9cad11b1ab71062e3 \
280 --hash=sha256:e913dc121446d92b33fe4f5bcca26d3a34e4ad19f2af160370d57c3d1e93b4e1 \
288 --hash=sha256:e913dc121446d92b33fe4f5bcca26d3a34e4ad19f2af160370d57c3d1e93b4e1 \
281 --hash=sha256:fbc2131cec57e422c6660e6cdb3420aff5be5169b8e45bb7c471f884b0590a2b
289 --hash=sha256:fbc2131cec57e422c6660e6cdb3420aff5be5169b8e45bb7c471f884b0590a2b
282 # via -r contrib/packaging/requirements-windows.txt.in
290 # via -r contrib/packaging/requirements-windows.txt.in
283 wrapt==1.12.1 \
291 wrapt==1.12.1 \
284 --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7
292 --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7
285 # via vcrpy
293 # via vcrpy
286 yarl==1.6.3 \
294 yarl==1.6.3 \
287 --hash=sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e \
295 --hash=sha256:00d7ad91b6583602eb9c1d085a2cf281ada267e9a197e8b7cae487dadbfa293e \
288 --hash=sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434 \
296 --hash=sha256:0355a701b3998dcd832d0dc47cc5dedf3874f966ac7f870e0f3a6788d802d434 \
289 --hash=sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366 \
297 --hash=sha256:15263c3b0b47968c1d90daa89f21fcc889bb4b1aac5555580d74565de6836366 \
290 --hash=sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3 \
298 --hash=sha256:2ce4c621d21326a4a5500c25031e102af589edb50c09b321049e388b3934eec3 \
291 --hash=sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec \
299 --hash=sha256:31ede6e8c4329fb81c86706ba8f6bf661a924b53ba191b27aa5fcee5714d18ec \
292 --hash=sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959 \
300 --hash=sha256:324ba3d3c6fee56e2e0b0d09bf5c73824b9f08234339d2b788af65e60040c959 \
293 --hash=sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e \
301 --hash=sha256:329412812ecfc94a57cd37c9d547579510a9e83c516bc069470db5f75684629e \
294 --hash=sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c \
302 --hash=sha256:4736eaee5626db8d9cda9eb5282028cc834e2aeb194e0d8b50217d707e98bb5c \
295 --hash=sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6 \
303 --hash=sha256:4953fb0b4fdb7e08b2f3b3be80a00d28c5c8a2056bb066169de00e6501b986b6 \
296 --hash=sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a \
304 --hash=sha256:4c5bcfc3ed226bf6419f7a33982fb4b8ec2e45785a0561eb99274ebbf09fdd6a \
297 --hash=sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6 \
305 --hash=sha256:547f7665ad50fa8563150ed079f8e805e63dd85def6674c97efd78eed6c224a6 \
298 --hash=sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424 \
306 --hash=sha256:5b883e458058f8d6099e4420f0cc2567989032b5f34b271c0827de9f1079a424 \
299 --hash=sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e \
307 --hash=sha256:63f90b20ca654b3ecc7a8d62c03ffa46999595f0167d6450fa8383bab252987e \
300 --hash=sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f \
308 --hash=sha256:68dc568889b1c13f1e4745c96b931cc94fdd0defe92a72c2b8ce01091b22e35f \
301 --hash=sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50 \
309 --hash=sha256:69ee97c71fee1f63d04c945f56d5d726483c4762845400a6795a3b75d56b6c50 \
302 --hash=sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2 \
310 --hash=sha256:6d6283d8e0631b617edf0fd726353cb76630b83a089a40933043894e7f6721e2 \
303 --hash=sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc \
311 --hash=sha256:72a660bdd24497e3e84f5519e57a9ee9220b6f3ac4d45056961bf22838ce20cc \
304 --hash=sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4 \
312 --hash=sha256:73494d5b71099ae8cb8754f1df131c11d433b387efab7b51849e7e1e851f07a4 \
305 --hash=sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970 \
313 --hash=sha256:7356644cbed76119d0b6bd32ffba704d30d747e0c217109d7979a7bc36c4d970 \
306 --hash=sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10 \
314 --hash=sha256:8a9066529240171b68893d60dca86a763eae2139dd42f42106b03cf4b426bf10 \
307 --hash=sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0 \
315 --hash=sha256:8aa3decd5e0e852dc68335abf5478a518b41bf2ab2f330fe44916399efedfae0 \
308 --hash=sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406 \
316 --hash=sha256:97b5bdc450d63c3ba30a127d018b866ea94e65655efaf889ebeabc20f7d12406 \
309 --hash=sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896 \
317 --hash=sha256:9ede61b0854e267fd565e7527e2f2eb3ef8858b301319be0604177690e1a3896 \
310 --hash=sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643 \
318 --hash=sha256:b2e9a456c121e26d13c29251f8267541bd75e6a1ccf9e859179701c36a078643 \
311 --hash=sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721 \
319 --hash=sha256:b5dfc9a40c198334f4f3f55880ecf910adebdcb2a0b9a9c23c9345faa9185721 \
312 --hash=sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478 \
320 --hash=sha256:bafb450deef6861815ed579c7a6113a879a6ef58aed4c3a4be54400ae8871478 \
313 --hash=sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724 \
321 --hash=sha256:c49ff66d479d38ab863c50f7bb27dee97c6627c5fe60697de15529da9c3de724 \
314 --hash=sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e \
322 --hash=sha256:ce3beb46a72d9f2190f9e1027886bfc513702d748047b548b05dab7dfb584d2e \
315 --hash=sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8 \
323 --hash=sha256:d26608cf178efb8faa5ff0f2d2e77c208f471c5a3709e577a7b3fd0445703ac8 \
316 --hash=sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96 \
324 --hash=sha256:d597767fcd2c3dc49d6eea360c458b65643d1e4dbed91361cf5e36e53c1f8c96 \
317 --hash=sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25 \
325 --hash=sha256:d5c32c82990e4ac4d8150fd7652b972216b204de4e83a122546dce571c1bdf25 \
318 --hash=sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76 \
326 --hash=sha256:d8d07d102f17b68966e2de0e07bfd6e139c7c02ef06d3a0f8d2f0f055e13bb76 \
319 --hash=sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2 \
327 --hash=sha256:e46fba844f4895b36f4c398c5af062a9808d1f26b2999c58909517384d5deda2 \
320 --hash=sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2 \
328 --hash=sha256:e6b5460dc5ad42ad2b36cca524491dfcaffbfd9c8df50508bddc354e787b8dc2 \
321 --hash=sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c \
329 --hash=sha256:f040bcc6725c821a4c0665f3aa96a4d0805a7aaf2caf266d256b8ed71b9f041c \
322 --hash=sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a \
330 --hash=sha256:f0b059678fd549c66b89bed03efcabb009075bd131c248ecdf087bdb6faba24a \
323 --hash=sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71
331 --hash=sha256:fcbb48a93e8699eae920f8d92f7160c03567b421bc17362a9ffbbd706a816f71
324 # via vcrpy
332 # via vcrpy
325 zipp==3.4.0 \
333 zipp==3.4.0 \
326 --hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
334 --hash=sha256:102c24ef8f171fd729d46599845e95c7ab894a4cf45f5de11a44cc7444fb1108 \
327 --hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb
335 --hash=sha256:ed5eee1974372595f9e416cc7bbeeb12335201d8081ca8a0743c954d4446e5cb
328 # via importlib-metadata
336 # via importlib-metadata
@@ -1,1000 +1,1016 b''
1 # __init__.py - fsmonitor initialization and overrides
1 # __init__.py - fsmonitor initialization and overrides
2 #
2 #
3 # Copyright 2013-2016 Facebook, Inc.
3 # Copyright 2013-2016 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 '''Faster status operations with the Watchman file monitor (EXPERIMENTAL)
8 '''Faster status operations with the Watchman file monitor (EXPERIMENTAL)
9
9
10 Integrates the file-watching program Watchman with Mercurial to produce faster
10 Integrates the file-watching program Watchman with Mercurial to produce faster
11 status results.
11 status results.
12
12
13 On a particular Linux system, for a real-world repository with over 400,000
13 On a particular Linux system, for a real-world repository with over 400,000
14 files hosted on ext4, vanilla `hg status` takes 1.3 seconds. On the same
14 files hosted on ext4, vanilla `hg status` takes 1.3 seconds. On the same
15 system, with fsmonitor it takes about 0.3 seconds.
15 system, with fsmonitor it takes about 0.3 seconds.
16
16
17 fsmonitor requires no configuration -- it will tell Watchman about your
17 fsmonitor requires no configuration -- it will tell Watchman about your
18 repository as necessary. You'll need to install Watchman from
18 repository as necessary. You'll need to install Watchman from
19 https://facebook.github.io/watchman/ and make sure it is in your PATH.
19 https://facebook.github.io/watchman/ and make sure it is in your PATH.
20
20
21 fsmonitor is incompatible with the largefiles and eol extensions, and
21 fsmonitor is incompatible with the largefiles and eol extensions, and
22 will disable itself if any of those are active.
22 will disable itself if any of those are active.
23
23
24 The following configuration options exist:
24 The following configuration options exist:
25
25
26 ::
26 ::
27
27
28 [fsmonitor]
28 [fsmonitor]
29 mode = {off, on, paranoid}
29 mode = {off, on, paranoid}
30
30
31 When `mode = off`, fsmonitor will disable itself (similar to not loading the
31 When `mode = off`, fsmonitor will disable itself (similar to not loading the
32 extension at all). When `mode = on`, fsmonitor will be enabled (the default).
32 extension at all). When `mode = on`, fsmonitor will be enabled (the default).
33 When `mode = paranoid`, fsmonitor will query both Watchman and the filesystem,
33 When `mode = paranoid`, fsmonitor will query both Watchman and the filesystem,
34 and ensure that the results are consistent.
34 and ensure that the results are consistent.
35
35
36 ::
36 ::
37
37
38 [fsmonitor]
38 [fsmonitor]
39 timeout = (float)
39 timeout = (float)
40
40
41 A value, in seconds, that determines how long fsmonitor will wait for Watchman
41 A value, in seconds, that determines how long fsmonitor will wait for Watchman
42 to return results. Defaults to `2.0`.
42 to return results. Defaults to `2.0`.
43
43
44 ::
44 ::
45
45
46 [fsmonitor]
46 [fsmonitor]
47 blacklistusers = (list of userids)
47 blacklistusers = (list of userids)
48
48
49 A list of usernames for which fsmonitor will disable itself altogether.
49 A list of usernames for which fsmonitor will disable itself altogether.
50
50
51 ::
51 ::
52
52
53 [fsmonitor]
53 [fsmonitor]
54 walk_on_invalidate = (boolean)
54 walk_on_invalidate = (boolean)
55
55
56 Whether or not to walk the whole repo ourselves when our cached state has been
56 Whether or not to walk the whole repo ourselves when our cached state has been
57 invalidated, for example when Watchman has been restarted or .hgignore rules
57 invalidated, for example when Watchman has been restarted or .hgignore rules
58 have been changed. Walking the repo in that case can result in competing for
58 have been changed. Walking the repo in that case can result in competing for
59 I/O with Watchman. For large repos it is recommended to set this value to
59 I/O with Watchman. For large repos it is recommended to set this value to
60 false. You may wish to set this to true if you have a very fast filesystem
60 false. You may wish to set this to true if you have a very fast filesystem
61 that can outpace the IPC overhead of getting the result data for the full repo
61 that can outpace the IPC overhead of getting the result data for the full repo
62 from Watchman. Defaults to false.
62 from Watchman. Defaults to false.
63
63
64 ::
64 ::
65
65
66 [fsmonitor]
66 [fsmonitor]
67 warn_when_unused = (boolean)
67 warn_when_unused = (boolean)
68
68
69 Whether to print a warning during certain operations when fsmonitor would be
69 Whether to print a warning during certain operations when fsmonitor would be
70 beneficial to performance but isn't enabled.
70 beneficial to performance but isn't enabled.
71
71
72 ::
72 ::
73
73
74 [fsmonitor]
74 [fsmonitor]
75 warn_update_file_count = (integer)
75 warn_update_file_count = (integer)
76 # or when mercurial is built with rust support
76 # or when mercurial is built with rust support
77 warn_update_file_count_rust = (integer)
77 warn_update_file_count_rust = (integer)
78
78
79 If ``warn_when_unused`` is set and fsmonitor isn't enabled, a warning will
79 If ``warn_when_unused`` is set and fsmonitor isn't enabled, a warning will
80 be printed during working directory updates if this many files will be
80 be printed during working directory updates if this many files will be
81 created.
81 created.
82 '''
82 '''
83
83
84 # Platforms Supported
84 # Platforms Supported
85 # ===================
85 # ===================
86 #
86 #
87 # **Linux:** *Stable*. Watchman and fsmonitor are both known to work reliably,
87 # **Linux:** *Stable*. Watchman and fsmonitor are both known to work reliably,
88 # even under severe loads.
88 # even under severe loads.
89 #
89 #
90 # **Mac OS X:** *Stable*. The Mercurial test suite passes with fsmonitor
90 # **Mac OS X:** *Stable*. The Mercurial test suite passes with fsmonitor
91 # turned on, on case-insensitive HFS+. There has been a reasonable amount of
91 # turned on, on case-insensitive HFS+. There has been a reasonable amount of
92 # user testing under normal loads.
92 # user testing under normal loads.
93 #
93 #
94 # **Solaris, BSD:** *Alpha*. watchman and fsmonitor are believed to work, but
94 # **Solaris, BSD:** *Alpha*. watchman and fsmonitor are believed to work, but
95 # very little testing has been done.
95 # very little testing has been done.
96 #
96 #
97 # **Windows:** *Alpha*. Not in a release version of watchman or fsmonitor yet.
97 # **Windows:** *Alpha*. Not in a release version of watchman or fsmonitor yet.
98 #
98 #
99 # Known Issues
99 # Known Issues
100 # ============
100 # ============
101 #
101 #
102 # * fsmonitor will disable itself if any of the following extensions are
102 # * fsmonitor will disable itself if any of the following extensions are
103 # enabled: largefiles, inotify, eol; or if the repository has subrepos.
103 # enabled: largefiles, inotify, eol; or if the repository has subrepos.
104 # * fsmonitor will produce incorrect results if nested repos that are not
104 # * fsmonitor will produce incorrect results if nested repos that are not
105 # subrepos exist. *Workaround*: add nested repo paths to your `.hgignore`.
105 # subrepos exist. *Workaround*: add nested repo paths to your `.hgignore`.
106 #
106 #
107 # The issues related to nested repos and subrepos are probably not fundamental
107 # The issues related to nested repos and subrepos are probably not fundamental
108 # ones. Patches to fix them are welcome.
108 # ones. Patches to fix them are welcome.
109
109
110
110
111 import codecs
111 import codecs
112 import os
112 import os
113 import stat
113 import stat
114 import sys
114 import sys
115 import tempfile
115 import tempfile
116 import weakref
116 import weakref
117
117
118 from mercurial.i18n import _
118 from mercurial.i18n import _
119 from mercurial.node import hex
119 from mercurial.node import hex
120
120 from mercurial.pycompat import open
121 from mercurial.pycompat import open
121 from mercurial import (
122 from mercurial import (
122 context,
123 context,
123 encoding,
124 encoding,
124 error,
125 error,
125 extensions,
126 extensions,
126 localrepo,
127 localrepo,
127 merge,
128 merge,
128 pathutil,
129 pathutil,
129 pycompat,
130 pycompat,
130 registrar,
131 registrar,
131 scmutil,
132 scmutil,
132 util,
133 util,
133 )
134 )
135
136 # no-check-code because we're accessing private information only public in pure
137 from mercurial.pure import parsers
134 from mercurial import match as matchmod
138 from mercurial import match as matchmod
135 from mercurial.utils import (
139 from mercurial.utils import (
136 hashutil,
140 hashutil,
137 stringutil,
141 stringutil,
138 )
142 )
139
143
140 from . import (
144 from . import (
141 pywatchman,
145 pywatchman,
142 state,
146 state,
143 watchmanclient,
147 watchmanclient,
144 )
148 )
145
149
146 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
150 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
147 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
151 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
148 # be specifying the version(s) of Mercurial they are tested with, or
152 # be specifying the version(s) of Mercurial they are tested with, or
149 # leave the attribute unspecified.
153 # leave the attribute unspecified.
150 testedwith = b'ships-with-hg-core'
154 testedwith = b'ships-with-hg-core'
151
155
152 configtable = {}
156 configtable = {}
153 configitem = registrar.configitem(configtable)
157 configitem = registrar.configitem(configtable)
154
158
155 configitem(
159 configitem(
156 b'fsmonitor',
160 b'fsmonitor',
157 b'mode',
161 b'mode',
158 default=b'on',
162 default=b'on',
159 )
163 )
160 configitem(
164 configitem(
161 b'fsmonitor',
165 b'fsmonitor',
162 b'walk_on_invalidate',
166 b'walk_on_invalidate',
163 default=False,
167 default=False,
164 )
168 )
165 configitem(
169 configitem(
166 b'fsmonitor',
170 b'fsmonitor',
167 b'timeout',
171 b'timeout',
168 default=b'2',
172 default=b'2',
169 )
173 )
170 configitem(
174 configitem(
171 b'fsmonitor',
175 b'fsmonitor',
172 b'blacklistusers',
176 b'blacklistusers',
173 default=list,
177 default=list,
174 )
178 )
175 configitem(
179 configitem(
176 b'fsmonitor',
180 b'fsmonitor',
177 b'watchman_exe',
181 b'watchman_exe',
178 default=b'watchman',
182 default=b'watchman',
179 )
183 )
180 configitem(
184 configitem(
181 b'fsmonitor',
185 b'fsmonitor',
182 b'verbose',
186 b'verbose',
183 default=True,
187 default=True,
184 experimental=True,
188 experimental=True,
185 )
189 )
186 configitem(
190 configitem(
187 b'experimental',
191 b'experimental',
188 b'fsmonitor.transaction_notify',
192 b'fsmonitor.transaction_notify',
189 default=False,
193 default=False,
190 )
194 )
191
195
192 # This extension is incompatible with the following blacklisted extensions
196 # This extension is incompatible with the following blacklisted extensions
193 # and will disable itself when encountering one of these:
197 # and will disable itself when encountering one of these:
194 _blacklist = [b'largefiles', b'eol']
198 _blacklist = [b'largefiles', b'eol']
195
199
196
200
197 def debuginstall(ui, fm):
201 def debuginstall(ui, fm):
198 fm.write(
202 fm.write(
199 b"fsmonitor-watchman",
203 b"fsmonitor-watchman",
200 _(b"fsmonitor checking for watchman binary... (%s)\n"),
204 _(b"fsmonitor checking for watchman binary... (%s)\n"),
201 ui.configpath(b"fsmonitor", b"watchman_exe"),
205 ui.configpath(b"fsmonitor", b"watchman_exe"),
202 )
206 )
203 root = tempfile.mkdtemp()
207 root = tempfile.mkdtemp()
204 c = watchmanclient.client(ui, root)
208 c = watchmanclient.client(ui, root)
205 err = None
209 err = None
206 try:
210 try:
207 v = c.command(b"version")
211 v = c.command(b"version")
208 fm.write(
212 fm.write(
209 b"fsmonitor-watchman-version",
213 b"fsmonitor-watchman-version",
210 _(b" watchman binary version %s\n"),
214 _(b" watchman binary version %s\n"),
211 pycompat.bytestr(v["version"]),
215 pycompat.bytestr(v["version"]),
212 )
216 )
213 except watchmanclient.Unavailable as e:
217 except watchmanclient.Unavailable as e:
214 err = stringutil.forcebytestr(e)
218 err = stringutil.forcebytestr(e)
215 fm.condwrite(
219 fm.condwrite(
216 err,
220 err,
217 b"fsmonitor-watchman-error",
221 b"fsmonitor-watchman-error",
218 _(b" watchman binary missing or broken: %s\n"),
222 _(b" watchman binary missing or broken: %s\n"),
219 err,
223 err,
220 )
224 )
221 return 1 if err else 0
225 return 1 if err else 0
222
226
223
227
224 def _handleunavailable(ui, state, ex):
228 def _handleunavailable(ui, state, ex):
225 """Exception handler for Watchman interaction exceptions"""
229 """Exception handler for Watchman interaction exceptions"""
226 if isinstance(ex, watchmanclient.Unavailable):
230 if isinstance(ex, watchmanclient.Unavailable):
227 # experimental config: fsmonitor.verbose
231 # experimental config: fsmonitor.verbose
228 if ex.warn and ui.configbool(b'fsmonitor', b'verbose'):
232 if ex.warn and ui.configbool(b'fsmonitor', b'verbose'):
229 if b'illegal_fstypes' not in stringutil.forcebytestr(ex):
233 if b'illegal_fstypes' not in stringutil.forcebytestr(ex):
230 ui.warn(stringutil.forcebytestr(ex) + b'\n')
234 ui.warn(stringutil.forcebytestr(ex) + b'\n')
231 if ex.invalidate:
235 if ex.invalidate:
232 state.invalidate()
236 state.invalidate()
233 # experimental config: fsmonitor.verbose
237 # experimental config: fsmonitor.verbose
234 if ui.configbool(b'fsmonitor', b'verbose'):
238 if ui.configbool(b'fsmonitor', b'verbose'):
235 ui.log(
239 ui.log(
236 b'fsmonitor',
240 b'fsmonitor',
237 b'Watchman unavailable: %s\n',
241 b'Watchman unavailable: %s\n',
238 stringutil.forcebytestr(ex.msg),
242 stringutil.forcebytestr(ex.msg),
239 )
243 )
240 else:
244 else:
241 ui.log(
245 ui.log(
242 b'fsmonitor',
246 b'fsmonitor',
243 b'Watchman exception: %s\n',
247 b'Watchman exception: %s\n',
244 stringutil.forcebytestr(ex),
248 stringutil.forcebytestr(ex),
245 )
249 )
246
250
247
251
248 def _hashignore(ignore):
252 def _hashignore(ignore):
249 """Calculate hash for ignore patterns and filenames
253 """Calculate hash for ignore patterns and filenames
250
254
251 If this information changes between Mercurial invocations, we can't
255 If this information changes between Mercurial invocations, we can't
252 rely on Watchman information anymore and have to re-scan the working
256 rely on Watchman information anymore and have to re-scan the working
253 copy.
257 copy.
254
258
255 """
259 """
256 sha1 = hashutil.sha1()
260 sha1 = hashutil.sha1()
257 sha1.update(pycompat.byterepr(ignore))
261 sha1.update(pycompat.byterepr(ignore))
258 return pycompat.sysbytes(sha1.hexdigest())
262 return pycompat.sysbytes(sha1.hexdigest())
259
263
260
264
261 _watchmanencoding = pywatchman.encoding.get_local_encoding()
265 _watchmanencoding = pywatchman.encoding.get_local_encoding()
262 _fsencoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
266 _fsencoding = sys.getfilesystemencoding() or sys.getdefaultencoding()
263 _fixencoding = codecs.lookup(_watchmanencoding) != codecs.lookup(_fsencoding)
267 _fixencoding = codecs.lookup(_watchmanencoding) != codecs.lookup(_fsencoding)
264
268
265
269
266 def _watchmantofsencoding(path):
270 def _watchmantofsencoding(path):
267 """Fix path to match watchman and local filesystem encoding
271 """Fix path to match watchman and local filesystem encoding
268
272
269 watchman's paths encoding can differ from filesystem encoding. For example,
273 watchman's paths encoding can differ from filesystem encoding. For example,
270 on Windows, it's always utf-8.
274 on Windows, it's always utf-8.
271 """
275 """
272 try:
276 try:
273 decoded = path.decode(_watchmanencoding)
277 decoded = path.decode(_watchmanencoding)
274 except UnicodeDecodeError as e:
278 except UnicodeDecodeError as e:
275 raise error.Abort(
279 raise error.Abort(
276 stringutil.forcebytestr(e), hint=b'watchman encoding error'
280 stringutil.forcebytestr(e), hint=b'watchman encoding error'
277 )
281 )
278
282
279 try:
283 try:
280 encoded = decoded.encode(_fsencoding, 'strict')
284 encoded = decoded.encode(_fsencoding, 'strict')
281 except UnicodeEncodeError as e:
285 except UnicodeEncodeError as e:
282 raise error.Abort(stringutil.forcebytestr(e))
286 raise error.Abort(stringutil.forcebytestr(e))
283
287
284 return encoded
288 return encoded
285
289
286
290
287 def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True):
291 def overridewalk(orig, self, match, subrepos, unknown, ignored, full=True):
288 """Replacement for dirstate.walk, hooking into Watchman.
292 """Replacement for dirstate.walk, hooking into Watchman.
289
293
290 Whenever full is False, ignored is False, and the Watchman client is
294 Whenever full is False, ignored is False, and the Watchman client is
291 available, use Watchman combined with saved state to possibly return only a
295 available, use Watchman combined with saved state to possibly return only a
292 subset of files."""
296 subset of files."""
293
297
294 def bail(reason):
298 def bail(reason):
295 self._ui.debug(b'fsmonitor: fallback to core status, %s\n' % reason)
299 self._ui.debug(b'fsmonitor: fallback to core status, %s\n' % reason)
296 return orig(match, subrepos, unknown, ignored, full=True)
300 return orig(match, subrepos, unknown, ignored, full=True)
297
301
298 if full:
302 if full:
299 return bail(b'full rewalk requested')
303 return bail(b'full rewalk requested')
300 if ignored:
304 if ignored:
301 return bail(b'listing ignored files')
305 return bail(b'listing ignored files')
302 if not self._watchmanclient.available():
306 if not self._watchmanclient.available():
303 return bail(b'client unavailable')
307 return bail(b'client unavailable')
304 state = self._fsmonitorstate
308 state = self._fsmonitorstate
305 clock, ignorehash, notefiles = state.get()
309 clock, ignorehash, notefiles = state.get()
306 if not clock:
310 if not clock:
307 if state.walk_on_invalidate:
311 if state.walk_on_invalidate:
308 return bail(b'no clock')
312 return bail(b'no clock')
309 # Initial NULL clock value, see
313 # Initial NULL clock value, see
310 # https://facebook.github.io/watchman/docs/clockspec.html
314 # https://facebook.github.io/watchman/docs/clockspec.html
311 clock = b'c:0:0'
315 clock = b'c:0:0'
312 notefiles = []
316 notefiles = []
313
317
314 ignore = self._ignore
318 ignore = self._ignore
315 dirignore = self._dirignore
319 dirignore = self._dirignore
316 if unknown:
320 if unknown:
317 if _hashignore(ignore) != ignorehash and clock != b'c:0:0':
321 if _hashignore(ignore) != ignorehash and clock != b'c:0:0':
318 # ignore list changed -- can't rely on Watchman state any more
322 # ignore list changed -- can't rely on Watchman state any more
319 if state.walk_on_invalidate:
323 if state.walk_on_invalidate:
320 return bail(b'ignore rules changed')
324 return bail(b'ignore rules changed')
321 notefiles = []
325 notefiles = []
322 clock = b'c:0:0'
326 clock = b'c:0:0'
323 else:
327 else:
324 # always ignore
328 # always ignore
325 ignore = util.always
329 ignore = util.always
326 dirignore = util.always
330 dirignore = util.always
327
331
328 matchfn = match.matchfn
332 matchfn = match.matchfn
329 matchalways = match.always()
333 matchalways = match.always()
330 dmap = self._map
334 dmap = self._map
331 if util.safehasattr(dmap, b'_map'):
335 if util.safehasattr(dmap, b'_map'):
332 # for better performance, directly access the inner dirstate map if the
336 # for better performance, directly access the inner dirstate map if the
333 # standard dirstate implementation is in use.
337 # standard dirstate implementation is in use.
334 dmap = dmap._map
338 dmap = dmap._map
339
340 has_mtime = parsers.DIRSTATE_V2_HAS_MTIME
341 mtime_is_ambiguous = parsers.DIRSTATE_V2_MTIME_SECOND_AMBIGUOUS
342 mask = has_mtime | mtime_is_ambiguous
343
344 # All entries that may not be clean
335 nonnormalset = {
345 nonnormalset = {
336 f
346 f
337 for f, e in self._map.items()
347 for f, e in self._map.items()
338 if e._v1_state() != b"n" or e._v1_mtime() == -1
348 if not e.maybe_clean
349 # same as "not has_time or has_ambiguous_time", but factored to only
350 # need a single access to flags for performance.
351 # `mask` removes all irrelevant bits, then we flip the `mtime` bit so
352 # its `true` value is NOT having a mtime, then check if either bit
353 # is set.
354 or bool((e.v2_data()[0] & mask) ^ has_mtime)
339 }
355 }
340
356
341 copymap = self._map.copymap
357 copymap = self._map.copymap
342 getkind = stat.S_IFMT
358 getkind = stat.S_IFMT
343 dirkind = stat.S_IFDIR
359 dirkind = stat.S_IFDIR
344 regkind = stat.S_IFREG
360 regkind = stat.S_IFREG
345 lnkkind = stat.S_IFLNK
361 lnkkind = stat.S_IFLNK
346 join = self._join
362 join = self._join
347 normcase = util.normcase
363 normcase = util.normcase
348 fresh_instance = False
364 fresh_instance = False
349
365
350 exact = skipstep3 = False
366 exact = skipstep3 = False
351 if match.isexact(): # match.exact
367 if match.isexact(): # match.exact
352 exact = True
368 exact = True
353 dirignore = util.always # skip step 2
369 dirignore = util.always # skip step 2
354 elif match.prefix(): # match.match, no patterns
370 elif match.prefix(): # match.match, no patterns
355 skipstep3 = True
371 skipstep3 = True
356
372
357 if not exact and self._checkcase:
373 if not exact and self._checkcase:
358 # note that even though we could receive directory entries, we're only
374 # note that even though we could receive directory entries, we're only
359 # interested in checking if a file with the same name exists. So only
375 # interested in checking if a file with the same name exists. So only
360 # normalize files if possible.
376 # normalize files if possible.
361 normalize = self._normalizefile
377 normalize = self._normalizefile
362 skipstep3 = False
378 skipstep3 = False
363 else:
379 else:
364 normalize = None
380 normalize = None
365
381
366 # step 1: find all explicit files
382 # step 1: find all explicit files
367 results, work, dirsnotfound = self._walkexplicit(match, subrepos)
383 results, work, dirsnotfound = self._walkexplicit(match, subrepos)
368
384
369 skipstep3 = skipstep3 and not (work or dirsnotfound)
385 skipstep3 = skipstep3 and not (work or dirsnotfound)
370 work = [d for d in work if not dirignore(d[0])]
386 work = [d for d in work if not dirignore(d[0])]
371
387
372 if not work and (exact or skipstep3):
388 if not work and (exact or skipstep3):
373 for s in subrepos:
389 for s in subrepos:
374 del results[s]
390 del results[s]
375 del results[b'.hg']
391 del results[b'.hg']
376 return results
392 return results
377
393
378 # step 2: query Watchman
394 # step 2: query Watchman
379 try:
395 try:
380 # Use the user-configured timeout for the query.
396 # Use the user-configured timeout for the query.
381 # Add a little slack over the top of the user query to allow for
397 # Add a little slack over the top of the user query to allow for
382 # overheads while transferring the data
398 # overheads while transferring the data
383 self._watchmanclient.settimeout(state.timeout + 0.1)
399 self._watchmanclient.settimeout(state.timeout + 0.1)
384 result = self._watchmanclient.command(
400 result = self._watchmanclient.command(
385 b'query',
401 b'query',
386 {
402 {
387 b'fields': [b'mode', b'mtime', b'size', b'exists', b'name'],
403 b'fields': [b'mode', b'mtime', b'size', b'exists', b'name'],
388 b'since': clock,
404 b'since': clock,
389 b'expression': [
405 b'expression': [
390 b'not',
406 b'not',
391 [
407 [
392 b'anyof',
408 b'anyof',
393 [b'dirname', b'.hg'],
409 [b'dirname', b'.hg'],
394 [b'name', b'.hg', b'wholename'],
410 [b'name', b'.hg', b'wholename'],
395 ],
411 ],
396 ],
412 ],
397 b'sync_timeout': int(state.timeout * 1000),
413 b'sync_timeout': int(state.timeout * 1000),
398 b'empty_on_fresh_instance': state.walk_on_invalidate,
414 b'empty_on_fresh_instance': state.walk_on_invalidate,
399 },
415 },
400 )
416 )
401 except Exception as ex:
417 except Exception as ex:
402 _handleunavailable(self._ui, state, ex)
418 _handleunavailable(self._ui, state, ex)
403 self._watchmanclient.clearconnection()
419 self._watchmanclient.clearconnection()
404 return bail(b'exception during run')
420 return bail(b'exception during run')
405 else:
421 else:
406 # We need to propagate the last observed clock up so that we
422 # We need to propagate the last observed clock up so that we
407 # can use it for our next query
423 # can use it for our next query
408 state.setlastclock(pycompat.sysbytes(result[b'clock']))
424 state.setlastclock(pycompat.sysbytes(result[b'clock']))
409 if result[b'is_fresh_instance']:
425 if result[b'is_fresh_instance']:
410 if state.walk_on_invalidate:
426 if state.walk_on_invalidate:
411 state.invalidate()
427 state.invalidate()
412 return bail(b'fresh instance')
428 return bail(b'fresh instance')
413 fresh_instance = True
429 fresh_instance = True
414 # Ignore any prior noteable files from the state info
430 # Ignore any prior noteable files from the state info
415 notefiles = []
431 notefiles = []
416
432
417 # for file paths which require normalization and we encounter a case
433 # for file paths which require normalization and we encounter a case
418 # collision, we store our own foldmap
434 # collision, we store our own foldmap
419 if normalize:
435 if normalize:
420 foldmap = {normcase(k): k for k in results}
436 foldmap = {normcase(k): k for k in results}
421
437
422 switch_slashes = pycompat.ossep == b'\\'
438 switch_slashes = pycompat.ossep == b'\\'
423 # The order of the results is, strictly speaking, undefined.
439 # The order of the results is, strictly speaking, undefined.
424 # For case changes on a case insensitive filesystem we may receive
440 # For case changes on a case insensitive filesystem we may receive
425 # two entries, one with exists=True and another with exists=False.
441 # two entries, one with exists=True and another with exists=False.
426 # The exists=True entries in the same response should be interpreted
442 # The exists=True entries in the same response should be interpreted
427 # as being happens-after the exists=False entries due to the way that
443 # as being happens-after the exists=False entries due to the way that
428 # Watchman tracks files. We use this property to reconcile deletes
444 # Watchman tracks files. We use this property to reconcile deletes
429 # for name case changes.
445 # for name case changes.
430 for entry in result[b'files']:
446 for entry in result[b'files']:
431 fname = entry[b'name']
447 fname = entry[b'name']
432
448
433 # Watchman always give us a str. Normalize to bytes on Python 3
449 # Watchman always give us a str. Normalize to bytes on Python 3
434 # using Watchman's encoding, if needed.
450 # using Watchman's encoding, if needed.
435 if not isinstance(fname, bytes):
451 if not isinstance(fname, bytes):
436 fname = fname.encode(_watchmanencoding)
452 fname = fname.encode(_watchmanencoding)
437
453
438 if _fixencoding:
454 if _fixencoding:
439 fname = _watchmantofsencoding(fname)
455 fname = _watchmantofsencoding(fname)
440
456
441 if switch_slashes:
457 if switch_slashes:
442 fname = fname.replace(b'\\', b'/')
458 fname = fname.replace(b'\\', b'/')
443 if normalize:
459 if normalize:
444 normed = normcase(fname)
460 normed = normcase(fname)
445 fname = normalize(fname, True, True)
461 fname = normalize(fname, True, True)
446 foldmap[normed] = fname
462 foldmap[normed] = fname
447 fmode = entry[b'mode']
463 fmode = entry[b'mode']
448 fexists = entry[b'exists']
464 fexists = entry[b'exists']
449 kind = getkind(fmode)
465 kind = getkind(fmode)
450
466
451 if b'/.hg/' in fname or fname.endswith(b'/.hg'):
467 if b'/.hg/' in fname or fname.endswith(b'/.hg'):
452 return bail(b'nested-repo-detected')
468 return bail(b'nested-repo-detected')
453
469
454 if not fexists:
470 if not fexists:
455 # if marked as deleted and we don't already have a change
471 # if marked as deleted and we don't already have a change
456 # record, mark it as deleted. If we already have an entry
472 # record, mark it as deleted. If we already have an entry
457 # for fname then it was either part of walkexplicit or was
473 # for fname then it was either part of walkexplicit or was
458 # an earlier result that was a case change
474 # an earlier result that was a case change
459 if (
475 if (
460 fname not in results
476 fname not in results
461 and fname in dmap
477 and fname in dmap
462 and (matchalways or matchfn(fname))
478 and (matchalways or matchfn(fname))
463 ):
479 ):
464 results[fname] = None
480 results[fname] = None
465 elif kind == dirkind:
481 elif kind == dirkind:
466 if fname in dmap and (matchalways or matchfn(fname)):
482 if fname in dmap and (matchalways or matchfn(fname)):
467 results[fname] = None
483 results[fname] = None
468 elif kind == regkind or kind == lnkkind:
484 elif kind == regkind or kind == lnkkind:
469 if fname in dmap:
485 if fname in dmap:
470 if matchalways or matchfn(fname):
486 if matchalways or matchfn(fname):
471 results[fname] = entry
487 results[fname] = entry
472 elif (matchalways or matchfn(fname)) and not ignore(fname):
488 elif (matchalways or matchfn(fname)) and not ignore(fname):
473 results[fname] = entry
489 results[fname] = entry
474 elif fname in dmap and (matchalways or matchfn(fname)):
490 elif fname in dmap and (matchalways or matchfn(fname)):
475 results[fname] = None
491 results[fname] = None
476
492
477 # step 3: query notable files we don't already know about
493 # step 3: query notable files we don't already know about
478 # XXX try not to iterate over the entire dmap
494 # XXX try not to iterate over the entire dmap
479 if normalize:
495 if normalize:
480 # any notable files that have changed case will already be handled
496 # any notable files that have changed case will already be handled
481 # above, so just check membership in the foldmap
497 # above, so just check membership in the foldmap
482 notefiles = {
498 notefiles = {
483 normalize(f, True, True)
499 normalize(f, True, True)
484 for f in notefiles
500 for f in notefiles
485 if normcase(f) not in foldmap
501 if normcase(f) not in foldmap
486 }
502 }
487 visit = {
503 visit = {
488 f
504 f
489 for f in notefiles
505 for f in notefiles
490 if (f not in results and matchfn(f) and (f in dmap or not ignore(f)))
506 if (f not in results and matchfn(f) and (f in dmap or not ignore(f)))
491 }
507 }
492
508
493 if not fresh_instance:
509 if not fresh_instance:
494 if matchalways:
510 if matchalways:
495 visit.update(f for f in nonnormalset if f not in results)
511 visit.update(f for f in nonnormalset if f not in results)
496 visit.update(f for f in copymap if f not in results)
512 visit.update(f for f in copymap if f not in results)
497 else:
513 else:
498 visit.update(
514 visit.update(
499 f for f in nonnormalset if f not in results and matchfn(f)
515 f for f in nonnormalset if f not in results and matchfn(f)
500 )
516 )
501 visit.update(f for f in copymap if f not in results and matchfn(f))
517 visit.update(f for f in copymap if f not in results and matchfn(f))
502 else:
518 else:
503 if matchalways:
519 if matchalways:
504 visit.update(f for f, st in dmap.items() if f not in results)
520 visit.update(f for f, st in dmap.items() if f not in results)
505 visit.update(f for f in copymap if f not in results)
521 visit.update(f for f in copymap if f not in results)
506 else:
522 else:
507 visit.update(
523 visit.update(
508 f for f, st in dmap.items() if f not in results and matchfn(f)
524 f for f, st in dmap.items() if f not in results and matchfn(f)
509 )
525 )
510 visit.update(f for f in copymap if f not in results and matchfn(f))
526 visit.update(f for f in copymap if f not in results and matchfn(f))
511
527
512 audit = pathutil.pathauditor(self._root, cached=True).check
528 audit = pathutil.pathauditor(self._root, cached=True).check
513 auditpass = [f for f in visit if audit(f)]
529 auditpass = [f for f in visit if audit(f)]
514 auditpass.sort()
530 auditpass.sort()
515 auditfail = visit.difference(auditpass)
531 auditfail = visit.difference(auditpass)
516 for f in auditfail:
532 for f in auditfail:
517 results[f] = None
533 results[f] = None
518
534
519 nf = iter(auditpass)
535 nf = iter(auditpass)
520 for st in util.statfiles([join(f) for f in auditpass]):
536 for st in util.statfiles([join(f) for f in auditpass]):
521 f = next(nf)
537 f = next(nf)
522 if st or f in dmap:
538 if st or f in dmap:
523 results[f] = st
539 results[f] = st
524
540
525 for s in subrepos:
541 for s in subrepos:
526 del results[s]
542 del results[s]
527 del results[b'.hg']
543 del results[b'.hg']
528 return results
544 return results
529
545
530
546
531 def overridestatus(
547 def overridestatus(
532 orig,
548 orig,
533 self,
549 self,
534 node1=b'.',
550 node1=b'.',
535 node2=None,
551 node2=None,
536 match=None,
552 match=None,
537 ignored=False,
553 ignored=False,
538 clean=False,
554 clean=False,
539 unknown=False,
555 unknown=False,
540 listsubrepos=False,
556 listsubrepos=False,
541 ):
557 ):
542 listignored = ignored
558 listignored = ignored
543 listclean = clean
559 listclean = clean
544 listunknown = unknown
560 listunknown = unknown
545
561
546 def _cmpsets(l1, l2):
562 def _cmpsets(l1, l2):
547 try:
563 try:
548 if b'FSMONITOR_LOG_FILE' in encoding.environ:
564 if b'FSMONITOR_LOG_FILE' in encoding.environ:
549 fn = encoding.environ[b'FSMONITOR_LOG_FILE']
565 fn = encoding.environ[b'FSMONITOR_LOG_FILE']
550 f = open(fn, b'wb')
566 f = open(fn, b'wb')
551 else:
567 else:
552 fn = b'fsmonitorfail.log'
568 fn = b'fsmonitorfail.log'
553 f = self.vfs.open(fn, b'wb')
569 f = self.vfs.open(fn, b'wb')
554 except (IOError, OSError):
570 except (IOError, OSError):
555 self.ui.warn(_(b'warning: unable to write to %s\n') % fn)
571 self.ui.warn(_(b'warning: unable to write to %s\n') % fn)
556 return
572 return
557
573
558 try:
574 try:
559 for i, (s1, s2) in enumerate(zip(l1, l2)):
575 for i, (s1, s2) in enumerate(zip(l1, l2)):
560 if set(s1) != set(s2):
576 if set(s1) != set(s2):
561 f.write(b'sets at position %d are unequal\n' % i)
577 f.write(b'sets at position %d are unequal\n' % i)
562 f.write(b'watchman returned: %r\n' % s1)
578 f.write(b'watchman returned: %r\n' % s1)
563 f.write(b'stat returned: %r\n' % s2)
579 f.write(b'stat returned: %r\n' % s2)
564 finally:
580 finally:
565 f.close()
581 f.close()
566
582
567 if isinstance(node1, context.changectx):
583 if isinstance(node1, context.changectx):
568 ctx1 = node1
584 ctx1 = node1
569 else:
585 else:
570 ctx1 = self[node1]
586 ctx1 = self[node1]
571 if isinstance(node2, context.changectx):
587 if isinstance(node2, context.changectx):
572 ctx2 = node2
588 ctx2 = node2
573 else:
589 else:
574 ctx2 = self[node2]
590 ctx2 = self[node2]
575
591
576 working = ctx2.rev() is None
592 working = ctx2.rev() is None
577 parentworking = working and ctx1 == self[b'.']
593 parentworking = working and ctx1 == self[b'.']
578 match = match or matchmod.always()
594 match = match or matchmod.always()
579
595
580 # Maybe we can use this opportunity to update Watchman's state.
596 # Maybe we can use this opportunity to update Watchman's state.
581 # Mercurial uses workingcommitctx and/or memctx to represent the part of
597 # Mercurial uses workingcommitctx and/or memctx to represent the part of
582 # the workingctx that is to be committed. So don't update the state in
598 # the workingctx that is to be committed. So don't update the state in
583 # that case.
599 # that case.
584 # HG_PENDING is set in the environment when the dirstate is being updated
600 # HG_PENDING is set in the environment when the dirstate is being updated
585 # in the middle of a transaction; we must not update our state in that
601 # in the middle of a transaction; we must not update our state in that
586 # case, or we risk forgetting about changes in the working copy.
602 # case, or we risk forgetting about changes in the working copy.
587 updatestate = (
603 updatestate = (
588 parentworking
604 parentworking
589 and match.always()
605 and match.always()
590 and not isinstance(ctx2, (context.workingcommitctx, context.memctx))
606 and not isinstance(ctx2, (context.workingcommitctx, context.memctx))
591 and b'HG_PENDING' not in encoding.environ
607 and b'HG_PENDING' not in encoding.environ
592 )
608 )
593
609
594 try:
610 try:
595 if self._fsmonitorstate.walk_on_invalidate:
611 if self._fsmonitorstate.walk_on_invalidate:
596 # Use a short timeout to query the current clock. If that
612 # Use a short timeout to query the current clock. If that
597 # takes too long then we assume that the service will be slow
613 # takes too long then we assume that the service will be slow
598 # to answer our query.
614 # to answer our query.
599 # walk_on_invalidate indicates that we prefer to walk the
615 # walk_on_invalidate indicates that we prefer to walk the
600 # tree ourselves because we can ignore portions that Watchman
616 # tree ourselves because we can ignore portions that Watchman
601 # cannot and we tend to be faster in the warmer buffer cache
617 # cannot and we tend to be faster in the warmer buffer cache
602 # cases.
618 # cases.
603 self._watchmanclient.settimeout(0.1)
619 self._watchmanclient.settimeout(0.1)
604 else:
620 else:
605 # Give Watchman more time to potentially complete its walk
621 # Give Watchman more time to potentially complete its walk
606 # and return the initial clock. In this mode we assume that
622 # and return the initial clock. In this mode we assume that
607 # the filesystem will be slower than parsing a potentially
623 # the filesystem will be slower than parsing a potentially
608 # very large Watchman result set.
624 # very large Watchman result set.
609 self._watchmanclient.settimeout(self._fsmonitorstate.timeout + 0.1)
625 self._watchmanclient.settimeout(self._fsmonitorstate.timeout + 0.1)
610 startclock = self._watchmanclient.getcurrentclock()
626 startclock = self._watchmanclient.getcurrentclock()
611 except Exception as ex:
627 except Exception as ex:
612 self._watchmanclient.clearconnection()
628 self._watchmanclient.clearconnection()
613 _handleunavailable(self.ui, self._fsmonitorstate, ex)
629 _handleunavailable(self.ui, self._fsmonitorstate, ex)
614 # boo, Watchman failed. bail
630 # boo, Watchman failed. bail
615 return orig(
631 return orig(
616 node1,
632 node1,
617 node2,
633 node2,
618 match,
634 match,
619 listignored,
635 listignored,
620 listclean,
636 listclean,
621 listunknown,
637 listunknown,
622 listsubrepos,
638 listsubrepos,
623 )
639 )
624
640
625 if updatestate:
641 if updatestate:
626 # We need info about unknown files. This may make things slower the
642 # We need info about unknown files. This may make things slower the
627 # first time, but whatever.
643 # first time, but whatever.
628 stateunknown = True
644 stateunknown = True
629 else:
645 else:
630 stateunknown = listunknown
646 stateunknown = listunknown
631
647
632 if updatestate:
648 if updatestate:
633 ps = poststatus(startclock)
649 ps = poststatus(startclock)
634 self.addpostdsstatus(ps)
650 self.addpostdsstatus(ps)
635
651
636 r = orig(
652 r = orig(
637 node1, node2, match, listignored, listclean, stateunknown, listsubrepos
653 node1, node2, match, listignored, listclean, stateunknown, listsubrepos
638 )
654 )
639 modified, added, removed, deleted, unknown, ignored, clean = r
655 modified, added, removed, deleted, unknown, ignored, clean = r
640
656
641 if not listunknown:
657 if not listunknown:
642 unknown = []
658 unknown = []
643
659
644 # don't do paranoid checks if we're not going to query Watchman anyway
660 # don't do paranoid checks if we're not going to query Watchman anyway
645 full = listclean or match.traversedir is not None
661 full = listclean or match.traversedir is not None
646 if self._fsmonitorstate.mode == b'paranoid' and not full:
662 if self._fsmonitorstate.mode == b'paranoid' and not full:
647 # run status again and fall back to the old walk this time
663 # run status again and fall back to the old walk this time
648 self.dirstate._fsmonitordisable = True
664 self.dirstate._fsmonitordisable = True
649
665
650 # shut the UI up
666 # shut the UI up
651 quiet = self.ui.quiet
667 quiet = self.ui.quiet
652 self.ui.quiet = True
668 self.ui.quiet = True
653 fout, ferr = self.ui.fout, self.ui.ferr
669 fout, ferr = self.ui.fout, self.ui.ferr
654 self.ui.fout = self.ui.ferr = open(os.devnull, b'wb')
670 self.ui.fout = self.ui.ferr = open(os.devnull, b'wb')
655
671
656 try:
672 try:
657 rv2 = orig(
673 rv2 = orig(
658 node1,
674 node1,
659 node2,
675 node2,
660 match,
676 match,
661 listignored,
677 listignored,
662 listclean,
678 listclean,
663 listunknown,
679 listunknown,
664 listsubrepos,
680 listsubrepos,
665 )
681 )
666 finally:
682 finally:
667 self.dirstate._fsmonitordisable = False
683 self.dirstate._fsmonitordisable = False
668 self.ui.quiet = quiet
684 self.ui.quiet = quiet
669 self.ui.fout, self.ui.ferr = fout, ferr
685 self.ui.fout, self.ui.ferr = fout, ferr
670
686
671 # clean isn't tested since it's set to True above
687 # clean isn't tested since it's set to True above
672 with self.wlock():
688 with self.wlock():
673 _cmpsets(
689 _cmpsets(
674 [modified, added, removed, deleted, unknown, ignored, clean],
690 [modified, added, removed, deleted, unknown, ignored, clean],
675 rv2,
691 rv2,
676 )
692 )
677 modified, added, removed, deleted, unknown, ignored, clean = rv2
693 modified, added, removed, deleted, unknown, ignored, clean = rv2
678
694
679 return scmutil.status(
695 return scmutil.status(
680 modified, added, removed, deleted, unknown, ignored, clean
696 modified, added, removed, deleted, unknown, ignored, clean
681 )
697 )
682
698
683
699
684 class poststatus:
700 class poststatus:
685 def __init__(self, startclock):
701 def __init__(self, startclock):
686 self._startclock = pycompat.sysbytes(startclock)
702 self._startclock = pycompat.sysbytes(startclock)
687
703
688 def __call__(self, wctx, status):
704 def __call__(self, wctx, status):
689 clock = wctx.repo()._fsmonitorstate.getlastclock() or self._startclock
705 clock = wctx.repo()._fsmonitorstate.getlastclock() or self._startclock
690 hashignore = _hashignore(wctx.repo().dirstate._ignore)
706 hashignore = _hashignore(wctx.repo().dirstate._ignore)
691 notefiles = (
707 notefiles = (
692 status.modified
708 status.modified
693 + status.added
709 + status.added
694 + status.removed
710 + status.removed
695 + status.deleted
711 + status.deleted
696 + status.unknown
712 + status.unknown
697 )
713 )
698 wctx.repo()._fsmonitorstate.set(clock, hashignore, notefiles)
714 wctx.repo()._fsmonitorstate.set(clock, hashignore, notefiles)
699
715
700
716
701 def makedirstate(repo, dirstate):
717 def makedirstate(repo, dirstate):
702 class fsmonitordirstate(dirstate.__class__):
718 class fsmonitordirstate(dirstate.__class__):
703 def _fsmonitorinit(self, repo):
719 def _fsmonitorinit(self, repo):
704 # _fsmonitordisable is used in paranoid mode
720 # _fsmonitordisable is used in paranoid mode
705 self._fsmonitordisable = False
721 self._fsmonitordisable = False
706 self._fsmonitorstate = repo._fsmonitorstate
722 self._fsmonitorstate = repo._fsmonitorstate
707 self._watchmanclient = repo._watchmanclient
723 self._watchmanclient = repo._watchmanclient
708 self._repo = weakref.proxy(repo)
724 self._repo = weakref.proxy(repo)
709
725
710 def walk(self, *args, **kwargs):
726 def walk(self, *args, **kwargs):
711 orig = super(fsmonitordirstate, self).walk
727 orig = super(fsmonitordirstate, self).walk
712 if self._fsmonitordisable:
728 if self._fsmonitordisable:
713 return orig(*args, **kwargs)
729 return orig(*args, **kwargs)
714 return overridewalk(orig, self, *args, **kwargs)
730 return overridewalk(orig, self, *args, **kwargs)
715
731
716 def rebuild(self, *args, **kwargs):
732 def rebuild(self, *args, **kwargs):
717 self._fsmonitorstate.invalidate()
733 self._fsmonitorstate.invalidate()
718 return super(fsmonitordirstate, self).rebuild(*args, **kwargs)
734 return super(fsmonitordirstate, self).rebuild(*args, **kwargs)
719
735
720 def invalidate(self, *args, **kwargs):
736 def invalidate(self, *args, **kwargs):
721 self._fsmonitorstate.invalidate()
737 self._fsmonitorstate.invalidate()
722 return super(fsmonitordirstate, self).invalidate(*args, **kwargs)
738 return super(fsmonitordirstate, self).invalidate(*args, **kwargs)
723
739
724 dirstate.__class__ = fsmonitordirstate
740 dirstate.__class__ = fsmonitordirstate
725 dirstate._fsmonitorinit(repo)
741 dirstate._fsmonitorinit(repo)
726
742
727
743
728 def wrapdirstate(orig, self):
744 def wrapdirstate(orig, self):
729 ds = orig(self)
745 ds = orig(self)
730 # only override the dirstate when Watchman is available for the repo
746 # only override the dirstate when Watchman is available for the repo
731 if util.safehasattr(self, b'_fsmonitorstate'):
747 if util.safehasattr(self, b'_fsmonitorstate'):
732 makedirstate(self, ds)
748 makedirstate(self, ds)
733 return ds
749 return ds
734
750
735
751
736 def extsetup(ui):
752 def extsetup(ui):
737 extensions.wrapfilecache(
753 extensions.wrapfilecache(
738 localrepo.localrepository, b'dirstate', wrapdirstate
754 localrepo.localrepository, b'dirstate', wrapdirstate
739 )
755 )
740 if pycompat.isdarwin:
756 if pycompat.isdarwin:
741 # An assist for avoiding the dangling-symlink fsevents bug
757 # An assist for avoiding the dangling-symlink fsevents bug
742 extensions.wrapfunction(os, b'symlink', wrapsymlink)
758 extensions.wrapfunction(os, b'symlink', wrapsymlink)
743
759
744 extensions.wrapfunction(merge, b'_update', wrapupdate)
760 extensions.wrapfunction(merge, b'_update', wrapupdate)
745
761
746
762
747 def wrapsymlink(orig, source, link_name):
763 def wrapsymlink(orig, source, link_name):
748 """if we create a dangling symlink, also touch the parent dir
764 """if we create a dangling symlink, also touch the parent dir
749 to encourage fsevents notifications to work more correctly"""
765 to encourage fsevents notifications to work more correctly"""
750 try:
766 try:
751 return orig(source, link_name)
767 return orig(source, link_name)
752 finally:
768 finally:
753 try:
769 try:
754 os.utime(os.path.dirname(link_name), None)
770 os.utime(os.path.dirname(link_name), None)
755 except OSError:
771 except OSError:
756 pass
772 pass
757
773
758
774
759 class state_update:
775 class state_update:
760 """This context manager is responsible for dispatching the state-enter
776 """This context manager is responsible for dispatching the state-enter
761 and state-leave signals to the watchman service. The enter and leave
777 and state-leave signals to the watchman service. The enter and leave
762 methods can be invoked manually (for scenarios where context manager
778 methods can be invoked manually (for scenarios where context manager
763 semantics are not possible). If parameters oldnode and newnode are None,
779 semantics are not possible). If parameters oldnode and newnode are None,
764 they will be populated based on current working copy in enter and
780 they will be populated based on current working copy in enter and
765 leave, respectively. Similarly, if the distance is none, it will be
781 leave, respectively. Similarly, if the distance is none, it will be
766 calculated based on the oldnode and newnode in the leave method."""
782 calculated based on the oldnode and newnode in the leave method."""
767
783
768 def __init__(
784 def __init__(
769 self,
785 self,
770 repo,
786 repo,
771 name,
787 name,
772 oldnode=None,
788 oldnode=None,
773 newnode=None,
789 newnode=None,
774 distance=None,
790 distance=None,
775 partial=False,
791 partial=False,
776 ):
792 ):
777 self.repo = repo.unfiltered()
793 self.repo = repo.unfiltered()
778 self.name = name
794 self.name = name
779 self.oldnode = oldnode
795 self.oldnode = oldnode
780 self.newnode = newnode
796 self.newnode = newnode
781 self.distance = distance
797 self.distance = distance
782 self.partial = partial
798 self.partial = partial
783 self._lock = None
799 self._lock = None
784 self.need_leave = False
800 self.need_leave = False
785
801
786 def __enter__(self):
802 def __enter__(self):
787 self.enter()
803 self.enter()
788
804
789 def enter(self):
805 def enter(self):
790 # Make sure we have a wlock prior to sending notifications to watchman.
806 # Make sure we have a wlock prior to sending notifications to watchman.
791 # We don't want to race with other actors. In the update case,
807 # We don't want to race with other actors. In the update case,
792 # merge.update is going to take the wlock almost immediately. We are
808 # merge.update is going to take the wlock almost immediately. We are
793 # effectively extending the lock around several short sanity checks.
809 # effectively extending the lock around several short sanity checks.
794 if self.oldnode is None:
810 if self.oldnode is None:
795 self.oldnode = self.repo[b'.'].node()
811 self.oldnode = self.repo[b'.'].node()
796
812
797 if self.repo.currentwlock() is None:
813 if self.repo.currentwlock() is None:
798 if util.safehasattr(self.repo, b'wlocknostateupdate'):
814 if util.safehasattr(self.repo, b'wlocknostateupdate'):
799 self._lock = self.repo.wlocknostateupdate()
815 self._lock = self.repo.wlocknostateupdate()
800 else:
816 else:
801 self._lock = self.repo.wlock()
817 self._lock = self.repo.wlock()
802 self.need_leave = self._state(b'state-enter', hex(self.oldnode))
818 self.need_leave = self._state(b'state-enter', hex(self.oldnode))
803 return self
819 return self
804
820
805 def __exit__(self, type_, value, tb):
821 def __exit__(self, type_, value, tb):
806 abort = True if type_ else False
822 abort = True if type_ else False
807 self.exit(abort=abort)
823 self.exit(abort=abort)
808
824
809 def exit(self, abort=False):
825 def exit(self, abort=False):
810 try:
826 try:
811 if self.need_leave:
827 if self.need_leave:
812 status = b'failed' if abort else b'ok'
828 status = b'failed' if abort else b'ok'
813 if self.newnode is None:
829 if self.newnode is None:
814 self.newnode = self.repo[b'.'].node()
830 self.newnode = self.repo[b'.'].node()
815 if self.distance is None:
831 if self.distance is None:
816 self.distance = calcdistance(
832 self.distance = calcdistance(
817 self.repo, self.oldnode, self.newnode
833 self.repo, self.oldnode, self.newnode
818 )
834 )
819 self._state(b'state-leave', hex(self.newnode), status=status)
835 self._state(b'state-leave', hex(self.newnode), status=status)
820 finally:
836 finally:
821 self.need_leave = False
837 self.need_leave = False
822 if self._lock:
838 if self._lock:
823 self._lock.release()
839 self._lock.release()
824
840
825 def _state(self, cmd, commithash, status=b'ok'):
841 def _state(self, cmd, commithash, status=b'ok'):
826 if not util.safehasattr(self.repo, b'_watchmanclient'):
842 if not util.safehasattr(self.repo, b'_watchmanclient'):
827 return False
843 return False
828 try:
844 try:
829 self.repo._watchmanclient.command(
845 self.repo._watchmanclient.command(
830 cmd,
846 cmd,
831 {
847 {
832 b'name': self.name,
848 b'name': self.name,
833 b'metadata': {
849 b'metadata': {
834 # the target revision
850 # the target revision
835 b'rev': commithash,
851 b'rev': commithash,
836 # approximate number of commits between current and target
852 # approximate number of commits between current and target
837 b'distance': self.distance if self.distance else 0,
853 b'distance': self.distance if self.distance else 0,
838 # success/failure (only really meaningful for state-leave)
854 # success/failure (only really meaningful for state-leave)
839 b'status': status,
855 b'status': status,
840 # whether the working copy parent is changing
856 # whether the working copy parent is changing
841 b'partial': self.partial,
857 b'partial': self.partial,
842 },
858 },
843 },
859 },
844 )
860 )
845 return True
861 return True
846 except Exception as e:
862 except Exception as e:
847 # Swallow any errors; fire and forget
863 # Swallow any errors; fire and forget
848 self.repo.ui.log(
864 self.repo.ui.log(
849 b'watchman', b'Exception %s while running %s\n', e, cmd
865 b'watchman', b'Exception %s while running %s\n', e, cmd
850 )
866 )
851 return False
867 return False
852
868
853
869
854 # Estimate the distance between two nodes
870 # Estimate the distance between two nodes
855 def calcdistance(repo, oldnode, newnode):
871 def calcdistance(repo, oldnode, newnode):
856 anc = repo.changelog.ancestor(oldnode, newnode)
872 anc = repo.changelog.ancestor(oldnode, newnode)
857 ancrev = repo[anc].rev()
873 ancrev = repo[anc].rev()
858 distance = abs(repo[oldnode].rev() - ancrev) + abs(
874 distance = abs(repo[oldnode].rev() - ancrev) + abs(
859 repo[newnode].rev() - ancrev
875 repo[newnode].rev() - ancrev
860 )
876 )
861 return distance
877 return distance
862
878
863
879
864 # Bracket working copy updates with calls to the watchman state-enter
880 # Bracket working copy updates with calls to the watchman state-enter
865 # and state-leave commands. This allows clients to perform more intelligent
881 # and state-leave commands. This allows clients to perform more intelligent
866 # settling during bulk file change scenarios
882 # settling during bulk file change scenarios
867 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling
883 # https://facebook.github.io/watchman/docs/cmd/subscribe.html#advanced-settling
868 def wrapupdate(
884 def wrapupdate(
869 orig,
885 orig,
870 repo,
886 repo,
871 node,
887 node,
872 branchmerge,
888 branchmerge,
873 force,
889 force,
874 ancestor=None,
890 ancestor=None,
875 mergeancestor=False,
891 mergeancestor=False,
876 labels=None,
892 labels=None,
877 matcher=None,
893 matcher=None,
878 **kwargs
894 **kwargs
879 ):
895 ):
880
896
881 distance = 0
897 distance = 0
882 partial = True
898 partial = True
883 oldnode = repo[b'.'].node()
899 oldnode = repo[b'.'].node()
884 newnode = repo[node].node()
900 newnode = repo[node].node()
885 if matcher is None or matcher.always():
901 if matcher is None or matcher.always():
886 partial = False
902 partial = False
887 distance = calcdistance(repo.unfiltered(), oldnode, newnode)
903 distance = calcdistance(repo.unfiltered(), oldnode, newnode)
888
904
889 with state_update(
905 with state_update(
890 repo,
906 repo,
891 name=b"hg.update",
907 name=b"hg.update",
892 oldnode=oldnode,
908 oldnode=oldnode,
893 newnode=newnode,
909 newnode=newnode,
894 distance=distance,
910 distance=distance,
895 partial=partial,
911 partial=partial,
896 ):
912 ):
897 return orig(
913 return orig(
898 repo,
914 repo,
899 node,
915 node,
900 branchmerge,
916 branchmerge,
901 force,
917 force,
902 ancestor,
918 ancestor,
903 mergeancestor,
919 mergeancestor,
904 labels,
920 labels,
905 matcher,
921 matcher,
906 **kwargs
922 **kwargs
907 )
923 )
908
924
909
925
910 def repo_has_depth_one_nested_repo(repo):
926 def repo_has_depth_one_nested_repo(repo):
911 for f in repo.wvfs.listdir():
927 for f in repo.wvfs.listdir():
912 if os.path.isdir(os.path.join(repo.root, f, b'.hg')):
928 if os.path.isdir(os.path.join(repo.root, f, b'.hg')):
913 msg = b'fsmonitor: sub-repository %r detected, fsmonitor disabled\n'
929 msg = b'fsmonitor: sub-repository %r detected, fsmonitor disabled\n'
914 repo.ui.debug(msg % f)
930 repo.ui.debug(msg % f)
915 return True
931 return True
916 return False
932 return False
917
933
918
934
919 def reposetup(ui, repo):
935 def reposetup(ui, repo):
920 # We don't work with largefiles or inotify
936 # We don't work with largefiles or inotify
921 exts = extensions.enabled()
937 exts = extensions.enabled()
922 for ext in _blacklist:
938 for ext in _blacklist:
923 if ext in exts:
939 if ext in exts:
924 ui.warn(
940 ui.warn(
925 _(
941 _(
926 b'The fsmonitor extension is incompatible with the %s '
942 b'The fsmonitor extension is incompatible with the %s '
927 b'extension and has been disabled.\n'
943 b'extension and has been disabled.\n'
928 )
944 )
929 % ext
945 % ext
930 )
946 )
931 return
947 return
932
948
933 if repo.local():
949 if repo.local():
934 # We don't work with subrepos either.
950 # We don't work with subrepos either.
935 #
951 #
936 # if repo[None].substate can cause a dirstate parse, which is too
952 # if repo[None].substate can cause a dirstate parse, which is too
937 # slow. Instead, look for a file called hgsubstate,
953 # slow. Instead, look for a file called hgsubstate,
938 if repo.wvfs.exists(b'.hgsubstate') or repo.wvfs.exists(b'.hgsub'):
954 if repo.wvfs.exists(b'.hgsubstate') or repo.wvfs.exists(b'.hgsub'):
939 return
955 return
940
956
941 if repo_has_depth_one_nested_repo(repo):
957 if repo_has_depth_one_nested_repo(repo):
942 return
958 return
943
959
944 fsmonitorstate = state.state(repo)
960 fsmonitorstate = state.state(repo)
945 if fsmonitorstate.mode == b'off':
961 if fsmonitorstate.mode == b'off':
946 return
962 return
947
963
948 try:
964 try:
949 client = watchmanclient.client(repo.ui, repo.root)
965 client = watchmanclient.client(repo.ui, repo.root)
950 except Exception as ex:
966 except Exception as ex:
951 _handleunavailable(ui, fsmonitorstate, ex)
967 _handleunavailable(ui, fsmonitorstate, ex)
952 return
968 return
953
969
954 repo._fsmonitorstate = fsmonitorstate
970 repo._fsmonitorstate = fsmonitorstate
955 repo._watchmanclient = client
971 repo._watchmanclient = client
956
972
957 dirstate, cached = localrepo.isfilecached(repo, b'dirstate')
973 dirstate, cached = localrepo.isfilecached(repo, b'dirstate')
958 if cached:
974 if cached:
959 # at this point since fsmonitorstate wasn't present,
975 # at this point since fsmonitorstate wasn't present,
960 # repo.dirstate is not a fsmonitordirstate
976 # repo.dirstate is not a fsmonitordirstate
961 makedirstate(repo, dirstate)
977 makedirstate(repo, dirstate)
962
978
963 class fsmonitorrepo(repo.__class__):
979 class fsmonitorrepo(repo.__class__):
964 def status(self, *args, **kwargs):
980 def status(self, *args, **kwargs):
965 orig = super(fsmonitorrepo, self).status
981 orig = super(fsmonitorrepo, self).status
966 return overridestatus(orig, self, *args, **kwargs)
982 return overridestatus(orig, self, *args, **kwargs)
967
983
968 def wlocknostateupdate(self, *args, **kwargs):
984 def wlocknostateupdate(self, *args, **kwargs):
969 return super(fsmonitorrepo, self).wlock(*args, **kwargs)
985 return super(fsmonitorrepo, self).wlock(*args, **kwargs)
970
986
971 def wlock(self, *args, **kwargs):
987 def wlock(self, *args, **kwargs):
972 l = super(fsmonitorrepo, self).wlock(*args, **kwargs)
988 l = super(fsmonitorrepo, self).wlock(*args, **kwargs)
973 if not ui.configbool(
989 if not ui.configbool(
974 b"experimental", b"fsmonitor.transaction_notify"
990 b"experimental", b"fsmonitor.transaction_notify"
975 ):
991 ):
976 return l
992 return l
977 if l.held != 1:
993 if l.held != 1:
978 return l
994 return l
979 origrelease = l.releasefn
995 origrelease = l.releasefn
980
996
981 def staterelease():
997 def staterelease():
982 if origrelease:
998 if origrelease:
983 origrelease()
999 origrelease()
984 if l.stateupdate:
1000 if l.stateupdate:
985 l.stateupdate.exit()
1001 l.stateupdate.exit()
986 l.stateupdate = None
1002 l.stateupdate = None
987
1003
988 try:
1004 try:
989 l.stateupdate = None
1005 l.stateupdate = None
990 l.stateupdate = state_update(self, name=b"hg.transaction")
1006 l.stateupdate = state_update(self, name=b"hg.transaction")
991 l.stateupdate.enter()
1007 l.stateupdate.enter()
992 l.releasefn = staterelease
1008 l.releasefn = staterelease
993 except Exception as e:
1009 except Exception as e:
994 # Swallow any errors; fire and forget
1010 # Swallow any errors; fire and forget
995 self.ui.log(
1011 self.ui.log(
996 b'watchman', b'Exception in state update %s\n', e
1012 b'watchman', b'Exception in state update %s\n', e
997 )
1013 )
998 return l
1014 return l
999
1015
1000 repo.__class__ = fsmonitorrepo
1016 repo.__class__ = fsmonitorrepo
@@ -1,350 +1,352 b''
1 """grant Mercurial the ability to operate on Git repositories. (EXPERIMENTAL)
1 """grant Mercurial the ability to operate on Git repositories. (EXPERIMENTAL)
2
2
3 This is currently super experimental. It probably will consume your
3 This is currently super experimental. It probably will consume your
4 firstborn a la Rumpelstiltskin, etc.
4 firstborn a la Rumpelstiltskin, etc.
5 """
5 """
6
6
7
7
8 import os
8 import os
9
9
10 from mercurial.i18n import _
10 from mercurial.i18n import _
11
11
12 from mercurial import (
12 from mercurial import (
13 commands,
13 commands,
14 error,
14 error,
15 extensions,
15 extensions,
16 localrepo,
16 localrepo,
17 pycompat,
17 pycompat,
18 registrar,
18 registrar,
19 requirements as requirementsmod,
19 requirements as requirementsmod,
20 scmutil,
20 scmutil,
21 store,
21 store,
22 util,
22 util,
23 )
23 )
24
24
25 from . import (
25 from . import (
26 dirstate,
26 dirstate,
27 gitlog,
27 gitlog,
28 gitutil,
28 gitutil,
29 index,
29 index,
30 )
30 )
31
31
32 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
32 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
33 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
33 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
34 # be specifying the version(s) of Mercurial they are tested with, or
34 # be specifying the version(s) of Mercurial they are tested with, or
35 # leave the attribute unspecified.
35 # leave the attribute unspecified.
36 testedwith = b'ships-with-hg-core'
36 testedwith = b'ships-with-hg-core'
37
37
38 configtable = {}
38 configtable = {}
39 configitem = registrar.configitem(configtable)
39 configitem = registrar.configitem(configtable)
40 # git.log-index-cache-miss: internal knob for testing
40 # git.log-index-cache-miss: internal knob for testing
41 configitem(
41 configitem(
42 b"git",
42 b"git",
43 b"log-index-cache-miss",
43 b"log-index-cache-miss",
44 default=False,
44 default=False,
45 )
45 )
46
46
47 getversion = gitutil.pygit2_version
47 getversion = gitutil.pygit2_version
48
48
49
49
50 # TODO: extract an interface for this in core
50 # TODO: extract an interface for this in core
51 class gitstore: # store.basicstore):
51 class gitstore: # store.basicstore):
52 def __init__(self, path, vfstype):
52 def __init__(self, path, vfstype):
53 self.vfs = vfstype(path)
53 self.vfs = vfstype(path)
54 self.opener = self.vfs
54 self.opener = self.vfs
55 self.path = self.vfs.base
55 self.path = self.vfs.base
56 self.createmode = store._calcmode(self.vfs)
56 self.createmode = store._calcmode(self.vfs)
57 # above lines should go away in favor of:
57 # above lines should go away in favor of:
58 # super(gitstore, self).__init__(path, vfstype)
58 # super(gitstore, self).__init__(path, vfstype)
59
59
60 self.git = gitutil.get_pygit2().Repository(
60 self.git = gitutil.get_pygit2().Repository(
61 os.path.normpath(os.path.join(path, b'..', b'.git'))
61 os.path.normpath(os.path.join(path, b'..', b'.git'))
62 )
62 )
63 self._progress_factory = lambda *args, **kwargs: None
63 self._progress_factory = lambda *args, **kwargs: None
64 self._logfn = lambda x: None
64 self._logfn = lambda x: None
65
65
66 @util.propertycache
66 @util.propertycache
67 def _db(self):
67 def _db(self):
68 # We lazy-create the database because we want to thread a
68 # We lazy-create the database because we want to thread a
69 # progress callback down to the indexing process if it's
69 # progress callback down to the indexing process if it's
70 # required, and we don't have a ui handle in makestore().
70 # required, and we don't have a ui handle in makestore().
71 return index.get_index(self.git, self._logfn, self._progress_factory)
71 return index.get_index(self.git, self._logfn, self._progress_factory)
72
72
73 def join(self, f):
73 def join(self, f):
74 """Fake store.join method for git repositories.
74 """Fake store.join method for git repositories.
75
75
76 For the most part, store.join is used for @storecache
76 For the most part, store.join is used for @storecache
77 decorators to invalidate caches when various files
77 decorators to invalidate caches when various files
78 change. We'll map the ones we care about, and ignore the rest.
78 change. We'll map the ones we care about, and ignore the rest.
79 """
79 """
80 if f in (b'00changelog.i', b'00manifest.i'):
80 if f in (b'00changelog.i', b'00manifest.i'):
81 # This is close enough: in order for the changelog cache
81 # This is close enough: in order for the changelog cache
82 # to be invalidated, HEAD will have to change.
82 # to be invalidated, HEAD will have to change.
83 return os.path.join(self.path, b'HEAD')
83 return os.path.join(self.path, b'HEAD')
84 elif f == b'lock':
84 elif f == b'lock':
85 # TODO: we probably want to map this to a git lock, I
85 # TODO: we probably want to map this to a git lock, I
86 # suspect index.lock. We should figure out what the
86 # suspect index.lock. We should figure out what the
87 # most-alike file is in git-land. For now we're risking
87 # most-alike file is in git-land. For now we're risking
88 # bad concurrency errors if another git client is used.
88 # bad concurrency errors if another git client is used.
89 return os.path.join(self.path, b'hgit-bogus-lock')
89 return os.path.join(self.path, b'hgit-bogus-lock')
90 elif f in (b'obsstore', b'phaseroots', b'narrowspec', b'bookmarks'):
90 elif f in (b'obsstore', b'phaseroots', b'narrowspec', b'bookmarks'):
91 return os.path.join(self.path, b'..', b'.hg', f)
91 return os.path.join(self.path, b'..', b'.hg', f)
92 raise NotImplementedError(b'Need to pick file for %s.' % f)
92 raise NotImplementedError(b'Need to pick file for %s.' % f)
93
93
94 def changelog(self, trypending, concurrencychecker):
94 def changelog(self, trypending, concurrencychecker):
95 # TODO we don't have a plan for trypending in hg's git support yet
95 # TODO we don't have a plan for trypending in hg's git support yet
96 return gitlog.changelog(self.git, self._db)
96 return gitlog.changelog(self.git, self._db)
97
97
98 def manifestlog(self, repo, storenarrowmatch):
98 def manifestlog(self, repo, storenarrowmatch):
99 # TODO handle storenarrowmatch and figure out if we need the repo arg
99 # TODO handle storenarrowmatch and figure out if we need the repo arg
100 return gitlog.manifestlog(self.git, self._db)
100 return gitlog.manifestlog(self.git, self._db)
101
101
102 def invalidatecaches(self):
102 def invalidatecaches(self):
103 pass
103 pass
104
104
105 def write(self, tr=None):
105 def write(self, tr=None):
106 # normally this handles things like fncache writes, which we don't have
106 # normally this handles things like fncache writes, which we don't have
107 pass
107 pass
108
108
109
109
110 def _makestore(orig, requirements, storebasepath, vfstype):
110 def _makestore(orig, requirements, storebasepath, vfstype):
111 if b'git' in requirements:
111 if b'git' in requirements:
112 if not os.path.exists(os.path.join(storebasepath, b'..', b'.git')):
112 if not os.path.exists(os.path.join(storebasepath, b'..', b'.git')):
113 raise error.Abort(
113 raise error.Abort(
114 _(
114 _(
115 b'repository specified git format in '
115 b'repository specified git format in '
116 b'.hg/requires but has no .git directory'
116 b'.hg/requires but has no .git directory'
117 )
117 )
118 )
118 )
119 # Check for presence of pygit2 only here. The assumption is that we'll
119 # Check for presence of pygit2 only here. The assumption is that we'll
120 # run this code iff we'll later need pygit2.
120 # run this code iff we'll later need pygit2.
121 if gitutil.get_pygit2() is None:
121 if gitutil.get_pygit2() is None:
122 raise error.Abort(
122 raise error.Abort(
123 _(
123 _(
124 b'the git extension requires the Python '
124 b'the git extension requires the Python '
125 b'pygit2 library to be installed'
125 b'pygit2 library to be installed'
126 )
126 )
127 )
127 )
128
128
129 return gitstore(storebasepath, vfstype)
129 return gitstore(storebasepath, vfstype)
130 return orig(requirements, storebasepath, vfstype)
130 return orig(requirements, storebasepath, vfstype)
131
131
132
132
133 class gitfilestorage:
133 class gitfilestorage:
134 def file(self, path):
134 def file(self, path):
135 if path[0:1] == b'/':
135 if path[0:1] == b'/':
136 path = path[1:]
136 path = path[1:]
137 return gitlog.filelog(self.store.git, self.store._db, path)
137 return gitlog.filelog(self.store.git, self.store._db, path)
138
138
139
139
140 def _makefilestorage(orig, requirements, features, **kwargs):
140 def _makefilestorage(orig, requirements, features, **kwargs):
141 store = kwargs['store']
141 store = kwargs['store']
142 if isinstance(store, gitstore):
142 if isinstance(store, gitstore):
143 return gitfilestorage
143 return gitfilestorage
144 return orig(requirements, features, **kwargs)
144 return orig(requirements, features, **kwargs)
145
145
146
146
147 def _setupdothg(ui, path):
147 def _setupdothg(ui, path):
148 dothg = os.path.join(path, b'.hg')
148 dothg = os.path.join(path, b'.hg')
149 if os.path.exists(dothg):
149 if os.path.exists(dothg):
150 ui.warn(_(b'git repo already initialized for hg\n'))
150 ui.warn(_(b'git repo already initialized for hg\n'))
151 else:
151 else:
152 os.mkdir(os.path.join(path, b'.hg'))
152 os.mkdir(os.path.join(path, b'.hg'))
153 # TODO is it ok to extend .git/info/exclude like this?
153 # TODO is it ok to extend .git/info/exclude like this?
154 with open(
154 with open(
155 os.path.join(path, b'.git', b'info', b'exclude'), 'ab'
155 os.path.join(path, b'.git', b'info', b'exclude'), 'ab'
156 ) as exclude:
156 ) as exclude:
157 exclude.write(b'\n.hg\n')
157 exclude.write(b'\n.hg\n')
158 with open(os.path.join(dothg, b'requires'), 'wb') as f:
158 with open(os.path.join(dothg, b'requires'), 'wb') as f:
159 f.write(b'git\n')
159 f.write(b'git\n')
160
160
161
161
162 _BMS_PREFIX = 'refs/heads/'
162 _BMS_PREFIX = 'refs/heads/'
163
163
164
164
165 class gitbmstore:
165 class gitbmstore:
166 def __init__(self, gitrepo):
166 def __init__(self, gitrepo):
167 self.gitrepo = gitrepo
167 self.gitrepo = gitrepo
168 self._aclean = True
168 self._aclean = True
169 self._active = gitrepo.references['HEAD'] # git head, not mark
169 self._active = gitrepo.references['HEAD'] # git head, not mark
170
170
171 def __contains__(self, name):
171 def __contains__(self, name):
172 return (
172 return (
173 _BMS_PREFIX + pycompat.fsdecode(name)
173 _BMS_PREFIX + pycompat.fsdecode(name)
174 ) in self.gitrepo.references
174 ) in self.gitrepo.references
175
175
176 def __iter__(self):
176 def __iter__(self):
177 for r in self.gitrepo.listall_references():
177 for r in self.gitrepo.listall_references():
178 if r.startswith(_BMS_PREFIX):
178 if r.startswith(_BMS_PREFIX):
179 yield pycompat.fsencode(r[len(_BMS_PREFIX) :])
179 yield pycompat.fsencode(r[len(_BMS_PREFIX) :])
180
180
181 def __getitem__(self, k):
181 def __getitem__(self, k):
182 return (
182 return (
183 self.gitrepo.references[_BMS_PREFIX + pycompat.fsdecode(k)]
183 self.gitrepo.references[_BMS_PREFIX + pycompat.fsdecode(k)]
184 .peel()
184 .peel()
185 .id.raw
185 .id.raw
186 )
186 )
187
187
188 def get(self, k, default=None):
188 def get(self, k, default=None):
189 try:
189 try:
190 if k in self:
190 if k in self:
191 return self[k]
191 return self[k]
192 return default
192 return default
193 except gitutil.get_pygit2().InvalidSpecError:
193 except gitutil.get_pygit2().InvalidSpecError:
194 return default
194 return default
195
195
196 @property
196 @property
197 def active(self):
197 def active(self):
198 h = self.gitrepo.references['HEAD']
198 h = self.gitrepo.references['HEAD']
199 if not isinstance(h.target, str) or not h.target.startswith(
199 if not isinstance(h.target, str) or not h.target.startswith(
200 _BMS_PREFIX
200 _BMS_PREFIX
201 ):
201 ):
202 return None
202 return None
203 return pycompat.fsencode(h.target[len(_BMS_PREFIX) :])
203 return pycompat.fsencode(h.target[len(_BMS_PREFIX) :])
204
204
205 @active.setter
205 @active.setter
206 def active(self, mark):
206 def active(self, mark):
207 githead = mark is not None and (_BMS_PREFIX + mark) or None
207 githead = None
208 if mark is not None:
209 githead = _BMS_PREFIX + pycompat.fsdecode(mark)
208 if githead is not None and githead not in self.gitrepo.references:
210 if githead is not None and githead not in self.gitrepo.references:
209 raise AssertionError(b'bookmark %s does not exist!' % mark)
211 raise AssertionError(b'bookmark %s does not exist!' % mark)
210
212
211 self._active = githead
213 self._active = githead
212 self._aclean = False
214 self._aclean = False
213
215
214 def _writeactive(self):
216 def _writeactive(self):
215 if self._aclean:
217 if self._aclean:
216 return
218 return
217 self.gitrepo.references.create('HEAD', self._active, True)
219 self.gitrepo.references.create('HEAD', self._active, True)
218 self._aclean = True
220 self._aclean = True
219
221
220 def names(self, node):
222 def names(self, node):
221 r = []
223 r = []
222 for ref in self.gitrepo.listall_references():
224 for ref in self.gitrepo.listall_references():
223 if not ref.startswith(_BMS_PREFIX):
225 if not ref.startswith(_BMS_PREFIX):
224 continue
226 continue
225 if self.gitrepo.references[ref].peel().id.raw != node:
227 if self.gitrepo.references[ref].peel().id.raw != node:
226 continue
228 continue
227 r.append(pycompat.fsencode(ref[len(_BMS_PREFIX) :]))
229 r.append(pycompat.fsencode(ref[len(_BMS_PREFIX) :]))
228 return r
230 return r
229
231
230 # Cleanup opportunity: this is *identical* to core's bookmarks store.
232 # Cleanup opportunity: this is *identical* to core's bookmarks store.
231 def expandname(self, bname):
233 def expandname(self, bname):
232 if bname == b'.':
234 if bname == b'.':
233 if self.active:
235 if self.active:
234 return self.active
236 return self.active
235 raise error.RepoLookupError(_(b"no active bookmark"))
237 raise error.RepoLookupError(_(b"no active bookmark"))
236 return bname
238 return bname
237
239
238 def applychanges(self, repo, tr, changes):
240 def applychanges(self, repo, tr, changes):
239 """Apply a list of changes to bookmarks"""
241 """Apply a list of changes to bookmarks"""
240 # TODO: this should respect transactions, but that's going to
242 # TODO: this should respect transactions, but that's going to
241 # require enlarging the gitbmstore to know how to do in-memory
243 # require enlarging the gitbmstore to know how to do in-memory
242 # temporary writes and read those back prior to transaction
244 # temporary writes and read those back prior to transaction
243 # finalization.
245 # finalization.
244 for name, node in changes:
246 for name, node in changes:
245 if node is None:
247 if node is None:
246 self.gitrepo.references.delete(
248 self.gitrepo.references.delete(
247 _BMS_PREFIX + pycompat.fsdecode(name)
249 _BMS_PREFIX + pycompat.fsdecode(name)
248 )
250 )
249 else:
251 else:
250 self.gitrepo.references.create(
252 self.gitrepo.references.create(
251 _BMS_PREFIX + pycompat.fsdecode(name),
253 _BMS_PREFIX + pycompat.fsdecode(name),
252 gitutil.togitnode(node),
254 gitutil.togitnode(node),
253 force=True,
255 force=True,
254 )
256 )
255
257
256 def checkconflict(self, mark, force=False, target=None):
258 def checkconflict(self, mark, force=False, target=None):
257 githead = _BMS_PREFIX + mark
259 githead = _BMS_PREFIX + pycompat.fsdecode(mark)
258 cur = self.gitrepo.references['HEAD']
260 cur = self.gitrepo.references['HEAD']
259 if githead in self.gitrepo.references and not force:
261 if githead in self.gitrepo.references and not force:
260 if target:
262 if target:
261 if self.gitrepo.references[githead] == target and target == cur:
263 if self.gitrepo.references[githead] == target and target == cur:
262 # re-activating a bookmark
264 # re-activating a bookmark
263 return []
265 return []
264 # moving a bookmark - forward?
266 # moving a bookmark - forward?
265 raise NotImplementedError
267 raise NotImplementedError
266 raise error.Abort(
268 raise error.Abort(
267 _(b"bookmark '%s' already exists (use -f to force)") % mark
269 _(b"bookmark '%s' already exists (use -f to force)") % mark
268 )
270 )
269 if len(mark) > 3 and not force:
271 if len(mark) > 3 and not force:
270 try:
272 try:
271 shadowhash = scmutil.isrevsymbol(self._repo, mark)
273 shadowhash = scmutil.isrevsymbol(self._repo, mark)
272 except error.LookupError: # ambiguous identifier
274 except error.LookupError: # ambiguous identifier
273 shadowhash = False
275 shadowhash = False
274 if shadowhash:
276 if shadowhash:
275 self._repo.ui.warn(
277 self._repo.ui.warn(
276 _(
278 _(
277 b"bookmark %s matches a changeset hash\n"
279 b"bookmark %s matches a changeset hash\n"
278 b"(did you leave a -r out of an 'hg bookmark' "
280 b"(did you leave a -r out of an 'hg bookmark' "
279 b"command?)\n"
281 b"command?)\n"
280 )
282 )
281 % mark
283 % mark
282 )
284 )
283 return []
285 return []
284
286
285
287
286 def init(orig, ui, dest=b'.', **opts):
288 def init(orig, ui, dest=b'.', **opts):
287 if opts.get('git', False):
289 if opts.get('git', False):
288 path = util.abspath(dest)
290 path = util.abspath(dest)
289 # TODO: walk up looking for the git repo
291 # TODO: walk up looking for the git repo
290 _setupdothg(ui, path)
292 _setupdothg(ui, path)
291 return 0
293 return 0
292 return orig(ui, dest=dest, **opts)
294 return orig(ui, dest=dest, **opts)
293
295
294
296
295 def reposetup(ui, repo):
297 def reposetup(ui, repo):
296 if repo.local() and isinstance(repo.store, gitstore):
298 if repo.local() and isinstance(repo.store, gitstore):
297 orig = repo.__class__
299 orig = repo.__class__
298 repo.store._progress_factory = repo.ui.makeprogress
300 repo.store._progress_factory = repo.ui.makeprogress
299 if ui.configbool(b'git', b'log-index-cache-miss'):
301 if ui.configbool(b'git', b'log-index-cache-miss'):
300 repo.store._logfn = repo.ui.warn
302 repo.store._logfn = repo.ui.warn
301
303
302 class gitlocalrepo(orig):
304 class gitlocalrepo(orig):
303 def _makedirstate(self):
305 def _makedirstate(self):
304 v2_req = requirementsmod.DIRSTATE_V2_REQUIREMENT
306 v2_req = requirementsmod.DIRSTATE_V2_REQUIREMENT
305 use_dirstate_v2 = v2_req in self.requirements
307 use_dirstate_v2 = v2_req in self.requirements
306
308
307 # TODO narrow support here
309 # TODO narrow support here
308 return dirstate.gitdirstate(
310 return dirstate.gitdirstate(
309 self.ui,
311 self.ui,
310 self.vfs,
312 self.vfs,
311 self.store.git,
313 self.store.git,
312 use_dirstate_v2,
314 use_dirstate_v2,
313 )
315 )
314
316
315 def commit(self, *args, **kwargs):
317 def commit(self, *args, **kwargs):
316 ret = orig.commit(self, *args, **kwargs)
318 ret = orig.commit(self, *args, **kwargs)
317 if ret is None:
319 if ret is None:
318 # there was nothing to commit, so we should skip
320 # there was nothing to commit, so we should skip
319 # the index fixup logic we'd otherwise do.
321 # the index fixup logic we'd otherwise do.
320 return None
322 return None
321 tid = self.store.git[gitutil.togitnode(ret)].tree.id
323 tid = self.store.git[gitutil.togitnode(ret)].tree.id
322 # DANGER! This will flush any writes staged to the
324 # DANGER! This will flush any writes staged to the
323 # index in Git, but we're sidestepping the index in a
325 # index in Git, but we're sidestepping the index in a
324 # way that confuses git when we commit. Alas.
326 # way that confuses git when we commit. Alas.
325 self.store.git.index.read_tree(tid)
327 self.store.git.index.read_tree(tid)
326 self.store.git.index.write()
328 self.store.git.index.write()
327 return ret
329 return ret
328
330
329 @property
331 @property
330 def _bookmarks(self):
332 def _bookmarks(self):
331 return gitbmstore(self.store.git)
333 return gitbmstore(self.store.git)
332
334
333 repo.__class__ = gitlocalrepo
335 repo.__class__ = gitlocalrepo
334 return repo
336 return repo
335
337
336
338
337 def _featuresetup(ui, supported):
339 def _featuresetup(ui, supported):
338 # don't die on seeing a repo with the git requirement
340 # don't die on seeing a repo with the git requirement
339 supported |= {b'git'}
341 supported |= {b'git'}
340
342
341
343
342 def extsetup(ui):
344 def extsetup(ui):
343 extensions.wrapfunction(localrepo, b'makestore', _makestore)
345 extensions.wrapfunction(localrepo, b'makestore', _makestore)
344 extensions.wrapfunction(localrepo, b'makefilestorage', _makefilestorage)
346 extensions.wrapfunction(localrepo, b'makefilestorage', _makefilestorage)
345 # Inject --git flag for `hg init`
347 # Inject --git flag for `hg init`
346 entry = extensions.wrapcommand(commands.table, b'init', init)
348 entry = extensions.wrapcommand(commands.table, b'init', init)
347 entry[1].extend(
349 entry[1].extend(
348 [(b'', b'git', None, b'setup up a git repository instead of hg')]
350 [(b'', b'git', None, b'setup up a git repository instead of hg')]
349 )
351 )
350 localrepo.featuresetupfuncs.add(_featuresetup)
352 localrepo.featuresetupfuncs.add(_featuresetup)
@@ -1,401 +1,402 b''
1 import contextlib
1 import contextlib
2 import os
2 import os
3
3
4 from mercurial.node import sha1nodeconstants
4 from mercurial.node import sha1nodeconstants
5 from mercurial import (
5 from mercurial import (
6 dirstatemap,
6 dirstatemap,
7 error,
7 error,
8 extensions,
8 extensions,
9 match as matchmod,
9 match as matchmod,
10 pycompat,
10 pycompat,
11 scmutil,
11 scmutil,
12 util,
12 util,
13 )
13 )
14 from mercurial.dirstateutils import (
14 from mercurial.dirstateutils import (
15 timestamp,
15 timestamp,
16 )
16 )
17 from mercurial.interfaces import (
17 from mercurial.interfaces import (
18 dirstate as intdirstate,
18 dirstate as intdirstate,
19 util as interfaceutil,
19 util as interfaceutil,
20 )
20 )
21
21
22 from . import gitutil
22 from . import gitutil
23
23
24
24
25 DirstateItem = dirstatemap.DirstateItem
25 DirstateItem = dirstatemap.DirstateItem
26 propertycache = util.propertycache
26 propertycache = util.propertycache
27 pygit2 = gitutil.get_pygit2()
27 pygit2 = gitutil.get_pygit2()
28
28
29
29
30 def readpatternfile(orig, filepath, warn, sourceinfo=False):
30 def readpatternfile(orig, filepath, warn, sourceinfo=False):
31 if not (b'info/exclude' in filepath or filepath.endswith(b'.gitignore')):
31 if not (b'info/exclude' in filepath or filepath.endswith(b'.gitignore')):
32 return orig(filepath, warn, sourceinfo=False)
32 return orig(filepath, warn, sourceinfo=False)
33 result = []
33 result = []
34 warnings = []
34 warnings = []
35 with open(filepath, 'rb') as fp:
35 with open(filepath, 'rb') as fp:
36 for l in fp:
36 for l in fp:
37 l = l.strip()
37 l = l.strip()
38 if not l or l.startswith(b'#'):
38 if not l or l.startswith(b'#'):
39 continue
39 continue
40 if l.startswith(b'!'):
40 if l.startswith(b'!'):
41 warnings.append(b'unsupported ignore pattern %s' % l)
41 warnings.append(b'unsupported ignore pattern %s' % l)
42 continue
42 continue
43 if l.startswith(b'/'):
43 if l.startswith(b'/'):
44 result.append(b'rootglob:' + l[1:])
44 result.append(b'rootglob:' + l[1:])
45 else:
45 else:
46 result.append(b'relglob:' + l)
46 result.append(b'relglob:' + l)
47 return result, warnings
47 return result, warnings
48
48
49
49
50 extensions.wrapfunction(matchmod, b'readpatternfile', readpatternfile)
50 extensions.wrapfunction(matchmod, b'readpatternfile', readpatternfile)
51
51
52
52
53 _STATUS_MAP = {}
53 _STATUS_MAP = {}
54 if pygit2:
54 if pygit2:
55 _STATUS_MAP = {
55 _STATUS_MAP = {
56 pygit2.GIT_STATUS_CONFLICTED: b'm',
56 pygit2.GIT_STATUS_CONFLICTED: b'm',
57 pygit2.GIT_STATUS_CURRENT: b'n',
57 pygit2.GIT_STATUS_CURRENT: b'n',
58 pygit2.GIT_STATUS_IGNORED: b'?',
58 pygit2.GIT_STATUS_IGNORED: b'?',
59 pygit2.GIT_STATUS_INDEX_DELETED: b'r',
59 pygit2.GIT_STATUS_INDEX_DELETED: b'r',
60 pygit2.GIT_STATUS_INDEX_MODIFIED: b'n',
60 pygit2.GIT_STATUS_INDEX_MODIFIED: b'n',
61 pygit2.GIT_STATUS_INDEX_NEW: b'a',
61 pygit2.GIT_STATUS_INDEX_NEW: b'a',
62 pygit2.GIT_STATUS_INDEX_RENAMED: b'a',
62 pygit2.GIT_STATUS_INDEX_RENAMED: b'a',
63 pygit2.GIT_STATUS_INDEX_TYPECHANGE: b'n',
63 pygit2.GIT_STATUS_INDEX_TYPECHANGE: b'n',
64 pygit2.GIT_STATUS_WT_DELETED: b'r',
64 pygit2.GIT_STATUS_WT_DELETED: b'r',
65 pygit2.GIT_STATUS_WT_MODIFIED: b'n',
65 pygit2.GIT_STATUS_WT_MODIFIED: b'n',
66 pygit2.GIT_STATUS_WT_NEW: b'?',
66 pygit2.GIT_STATUS_WT_NEW: b'?',
67 pygit2.GIT_STATUS_WT_RENAMED: b'a',
67 pygit2.GIT_STATUS_WT_RENAMED: b'a',
68 pygit2.GIT_STATUS_WT_TYPECHANGE: b'n',
68 pygit2.GIT_STATUS_WT_TYPECHANGE: b'n',
69 pygit2.GIT_STATUS_WT_UNREADABLE: b'?',
69 pygit2.GIT_STATUS_WT_UNREADABLE: b'?',
70 pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_WT_MODIFIED: b'm',
70 pygit2.GIT_STATUS_INDEX_MODIFIED | pygit2.GIT_STATUS_WT_MODIFIED: b'm',
71 }
71 }
72
72
73
73
74 @interfaceutil.implementer(intdirstate.idirstate)
74 @interfaceutil.implementer(intdirstate.idirstate)
75 class gitdirstate:
75 class gitdirstate:
76 def __init__(self, ui, vfs, gitrepo, use_dirstate_v2):
76 def __init__(self, ui, vfs, gitrepo, use_dirstate_v2):
77 self._ui = ui
77 self._ui = ui
78 self._root = os.path.dirname(vfs.base)
78 self._root = os.path.dirname(vfs.base)
79 self._opener = vfs
79 self._opener = vfs
80 self.git = gitrepo
80 self.git = gitrepo
81 self._plchangecallbacks = {}
81 self._plchangecallbacks = {}
82 # TODO: context.poststatusfixup is bad and uses this attribute
82 # TODO: context.poststatusfixup is bad and uses this attribute
83 self._dirty = False
83 self._dirty = False
84 self._mapcls = dirstatemap.dirstatemap
84 self._mapcls = dirstatemap.dirstatemap
85 self._use_dirstate_v2 = use_dirstate_v2
85 self._use_dirstate_v2 = use_dirstate_v2
86
86
87 @propertycache
87 @propertycache
88 def _map(self):
88 def _map(self):
89 """Return the dirstate contents (see documentation for dirstatemap)."""
89 """Return the dirstate contents (see documentation for dirstatemap)."""
90 self._map = self._mapcls(
90 self._map = self._mapcls(
91 self._ui,
91 self._ui,
92 self._opener,
92 self._opener,
93 self._root,
93 self._root,
94 sha1nodeconstants,
94 sha1nodeconstants,
95 self._use_dirstate_v2,
95 self._use_dirstate_v2,
96 )
96 )
97 return self._map
97 return self._map
98
98
99 def p1(self):
99 def p1(self):
100 try:
100 try:
101 return self.git.head.peel().id.raw
101 return self.git.head.peel().id.raw
102 except pygit2.GitError:
102 except pygit2.GitError:
103 # Typically happens when peeling HEAD fails, as in an
103 # Typically happens when peeling HEAD fails, as in an
104 # empty repository.
104 # empty repository.
105 return sha1nodeconstants.nullid
105 return sha1nodeconstants.nullid
106
106
107 def p2(self):
107 def p2(self):
108 # TODO: MERGE_HEAD? something like that, right?
108 # TODO: MERGE_HEAD? something like that, right?
109 return sha1nodeconstants.nullid
109 return sha1nodeconstants.nullid
110
110
111 def setparents(self, p1, p2=None):
111 def setparents(self, p1, p2=None):
112 if p2 is None:
112 if p2 is None:
113 p2 = sha1nodeconstants.nullid
113 p2 = sha1nodeconstants.nullid
114 assert p2 == sha1nodeconstants.nullid, b'TODO merging support'
114 assert p2 == sha1nodeconstants.nullid, b'TODO merging support'
115 self.git.head.set_target(gitutil.togitnode(p1))
115 self.git.head.set_target(gitutil.togitnode(p1))
116
116
117 @util.propertycache
117 @util.propertycache
118 def identity(self):
118 def identity(self):
119 return util.filestat.frompath(
119 return util.filestat.frompath(
120 os.path.join(self._root, b'.git', b'index')
120 os.path.join(self._root, b'.git', b'index')
121 )
121 )
122
122
123 def branch(self):
123 def branch(self):
124 return b'default'
124 return b'default'
125
125
126 def parents(self):
126 def parents(self):
127 # TODO how on earth do we find p2 if a merge is in flight?
127 # TODO how on earth do we find p2 if a merge is in flight?
128 return self.p1(), sha1nodeconstants.nullid
128 return self.p1(), sha1nodeconstants.nullid
129
129
130 def __iter__(self):
130 def __iter__(self):
131 return (pycompat.fsencode(f.path) for f in self.git.index)
131 return (pycompat.fsencode(f.path) for f in self.git.index)
132
132
133 def items(self):
133 def items(self):
134 for ie in self.git.index:
134 for ie in self.git.index:
135 yield ie.path, None # value should be a DirstateItem
135 yield ie.path, None # value should be a DirstateItem
136
136
137 # py2,3 compat forward
137 # py2,3 compat forward
138 iteritems = items
138 iteritems = items
139
139
140 def __getitem__(self, filename):
140 def __getitem__(self, filename):
141 try:
141 try:
142 gs = self.git.status_file(filename)
142 gs = self.git.status_file(filename)
143 except KeyError:
143 except KeyError:
144 return b'?'
144 return b'?'
145 return _STATUS_MAP[gs]
145 return _STATUS_MAP[gs]
146
146
147 def __contains__(self, filename):
147 def __contains__(self, filename):
148 try:
148 try:
149 gs = self.git.status_file(filename)
149 gs = self.git.status_file(filename)
150 return _STATUS_MAP[gs] != b'?'
150 return _STATUS_MAP[gs] != b'?'
151 except KeyError:
151 except KeyError:
152 return False
152 return False
153
153
154 def status(self, match, subrepos, ignored, clean, unknown):
154 def status(self, match, subrepos, ignored, clean, unknown):
155 listclean = clean
155 listclean = clean
156 # TODO handling of clean files - can we get that from git.status()?
156 # TODO handling of clean files - can we get that from git.status()?
157 modified, added, removed, deleted, unknown, ignored, clean = (
157 modified, added, removed, deleted, unknown, ignored, clean = (
158 [],
158 [],
159 [],
159 [],
160 [],
160 [],
161 [],
161 [],
162 [],
162 [],
163 [],
163 [],
164 [],
164 [],
165 )
165 )
166
166
167 try:
167 try:
168 mtime_boundary = timestamp.get_fs_now(self._opener)
168 mtime_boundary = timestamp.get_fs_now(self._opener)
169 except OSError:
169 except OSError:
170 # In largefiles or readonly context
170 # In largefiles or readonly context
171 mtime_boundary = None
171 mtime_boundary = None
172
172
173 gstatus = self.git.status()
173 gstatus = self.git.status()
174 for path, status in gstatus.items():
174 for path, status in gstatus.items():
175 path = pycompat.fsencode(path)
175 path = pycompat.fsencode(path)
176 if not match(path):
176 if not match(path):
177 continue
177 continue
178 if status == pygit2.GIT_STATUS_IGNORED:
178 if status == pygit2.GIT_STATUS_IGNORED:
179 if path.endswith(b'/'):
179 if path.endswith(b'/'):
180 continue
180 continue
181 ignored.append(path)
181 ignored.append(path)
182 elif status in (
182 elif status in (
183 pygit2.GIT_STATUS_WT_MODIFIED,
183 pygit2.GIT_STATUS_WT_MODIFIED,
184 pygit2.GIT_STATUS_INDEX_MODIFIED,
184 pygit2.GIT_STATUS_INDEX_MODIFIED,
185 pygit2.GIT_STATUS_WT_MODIFIED
185 pygit2.GIT_STATUS_WT_MODIFIED
186 | pygit2.GIT_STATUS_INDEX_MODIFIED,
186 | pygit2.GIT_STATUS_INDEX_MODIFIED,
187 ):
187 ):
188 modified.append(path)
188 modified.append(path)
189 elif status == pygit2.GIT_STATUS_INDEX_NEW:
189 elif status == pygit2.GIT_STATUS_INDEX_NEW:
190 added.append(path)
190 added.append(path)
191 elif status == pygit2.GIT_STATUS_WT_NEW:
191 elif status == pygit2.GIT_STATUS_WT_NEW:
192 unknown.append(path)
192 unknown.append(path)
193 elif status == pygit2.GIT_STATUS_WT_DELETED:
193 elif status == pygit2.GIT_STATUS_WT_DELETED:
194 deleted.append(path)
194 deleted.append(path)
195 elif status == pygit2.GIT_STATUS_INDEX_DELETED:
195 elif status == pygit2.GIT_STATUS_INDEX_DELETED:
196 removed.append(path)
196 removed.append(path)
197 else:
197 else:
198 raise error.Abort(
198 raise error.Abort(
199 b'unhandled case: status for %r is %r' % (path, status)
199 b'unhandled case: status for %r is %r' % (path, status)
200 )
200 )
201
201
202 if listclean:
202 if listclean:
203 observed = set(
203 observed = set(
204 modified + added + removed + deleted + unknown + ignored
204 modified + added + removed + deleted + unknown + ignored
205 )
205 )
206 index = self.git.index
206 index = self.git.index
207 index.read()
207 index.read()
208 for entry in index:
208 for entry in index:
209 path = pycompat.fsencode(entry.path)
209 path = pycompat.fsencode(entry.path)
210 if not match(path):
210 if not match(path):
211 continue
211 continue
212 if path in observed:
212 if path in observed:
213 continue # already in some other set
213 continue # already in some other set
214 if path[-1] == b'/':
214 if path[-1] == b'/':
215 continue # directory
215 continue # directory
216 clean.append(path)
216 clean.append(path)
217
217
218 # TODO are we really always sure of status here?
218 # TODO are we really always sure of status here?
219 return (
219 return (
220 False,
220 False,
221 scmutil.status(
221 scmutil.status(
222 modified, added, removed, deleted, unknown, ignored, clean
222 modified, added, removed, deleted, unknown, ignored, clean
223 ),
223 ),
224 mtime_boundary,
224 mtime_boundary,
225 )
225 )
226
226
227 def flagfunc(self, buildfallback):
227 def flagfunc(self, buildfallback):
228 # TODO we can do better
228 # TODO we can do better
229 return buildfallback()
229 return buildfallback()
230
230
231 def getcwd(self):
231 def getcwd(self):
232 # TODO is this a good way to do this?
232 # TODO is this a good way to do this?
233 return os.path.dirname(
233 return os.path.dirname(
234 os.path.dirname(pycompat.fsencode(self.git.path))
234 os.path.dirname(pycompat.fsencode(self.git.path))
235 )
235 )
236
236
237 def get_entry(self, path):
237 def get_entry(self, path):
238 """return a DirstateItem for the associated path"""
238 """return a DirstateItem for the associated path"""
239 entry = self._map.get(path)
239 entry = self._map.get(path)
240 if entry is None:
240 if entry is None:
241 return DirstateItem()
241 return DirstateItem()
242 return entry
242 return entry
243
243
244 def normalize(self, path):
244 def normalize(self, path):
245 normed = util.normcase(path)
245 normed = util.normcase(path)
246 assert normed == path, b"TODO handling of case folding: %s != %s" % (
246 assert normed == path, b"TODO handling of case folding: %s != %s" % (
247 normed,
247 normed,
248 path,
248 path,
249 )
249 )
250 return path
250 return path
251
251
252 @property
252 @property
253 def _checklink(self):
253 def _checklink(self):
254 return util.checklink(os.path.dirname(pycompat.fsencode(self.git.path)))
254 return util.checklink(os.path.dirname(pycompat.fsencode(self.git.path)))
255
255
256 def copies(self):
256 def copies(self):
257 # TODO support copies?
257 # TODO support copies?
258 return {}
258 return {}
259
259
260 # # TODO what the heck is this
260 # # TODO what the heck is this
261 _filecache = set()
261 _filecache = set()
262
262
263 def pendingparentchange(self):
263 def pendingparentchange(self):
264 # TODO: we need to implement the context manager bits and
264 # TODO: we need to implement the context manager bits and
265 # correctly stage/revert index edits.
265 # correctly stage/revert index edits.
266 return False
266 return False
267
267
268 def write(self, tr):
268 def write(self, tr):
269 # TODO: call parent change callbacks
269 # TODO: call parent change callbacks
270
270
271 if tr:
271 if tr:
272
272
273 def writeinner(category):
273 def writeinner(category):
274 self.git.index.write()
274 self.git.index.write()
275
275
276 tr.addpending(b'gitdirstate', writeinner)
276 tr.addpending(b'gitdirstate', writeinner)
277 else:
277 else:
278 self.git.index.write()
278 self.git.index.write()
279
279
280 def pathto(self, f, cwd=None):
280 def pathto(self, f, cwd=None):
281 if cwd is None:
281 if cwd is None:
282 cwd = self.getcwd()
282 cwd = self.getcwd()
283 # TODO core dirstate does something about slashes here
283 # TODO core dirstate does something about slashes here
284 assert isinstance(f, bytes)
284 assert isinstance(f, bytes)
285 r = util.pathto(self._root, cwd, f)
285 r = util.pathto(self._root, cwd, f)
286 return r
286 return r
287
287
288 def matches(self, match):
288 def matches(self, match):
289 for x in self.git.index:
289 for x in self.git.index:
290 p = pycompat.fsencode(x.path)
290 p = pycompat.fsencode(x.path)
291 if match(p):
291 if match(p):
292 yield p
292 yield p
293
293
294 def set_clean(self, f, parentfiledata):
294 def set_clean(self, f, parentfiledata):
295 """Mark a file normal and clean."""
295 """Mark a file normal and clean."""
296 # TODO: for now we just let libgit2 re-stat the file. We can
296 # TODO: for now we just let libgit2 re-stat the file. We can
297 # clearly do better.
297 # clearly do better.
298
298
299 def set_possibly_dirty(self, f):
299 def set_possibly_dirty(self, f):
300 """Mark a file normal, but possibly dirty."""
300 """Mark a file normal, but possibly dirty."""
301 # TODO: for now we just let libgit2 re-stat the file. We can
301 # TODO: for now we just let libgit2 re-stat the file. We can
302 # clearly do better.
302 # clearly do better.
303
303
304 def walk(self, match, subrepos, unknown, ignored, full=True):
304 def walk(self, match, subrepos, unknown, ignored, full=True):
305 # TODO: we need to use .status() and not iterate the index,
305 # TODO: we need to use .status() and not iterate the index,
306 # because the index doesn't force a re-walk and so `hg add` of
306 # because the index doesn't force a re-walk and so `hg add` of
307 # a new file without an intervening call to status will
307 # a new file without an intervening call to status will
308 # silently do nothing.
308 # silently do nothing.
309 r = {}
309 r = {}
310 cwd = self.getcwd()
310 cwd = self.getcwd()
311 for path, status in self.git.status().items():
311 for path, status in self.git.status().items():
312 if path.startswith('.hg/'):
312 if path.startswith('.hg/'):
313 continue
313 continue
314 path = pycompat.fsencode(path)
314 path = pycompat.fsencode(path)
315 if not match(path):
315 if not match(path):
316 continue
316 continue
317 # TODO construct the stat info from the status object?
317 # TODO construct the stat info from the status object?
318 try:
318 try:
319 s = os.stat(os.path.join(cwd, path))
319 s = os.stat(os.path.join(cwd, path))
320 except FileNotFoundError:
320 except FileNotFoundError:
321 continue
321 continue
322 r[path] = s
322 r[path] = s
323 return r
323 return r
324
324
325 def savebackup(self, tr, backupname):
325 def savebackup(self, tr, backupname):
326 # TODO: figure out a strategy for saving index backups.
326 # TODO: figure out a strategy for saving index backups.
327 pass
327 pass
328
328
329 def restorebackup(self, tr, backupname):
329 def restorebackup(self, tr, backupname):
330 # TODO: figure out a strategy for saving index backups.
330 # TODO: figure out a strategy for saving index backups.
331 pass
331 pass
332
332
333 def set_tracked(self, f):
333 def set_tracked(self, f, reset_copy=False):
334 # TODO: support copies and reset_copy=True
334 uf = pycompat.fsdecode(f)
335 uf = pycompat.fsdecode(f)
335 if uf in self.git.index:
336 if uf in self.git.index:
336 return False
337 return False
337 index = self.git.index
338 index = self.git.index
338 index.read()
339 index.read()
339 index.add(uf)
340 index.add(uf)
340 index.write()
341 index.write()
341 return True
342 return True
342
343
343 def add(self, f):
344 def add(self, f):
344 index = self.git.index
345 index = self.git.index
345 index.read()
346 index.read()
346 index.add(pycompat.fsdecode(f))
347 index.add(pycompat.fsdecode(f))
347 index.write()
348 index.write()
348
349
349 def drop(self, f):
350 def drop(self, f):
350 index = self.git.index
351 index = self.git.index
351 index.read()
352 index.read()
352 fs = pycompat.fsdecode(f)
353 fs = pycompat.fsdecode(f)
353 if fs in index:
354 if fs in index:
354 index.remove(fs)
355 index.remove(fs)
355 index.write()
356 index.write()
356
357
357 def set_untracked(self, f):
358 def set_untracked(self, f):
358 index = self.git.index
359 index = self.git.index
359 index.read()
360 index.read()
360 fs = pycompat.fsdecode(f)
361 fs = pycompat.fsdecode(f)
361 if fs in index:
362 if fs in index:
362 index.remove(fs)
363 index.remove(fs)
363 index.write()
364 index.write()
364 return True
365 return True
365 return False
366 return False
366
367
367 def remove(self, f):
368 def remove(self, f):
368 index = self.git.index
369 index = self.git.index
369 index.read()
370 index.read()
370 index.remove(pycompat.fsdecode(f))
371 index.remove(pycompat.fsdecode(f))
371 index.write()
372 index.write()
372
373
373 def copied(self, path):
374 def copied(self, path):
374 # TODO: track copies?
375 # TODO: track copies?
375 return None
376 return None
376
377
377 def prefetch_parents(self):
378 def prefetch_parents(self):
378 # TODO
379 # TODO
379 pass
380 pass
380
381
381 def update_file(self, *args, **kwargs):
382 def update_file(self, *args, **kwargs):
382 # TODO
383 # TODO
383 pass
384 pass
384
385
385 @contextlib.contextmanager
386 @contextlib.contextmanager
386 def parentchange(self):
387 def parentchange(self):
387 # TODO: track this maybe?
388 # TODO: track this maybe?
388 yield
389 yield
389
390
390 def addparentchangecallback(self, category, callback):
391 def addparentchangecallback(self, category, callback):
391 # TODO: should this be added to the dirstate interface?
392 # TODO: should this be added to the dirstate interface?
392 self._plchangecallbacks[category] = callback
393 self._plchangecallbacks[category] = callback
393
394
394 def clearbackup(self, tr, backupname):
395 def clearbackup(self, tr, backupname):
395 # TODO
396 # TODO
396 pass
397 pass
397
398
398 def setbranch(self, branch):
399 def setbranch(self, branch):
399 raise error.Abort(
400 raise error.Abort(
400 b'git repos do not support branches. try using bookmarks'
401 b'git repos do not support branches. try using bookmarks'
401 )
402 )
@@ -1,546 +1,570 b''
1 from mercurial.i18n import _
1 from mercurial.i18n import _
2
2
3 from mercurial.node import (
3 from mercurial.node import (
4 bin,
4 bin,
5 hex,
5 hex,
6 nullrev,
6 nullrev,
7 sha1nodeconstants,
7 sha1nodeconstants,
8 )
8 )
9 from mercurial import (
9 from mercurial import (
10 ancestor,
10 ancestor,
11 changelog as hgchangelog,
11 changelog as hgchangelog,
12 dagop,
12 dagop,
13 encoding,
13 encoding,
14 error,
14 error,
15 manifest,
15 manifest,
16 pycompat,
16 pycompat,
17 )
17 )
18 from mercurial.interfaces import (
18 from mercurial.interfaces import (
19 repository,
19 repository,
20 util as interfaceutil,
20 util as interfaceutil,
21 )
21 )
22 from mercurial.utils import stringutil
22 from mercurial.utils import stringutil
23 from . import (
23 from . import (
24 gitutil,
24 gitutil,
25 index,
25 index,
26 manifest as gitmanifest,
26 manifest as gitmanifest,
27 )
27 )
28
28
29 pygit2 = gitutil.get_pygit2()
29 pygit2 = gitutil.get_pygit2()
30
30
31
31
32 class baselog: # revlog.revlog):
32 class baselog: # revlog.revlog):
33 """Common implementations between changelog and manifestlog."""
33 """Common implementations between changelog and manifestlog."""
34
34
35 def __init__(self, gr, db):
35 def __init__(self, gr, db):
36 self.gitrepo = gr
36 self.gitrepo = gr
37 self._db = db
37 self._db = db
38
38
39 def __len__(self):
39 def __len__(self):
40 return int(
40 return int(
41 self._db.execute('SELECT COUNT(*) FROM changelog').fetchone()[0]
41 self._db.execute('SELECT COUNT(*) FROM changelog').fetchone()[0]
42 )
42 )
43
43
44 def rev(self, n):
44 def rev(self, n):
45 if n == sha1nodeconstants.nullid:
45 if n == sha1nodeconstants.nullid:
46 return -1
46 return -1
47 t = self._db.execute(
47 t = self._db.execute(
48 'SELECT rev FROM changelog WHERE node = ?', (gitutil.togitnode(n),)
48 'SELECT rev FROM changelog WHERE node = ?', (gitutil.togitnode(n),)
49 ).fetchone()
49 ).fetchone()
50 if t is None:
50 if t is None:
51 raise error.LookupError(n, b'00changelog.i', _(b'no node %d'))
51 raise error.LookupError(n, b'00changelog.i', _(b'no node %d'))
52 return t[0]
52 return t[0]
53
53
54 def node(self, r):
54 def node(self, r):
55 if r == nullrev:
55 if r == nullrev:
56 return sha1nodeconstants.nullid
56 return sha1nodeconstants.nullid
57 t = self._db.execute(
57 t = self._db.execute(
58 'SELECT node FROM changelog WHERE rev = ?', (r,)
58 'SELECT node FROM changelog WHERE rev = ?', (r,)
59 ).fetchone()
59 ).fetchone()
60 if t is None:
60 if t is None:
61 raise error.LookupError(r, b'00changelog.i', _(b'no node'))
61 raise error.LookupError(r, b'00changelog.i', _(b'no node'))
62 return bin(t[0])
62 return bin(t[0])
63
63
64 def hasnode(self, n):
64 def hasnode(self, n):
65 t = self._db.execute(
65 t = self._db.execute(
66 'SELECT node FROM changelog WHERE node = ?',
66 'SELECT node FROM changelog WHERE node = ?',
67 (pycompat.sysstr(n),),
67 (pycompat.sysstr(n),),
68 ).fetchone()
68 ).fetchone()
69 return t is not None
69 return t is not None
70
70
71
71
72 class baselogindex:
72 class baselogindex:
73 def __init__(self, log):
73 def __init__(self, log):
74 self._log = log
74 self._log = log
75
75
76 def has_node(self, n):
76 def has_node(self, n):
77 return self._log.rev(n) != -1
77 return self._log.rev(n) != -1
78
78
79 def __len__(self):
79 def __len__(self):
80 return len(self._log)
80 return len(self._log)
81
81
82 def __getitem__(self, idx):
82 def __getitem__(self, idx):
83 p1rev, p2rev = self._log.parentrevs(idx)
83 p1rev, p2rev = self._log.parentrevs(idx)
84 # TODO: it's messy that the index leaks so far out of the
84 # TODO: it's messy that the index leaks so far out of the
85 # storage layer that we have to implement things like reading
85 # storage layer that we have to implement things like reading
86 # this raw tuple, which exposes revlog internals.
86 # this raw tuple, which exposes revlog internals.
87 return (
87 return (
88 # Pretend offset is just the index, since we don't really care.
88 # Pretend offset is just the index, since we don't really care.
89 idx,
89 idx,
90 # Same with lengths
90 # Same with lengths
91 idx, # length
91 idx, # length
92 idx, # rawsize
92 idx, # rawsize
93 -1, # delta base
93 -1, # delta base
94 idx, # linkrev TODO is this right?
94 idx, # linkrev TODO is this right?
95 p1rev,
95 p1rev,
96 p2rev,
96 p2rev,
97 self._log.node(idx),
97 self._log.node(idx),
98 )
98 )
99
99
100
100
101 # TODO: an interface for the changelog type?
101 # TODO: an interface for the changelog type?
102 class changelog(baselog):
102 class changelog(baselog):
103 # TODO: this appears to be an enumerated type, and should probably
103 # TODO: this appears to be an enumerated type, and should probably
104 # be part of the public changelog interface
104 # be part of the public changelog interface
105 _copiesstorage = b'extra'
105 _copiesstorage = b'extra'
106
106
107 def __contains__(self, rev):
107 def __contains__(self, rev):
108 try:
108 try:
109 self.node(rev)
109 self.node(rev)
110 return True
110 return True
111 except error.LookupError:
111 except error.LookupError:
112 return False
112 return False
113
113
114 def __iter__(self):
114 def __iter__(self):
115 return iter(range(len(self)))
115 return iter(range(len(self)))
116
116
117 @property
117 @property
118 def filteredrevs(self):
118 def filteredrevs(self):
119 # TODO: we should probably add a refs/hg/ namespace for hidden
119 # TODO: we should probably add a refs/hg/ namespace for hidden
120 # heads etc, but that's an idea for later.
120 # heads etc, but that's an idea for later.
121 return set()
121 return set()
122
122
123 @property
123 @property
124 def index(self):
124 def index(self):
125 return baselogindex(self)
125 return baselogindex(self)
126
126
127 @property
127 @property
128 def nodemap(self):
128 def nodemap(self):
129 r = {
129 r = {
130 bin(v[0]): v[1]
130 bin(v[0]): v[1]
131 for v in self._db.execute('SELECT node, rev FROM changelog')
131 for v in self._db.execute('SELECT node, rev FROM changelog')
132 }
132 }
133 r[sha1nodeconstants.nullid] = nullrev
133 r[sha1nodeconstants.nullid] = nullrev
134 return r
134 return r
135
135
136 def tip(self):
136 def tip(self):
137 t = self._db.execute(
137 t = self._db.execute(
138 'SELECT node FROM changelog ORDER BY rev DESC LIMIT 1'
138 'SELECT node FROM changelog ORDER BY rev DESC LIMIT 1'
139 ).fetchone()
139 ).fetchone()
140 if t:
140 if t:
141 return bin(t[0])
141 return bin(t[0])
142 return sha1nodeconstants.nullid
142 return sha1nodeconstants.nullid
143
143
144 def revs(self, start=0, stop=None):
144 def revs(self, start=0, stop=None):
145 if stop is None:
145 if stop is None:
146 stop = self.tiprev()
146 stop = self.tiprev()
147 t = self._db.execute(
147 t = self._db.execute(
148 'SELECT rev FROM changelog '
148 'SELECT rev FROM changelog '
149 'WHERE rev >= ? AND rev <= ? '
149 'WHERE rev >= ? AND rev <= ? '
150 'ORDER BY REV ASC',
150 'ORDER BY REV ASC',
151 (start, stop),
151 (start, stop),
152 )
152 )
153 return (int(r[0]) for r in t)
153 return (int(r[0]) for r in t)
154
154
155 def tiprev(self):
155 def tiprev(self):
156 t = self._db.execute(
156 t = self._db.execute(
157 'SELECT rev FROM changelog ' 'ORDER BY REV DESC ' 'LIMIT 1'
157 'SELECT rev FROM changelog ' 'ORDER BY REV DESC ' 'LIMIT 1'
158 ).fetchone()
158 ).fetchone()
159
159
160 if t is not None:
160 if t is not None:
161 return t[0]
161 return t[0]
162 return -1
162 return -1
163
163
164 def _partialmatch(self, id):
164 def _partialmatch(self, id):
165 if sha1nodeconstants.wdirhex.startswith(id):
165 if sha1nodeconstants.wdirhex.startswith(id):
166 raise error.WdirUnsupported
166 raise error.WdirUnsupported
167 candidates = [
167 candidates = [
168 bin(x[0])
168 bin(x[0])
169 for x in self._db.execute(
169 for x in self._db.execute(
170 'SELECT node FROM changelog WHERE node LIKE ?',
170 'SELECT node FROM changelog WHERE node LIKE ?',
171 (pycompat.sysstr(id + b'%'),),
171 (pycompat.sysstr(id + b'%'),),
172 )
172 )
173 ]
173 ]
174 if sha1nodeconstants.nullhex.startswith(id):
174 if sha1nodeconstants.nullhex.startswith(id):
175 candidates.append(sha1nodeconstants.nullid)
175 candidates.append(sha1nodeconstants.nullid)
176 if len(candidates) > 1:
176 if len(candidates) > 1:
177 raise error.AmbiguousPrefixLookupError(
177 raise error.AmbiguousPrefixLookupError(
178 id, b'00changelog.i', _(b'ambiguous identifier')
178 id, b'00changelog.i', _(b'ambiguous identifier')
179 )
179 )
180 if candidates:
180 if candidates:
181 return candidates[0]
181 return candidates[0]
182 return None
182 return None
183
183
184 def flags(self, rev):
184 def flags(self, rev):
185 return 0
185 return 0
186
186
187 def shortest(self, node, minlength=1):
187 def shortest(self, node, minlength=1):
188 nodehex = hex(node)
188 nodehex = hex(node)
189 for attempt in range(minlength, len(nodehex) + 1):
189 for attempt in range(minlength, len(nodehex) + 1):
190 candidate = nodehex[:attempt]
190 candidate = nodehex[:attempt]
191 matches = int(
191 matches = int(
192 self._db.execute(
192 self._db.execute(
193 'SELECT COUNT(*) FROM changelog WHERE node LIKE ?',
193 'SELECT COUNT(*) FROM changelog WHERE node LIKE ?',
194 (pycompat.sysstr(candidate + b'%'),),
194 (pycompat.sysstr(candidate + b'%'),),
195 ).fetchone()[0]
195 ).fetchone()[0]
196 )
196 )
197 if matches == 1:
197 if matches == 1:
198 return candidate
198 return candidate
199 return nodehex
199 return nodehex
200
200
201 def headrevs(self, revs=None):
201 def headrevs(self, revs=None):
202 realheads = [
202 realheads = [
203 int(x[0])
203 int(x[0])
204 for x in self._db.execute(
204 for x in self._db.execute(
205 'SELECT rev FROM changelog '
205 'SELECT rev FROM changelog '
206 'INNER JOIN heads ON changelog.node = heads.node'
206 'INNER JOIN heads ON changelog.node = heads.node'
207 )
207 )
208 ]
208 ]
209 if revs:
209 if revs:
210 return sorted([r for r in revs if r in realheads])
210 return sorted([r for r in revs if r in realheads])
211 return sorted(realheads)
211 return sorted(realheads)
212
212
213 def changelogrevision(self, nodeorrev):
213 def changelogrevision(self, nodeorrev):
214 # Ensure we have a node id
214 # Ensure we have a node id
215 if isinstance(nodeorrev, int):
215 if isinstance(nodeorrev, int):
216 n = self.node(nodeorrev)
216 n = self.node(nodeorrev)
217 else:
217 else:
218 n = nodeorrev
218 n = nodeorrev
219 extra = {b'branch': b'default'}
219 extra = {b'branch': b'default'}
220 # handle looking up nullid
220 # handle looking up nullid
221 if n == sha1nodeconstants.nullid:
221 if n == sha1nodeconstants.nullid:
222 return hgchangelog._changelogrevision(
222 return hgchangelog._changelogrevision(
223 extra=extra, manifest=sha1nodeconstants.nullid
223 extra=extra, manifest=sha1nodeconstants.nullid
224 )
224 )
225 hn = gitutil.togitnode(n)
225 hn = gitutil.togitnode(n)
226 # We've got a real commit!
226 # We've got a real commit!
227 files = [
227 files = [
228 r[0]
228 r[0]
229 for r in self._db.execute(
229 for r in self._db.execute(
230 'SELECT filename FROM changedfiles '
230 'SELECT filename FROM changedfiles '
231 'WHERE node = ? and filenode != ?',
231 'WHERE node = ? and filenode != ?',
232 (hn, gitutil.nullgit),
232 (hn, gitutil.nullgit),
233 )
233 )
234 ]
234 ]
235 filesremoved = [
235 filesremoved = [
236 r[0]
236 r[0]
237 for r in self._db.execute(
237 for r in self._db.execute(
238 'SELECT filename FROM changedfiles '
238 'SELECT filename FROM changedfiles '
239 'WHERE node = ? and filenode = ?',
239 'WHERE node = ? and filenode = ?',
240 (hn, gitutil.nullgit),
240 (hn, gitutil.nullgit),
241 )
241 )
242 ]
242 ]
243 c = self.gitrepo[hn]
243 c = self.gitrepo[hn]
244 return hgchangelog._changelogrevision(
244 return hgchangelog._changelogrevision(
245 manifest=n, # pretend manifest the same as the commit node
245 manifest=n, # pretend manifest the same as the commit node
246 user=b'%s <%s>'
246 user=b'%s <%s>'
247 % (c.author.name.encode('utf8'), c.author.email.encode('utf8')),
247 % (c.author.name.encode('utf8'), c.author.email.encode('utf8')),
248 date=(c.author.time, -c.author.offset * 60),
248 date=(c.author.time, -c.author.offset * 60),
249 files=files,
249 files=files,
250 # TODO filesadded in the index
250 # TODO filesadded in the index
251 filesremoved=filesremoved,
251 filesremoved=filesremoved,
252 description=c.message.encode('utf8'),
252 description=c.message.encode('utf8'),
253 # TODO do we want to handle extra? how?
253 # TODO do we want to handle extra? how?
254 extra=extra,
254 extra=extra,
255 )
255 )
256
256
257 def ancestors(self, revs, stoprev=0, inclusive=False):
257 def ancestors(self, revs, stoprev=0, inclusive=False):
258 revs = list(revs)
258 revs = list(revs)
259 tip = self.rev(self.tip())
259 tip = self.rev(self.tip())
260 for r in revs:
260 for r in revs:
261 if r > tip:
261 if r > tip:
262 raise IndexError(b'Invalid rev %r' % r)
262 raise IndexError(b'Invalid rev %r' % r)
263 return ancestor.lazyancestors(
263 return ancestor.lazyancestors(
264 self.parentrevs, revs, stoprev=stoprev, inclusive=inclusive
264 self.parentrevs, revs, stoprev=stoprev, inclusive=inclusive
265 )
265 )
266
266
267 # Cleanup opportunity: this is *identical* to the revlog.py version
267 # Cleanup opportunity: this is *identical* to the revlog.py version
268 def descendants(self, revs):
268 def descendants(self, revs):
269 return dagop.descendantrevs(revs, self.revs, self.parentrevs)
269 return dagop.descendantrevs(revs, self.revs, self.parentrevs)
270
270
271 def incrementalmissingrevs(self, common=None):
271 def incrementalmissingrevs(self, common=None):
272 """Return an object that can be used to incrementally compute the
272 """Return an object that can be used to incrementally compute the
273 revision numbers of the ancestors of arbitrary sets that are not
273 revision numbers of the ancestors of arbitrary sets that are not
274 ancestors of common. This is an ancestor.incrementalmissingancestors
274 ancestors of common. This is an ancestor.incrementalmissingancestors
275 object.
275 object.
276
276
277 'common' is a list of revision numbers. If common is not supplied, uses
277 'common' is a list of revision numbers. If common is not supplied, uses
278 nullrev.
278 nullrev.
279 """
279 """
280 if common is None:
280 if common is None:
281 common = [nullrev]
281 common = [nullrev]
282
282
283 return ancestor.incrementalmissingancestors(self.parentrevs, common)
283 return ancestor.incrementalmissingancestors(self.parentrevs, common)
284
284
285 def findmissingrevs(self, common=None, heads=None):
286 """Return the revision numbers of the ancestors of heads that
287 are not ancestors of common.
288
289 More specifically, return a list of revision numbers corresponding to
290 nodes N such that every N satisfies the following constraints:
291
292 1. N is an ancestor of some node in 'heads'
293 2. N is not an ancestor of any node in 'common'
294
295 The list is sorted by revision number, meaning it is
296 topologically sorted.
297
298 'heads' and 'common' are both lists of revision numbers. If heads is
299 not supplied, uses all of the revlog's heads. If common is not
300 supplied, uses nullid."""
301 if common is None:
302 common = [nullrev]
303 if heads is None:
304 heads = self.headrevs()
305
306 inc = self.incrementalmissingrevs(common=common)
307 return inc.missingancestors(heads)
308
285 def findmissing(self, common=None, heads=None):
309 def findmissing(self, common=None, heads=None):
286 """Return the ancestors of heads that are not ancestors of common.
310 """Return the ancestors of heads that are not ancestors of common.
287
311
288 More specifically, return a list of nodes N such that every N
312 More specifically, return a list of nodes N such that every N
289 satisfies the following constraints:
313 satisfies the following constraints:
290
314
291 1. N is an ancestor of some node in 'heads'
315 1. N is an ancestor of some node in 'heads'
292 2. N is not an ancestor of any node in 'common'
316 2. N is not an ancestor of any node in 'common'
293
317
294 The list is sorted by revision number, meaning it is
318 The list is sorted by revision number, meaning it is
295 topologically sorted.
319 topologically sorted.
296
320
297 'heads' and 'common' are both lists of node IDs. If heads is
321 'heads' and 'common' are both lists of node IDs. If heads is
298 not supplied, uses all of the revlog's heads. If common is not
322 not supplied, uses all of the revlog's heads. If common is not
299 supplied, uses nullid."""
323 supplied, uses nullid."""
300 if common is None:
324 if common is None:
301 common = [sha1nodeconstants.nullid]
325 common = [sha1nodeconstants.nullid]
302 if heads is None:
326 if heads is None:
303 heads = self.heads()
327 heads = self.heads()
304
328
305 common = [self.rev(n) for n in common]
329 common = [self.rev(n) for n in common]
306 heads = [self.rev(n) for n in heads]
330 heads = [self.rev(n) for n in heads]
307
331
308 inc = self.incrementalmissingrevs(common=common)
332 inc = self.incrementalmissingrevs(common=common)
309 return [self.node(r) for r in inc.missingancestors(heads)]
333 return [self.node(r) for r in inc.missingancestors(heads)]
310
334
311 def children(self, node):
335 def children(self, node):
312 """find the children of a given node"""
336 """find the children of a given node"""
313 c = []
337 c = []
314 p = self.rev(node)
338 p = self.rev(node)
315 for r in self.revs(start=p + 1):
339 for r in self.revs(start=p + 1):
316 prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
340 prevs = [pr for pr in self.parentrevs(r) if pr != nullrev]
317 if prevs:
341 if prevs:
318 for pr in prevs:
342 for pr in prevs:
319 if pr == p:
343 if pr == p:
320 c.append(self.node(r))
344 c.append(self.node(r))
321 elif p == nullrev:
345 elif p == nullrev:
322 c.append(self.node(r))
346 c.append(self.node(r))
323 return c
347 return c
324
348
325 def reachableroots(self, minroot, heads, roots, includepath=False):
349 def reachableroots(self, minroot, heads, roots, includepath=False):
326 return dagop._reachablerootspure(
350 return dagop._reachablerootspure(
327 self.parentrevs, minroot, roots, heads, includepath
351 self.parentrevs, minroot, roots, heads, includepath
328 )
352 )
329
353
330 # Cleanup opportunity: this is *identical* to the revlog.py version
354 # Cleanup opportunity: this is *identical* to the revlog.py version
331 def isancestor(self, a, b):
355 def isancestor(self, a, b):
332 a, b = self.rev(a), self.rev(b)
356 a, b = self.rev(a), self.rev(b)
333 return self.isancestorrev(a, b)
357 return self.isancestorrev(a, b)
334
358
335 # Cleanup opportunity: this is *identical* to the revlog.py version
359 # Cleanup opportunity: this is *identical* to the revlog.py version
336 def isancestorrev(self, a, b):
360 def isancestorrev(self, a, b):
337 if a == nullrev:
361 if a == nullrev:
338 return True
362 return True
339 elif a == b:
363 elif a == b:
340 return True
364 return True
341 elif a > b:
365 elif a > b:
342 return False
366 return False
343 return bool(self.reachableroots(a, [b], [a], includepath=False))
367 return bool(self.reachableroots(a, [b], [a], includepath=False))
344
368
345 def parentrevs(self, rev):
369 def parentrevs(self, rev):
346 n = self.node(rev)
370 n = self.node(rev)
347 hn = gitutil.togitnode(n)
371 hn = gitutil.togitnode(n)
348 if hn != gitutil.nullgit:
372 if hn != gitutil.nullgit:
349 c = self.gitrepo[hn]
373 c = self.gitrepo[hn]
350 else:
374 else:
351 return nullrev, nullrev
375 return nullrev, nullrev
352 p1 = p2 = nullrev
376 p1 = p2 = nullrev
353 if c.parents:
377 if c.parents:
354 p1 = self.rev(c.parents[0].id.raw)
378 p1 = self.rev(c.parents[0].id.raw)
355 if len(c.parents) > 2:
379 if len(c.parents) > 2:
356 raise error.Abort(b'TODO octopus merge handling')
380 raise error.Abort(b'TODO octopus merge handling')
357 if len(c.parents) == 2:
381 if len(c.parents) == 2:
358 p2 = self.rev(c.parents[1].id.raw)
382 p2 = self.rev(c.parents[1].id.raw)
359 return p1, p2
383 return p1, p2
360
384
361 # Private method is used at least by the tags code.
385 # Private method is used at least by the tags code.
362 _uncheckedparentrevs = parentrevs
386 _uncheckedparentrevs = parentrevs
363
387
364 def commonancestorsheads(self, a, b):
388 def commonancestorsheads(self, a, b):
365 # TODO the revlog verson of this has a C path, so we probably
389 # TODO the revlog verson of this has a C path, so we probably
366 # need to optimize this...
390 # need to optimize this...
367 a, b = self.rev(a), self.rev(b)
391 a, b = self.rev(a), self.rev(b)
368 return [
392 return [
369 self.node(n)
393 self.node(n)
370 for n in ancestor.commonancestorsheads(self.parentrevs, a, b)
394 for n in ancestor.commonancestorsheads(self.parentrevs, a, b)
371 ]
395 ]
372
396
373 def branchinfo(self, rev):
397 def branchinfo(self, rev):
374 """Git doesn't do named branches, so just put everything on default."""
398 """Git doesn't do named branches, so just put everything on default."""
375 return b'default', False
399 return b'default', False
376
400
377 def delayupdate(self, tr):
401 def delayupdate(self, tr):
378 # TODO: I think we can elide this because we're just dropping
402 # TODO: I think we can elide this because we're just dropping
379 # an object in the git repo?
403 # an object in the git repo?
380 pass
404 pass
381
405
382 def add(
406 def add(
383 self,
407 self,
384 manifest,
408 manifest,
385 files,
409 files,
386 desc,
410 desc,
387 transaction,
411 transaction,
388 p1,
412 p1,
389 p2,
413 p2,
390 user,
414 user,
391 date=None,
415 date=None,
392 extra=None,
416 extra=None,
393 p1copies=None,
417 p1copies=None,
394 p2copies=None,
418 p2copies=None,
395 filesadded=None,
419 filesadded=None,
396 filesremoved=None,
420 filesremoved=None,
397 ):
421 ):
398 parents = []
422 parents = []
399 hp1, hp2 = gitutil.togitnode(p1), gitutil.togitnode(p2)
423 hp1, hp2 = gitutil.togitnode(p1), gitutil.togitnode(p2)
400 if p1 != sha1nodeconstants.nullid:
424 if p1 != sha1nodeconstants.nullid:
401 parents.append(hp1)
425 parents.append(hp1)
402 if p2 and p2 != sha1nodeconstants.nullid:
426 if p2 and p2 != sha1nodeconstants.nullid:
403 parents.append(hp2)
427 parents.append(hp2)
404 assert date is not None
428 assert date is not None
405 timestamp, tz = date
429 timestamp, tz = date
406 sig = pygit2.Signature(
430 sig = pygit2.Signature(
407 encoding.unifromlocal(stringutil.person(user)),
431 encoding.unifromlocal(stringutil.person(user)),
408 encoding.unifromlocal(stringutil.email(user)),
432 encoding.unifromlocal(stringutil.email(user)),
409 int(timestamp),
433 int(timestamp),
410 -int(tz // 60),
434 -int(tz // 60),
411 )
435 )
412 oid = self.gitrepo.create_commit(
436 oid = self.gitrepo.create_commit(
413 None, sig, sig, desc, gitutil.togitnode(manifest), parents
437 None, sig, sig, desc, gitutil.togitnode(manifest), parents
414 )
438 )
415 # Set up an internal reference to force the commit into the
439 # Set up an internal reference to force the commit into the
416 # changelog. Hypothetically, we could even use this refs/hg/
440 # changelog. Hypothetically, we could even use this refs/hg/
417 # namespace to allow for anonymous heads on git repos, which
441 # namespace to allow for anonymous heads on git repos, which
418 # would be neat.
442 # would be neat.
419 self.gitrepo.references.create(
443 self.gitrepo.references.create(
420 'refs/hg/internal/latest-commit', oid, force=True
444 'refs/hg/internal/latest-commit', oid, force=True
421 )
445 )
422 # Reindex now to pick up changes. We omit the progress
446 # Reindex now to pick up changes. We omit the progress
423 # and log callbacks because this will be very quick.
447 # and log callbacks because this will be very quick.
424 index._index_repo(self.gitrepo, self._db)
448 index._index_repo(self.gitrepo, self._db)
425 return oid.raw
449 return oid.raw
426
450
427
451
428 class manifestlog(baselog):
452 class manifestlog(baselog):
429 nodeconstants = sha1nodeconstants
453 nodeconstants = sha1nodeconstants
430
454
431 def __getitem__(self, node):
455 def __getitem__(self, node):
432 return self.get(b'', node)
456 return self.get(b'', node)
433
457
434 def get(self, relpath, node):
458 def get(self, relpath, node):
435 if node == sha1nodeconstants.nullid:
459 if node == sha1nodeconstants.nullid:
436 # TODO: this should almost certainly be a memgittreemanifestctx
460 # TODO: this should almost certainly be a memgittreemanifestctx
437 return manifest.memtreemanifestctx(self, relpath)
461 return manifest.memtreemanifestctx(self, relpath)
438 commit = self.gitrepo[gitutil.togitnode(node)]
462 commit = self.gitrepo[gitutil.togitnode(node)]
439 t = commit.tree
463 t = commit.tree
440 if relpath:
464 if relpath:
441 parts = relpath.split(b'/')
465 parts = relpath.split(b'/')
442 for p in parts:
466 for p in parts:
443 te = t[p]
467 te = t[p]
444 t = self.gitrepo[te.id]
468 t = self.gitrepo[te.id]
445 return gitmanifest.gittreemanifestctx(self.gitrepo, t)
469 return gitmanifest.gittreemanifestctx(self.gitrepo, t)
446
470
447
471
448 @interfaceutil.implementer(repository.ifilestorage)
472 @interfaceutil.implementer(repository.ifilestorage)
449 class filelog(baselog):
473 class filelog(baselog):
450 def __init__(self, gr, db, path):
474 def __init__(self, gr, db, path):
451 super(filelog, self).__init__(gr, db)
475 super(filelog, self).__init__(gr, db)
452 assert isinstance(path, bytes)
476 assert isinstance(path, bytes)
453 self.path = path
477 self.path = path
454 self.nullid = sha1nodeconstants.nullid
478 self.nullid = sha1nodeconstants.nullid
455
479
456 def read(self, node):
480 def read(self, node):
457 if node == sha1nodeconstants.nullid:
481 if node == sha1nodeconstants.nullid:
458 return b''
482 return b''
459 return self.gitrepo[gitutil.togitnode(node)].data
483 return self.gitrepo[gitutil.togitnode(node)].data
460
484
461 def lookup(self, node):
485 def lookup(self, node):
462 if len(node) not in (20, 40):
486 if len(node) not in (20, 40):
463 node = int(node)
487 node = int(node)
464 if isinstance(node, int):
488 if isinstance(node, int):
465 assert False, b'todo revnums for nodes'
489 assert False, b'todo revnums for nodes'
466 if len(node) == 40:
490 if len(node) == 40:
467 node = bin(node)
491 node = bin(node)
468 hnode = gitutil.togitnode(node)
492 hnode = gitutil.togitnode(node)
469 if hnode in self.gitrepo:
493 if hnode in self.gitrepo:
470 return node
494 return node
471 raise error.LookupError(self.path, node, _(b'no match found'))
495 raise error.LookupError(self.path, node, _(b'no match found'))
472
496
473 def cmp(self, node, text):
497 def cmp(self, node, text):
474 """Returns True if text is different than content at `node`."""
498 """Returns True if text is different than content at `node`."""
475 return self.read(node) != text
499 return self.read(node) != text
476
500
477 def add(self, text, meta, transaction, link, p1=None, p2=None):
501 def add(self, text, meta, transaction, link, p1=None, p2=None):
478 assert not meta # Should we even try to handle this?
502 assert not meta # Should we even try to handle this?
479 return self.gitrepo.create_blob(text).raw
503 return self.gitrepo.create_blob(text).raw
480
504
481 def __iter__(self):
505 def __iter__(self):
482 for clrev in self._db.execute(
506 for clrev in self._db.execute(
483 '''
507 '''
484 SELECT rev FROM changelog
508 SELECT rev FROM changelog
485 INNER JOIN changedfiles ON changelog.node = changedfiles.node
509 INNER JOIN changedfiles ON changelog.node = changedfiles.node
486 WHERE changedfiles.filename = ? AND changedfiles.filenode != ?
510 WHERE changedfiles.filename = ? AND changedfiles.filenode != ?
487 ''',
511 ''',
488 (pycompat.fsdecode(self.path), gitutil.nullgit),
512 (pycompat.fsdecode(self.path), gitutil.nullgit),
489 ):
513 ):
490 yield clrev[0]
514 yield clrev[0]
491
515
492 def linkrev(self, fr):
516 def linkrev(self, fr):
493 return fr
517 return fr
494
518
495 def rev(self, node):
519 def rev(self, node):
496 row = self._db.execute(
520 row = self._db.execute(
497 '''
521 '''
498 SELECT rev FROM changelog
522 SELECT rev FROM changelog
499 INNER JOIN changedfiles ON changelog.node = changedfiles.node
523 INNER JOIN changedfiles ON changelog.node = changedfiles.node
500 WHERE changedfiles.filename = ? AND changedfiles.filenode = ?''',
524 WHERE changedfiles.filename = ? AND changedfiles.filenode = ?''',
501 (pycompat.fsdecode(self.path), gitutil.togitnode(node)),
525 (pycompat.fsdecode(self.path), gitutil.togitnode(node)),
502 ).fetchone()
526 ).fetchone()
503 if row is None:
527 if row is None:
504 raise error.LookupError(self.path, node, _(b'no such node'))
528 raise error.LookupError(self.path, node, _(b'no such node'))
505 return int(row[0])
529 return int(row[0])
506
530
507 def node(self, rev):
531 def node(self, rev):
508 maybe = self._db.execute(
532 maybe = self._db.execute(
509 '''SELECT filenode FROM changedfiles
533 '''SELECT filenode FROM changedfiles
510 INNER JOIN changelog ON changelog.node = changedfiles.node
534 INNER JOIN changelog ON changelog.node = changedfiles.node
511 WHERE changelog.rev = ? AND filename = ?
535 WHERE changelog.rev = ? AND filename = ?
512 ''',
536 ''',
513 (rev, pycompat.fsdecode(self.path)),
537 (rev, pycompat.fsdecode(self.path)),
514 ).fetchone()
538 ).fetchone()
515 if maybe is None:
539 if maybe is None:
516 raise IndexError('gitlog %r out of range %d' % (self.path, rev))
540 raise IndexError('gitlog %r out of range %d' % (self.path, rev))
517 return bin(maybe[0])
541 return bin(maybe[0])
518
542
519 def parents(self, node):
543 def parents(self, node):
520 gn = gitutil.togitnode(node)
544 gn = gitutil.togitnode(node)
521 gp = pycompat.fsdecode(self.path)
545 gp = pycompat.fsdecode(self.path)
522 ps = []
546 ps = []
523 for p in self._db.execute(
547 for p in self._db.execute(
524 '''SELECT p1filenode, p2filenode FROM changedfiles
548 '''SELECT p1filenode, p2filenode FROM changedfiles
525 WHERE filenode = ? AND filename = ?
549 WHERE filenode = ? AND filename = ?
526 ''',
550 ''',
527 (gn, gp),
551 (gn, gp),
528 ).fetchone():
552 ).fetchone():
529 if p is None:
553 if p is None:
530 commit = self._db.execute(
554 commit = self._db.execute(
531 "SELECT node FROM changedfiles "
555 "SELECT node FROM changedfiles "
532 "WHERE filenode = ? AND filename = ?",
556 "WHERE filenode = ? AND filename = ?",
533 (gn, gp),
557 (gn, gp),
534 ).fetchone()[0]
558 ).fetchone()[0]
535 # This filelog is missing some data. Build the
559 # This filelog is missing some data. Build the
536 # filelog, then recurse (which will always find data).
560 # filelog, then recurse (which will always find data).
537 commit = commit.decode('ascii')
561 commit = commit.decode('ascii')
538 index.fill_in_filelog(self.gitrepo, self._db, commit, gp, gn)
562 index.fill_in_filelog(self.gitrepo, self._db, commit, gp, gn)
539 return self.parents(node)
563 return self.parents(node)
540 else:
564 else:
541 ps.append(bin(p))
565 ps.append(bin(p))
542 return ps
566 return ps
543
567
544 def renamed(self, node):
568 def renamed(self, node):
545 # TODO: renames/copies
569 # TODO: renames/copies
546 return False
570 return False
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now