mirror of
https://github.com/microsoft/debugpy.git
synced 2025-12-23 08:48:12 +00:00
Compare commits
516 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
698499e9ec | ||
|
|
e5017d7360 | ||
|
|
1e3fd91306 | ||
|
|
378339a3a8 | ||
|
|
93d93f2d6c | ||
|
|
8f13145a23 | ||
|
|
275caca690 | ||
|
|
82e409e883 | ||
|
|
6cbdf8767e | ||
|
|
2eb3afede0 | ||
|
|
b00a812997 | ||
|
|
1aff9aa541 | ||
|
|
ead90f6f71 | ||
|
|
2b1e361eac | ||
|
|
ea1dd9a838 | ||
|
|
b387710b7f | ||
|
|
0d65353cc6 | ||
|
|
99b202ee21 | ||
|
|
34d5de99a0 | ||
|
|
4bc7343c05 | ||
|
|
8b5b84aec3 | ||
|
|
644349da3e | ||
|
|
2d220f8db8 | ||
|
|
f7d8963f99 | ||
|
|
e01e6dd8a9 | ||
|
|
24001704d8 | ||
|
|
f054965148 | ||
|
|
96de4376a5 | ||
|
|
ed9f2949f6 | ||
|
|
fb0b06cab1 | ||
|
|
4c226dd7e9 | ||
|
|
40a471e24a | ||
|
|
d266361676 | ||
|
|
02723de140 | ||
|
|
7597262c80 | ||
|
|
cc85ca8e01 | ||
|
|
24aa6a5f8e | ||
|
|
34cc53b2ac | ||
|
|
a99d933411 | ||
|
|
5014f2538a | ||
|
|
43f41029ea | ||
|
|
a78e5c28cd | ||
|
|
3823aba95e | ||
|
|
f4ba976121 | ||
|
|
73be8fb5df | ||
|
|
3573ca0e2b | ||
|
|
7d0ff33340 | ||
|
|
af0d29f6bc | ||
|
|
cebb7475a3 | ||
|
|
2036f44606 | ||
|
|
22fbc53ee3 | ||
|
|
37eaf86e1a | ||
|
|
db63cd5bd1 | ||
|
|
abf4bb651a | ||
|
|
1eb92e64b1 | ||
|
|
8f2aed19da | ||
|
|
740fa9dd5a | ||
|
|
6a7f7c0f2d | ||
|
|
b028e5c039 | ||
|
|
064a78f9cb | ||
|
|
a7d5a7ec12 | ||
|
|
8ab4ee89e9 | ||
|
|
e3c68e9ea9 | ||
|
|
462d99aa8d | ||
|
|
d07f941e12 | ||
|
|
281d5057cc | ||
|
|
4d86a42380 | ||
|
|
23c5eb71ae | ||
|
|
00e6434e80 | ||
|
|
39879bdeea | ||
|
|
0116f9f65e | ||
|
|
178a0f4158 | ||
|
|
f7d5df027c | ||
|
|
25955a05d8 | ||
|
|
ae6812bdac | ||
|
|
a2f80817a1 | ||
|
|
fb6158a059 | ||
|
|
ddcb19353d | ||
|
|
a68a804f7a | ||
|
|
ae01f967e6 | ||
|
|
dc58df149f | ||
|
|
7b3dfb808d | ||
|
|
aaab993245 | ||
|
|
1245e8e062 | ||
|
|
bcab469038 | ||
|
|
820d21e384 | ||
|
|
7abb9cc537 | ||
|
|
0274b12d5c | ||
|
|
6e7248f172 | ||
|
|
853cc05f50 | ||
|
|
afaee41ca9 | ||
|
|
bf4ce2b832 | ||
|
|
e3bf7a9665 | ||
|
|
c5259c7e3f | ||
|
|
05709cfa10 | ||
|
|
ac37980f6f | ||
|
|
da6a6482f1 | ||
|
|
382bc69a2b | ||
|
|
e0f2a8be98 | ||
|
|
5b9bfaf3a8 | ||
|
|
a0a6cfbf1f | ||
|
|
c77190f892 | ||
|
|
1a9736bbe9 | ||
|
|
f31df56792 | ||
|
|
fb14d133d3 | ||
|
|
4ba9da6087 | ||
|
|
6e8e5becb2 | ||
|
|
e58f228e92 | ||
|
|
ed9a632925 | ||
|
|
ff88ce330e | ||
|
|
df254f6aab | ||
|
|
16a4b9c0a6 | ||
|
|
96e9f1e909 | ||
|
|
1d7c662a56 | ||
|
|
cfe3fef401 | ||
|
|
a286befecd | ||
|
|
c2fcaf7e89 | ||
|
|
09b5af0bb7 | ||
|
|
48855b0640 | ||
|
|
09ba39c531 | ||
|
|
b6ce45e52d | ||
|
|
5cef52cbd9 | ||
|
|
85c26ece15 | ||
|
|
5a81ad6b22 | ||
|
|
d9ae0af1a1 | ||
|
|
2ee8168db3 | ||
|
|
1bebec6a62 | ||
|
|
e5988e47b4 | ||
|
|
0035e83a40 | ||
|
|
42853a99c4 | ||
|
|
b9b09e662f | ||
|
|
e9a39f7ca5 | ||
|
|
2888f7299c | ||
|
|
e62da42e43 | ||
|
|
46a02e10a2 | ||
|
|
79882c1861 | ||
|
|
ef9a67fe15 | ||
|
|
7d09fb24dd | ||
|
|
131afb5a07 | ||
|
|
9cc65eb123 | ||
|
|
98032d8d7f | ||
|
|
4a03787784 | ||
|
|
cbd0c2a1c1 | ||
|
|
5723ed6b1a | ||
|
|
9e8d1033d0 | ||
|
|
3937f0d10a | ||
|
|
6ce72e20c8 | ||
|
|
912bc4fe48 | ||
|
|
9df4bbdbfe | ||
|
|
9df16cec07 | ||
|
|
8e91dfb085 | ||
|
|
16d39cc173 | ||
|
|
6340818a0e | ||
|
|
2fcb85fdfa | ||
|
|
ea3904ccb6 | ||
|
|
9997094101 | ||
|
|
ffec1b2db7 | ||
|
|
7b985fd36b | ||
|
|
70dba8e137 | ||
|
|
86d542e559 | ||
|
|
88bf2c7827 | ||
|
|
119ca8e589 | ||
|
|
1a18cdc5b8 | ||
|
|
85ceaf7d99 | ||
|
|
cd51305592 | ||
|
|
2d6a224471 | ||
|
|
f9372813f3 | ||
|
|
6e08ce2050 | ||
|
|
39ad5f47c5 | ||
|
|
2f48fc6479 | ||
|
|
83baa6d302 | ||
|
|
db3452db32 | ||
|
|
10aa6ffc6e | ||
|
|
12117683e7 | ||
|
|
1569cc8319 | ||
|
|
d642538d7b | ||
|
|
d55e351030 | ||
|
|
829957d3e1 | ||
|
|
8df8d343f3 | ||
|
|
d75b1f4ec1 | ||
|
|
014cdac951 | ||
|
|
86a0ede4c1 | ||
|
|
894fd5e4f4 | ||
|
|
6bb82234e2 | ||
|
|
f22e1851ef | ||
|
|
3bd802ea2a | ||
|
|
ba9e417a14 | ||
|
|
d73cf2226d | ||
|
|
3bd064e04d | ||
|
|
6735fcb073 | ||
|
|
5a37633830 | ||
|
|
dbcc9486e4 | ||
|
|
4821077d5b | ||
|
|
9695688b80 | ||
|
|
9442a22e6c | ||
|
|
da14ef2347 | ||
|
|
267678832a | ||
|
|
e30c40fbca | ||
|
|
2f3e0bb7d5 | ||
|
|
00bc5136e4 | ||
|
|
bc44eb85ff | ||
|
|
c3068fd6f6 | ||
|
|
35504f83ed | ||
|
|
34f7238e63 | ||
|
|
de6a9cf6d6 | ||
|
|
5601342de8 | ||
|
|
e9dc3e8844 | ||
|
|
9fd3e72235 | ||
|
|
6c3dca7918 | ||
|
|
c419d5a7fd | ||
|
|
66f85dce2d | ||
|
|
ed59c6d090 | ||
|
|
633597b1b5 | ||
|
|
19ea6f2625 | ||
|
|
158cbf663c | ||
|
|
69eaa61be0 | ||
|
|
bcf5281f29 | ||
|
|
1c79248ca6 | ||
|
|
bf5c644bc3 | ||
|
|
79b7c5634e | ||
|
|
9e94581915 | ||
|
|
86e0a3f47a | ||
|
|
bc9c596599 | ||
|
|
53cda4e36d | ||
|
|
45af79671f | ||
|
|
4067700ed8 | ||
|
|
727d0d0608 | ||
|
|
04403ddc1c | ||
|
|
6c1c3d6cb1 | ||
|
|
a2a3328388 | ||
|
|
5f75955915 | ||
|
|
ae189da2a8 | ||
|
|
ac6465760a | ||
|
|
fc645045f0 | ||
|
|
e7fb50add3 | ||
|
|
1d038201b3 | ||
|
|
46efd10d4a | ||
|
|
646d921dc1 | ||
|
|
7c8172e99c | ||
|
|
94ad68968a | ||
|
|
93f969720a | ||
|
|
fb40a0b002 | ||
|
|
ac6f5ea6c9 | ||
|
|
30a96bf6e8 | ||
|
|
01b1c7b238 | ||
|
|
9600483a05 | ||
|
|
349ff7337b | ||
|
|
c300080c62 | ||
|
|
761bacebb5 | ||
|
|
1dc82718d1 | ||
|
|
8d418fb3df | ||
|
|
1d7443e960 | ||
|
|
849e15c6a4 | ||
|
|
c2b3d5efe2 | ||
|
|
a08da17302 | ||
|
|
8157273a28 | ||
|
|
61321253e7 | ||
|
|
3272dace18 | ||
|
|
ea423ae598 | ||
|
|
e31df92e14 | ||
|
|
8b5eeee7e0 | ||
|
|
71d42ed63f | ||
|
|
6e247fb17b | ||
|
|
cccfb954bd | ||
|
|
6c19aba462 | ||
|
|
10d8839a4c | ||
|
|
83ff28006d | ||
|
|
4f6638b0a6 | ||
|
|
6b276e339c | ||
|
|
a294092d9c | ||
|
|
db43846a8d | ||
|
|
b31dee3e79 | ||
|
|
d117b091c5 | ||
|
|
b5072f33af | ||
|
|
5da7721d4d | ||
|
|
3f325f58dc | ||
|
|
4f2a4568f0 | ||
|
|
161aa2683f | ||
|
|
7676e298b5 | ||
|
|
627bc1d647 | ||
|
|
0a9b01b008 | ||
|
|
6d049b73ab | ||
|
|
e94b71925a | ||
|
|
b46500c5dc | ||
|
|
f214dbb8b4 | ||
|
|
d2aa99f56d | ||
|
|
ccce63e112 | ||
|
|
b0b8db12a5 | ||
|
|
eb126910c0 | ||
|
|
891bc7f88b | ||
|
|
3e90c5a903 | ||
|
|
78b030f509 | ||
|
|
0a40cabe6f | ||
|
|
57836de416 | ||
|
|
644c658e75 | ||
|
|
a9a170bd63 | ||
|
|
a9ea29ca22 | ||
|
|
7597e466c4 | ||
|
|
50632736bf | ||
|
|
eb8095cbe6 | ||
|
|
729c02f866 | ||
|
|
7623694856 | ||
|
|
eaadb6c681 | ||
|
|
3d7499958c | ||
|
|
e615771b24 | ||
|
|
6174f4c4bd | ||
|
|
7be59933b1 | ||
|
|
de58062f83 | ||
|
|
87facf1378 | ||
|
|
d1e5db7d8e | ||
|
|
dd5196fbfc | ||
|
|
cb25e2f106 | ||
|
|
3a1ecbac86 | ||
|
|
a6d63ce760 | ||
|
|
0f428178b0 | ||
|
|
1965b47034 | ||
|
|
98087352cb | ||
|
|
e87017e0b3 | ||
|
|
266a19809a | ||
|
|
87ef7307a4 | ||
|
|
f3d9eb7853 | ||
|
|
7f3ee2b120 | ||
|
|
7f25cb22b8 | ||
|
|
1b568ab86a | ||
|
|
2ac9538dd5 | ||
|
|
da25139b47 | ||
|
|
1a6c323599 | ||
|
|
fb56410a65 | ||
|
|
5e80ce1f77 | ||
|
|
094a8fd9c8 | ||
|
|
4d25af30cd | ||
|
|
dc734a817f | ||
|
|
dcca59687c | ||
|
|
9d5969a7b6 | ||
|
|
8ffb895dba | ||
|
|
fed292a89a | ||
|
|
02ebfabe97 | ||
|
|
e52a2ce2d6 | ||
|
|
f2af67be7d | ||
|
|
48a495c4df | ||
|
|
b8f1f5c5ed | ||
|
|
46403a6744 | ||
|
|
75e8f31d11 | ||
|
|
328d4026b1 | ||
|
|
eb7b7bb2ea | ||
|
|
090e3c3ef5 | ||
|
|
450fe8b201 | ||
|
|
356f665325 | ||
|
|
c5edec7708 | ||
|
|
796f63e3bc | ||
|
|
6134532263 | ||
|
|
1b8d5ab0be | ||
|
|
420a206385 | ||
|
|
4f12b1b47f | ||
|
|
ecb43b94d2 | ||
|
|
f2219b88a9 | ||
|
|
0105bd92ce | ||
|
|
36c7fc9eaf | ||
|
|
be8dd607f6 | ||
|
|
83b18ef703 | ||
|
|
b1ad4d66f1 | ||
|
|
a07f6e8d83 | ||
|
|
baf6121065 | ||
|
|
cf0d684566 | ||
|
|
043b11fd12 | ||
|
|
fba80681ad | ||
|
|
78bbf8be83 | ||
|
|
2a8758d18f | ||
|
|
30c150af91 | ||
|
|
f139ed7a67 | ||
|
|
f4c8e487fb | ||
|
|
fc67ea9e7d | ||
|
|
eb53282508 | ||
|
|
e25fc1dcca | ||
|
|
655e35642c | ||
|
|
ddb083cc25 | ||
|
|
ac360f4857 | ||
|
|
ef8e81bae0 | ||
|
|
f1ea183e25 | ||
|
|
3edb9f022f | ||
|
|
3e429288c8 | ||
|
|
9ad731d3be | ||
|
|
2bd30aba7c | ||
|
|
765b64c0a4 | ||
|
|
f14ba78c5c | ||
|
|
0a3fa3f94d | ||
|
|
02f3792636 | ||
|
|
869babbd93 | ||
|
|
9d8bb3fa3c | ||
|
|
5dc21d67b3 | ||
|
|
7cb12bed8b | ||
|
|
fdd1f4dc38 | ||
|
|
3ecfee9ffd | ||
|
|
59b9db9420 | ||
|
|
77b0a59bed | ||
|
|
68d82b02b2 | ||
|
|
514e54fa2b | ||
|
|
d9ca878cd2 | ||
|
|
2a2c371d98 | ||
|
|
3207466fc3 | ||
|
|
e59195d6a4 | ||
|
|
3a9f7d64c4 | ||
|
|
0e5b8f7a7c | ||
|
|
7a9b7baef7 | ||
|
|
202a5efbf2 | ||
|
|
8aa184e004 | ||
|
|
ae22e5e0d0 | ||
|
|
b826f57dbb | ||
|
|
75e5058b33 | ||
|
|
d7970b80ad | ||
|
|
623c503b58 | ||
|
|
58f97a9f15 | ||
|
|
0b242b21b7 | ||
|
|
eef3b4ef2b | ||
|
|
02477b5ac3 | ||
|
|
8d90ef2a45 | ||
|
|
b53ebf712e | ||
|
|
11b71244c8 | ||
|
|
e3f6f3ad4f | ||
|
|
b07f372d39 | ||
|
|
6403f1e369 | ||
|
|
ab4b9691b7 | ||
|
|
cbed5de015 | ||
|
|
0a7f2cd67d | ||
|
|
983d14f9fd | ||
|
|
edd84da7fa | ||
|
|
a5ced50c13 | ||
|
|
ddffe8cc00 | ||
|
|
e8b3f362fb | ||
|
|
6921731af6 | ||
|
|
35203011c9 | ||
|
|
e85fdf8ab4 | ||
|
|
c7bb276090 | ||
|
|
8ec0a316e6 | ||
|
|
5c35f28473 | ||
|
|
2ae7dc96ec | ||
|
|
511890562a | ||
|
|
d2a735c828 | ||
|
|
e9834c26ad | ||
|
|
0dd74a7257 | ||
|
|
2ebc4e71b5 | ||
|
|
cdc975c4fb | ||
|
|
9ab891b328 | ||
|
|
6ee41420e6 | ||
|
|
ed8cc0b724 | ||
|
|
4b32a3ccdd | ||
|
|
cbcfe221d7 | ||
|
|
c265d74bc5 | ||
|
|
44a07d030e | ||
|
|
aa36155221 | ||
|
|
59ee2edc49 | ||
|
|
218248080e | ||
|
|
f118b101eb | ||
|
|
6116bc1582 | ||
|
|
2191ce56b2 | ||
|
|
58ef3da9aa | ||
|
|
a7282e9232 | ||
|
|
e573ea771a | ||
|
|
93516395a9 | ||
|
|
f9b54cdcd9 | ||
|
|
2341614e14 | ||
|
|
9e2c8106bd | ||
|
|
ac05dab62b | ||
|
|
609af83703 | ||
|
|
d0bb24a8ab | ||
|
|
7d2a7a2b11 | ||
|
|
c6dc935fd8 | ||
|
|
75bb3a751d | ||
|
|
7aa6f4c83a | ||
|
|
70d4f5bcb7 | ||
|
|
b613ec84a0 | ||
|
|
97b1a61c91 | ||
|
|
ad09acb2c9 | ||
|
|
7485e76385 | ||
|
|
75944e5968 | ||
|
|
18bd28165b | ||
|
|
34e1e405a7 | ||
|
|
5384d23743 | ||
|
|
1727a3e109 | ||
|
|
1de5526317 | ||
|
|
fb7926fd80 | ||
|
|
9cda8e0515 | ||
|
|
74c4915099 | ||
|
|
49919cd40e | ||
|
|
3d472df2d6 | ||
|
|
d68a17170c | ||
|
|
6e1c7567d2 | ||
|
|
cf65911a7a | ||
|
|
18c0c282ff | ||
|
|
8368d89e91 | ||
|
|
71432a2c2d | ||
|
|
a7666a2ba4 | ||
|
|
e0c2d14f09 | ||
|
|
b6ebb18313 | ||
|
|
5f08b324e8 | ||
|
|
97d9d39c64 | ||
|
|
57d3eadc8a | ||
|
|
7859f5c4b2 | ||
|
|
562afbcde0 | ||
|
|
b81ca97d96 | ||
|
|
d3cb68f21a | ||
|
|
b8f45cec71 | ||
|
|
c071686879 | ||
|
|
78bd26571e | ||
|
|
e4d9baf1fa | ||
|
|
c595b6f07c | ||
|
|
793097ff40 | ||
|
|
74ea719786 | ||
|
|
c0243ca32e | ||
|
|
14ca4f07d1 | ||
|
|
1a93e56734 | ||
|
|
d69beaf987 | ||
|
|
7512ab01d6 | ||
|
|
6200c1db4f | ||
|
|
677fef79d1 | ||
|
|
44b01c8165 |
910 changed files with 181498 additions and 85193 deletions
4
.CodeQL.yml
Normal file
4
.CodeQL.yml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
path_classifiers:
|
||||
library:
|
||||
- "src/debugpy/_vendored/pydevd"
|
||||
|
||||
11
.coveragerc
11
.coveragerc
|
|
@ -11,16 +11,19 @@ omit =
|
|||
data_file = coverage/.coverage
|
||||
|
||||
[report]
|
||||
exclude_lines =
|
||||
# Have to re-enable the standard pragma.
|
||||
pragma: no cover
|
||||
|
||||
exclude_also =
|
||||
# __repr__ is mostly used for error messages.
|
||||
def __repr__
|
||||
|
||||
# Asserts and error conditions.
|
||||
raise AssertionError
|
||||
raise NotImplementedError
|
||||
raise TypeError
|
||||
raise ValueError
|
||||
raise AttributeError
|
||||
raise RuntimeError
|
||||
raise ComponentNotAvailable
|
||||
raise messaging.MessageHandlingError
|
||||
\.isnt_valid\(
|
||||
\.cant_handle\(
|
||||
|
||||
|
|
|
|||
1
.flake8
1
.flake8
|
|
@ -11,3 +11,4 @@ exclude =
|
|||
dist,
|
||||
versioneer.py,
|
||||
src/debugpy/_vendored/pydevd
|
||||
|
||||
|
|
|
|||
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1 +1 @@
|
|||
debugpy/_version.py export-subst
|
||||
src/debugpy/_version.py export-subst
|
||||
|
|
|
|||
5
.github/CODEOWNERS
vendored
5
.github/CODEOWNERS
vendored
|
|
@ -4,7 +4,4 @@
|
|||
# in the repository, i.e. bar/baz will match /bar/baz and /foo/bar/baz.
|
||||
|
||||
# The default owners for everything that is not overridden by specific patterns below.
|
||||
* @int19h @karthiknadig
|
||||
|
||||
# Order is important: the last matching pattern overrides all the preceding ones.
|
||||
/src/ptvsd/_vendored/pydevd/ @fabioz
|
||||
* @microsoft/pyrx-admins
|
||||
|
|
|
|||
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
|
|
@ -4,6 +4,8 @@ about: Create a report to help us improve
|
|||
|
||||
---
|
||||
|
||||
Before creating a new issue, please check the [FAQ](https://github.com/microsoft/debugpy/wiki/FAQ) to see if your question is answered there.
|
||||
|
||||
## Environment data
|
||||
|
||||
- debugpy version: XXX (run `import debugpy; print(debugpy.__version__)` if uncertain)
|
||||
|
|
|
|||
39
.github/workflows/auto-label.yml
vendored
Normal file
39
.github/workflows/auto-label.yml
vendored
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
name: Auto-label when user responds
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
env:
|
||||
TRIAGERS: '["int19h","karthiknadig","ericsnowcurrently","fabioz", "gramster", "StellaHuang95", "AdamYoblick"]'
|
||||
|
||||
jobs:
|
||||
run-check:
|
||||
runs-on: ubuntu-latest
|
||||
if: contains(github.event.issue.labels.*.name, 'waiting for response') && !contains(github.event.issue.labels.*.name, 'user responded')
|
||||
steps:
|
||||
- name: Add/Remove labels when user responds
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
const payload = context.payload;
|
||||
const commentAuthor = payload.comment.user.login;
|
||||
const isTeamMember = ${{ env.TRIAGERS }}.includes(commentAuthor);
|
||||
if (!isTeamMember) {
|
||||
const issue_number = payload.issue.number;
|
||||
await github.rest.issues.removeLabel({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue_number,
|
||||
name: 'waiting for response'
|
||||
});
|
||||
await github.rest.issues.addLabels({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
issue_number: issue_number,
|
||||
labels: ['user responded']
|
||||
});
|
||||
}
|
||||
53
.github/workflows/codeql.yml
vendored
53
.github/workflows/codeql.yml
vendored
|
|
@ -4,49 +4,30 @@ on:
|
|||
push:
|
||||
pull_request:
|
||||
schedule:
|
||||
- cron: '0 19 * * 0'
|
||||
- cron: "0 19 * * 0"
|
||||
|
||||
permissions:
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
CodeQL-Build:
|
||||
|
||||
# CodeQL runs on ubuntu-latest and windows-latest
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
# a pull request then we can checkout the head.
|
||||
fetch-depth: 2
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# If this run was triggered by a pull request event, then checkout
|
||||
# the head of the pull request instead of the merge commit.
|
||||
- run: git checkout HEAD^2
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v1
|
||||
# Override language selection by uncommenting this and choosing your languages
|
||||
# with:
|
||||
# languages: go, javascript, csharp, python, cpp, java
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
languages: python
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v1
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ℹ️ Command-line programs to run using the OS shell.
|
||||
# 📚 https://git.io/JvXDl
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
|
||||
# and modify them (or add more) to build your code if your project
|
||||
# uses a compiled language
|
||||
|
||||
#- run: |
|
||||
# make bootstrap
|
||||
# make release
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v1
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
|
|
|
|||
79
.github/workflows/round-robin.yml
vendored
Normal file
79
.github/workflows/round-robin.yml
vendored
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
name: round-robin
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
assignIssue:
|
||||
name: Assign Issue to Someone
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'microsoft/debugpy' && github.event.action == 'opened' && !contains( github.event.issue.labels.*.name, 'skip-reassign')
|
||||
steps:
|
||||
- name: Find last assigned
|
||||
id: assigned
|
||||
uses: actions/github-script@v6.3.3
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
result-encoding: string
|
||||
script: |
|
||||
const issue = await github.rest.issues.get({
|
||||
issue_number: 1649,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo
|
||||
});
|
||||
return (issue.data.assignees && issue.data.assignees[0].login) || '';
|
||||
- name: Dump last assigned
|
||||
env:
|
||||
LAST_ASSIGNED: ${{ steps.assigned.outputs.result }}
|
||||
run: echo "$LAST_ASSIGNED"
|
||||
- uses: lee-dohm/team-rotation@v1
|
||||
with:
|
||||
last: ${{ steps.assigned.outputs.result }}
|
||||
include: bschnurr heejaechang StellaHuang95 rchiodo gramster
|
||||
id: rotation
|
||||
- name: Dump next in rotation
|
||||
env:
|
||||
NEXT_ROTATION: ${{ steps.rotation.outputs.next }}
|
||||
run: echo "$NEXT_ROTATION"
|
||||
- name: Assign to next person
|
||||
uses: actions/github-script@v6.3.3
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
github.rest.issues.addAssignees({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
assignees: ['${{ steps.rotation.outputs.next }}']
|
||||
})
|
||||
- name: Give it the label 'needs repro'
|
||||
uses: actions/github-script@v6.3.3
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['needs repro']
|
||||
})
|
||||
- name: Save assignment to state
|
||||
uses: actions/github-script@v6.3.3
|
||||
with:
|
||||
github-token: ${{secrets.GITHUB_TOKEN}}
|
||||
script: |
|
||||
await github.rest.issues.removeAssignees({
|
||||
issue_number: 1649,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
assignees: ['${{ steps.assigned.outputs.result }}']
|
||||
});
|
||||
github.rest.issues.addAssignees({
|
||||
issue_number: 1649,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
assignees: ['${{ steps.rotation.outputs.next }}']
|
||||
})
|
||||
34
.github/workflows/stale.yml
vendored
Normal file
34
.github/workflows/stale.yml
vendored
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# This workflow closes issues that have been labeled as 'waiting for response' and had no activity for 30 days.
|
||||
#
|
||||
# You can adjust the behavior by modifying this file.
|
||||
# For more information, see:
|
||||
# https://github.com/actions/stale
|
||||
name: Close stale 'waiting for response' issues
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# ┌───────────── minute (0 - 59)
|
||||
# │ ┌───────────── hour (0 - 23)
|
||||
# │ │ ┌───────────── day of the month (1 - 31)
|
||||
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC)
|
||||
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT)
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# │ │ │ │ │
|
||||
# * * * * *
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
issues: write
|
||||
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-issue-stale: 30
|
||||
days-before-issue-close: 0
|
||||
close-issue-message: "This issue was closed because it has been stalled for 30 days with no activity. If the issue still persists, please reopen with the information requested. Thanks."
|
||||
any-of-labels: "waiting for response"
|
||||
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -5,11 +5,14 @@ __pycache__/
|
|||
|
||||
# C extensions
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
*.pdb
|
||||
*.exe
|
||||
|
||||
# Distribution / packaging
|
||||
.Python
|
||||
env/
|
||||
build/
|
||||
develop-eggs/
|
||||
dist/
|
||||
downloads/
|
||||
|
|
@ -22,7 +25,9 @@ pip-wheel-metadata/
|
|||
sdist/
|
||||
var/
|
||||
wheels/
|
||||
wheelhouse/
|
||||
*.egg-info/
|
||||
*.dist-info/
|
||||
.installed.cfg
|
||||
*.egg
|
||||
|
||||
|
|
@ -84,7 +89,7 @@ celerybeat-schedule
|
|||
*.sage.py
|
||||
|
||||
# virtualenv
|
||||
.venv
|
||||
.venv*
|
||||
venv/
|
||||
ENV/
|
||||
|
||||
|
|
@ -105,6 +110,7 @@ ENV/
|
|||
.vs/
|
||||
.vscode/*
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
# PyDev
|
||||
.project
|
||||
|
|
|
|||
37
.travis.yml
37
.travis.yml
|
|
@ -1,37 +0,0 @@
|
|||
language: python
|
||||
dist: xenial
|
||||
sudo: required
|
||||
cache: pip
|
||||
python:
|
||||
- "2.7"
|
||||
- "3.8"
|
||||
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- gdb
|
||||
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: lint
|
||||
python: "3.8"
|
||||
install:
|
||||
- pip install -U pip setuptools flake8
|
||||
script:
|
||||
- flake8
|
||||
|
||||
before_install:
|
||||
- sudo sysctl kernel.yama.ptrace_scope=0
|
||||
|
||||
install:
|
||||
- pip install -U pip setuptools tox tox-travis
|
||||
|
||||
script:
|
||||
- tox -- -n4 -v
|
||||
|
||||
env:
|
||||
- TOX_SKIP_ENV=.*-cov
|
||||
8
.vscode/extensions.json
vendored
Normal file
8
.vscode/extensions.json
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"ms-python.flake8",
|
||||
"ms-python.black-formatter"
|
||||
]
|
||||
}
|
||||
29
.vscode/launch.json
vendored
29
.vscode/launch.json
vendored
|
|
@ -11,7 +11,7 @@
|
|||
"console": "integratedTerminal",
|
||||
"program": "${file}",
|
||||
"logToFile": true,
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
},
|
||||
{
|
||||
"name": "Launch: module",
|
||||
|
|
@ -21,19 +21,16 @@
|
|||
"module": "${fileBasenameNoExtension}",
|
||||
"cwd": "${fileDirname}",
|
||||
"logToFile": true,
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
},
|
||||
{
|
||||
"name": "Launch: code",
|
||||
"type": "python",
|
||||
"request": "launch",
|
||||
"console": "integratedTerminal",
|
||||
"code": [
|
||||
"import runpy",
|
||||
"runpy.run_path(r'${file}')",
|
||||
],
|
||||
"code": ["import runpy", "runpy.run_path(r'${file}')"],
|
||||
"logToFile": true,
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
},
|
||||
{
|
||||
"name": "Attach: connect",
|
||||
|
|
@ -41,10 +38,10 @@
|
|||
"request": "attach",
|
||||
"connect": {
|
||||
"port": 5678,
|
||||
"host": "127.0.0.1",
|
||||
"host": "127.0.0.1"
|
||||
},
|
||||
"logToFile": true,
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
},
|
||||
{
|
||||
"name": "Attach: listen",
|
||||
|
|
@ -52,24 +49,26 @@
|
|||
"request": "attach",
|
||||
"listen": {
|
||||
"port": 5678,
|
||||
"host": "127.0.0.1",
|
||||
"host": "127.0.0.1"
|
||||
},
|
||||
"logToFile": true,
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
//"restart": true,
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
},
|
||||
{
|
||||
"name": "Attach: PID",
|
||||
"type": "python",
|
||||
"request": "attach",
|
||||
"processId": "${command:pickProcess}",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
},
|
||||
{
|
||||
"name": "Debug Tests",
|
||||
"type": "python",
|
||||
"request": "test",
|
||||
"request": "launch",
|
||||
"console": "integratedTerminal",
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter",
|
||||
"purpose": ["debug-test"],
|
||||
"debugAdapterPath": "${workspaceFolder}/src/debugpy/adapter"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
|
|||
202
CONTRIBUTING.md
202
CONTRIBUTING.md
|
|
@ -1,8 +1,7 @@
|
|||
# Contributing to `debugpy`
|
||||
|
||||
[](https://ptvsd.visualstudio.com/ptvsd/ptvsd%20Team/_build/index?definitionId=1)
|
||||
[](https://travis-ci.org/Microsoft/ptvsd)
|
||||
[](https://raw.githubusercontent.com/Microsoft/ptvsd/master/LICENSE)
|
||||
[](https://dev.azure.com/debugpy/debugpy/_build/latest?definitionId=1&branchName=main)
|
||||
[](https://raw.githubusercontent.com/microsoft/debugpy/main/LICENSE)
|
||||
[](https://pypi.org/project/ptvsd/)
|
||||
|
||||
|
||||
|
|
@ -25,7 +24,7 @@ The following tools are required to work on debugpy:
|
|||
- [Black](https://black.readthedocs.io/en/stable/)
|
||||
- [tox](https://tox.readthedocs.io/en/latest/)
|
||||
|
||||
We recommend using [Visual Studio Code](https://code.visualstudio.com/) with the (Python extension)[https://marketplace.visualstudio.com/items?itemName=ms-python.python] to work on debugpy, but it's not a requirement. A workspace file, [debugpy.code-workspace], is provided for the convenience of VSCode users, and sets it up to use the other tools listed above properly.
|
||||
We recommend using [Visual Studio Code](https://code.visualstudio.com/) with the [Python extension](https://marketplace.visualstudio.com/items?itemName=ms-python.python) to work on debugpy, but it's not a requirement. A workspace file, [debugpy.code-workspace], is provided for the convenience of VSCode users, and sets it up to use the other tools listed above properly.
|
||||
|
||||
Tools that are Python packages should be installed via pip corresponding to the Python 3 installation. On Windows:
|
||||
```
|
||||
|
|
@ -66,7 +65,7 @@ On Linux or macOS:
|
|||
```
|
||||
.../debugpy$ python3 -m tox
|
||||
```
|
||||
This will perform a full run with the default settings. A full run will run tests on Python 2.7 and 3.5-3.8, and requires all of those to be installed. If some versions are missing, or it is desired to skip them for a particular run, tox can be directed to only run tests on specific versions with `-e`. In addition, the `--developer` option can be used to skip the packaging step, running tests directly against the source code in `src/debugpy`. This should only be used when iterating on the code, and a proper run should be performed before submitting a PR. On Windows:
|
||||
This will perform a full run with the default settings. A full run will run tests on Python 2.7 and 3.5-3.8, and requires all of those to be installed. If some versions are missing, or it is desired to skip them for a particular run, tox can be directed to only run tests on specific versions with `-e`. In addition, the `--develop` option can be used to skip the packaging step, running tests directly against the source code in `src/debugpy`. This should only be used when iterating on the code, and a proper run should be performed before submitting a PR. On Windows:
|
||||
```
|
||||
...\debugpy> py -m tox -e py27,py37 --develop
|
||||
```
|
||||
|
|
@ -75,9 +74,173 @@ On Linux or macOS:
|
|||
.../debugpy$ python3 -m tox -e py27,py37 --develop
|
||||
```
|
||||
|
||||
You can run all tests in a single file using a specified python version, like this:
|
||||
```
|
||||
...\debugpy> py -m tox --develop -e py312 -- ".\tests\debugpy\server\test_cli.py"
|
||||
```
|
||||
|
||||
You can also specify a single test, like this:
|
||||
```
|
||||
...\debugpy> py -m tox --develop -e py312 -- ".\tests\debugpy\server\test_cli.py::test_duplicate_switch"
|
||||
```
|
||||
|
||||
The tests are run concurrently, and the default number of workers is 8. You can force a single worker by using the `-n0` flag, like this:
|
||||
```
|
||||
...\debugpy> py -m tox --develop -e py312 -- -n0 ".\tests\debugpy\server\test_cli.py"
|
||||
```
|
||||
|
||||
### Running tests without tox
|
||||
|
||||
While tox is the recommended way to run the test suite, pytest can also be invoked directly from the root of the repository. This requires packages in tests/test_requirements.txt to be installed first.
|
||||
While tox is the recommended way to run the test suite, pytest can also be invoked directly from the root of the repository. This requires packages in tests/requirements.txt to be installed first.
|
||||
|
||||
Using a venv created by tox in the '.tox' folder can make it easier to get the pytest configuration correct. Debugpy needs to be installed into the venv for the tests to run, so using the tox generated .venv makes that easier.
|
||||
|
||||
#### Keeping logs on test success
|
||||
|
||||
There's an internal setting `debugpy_log_passed` that if set to true will not erase the logs after a successful test run. Just search for this in the code and remove the code that deletes the logs on success.
|
||||
|
||||
#### Adding logging
|
||||
|
||||
Using `pydevd_log.debug` you can add logging just about anywhere in the pydevd code. However this code won't be called if CYTHON support is enabled without recreating the Cython output. To temporarily disable CYTHON support, look for `CYTHON_SUPPORTED` and make sure it's set to False
|
||||
|
||||
## Updating pydevd
|
||||
|
||||
Pydevd (at src/debugpy/_vendored/pydevd) is a subrepo of https://github.com/fabioz/PyDev.Debugger. We use the [subrepo](https://github.com/ingydotnet/git-subrepo) to have a copy of pydevd inside of debugpy
|
||||
|
||||
In order to update the source, you would:
|
||||
- git checkout -b "branch name"
|
||||
- python subrepo.py pull
|
||||
- git push
|
||||
- Fix any debugpy tests that are failing as a result of the pull
|
||||
- Create a PR from your branch
|
||||
|
||||
You might need to regenerate the Cython modules after any changes. This can be done by:
|
||||
|
||||
- Install Python latest (3.14 as of this writing)
|
||||
- pip install cython 'django>=1.9' 'setuptools>=0.9' 'wheel>0.21' twine
|
||||
- On a windows machine:
|
||||
- set FORCE_PYDEVD_VC_VARS=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat
|
||||
- in the pydevd folder: python .\build_tools\build.py
|
||||
|
||||
## Pushing pydevd back to PyDev.Debugger
|
||||
|
||||
If you've made changes to pydevd (at src/debugpy/_vendored/pydevd), you'll want to push back changes to pydevd so as Fabio makes changes to pydevd we can continue to share updates.
|
||||
|
||||
To do this, you would:
|
||||
|
||||
- Create a fork of https://github.com/fabioz/PyDev.Debugger
|
||||
- Switch back to your debugpy clone
|
||||
- python subrepo.py branch -m "pydevd branch you want to create"
|
||||
- git push -f https://github.com/"your fork"/PyDev.Debugger subrepo/src/debugpy/_vendored/pydevd:$(pydevd branch you want to create)
|
||||
- Create a PR from that branch
|
||||
- Get Fabio's buyoff on the changes
|
||||
|
||||
### Setting up pydevd to be testable
|
||||
|
||||
Follow these steps to get pydevd testable:
|
||||
|
||||
- create an environment to test. The list of stuff in your environment is outlined [here](https://github.com/fabioz/PyDev.Debugger/blob/6cd4d431e6a794448f33a73857d479149041500a/.github/workflows/pydevd-tests-python.yml#L83).
|
||||
- set PYTHONPATH=. (make sure you don't forget this part, otherwise a lot of tests will fail)
|
||||
|
||||
### Testing pydevd and fixing test failures
|
||||
|
||||
Pydevd has a lot more tests on execution than debugpy. They reside in all of the `test` folders under the root. The majority of the execution tests are in the `tests_python` folder.
|
||||
|
||||
You run all of the tests with (from the root folder):
|
||||
|
||||
- python -m pytest -n auto -rfE
|
||||
|
||||
That will run all of the tests in parallel and output any failures.
|
||||
|
||||
If you want to just see failures you can do this:
|
||||
|
||||
- python -m pytest -n auto -q
|
||||
|
||||
That should generate output that just lists the tests which failed.
|
||||
|
||||
```
|
||||
=============================================== short test summary info ===============================================
|
||||
FAILED tests_python/test_debugger.py::test_path_translation[True] - AssertionError: TimeoutError (note: error trying to dump threads on timeout).
|
||||
FAILED tests_python/test_debugger.py::test_remote_debugger_multi_proc[False] - AssertionError: TimeoutError
|
||||
FAILED tests_python/test_debugger.py::test_path_translation[False] - AssertionError: TimeoutError (note: error trying to dump threads on timeout).
|
||||
======================== 3 failed, 661 passed, 169 skipped, 77 warnings in 319.05s (0:05:19) =========================
|
||||
```
|
||||
With that you can then run individual tests like so:
|
||||
|
||||
- python -m pytest -n auto tests_python/test_debugger.py::test_path_translation[False]
|
||||
|
||||
That will generate a log from the test run.
|
||||
|
||||
Logging the test output can be tricky so here's some information on how to debug the tests.
|
||||
|
||||
#### Running pydevd tests inside of VS code
|
||||
|
||||
You can also run the pydevd tests inside of VS code using the test explorer (and debug the pytest code). To do so, set PYTHONPATH=. and open the `src/debugpy/_vendored/pydevd` folder in VS code. The test explorer should find all of the pydevd tests.
|
||||
|
||||
#### How to add more logging
|
||||
|
||||
The pydevd tests log everything to the console and to a text file during the test. If you scroll up in the console, it should show the log file it read the logs from:
|
||||
|
||||
```
|
||||
Log on failure:
|
||||
-------------------- C:\Users\rchiodo\AppData\Local\Temp\pytest-of-rchiodo\pytest-77\popen-gw3\test_path_translation_and_sour0\pydevd_debug_file_23524.32540.txt ------------------
|
||||
```
|
||||
|
||||
If you want to add more logging in order to investigate something that isn't working, you simply add a line like so in the code:
|
||||
|
||||
```python
|
||||
pydevd_log.debug("Some test logging", frame, etc)
|
||||
```
|
||||
|
||||
Make sure if you add this in a module that gets `cythonized`, that you turn off `Cython` support as listed above. Otherwise you'll have to regen the C code or you won't actually see your new log output.
|
||||
|
||||
#### How to use logs to debug failures
|
||||
|
||||
Investigating log failures can be done in multiple ways.
|
||||
|
||||
If you have an existing test failing, you can investigate it by running the test with the main branch and comparing the results. To do so you would:
|
||||
|
||||
- Clone the repo a second time
|
||||
- Change the code in `tests_python/debugger_unittest.py` so that the test prints out logs on success too (by default it only logs the output on a failure)
|
||||
- Run the failing test in the second clone
|
||||
- Run the failing test in your original clone (with the --capture=tee-sys so that it outputs the log)
|
||||
- Diff the results by finding the log file name in the output and diffing those two files
|
||||
- Add more logging around where the differences first appear
|
||||
- Repeat running and diffing
|
||||
|
||||
If you're adding a new test or just trying to figure out what the expected log output is, you would look at the failing test to see what steps are expected in the output. Here's an example:
|
||||
|
||||
```python
|
||||
def test_case_double_remove_breakpoint(case_setup):
|
||||
with case_setup.test_file("_debugger_case_remove_breakpoint.py") as writer:
|
||||
breakpoint_id = writer.write_add_breakpoint(writer.get_line_index_with_content("break here"))
|
||||
writer.write_make_initial_run()
|
||||
|
||||
hit = writer.wait_for_breakpoint_hit()
|
||||
writer.write_remove_breakpoint(breakpoint_id)
|
||||
writer.write_remove_breakpoint(breakpoint_id) # Double-remove (just check that we don't have an error).
|
||||
writer.write_run_thread(hit.thread_id)
|
||||
|
||||
writer.finished_ok = True
|
||||
```
|
||||
|
||||
That test would have events correlating to:
|
||||
|
||||
- Initialization (all debug sessions have this)
|
||||
- Setting breakpoints on a specific line
|
||||
- Breakpoint event being hit
|
||||
- Setting breakpoints to empty
|
||||
- Setting breakpoints to empty
|
||||
- Continue event
|
||||
|
||||
Those would show up in the log like so:
|
||||
|
||||
Breakpoint command
|
||||
```
|
||||
0.00s - Received command: CMD_SET_BREAK 111 3 1 python-line C:\Users\rchiodo\source\repos\PyDev.Debugger\tests_python\resources\_debugger_case_remove_breakpoint.py 7 None None None
|
||||
```
|
||||
|
||||
In order to investigate a failure you'd look for the CMDs you expect and then see where the CMDs deviate. At that point you'd add logging around what might have happened next.
|
||||
|
||||
## Using modified debugpy in Visual Studio Code
|
||||
To test integration between debugpy and Visual Studio Code, the latter can be directed to use a custom version of debugpy in lieu of the one bundled with the Python extension. This is done by specifying `"debugAdapterPath"` in `launch.json` - it must point at the root directory of the *package*, which is `src/debugpy` inside the repository:
|
||||
|
|
@ -85,7 +248,32 @@ To test integration between debugpy and Visual Studio Code, the latter can be di
|
|||
```json5
|
||||
{
|
||||
"type": "python",
|
||||
"debugAdapterPath": ".../debugpy/src/debugpy",
|
||||
"debugAdapterPath": ".../debugpy/src/debugpy/adapter",
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Enabling logging in VS code
|
||||
See the directions here:
|
||||
https://github.com/microsoft/debugpy/wiki/Enable-debugger-logs
|
||||
|
||||
## Debugging native code (Windows)
|
||||
|
||||
To debug the native components of `debugpy`, such as `attach.cpp`, you can use Visual Studio's native debugging feature.
|
||||
|
||||
Follow these steps to set up native debugging in Visual Studio:
|
||||
|
||||
1. Open Visual Studio and go to `Debug` > `Options` > `Symbols`.
|
||||
2. Check the option **Search for all module symbols unless excluded**. This ensures that Visual Studio loads the necessary symbols (PDB files) for all modules, including dynamically loaded ones.
|
||||
3. Click **OK** to close the options dialog.
|
||||
4. Run your Python script from the command line, for example: `python ./main.py`
|
||||
5. In Visual Studio, go to `Debug` > `Attach to Process`.
|
||||
6. From the list of processes, select the appropriate Python process. Be sure to choose the correct process, especially if you're using a virtual environment. You can verify this by checking the command line associated with each process in the **Task Manager**.
|
||||
7. Under **Attach to**, choose either **Automatic: Native code** or explicitly select **Native** to attach as a native debugger.
|
||||
8. Click **Attach**.
|
||||
9. Open the native source file you want to debug, such as `attach.cpp`, and set breakpoints where necessary (e.g., at `DoAttach`).
|
||||
10. Trigger the loading of the DLL, such as by attaching `debugpy` to the Python process (refer to `Attach: PID` in `debugpy`'s `launch.json` for more details on attaching to the process).
|
||||
11. Once the DLL is loaded, Visual Studio will automatically load the associated PDB files, and your breakpoints should become active.
|
||||
12. When the breakpoint is hit, you can debug the native code as you would in any debug session.
|
||||
|
||||
If you need to step into the Python code during the debug session, you can download the Python source code from [python.org](https://www.python.org/downloads/source/). Unzip it to a folder, and when Visual Studio prompts for the source location, point it to the folder where you extracted the Python source. Ensure that the Python version matches the interpreter used to run your script (e.g., `python ./main.py`).
|
||||
25
README.md
25
README.md
|
|
@ -1,7 +1,9 @@
|
|||
# debugpy - a debugger for Python
|
||||
|
||||
[](https://dev.azure.com/debugpy/debugpy/_build/latest?definitionId=1&branchName=master)
|
||||
[](https://raw.githubusercontent.com/microsoft/debugpy/master/LICENSE)
|
||||
An implementation of the [Debug Adapter Protocol](https://microsoft.github.io/debug-adapter-protocol/) for Python 3.
|
||||
|
||||
[](https://dev.azure.com/debugpy/debugpy/_build/latest?definitionId=1&branchName=main)
|
||||
[](https://raw.githubusercontent.com/microsoft/debugpy/main/LICENSE)
|
||||
[](https://pypi.org/project/debugpy/)
|
||||
[](https://pypi.org/project/debugpy/)
|
||||
|
||||
|
|
@ -13,9 +15,10 @@
|
|||
| Linux |  |
|
||||
| Mac |  |
|
||||
|
||||
This debugger implements the Debug Adapter Protocol: [debugProtocol.json](https://github.com/Microsoft/vscode-debugadapter-node/blob/master/debugProtocol.json)
|
||||
|
||||
## `debugpy` CLI Usage
|
||||
|
||||
For full details, see the [Command Line Reference](https://github.com/microsoft/debugpy/wiki/Command-Line-Reference).
|
||||
|
||||
### Debugging a script file
|
||||
To run a script file with debugging enabled, but without waiting for the client to attach (i.e. code starts executing immediately):
|
||||
```console
|
||||
|
|
@ -52,7 +55,17 @@ The following command injects the debugger into a process with a given PID that
|
|||
-m debugpy --listen localhost:5678 --pid 12345
|
||||
```
|
||||
|
||||
### Ignoring subprocesses
|
||||
The following command will ignore subprocesses started by the debugged process.
|
||||
```console
|
||||
-m debugpy --listen localhost:5678 --pid 12345 --configure-subProcess False
|
||||
```
|
||||
|
||||
|
||||
## `debugpy` Import usage
|
||||
|
||||
For full details, see the [API reference](https://github.com/microsoft/debugpy/wiki/API-Reference).
|
||||
|
||||
### Enabling debugging
|
||||
At the beginning of your script, import debugpy, and call `debugpy.listen()` to start the debug adapter, passing a `(host, port)` tuple as the first argument.
|
||||
```python
|
||||
|
|
@ -76,14 +89,14 @@ debugpy.wait_for_client() # blocks execution until client is attached
|
|||
```
|
||||
|
||||
### `breakpoint()` function
|
||||
In Python 3.7 and above, `debugpy` supports the standard `breakpoint()` function. Use `debugpy.breakpoint()` function for similar behavior and compatibility with older versions of Python. If the debugger is attached when either of these functions is invoked, it will pause execution on the calling line, as if it had a breakpoint set. If there's no client attached, the functions do nothing, and the code continues to execute normally.
|
||||
Where available, debugpy supports the standard `breakpoint()` function for programmatic breakpoints. Use `debugpy.breakpoint()` function to get the same behavior when `breakpoint()` handler installed by debugpy is overridden by another handler. If the debugger is attached when either of these functions is invoked, it will pause execution on the calling line, as if it had a breakpoint set. If there's no client attached, the functions do nothing, and the code continues to execute normally.
|
||||
```python
|
||||
import debugpy
|
||||
debugpy.listen(...)
|
||||
|
||||
while True:
|
||||
...
|
||||
breakpoint() # or debugpy.breakpoint() on 3.6 and below
|
||||
breakpoint() # or debugpy.breakpoint()
|
||||
...
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -28,5 +28,5 @@ If you want to debug library files, you have to disable `justMyCode` in `launch.
|
|||
When filing an issue, make sure you do the following:
|
||||
|
||||
- Check existing issues for the same problem (also see the "Known Issues" section above for widespread problems).
|
||||
- Follow instructions in [this](https://github.com/microsoft/debugpy/blob/master/.github/ISSUE_TEMPLATE/bug_report.md) template for filing a bug report.
|
||||
- Follow instructions in [this](https://github.com/microsoft/debugpy/blob/main/.github/ISSUE_TEMPLATE/bug_report.md) template for filing a bug report.
|
||||
- Include any debugger logs that you may have. See [here](https://github.com/microsoft/debugpy#debugger-logging) for instructions on how to enable logging.
|
||||
|
|
|
|||
|
|
@ -1,18 +1,37 @@
|
|||
# This pipeline is used to run unit test code coverage against debugpy public repo.
|
||||
|
||||
# Trigger ci builds for commits into master and any release branches
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
|
||||
# Trigger pr builds for commits into master and any release branches
|
||||
# Ignore draft PR's
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
drafts: "false"
|
||||
|
||||
variables:
|
||||
architecture: "x64"
|
||||
python.version: "3.8"
|
||||
architecture: "x64"
|
||||
python.version: "3.11"
|
||||
|
||||
jobs:
|
||||
- job: 'Coverage'
|
||||
timeoutInMinutes: 15
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
demands: java
|
||||
vmImage: "ubuntu-18.04"
|
||||
steps:
|
||||
- script: |
|
||||
sudo apt-get --yes install gdb
|
||||
sudo sysctl kernel.yama.ptrace_scope=0
|
||||
displayName: 'Install gdb'
|
||||
- job: "Coverage"
|
||||
timeoutInMinutes: "60"
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
demands: java
|
||||
vmImage: "ubuntu-latest"
|
||||
steps:
|
||||
- script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get --yes install gdb
|
||||
sudo sysctl kernel.yama.ptrace_scope=0
|
||||
displayName: "Install gdb"
|
||||
|
||||
- template: "templates/coverage.yml"
|
||||
- template: "templates/coverage.yml"
|
||||
|
|
|
|||
|
|
@ -1,17 +1,34 @@
|
|||
# This pipeline is used to run unit test code coverage against debugpy public repo.
|
||||
|
||||
# Trigger ci builds for commits into master and any release branches
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
|
||||
# Trigger pr builds for commits into master and any release branches
|
||||
# Ignore draft PR's
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
drafts: "false"
|
||||
|
||||
variables:
|
||||
architecture: "x64"
|
||||
python.version: "3.8"
|
||||
architecture: "x64"
|
||||
python.version: "3.11"
|
||||
|
||||
jobs:
|
||||
- job: 'Coverage'
|
||||
timeoutInMinutes: 15
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
demands: java
|
||||
vmImage: "macOS-10.15"
|
||||
steps:
|
||||
- script: |
|
||||
ulimit -Sn 8192
|
||||
displayName: 'Increase file descriptor limit'
|
||||
- job: "Coverage"
|
||||
timeoutInMinutes: "60"
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
demands: java
|
||||
vmImage: "macOS-latest"
|
||||
steps:
|
||||
- script: "ulimit -Sn 8192"
|
||||
displayName: "Increase file descriptor limit"
|
||||
|
||||
- template: "templates/coverage.yml"
|
||||
- template: "templates/coverage.yml"
|
||||
|
|
|
|||
|
|
@ -1,119 +1,250 @@
|
|||
# This pipeline is used to run PR validation and CI builds against the debugpy public repo.
|
||||
# Seperate internal pipelines are used for generating wheels, signing, and releasing to pypi.org
|
||||
|
||||
# Trigger ci builds for commits into master and any release branches
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
|
||||
# Trigger pr builds for commits into master and any release branches
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- '*'
|
||||
|
||||
variables:
|
||||
architecture: "x64"
|
||||
architecture: x64
|
||||
PYDEVD_ATTACH_TO_PROCESS: src/debugpy/_vendored/pydevd/pydevd_attach_to_process
|
||||
|
||||
jobs:
|
||||
- job: "Lint"
|
||||
timeoutInMinutes: 15
|
||||
displayName: "Lint"
|
||||
pool: { vmImage: "ubuntu-18.04" }
|
||||
stages:
|
||||
|
||||
variables:
|
||||
python.version: "3.8"
|
||||
- stage: Lint
|
||||
jobs:
|
||||
- job: Lint
|
||||
timeoutInMinutes: 5
|
||||
|
||||
steps:
|
||||
- template: "templates/use_python.yml"
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
||||
- script: |
|
||||
python3 -m pip install -U flake8
|
||||
python3 -m pip install -U git+https://github.com/karthiknadig/flake8reports
|
||||
displayName: "Setup flake8"
|
||||
variables:
|
||||
python.version: "3.9"
|
||||
|
||||
- script: |
|
||||
python3 -m flake8 --format=junit --output-file=$(Build.ArtifactStagingDirectory)/lint-flake8.xml
|
||||
displayName: "Run flake8"
|
||||
steps:
|
||||
|
||||
- task: "PublishTestResults@2"
|
||||
condition: "always()"
|
||||
- template: templates/use_python.yml
|
||||
|
||||
# Install and run ruff
|
||||
# See https://github.com/astral-sh/ruff and https://beta.ruff.rs/docs/
|
||||
- script: python3 -m pip install -U ruff
|
||||
displayName: Install ruff
|
||||
|
||||
# Run linter
|
||||
- script: python3 -m ruff check --output-format=junit --output-file=$(Build.ArtifactStagingDirectory)/lint-ruff.xml .
|
||||
displayName: Run ruff
|
||||
|
||||
# Publish results, even on failure
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish linting results
|
||||
inputs:
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
testResultsFiles: "lint-*.xml"
|
||||
searchFolder: "$(Build.ArtifactStagingDirectory)"
|
||||
displayName: "Publish linting results"
|
||||
testRunTitle: $(Agent.JobName)
|
||||
testResultsFiles: lint-*.xml
|
||||
searchFolder: $(Build.ArtifactStagingDirectory)
|
||||
condition: always()
|
||||
|
||||
- job: "Test_Linux"
|
||||
- stage: Pydevd
|
||||
jobs:
|
||||
- job: Build
|
||||
displayName: Build
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
Windows:
|
||||
image: windows-latest
|
||||
contents: |
|
||||
*.exe
|
||||
*.dll
|
||||
*.pdb
|
||||
script: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)/windows/compile_windows.bat
|
||||
workingDirectory: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)/windows
|
||||
macOS:
|
||||
image: macOS-latest
|
||||
contents: |
|
||||
*.dylib
|
||||
script: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)/linux_and_mac/compile_mac.sh
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)
|
||||
Linux:
|
||||
image: ubuntu-latest
|
||||
contents: |
|
||||
*.so
|
||||
script: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)/linux_and_mac/compile_linux.sh
|
||||
workingDirectory: $(System.DefaultWorkingDirectory)
|
||||
|
||||
pool:
|
||||
vmImage: $(image)
|
||||
|
||||
steps:
|
||||
|
||||
# Clean up old binaries
|
||||
- task: DeleteFiles@1
|
||||
displayName: Clean up old binaries
|
||||
inputs:
|
||||
SourceFolder: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)
|
||||
Contents: $(contents)
|
||||
|
||||
# Build pydevd binaries
|
||||
- script: $(script)
|
||||
displayName: Build pydevd binaries
|
||||
workingDirectory: $(workingDirectory)
|
||||
|
||||
# copy pydevd binaries
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy pydevd binaries
|
||||
inputs:
|
||||
SourceFolder: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)
|
||||
Contents: $(contents)
|
||||
TargetFolder: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
# Publish pydevd binaries
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish pydevd binaries
|
||||
inputs:
|
||||
artifactName: pydevd binaries
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)
|
||||
|
||||
- stage: Test
|
||||
dependsOn: Pydevd
|
||||
jobs:
|
||||
|
||||
- job: Tests_Linux
|
||||
displayName: Tests - Linux
|
||||
timeoutInMinutes: 30
|
||||
displayName: "Tests - Linux"
|
||||
pool: { vmImage: "ubuntu-18.04" }
|
||||
pool:
|
||||
vmImage: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
py27:
|
||||
python.version: "2.7"
|
||||
py35:
|
||||
python.version: "3.5"
|
||||
py36:
|
||||
python.version: "3.6"
|
||||
py37:
|
||||
python.version: "3.7"
|
||||
py38:
|
||||
python.version: "3.8"
|
||||
matrix:
|
||||
py39:
|
||||
python.version: 3.9
|
||||
py310:
|
||||
python.version: 3.10
|
||||
py311:
|
||||
python.version: 3.11
|
||||
py312:
|
||||
python.version: 3.12
|
||||
py313:
|
||||
python.version: 3.13
|
||||
py314:
|
||||
python.version: 3.14.0-rc.2
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
sudo apt-get --yes install gdb
|
||||
sudo sysctl kernel.yama.ptrace_scope=0
|
||||
displayName: "Setup gdb"
|
||||
|
||||
- template: "templates/use_python.yml"
|
||||
- script: |
|
||||
sudo apt-get update
|
||||
sudo apt-get --yes install gdb
|
||||
sudo sysctl kernel.yama.ptrace_scope=0
|
||||
displayName: Setup gdb
|
||||
|
||||
- template: "templates/run_tests.yml"
|
||||
- template: templates/use_python.yml
|
||||
|
||||
- job: "Test_MacOS"
|
||||
# download pydevd binaries
|
||||
- download: current
|
||||
displayName: Download pydevd binaries
|
||||
artifact: pydevd binaries
|
||||
|
||||
# copy pydevd binaries
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy pydevd binaries
|
||||
inputs:
|
||||
SourceFolder: $(Pipeline.Workspace)/pydevd binaries
|
||||
TargetFolder: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)
|
||||
|
||||
- template: templates/run_tests.yml
|
||||
|
||||
- job: Tests_Mac
|
||||
timeoutInMinutes: 30
|
||||
displayName: "Tests - macOS"
|
||||
pool: { vmImage: "macOS-10.15" }
|
||||
displayName: Tests - macOS
|
||||
pool:
|
||||
vmImage: macOS-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
py27:
|
||||
python.version: "2.7"
|
||||
py35:
|
||||
python.version: "3.5"
|
||||
py36:
|
||||
python.version: "3.6"
|
||||
py37:
|
||||
python.version: "3.7"
|
||||
py38:
|
||||
python.version: "3.8"
|
||||
matrix:
|
||||
py39:
|
||||
python.version: 3.9
|
||||
py310:
|
||||
python.version: 3.10
|
||||
py311:
|
||||
python.version: 3.11
|
||||
py312:
|
||||
python.version: 3.12
|
||||
py313:
|
||||
python.version: 3.13
|
||||
py314:
|
||||
python.version: 3.14.0-rc.2
|
||||
|
||||
steps:
|
||||
- script: |
|
||||
ulimit -Sn 8192
|
||||
displayName: "Increase file descriptor limit"
|
||||
|
||||
- template: "templates/use_python.yml"
|
||||
- script: ulimit -Sn 8192
|
||||
displayName: Increase file descriptor limit
|
||||
|
||||
- script: |
|
||||
python -m ensurepip --user
|
||||
displayName: "Bootstrap pip"
|
||||
- template: templates/use_python.yml
|
||||
|
||||
- template: "templates/run_tests.yml"
|
||||
- script: python -m ensurepip --user
|
||||
displayName: Bootstrap pip
|
||||
|
||||
- job: "Test_Windows"
|
||||
timeoutInMinutes: 30
|
||||
displayName: "Tests - Windows"
|
||||
pool: { vmImage: "windows-2019" }
|
||||
# download pydevd binaries
|
||||
- download: current
|
||||
displayName: Download pydevd binaries
|
||||
artifact: pydevd binaries
|
||||
|
||||
# copy pydevd binaries
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy pydevd binaries
|
||||
inputs:
|
||||
SourceFolder: $(Pipeline.Workspace)/pydevd binaries
|
||||
TargetFolder: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)
|
||||
|
||||
- template: templates/run_tests.yml
|
||||
|
||||
- job: Test_Windows
|
||||
timeoutInMinutes: 40
|
||||
displayName: Tests - Windows
|
||||
pool:
|
||||
vmImage: windows-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
py27:
|
||||
python.version: "2.7"
|
||||
py35:
|
||||
python.version: "3.5"
|
||||
py36:
|
||||
python.version: "3.6"
|
||||
py37:
|
||||
python.version: "3.7"
|
||||
py38:
|
||||
python.version: "3.8"
|
||||
py27_32:
|
||||
python.version: "2.7"
|
||||
architecture: "x86"
|
||||
py38_32:
|
||||
python.version: "3.8"
|
||||
architecture: "x86"
|
||||
matrix:
|
||||
py39:
|
||||
python.version: 3.9
|
||||
py39_32:
|
||||
python.version: 3.9
|
||||
architecture: x86
|
||||
py310:
|
||||
python.version: 3.10
|
||||
py311:
|
||||
python.version: 3.11
|
||||
py312:
|
||||
python.version: 3.12
|
||||
py313:
|
||||
python.version: 3.13
|
||||
py314:
|
||||
python.version: 3.14.0-rc.2
|
||||
|
||||
steps:
|
||||
- template: "templates/use_python.yml"
|
||||
|
||||
- template: "templates/run_tests.yml"
|
||||
- template: templates/use_python.yml
|
||||
|
||||
# download pydevd binaries
|
||||
- download: current
|
||||
displayName: Download pydevd binaries
|
||||
artifact: pydevd binaries
|
||||
|
||||
# copy pydevd binaries
|
||||
- task: CopyFiles@2
|
||||
displayName: Copy pydevd binaries
|
||||
inputs:
|
||||
SourceFolder: $(Pipeline.Workspace)/pydevd binaries
|
||||
TargetFolder: $(Build.SourcesDirectory)/$(PYDEVD_ATTACH_TO_PROCESS)
|
||||
|
||||
- template: templates/run_tests.yml
|
||||
|
|
|
|||
BIN
azure-pipelines/policheck/exceptions.mdb
Normal file
BIN
azure-pipelines/policheck/exceptions.mdb
Normal file
Binary file not shown.
3
azure-pipelines/policheck/exceptions.xml
Normal file
3
azure-pipelines/policheck/exceptions.xml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
<PoliCheckExclusions>
|
||||
<Exclusion Type="FolderPathFull">_vendored\pydevd</Exclusion>
|
||||
</PoliCheckExclusions>
|
||||
|
|
@ -1,37 +1,35 @@
|
|||
steps:
|
||||
- template: "use_python.yml"
|
||||
- template: "use_python.yml"
|
||||
|
||||
- script: |
|
||||
python -m pip install -U pip setuptools tox
|
||||
displayName: 'Setup Python packages'
|
||||
- script: "python -m pip install tox"
|
||||
displayName: "Setup Python packages"
|
||||
|
||||
- task: SonarCloudPrepare@1
|
||||
displayName: 'Prepare analysis on SonarCloud'
|
||||
inputs:
|
||||
SonarCloud: 'SonarCloud-debugpy'
|
||||
organization: microsoft
|
||||
scannerMode: CLI
|
||||
extraProperties: |
|
||||
sonar.python.coverage.reportPaths=$(Build.SourcesDirectory)/coverage/coverage.xml
|
||||
sonar.projectKey=microsoft_debugpy
|
||||
- task: SonarCloudPrepare@1
|
||||
displayName: "Prepare analysis on SonarCloud"
|
||||
inputs:
|
||||
SonarCloud: "SonarCloud-debugpy"
|
||||
organization: microsoft
|
||||
scannerMode: CLI
|
||||
extraProperties: |
|
||||
sonar.python.coverage.reportPaths=$(Build.SourcesDirectory)/coverage/coverage.xml
|
||||
sonar.projectKey=microsoft_debugpy
|
||||
|
||||
- script: |
|
||||
python -m tox --develop -e py38-cov -- --cov-report=html --cov-report=xml -vv
|
||||
displayName: 'Coverage Run'
|
||||
- script: "python -m tox --develop -e py311-cov -- --cov-report=html --cov-report=xml -vv"
|
||||
displayName: "Coverage Run"
|
||||
|
||||
- task: SonarCloudAnalyze@1
|
||||
displayName: 'Run Code Analysis'
|
||||
- task: SonarCloudAnalyze@1
|
||||
displayName: "Run Code Analysis"
|
||||
|
||||
- task: SonarCloudPublish@1
|
||||
displayName: 'Publish Quality Gate Result'
|
||||
inputs:
|
||||
pollingTimeoutSec: '300'
|
||||
- task: SonarCloudPublish@1
|
||||
displayName: "Publish Quality Gate Result"
|
||||
inputs:
|
||||
pollingTimeoutSec: "300"
|
||||
|
||||
- task: PublishCodeCoverageResults@1
|
||||
displayName: 'Publish Coverage Report'
|
||||
inputs:
|
||||
codeCoverageTool: Cobertura
|
||||
summaryFileLocation: '$(Build.SourcesDirectory)/coverage/coverage.xml'
|
||||
reportDirectory: '$(Build.SourcesDirectory)/coverage/html'
|
||||
failIfCoverageEmpty: true
|
||||
condition: always()
|
||||
- task: PublishCodeCoverageResults@1
|
||||
displayName: "Publish Coverage Report"
|
||||
inputs:
|
||||
codeCoverageTool: Cobertura
|
||||
summaryFileLocation: "$(Build.SourcesDirectory)/coverage/coverage.xml"
|
||||
reportDirectory: "$(Build.SourcesDirectory)/coverage/html"
|
||||
failIfCoverageEmpty: true
|
||||
condition: always()
|
||||
|
|
|
|||
|
|
@ -1,28 +1,39 @@
|
|||
steps:
|
||||
- script: |
|
||||
python -m pip install -U pip setuptools tox
|
||||
displayName: "Setup Python packages"
|
||||
- script: python -m pip install tox
|
||||
displayName: Setup Python packages
|
||||
|
||||
- pwsh: |
|
||||
$toxEnv = '$(python.version)'
|
||||
if (-not $toxEnv.startsWith('pypy')) {
|
||||
$toxEnv = 'py' + $toxEnv.Replace('.', '')
|
||||
}
|
||||
echo 'tox environment: $toxEnv'
|
||||
python -m tox -e $toxEnv -- -vv --junitxml=$(Build.ArtifactStagingDirectory)/tests.xml --debugpy-log-dir=$(Build.ArtifactStagingDirectory)/logs tests
|
||||
displayName: "Run tests using tox"
|
||||
- pwsh: |
|
||||
$raw = '$(python.version)'
|
||||
if ($raw.StartsWith('pypy')) {
|
||||
# For PyPy keep original pattern stripping dots after first two numeric components if needed later.
|
||||
$toxEnv = 'py' + ($raw -replace '^pypy(\d+)\.(\d+).*$','$1$2')
|
||||
}
|
||||
else {
|
||||
# Extract major.minor even from prerelease like 3.14.0-rc.2 -> 3.14
|
||||
$mm = [regex]::Match($raw,'^(\d+)\.(\d+)')
|
||||
if (-not $mm.Success) { throw "Unable to parse python.version '$raw'" }
|
||||
$toxEnv = 'py' + $mm.Groups[1].Value + $mm.Groups[2].Value
|
||||
}
|
||||
Write-Host "python.version raw: $raw"
|
||||
Write-Host "Derived tox environment: $toxEnv"
|
||||
python -m tox -e $toxEnv -- --junitxml=$(Build.ArtifactStagingDirectory)/tests.xml --debugpy-log-dir=$(Build.ArtifactStagingDirectory)/logs tests
|
||||
displayName: Run tests using tox
|
||||
env:
|
||||
DEBUGPY_PROCESS_SPAWN_TIMEOUT: 60
|
||||
DEBUGPY_LAUNCH_TIMEOUT: 60
|
||||
|
||||
- task: "PublishBuildArtifacts@1"
|
||||
condition: "failed()"
|
||||
inputs:
|
||||
artifactName: "Test logs"
|
||||
pathToPublish: "$(Build.ArtifactStagingDirectory)/logs"
|
||||
displayName: "Publish test logs"
|
||||
- task: PublishBuildArtifacts@1
|
||||
displayName: Publish test logs
|
||||
inputs:
|
||||
artifactName: Test logs
|
||||
pathToPublish: $(Build.ArtifactStagingDirectory)/logs
|
||||
condition: failed()
|
||||
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish test results
|
||||
inputs:
|
||||
testRunTitle: $(Agent.JobName)
|
||||
testResultsFiles: tests.xml
|
||||
searchFolder: $(Build.ArtifactStagingDirectory)
|
||||
condition: always()
|
||||
|
||||
- task: "PublishTestResults@2"
|
||||
condition: "always()"
|
||||
inputs:
|
||||
testRunTitle: "$(Agent.JobName)"
|
||||
testResultsFiles: "tests.xml"
|
||||
searchFolder: "$(Build.ArtifactStagingDirectory)"
|
||||
displayName: "Publish test results"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: "$(python.version)"
|
||||
architecture: "$(architecture)"
|
||||
displayName: "Use Python $(python.version) $(architecture)"
|
||||
- task: UsePythonVersion@0
|
||||
inputs:
|
||||
versionSpec: $(python.version)
|
||||
architecture: $(architecture)
|
||||
allowUnstable: true
|
||||
displayName: Use Python $(python.version) $(architecture)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,31 @@
|
|||
# This pipeline is used to run unit test code coverage against debugpy public repo.
|
||||
|
||||
# Trigger ci builds for commits into master and any release branches
|
||||
trigger:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
|
||||
# Trigger pr builds for commits into master and any release branches
|
||||
# Ignore draft PR's
|
||||
pr:
|
||||
branches:
|
||||
include:
|
||||
- main
|
||||
- release/*
|
||||
drafts: "false"
|
||||
|
||||
variables:
|
||||
architecture: "x64"
|
||||
python.version: "3.8"
|
||||
architecture: "x64"
|
||||
python.version: "3.11"
|
||||
|
||||
jobs:
|
||||
- job: 'Coverage'
|
||||
timeoutInMinutes: 20
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
demands: java
|
||||
vmImage: "windows-2019"
|
||||
steps:
|
||||
- template: "templates/coverage.yml"
|
||||
- job: "Coverage"
|
||||
timeoutInMinutes: "60"
|
||||
pool:
|
||||
name: Azure Pipelines
|
||||
demands: java
|
||||
vmImage: "windows-latest"
|
||||
steps:
|
||||
- template: "templates/coverage.yml"
|
||||
|
|
|
|||
1
build/git-subrepo/.gitattributes
vendored
Normal file
1
build/git-subrepo/.gitattributes
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
* text eol=lf
|
||||
12
build/git-subrepo/.gitrepo
Normal file
12
build/git-subrepo/.gitrepo
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = https://github.com/ingydotnet/git-subrepo.git
|
||||
branch = 0.4.1
|
||||
commit = a04d8c2e55c31931d66b5c92ef6d4fe4c59e3226
|
||||
parent = b341532bdd2eacaddca2d9c63421ef3ac9d3d239
|
||||
method = merge
|
||||
cmdver = 0.4.1
|
||||
38
build/git-subrepo/.rc
Normal file
38
build/git-subrepo/.rc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#!bash
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
#
|
||||
# This is the `git-subrepo` initialization script.
|
||||
#
|
||||
# This script turns on the `git-subrepo` Git subcommand, its manpages and TAB
|
||||
# completion for the *Bash* and *zsh* shells.
|
||||
#
|
||||
# Just add a line like this to your shell startup configuration:
|
||||
#
|
||||
# source /path/to/git-subrepo/.rc
|
||||
#
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
if [[ ${BASH_VERSION} ]]; then
|
||||
if [[ ${BASH_VERSINFO[0]} -lt 4 ]] ; then
|
||||
echo "The git-subrepo command requires that 'Bash 4+' is installed."
|
||||
echo "It doesn't need to be your shell, but it must be in your PATH."
|
||||
if [[ $OSTYPE == darwin* ]]; then
|
||||
echo "You appear to be on macOS."
|
||||
echo "Try: 'brew install bash'."
|
||||
echo "This will not change your user shell, it just installs 'Bash 5.x'."
|
||||
fi
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ -n ${ZSH_VERSION-} ]] &&
|
||||
GIT_SUBREPO_ROOT=$0 ||
|
||||
GIT_SUBREPO_ROOT=$BASH_SOURCE
|
||||
[[ $GIT_SUBREPO_ROOT =~ ^/ ]] ||
|
||||
GIT_SUBREPO_ROOT=$PWD/$GIT_SUBREPO_ROOT
|
||||
export GIT_SUBREPO_ROOT=$(cd "$(dirname "$GIT_SUBREPO_ROOT")"; pwd)
|
||||
|
||||
export PATH=$GIT_SUBREPO_ROOT/lib:$PATH
|
||||
export MANPATH=$GIT_SUBREPO_ROOT/man:$MANPATH
|
||||
source "$GIT_SUBREPO_ROOT/share/enable-completion.sh"
|
||||
31
build/git-subrepo/.travis.yml
Normal file
31
build/git-subrepo/.travis.yml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
language: shell
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- name: Git 2.21 on Ubuntu Xenial
|
||||
dist: xenial
|
||||
language: shell
|
||||
|
||||
# === This will need to removed when Travis drops support ===
|
||||
- name: Git 2.15.1 on Ubuntu Trusty
|
||||
dist: trusty
|
||||
language: shell
|
||||
|
||||
- name: Git on Mac
|
||||
os: osx
|
||||
osx_image: xcode8.3
|
||||
addons:
|
||||
homebrew:
|
||||
packages:
|
||||
- bash
|
||||
update: true
|
||||
|
||||
script:
|
||||
# NOTE: we have to make sure we're on a branch (rather than on a detached HEAD)
|
||||
# because tests rely on it.
|
||||
- git checkout -b travis-ci-dummy-branch-name
|
||||
- GIT_COMMITTER_NAME=Bob
|
||||
GIT_COMMITTER_EMAIL=bob@blob.net
|
||||
GIT_AUTHOR_NAME='Bob Blob'
|
||||
GIT_AUTHOR_EMAIL=bob@blob.net
|
||||
PROVEOPT=-v make test
|
||||
110
build/git-subrepo/Changes
Normal file
110
build/git-subrepo/Changes
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
---
|
||||
version: 0.4.1
|
||||
date: Thu Jan 9 17:11:21 CST 2020
|
||||
- Fix Bash version error messages and add to .rc
|
||||
- Nicer YAML formatting in .travis.yml
|
||||
- Wrap a long line
|
||||
- Update the docs
|
||||
- Force `make update` to always update docs
|
||||
- Don't use XXX in perl stuff
|
||||
- Add testing on MacOS
|
||||
- Remove conflicting -C from install -d commands.
|
||||
- Update version requirement documentation
|
||||
- Correct error message in branch
|
||||
- Use topo-order in subrepo branch
|
||||
- Make “git subrepo clean -f ...” delete refs correctly
|
||||
- Fix #410 Push empty repositories with recent git versions
|
||||
- Make subrepo work when run in a worktree
|
||||
- Simplify finding subrepos
|
||||
- Ask git to find the .gitrepo files
|
||||
- Doc: fix sentence repetition
|
||||
- Fix typos
|
||||
- Fixed typo
|
||||
- Travis CI not checking out a branch.
|
||||
---
|
||||
version: 0.4.0
|
||||
date: Thu Nov 8 12:26:38 CET 2018
|
||||
changes:
|
||||
- Fix #325 Do not squash main repo commits
|
||||
- Improve error message for worktree handling
|
||||
- Make version checking portable. #307
|
||||
- #307, improve version check
|
||||
- #307, update version requirement
|
||||
- Fix part #308, Add stderr output if commands fail
|
||||
- Fix #306: Add check to prevent following commits with no .gitrepo
|
||||
- Remove dry-run flag as it's not implemented. Make sure branch --force delete worktree
|
||||
- Fix #296, Replace --first-parent with --ancestry-path
|
||||
- Fix #291, specify Trusty host to get new 2.x git
|
||||
- Fix #258, add --no-tags to git fetch
|
||||
- Test that no remotes are created during clone
|
||||
- #257 Remove remote creation to avoid problems with fetch --all
|
||||
- (origin/issue/150_to_0.4.0) Fix remove-worktree, remove unused parameters
|
||||
- Regenerate completion files
|
||||
- filter-branch operation should not be done on HEAD
|
||||
- Cleanup push and add hint to push directly after pull
|
||||
- Simplify cleanup and add worktree to status
|
||||
- Add --method option to init/clone, add a 'config' command
|
||||
- Updated unit tests to support the new logic
|
||||
- Use 'git worktree' for merge/rebase
|
||||
- Update docs to reflect how things should work
|
||||
- Make it possible to specify commit messages
|
||||
- Redesign, trash the tree hash approach and use merges instead
|
||||
- Add release branches to travis-ci
|
||||
- Add --method option to init/clone, add a 'config' command
|
||||
- Detect multiple pulls, use -u flag to decide
|
||||
- Don't reuse previous commit message when using --all
|
||||
- Update the docs for pull and push
|
||||
- Update error messages when failing merge/rebase
|
||||
- Fix env var bug in test/push.t
|
||||
- Do not overwrite author information
|
||||
---
|
||||
version: 0.3.1
|
||||
date: Tue Jan 3 23:08:56 PST 2017
|
||||
changes:
|
||||
- Updated release for homebrew
|
||||
- Fix #192
|
||||
---
|
||||
version: 0.3.0
|
||||
date: Wed Dec 2 19:19:43 PST 2015
|
||||
changes:
|
||||
- Fix issue #98 and host of others (89, 91, 95, 96)
|
||||
- Adds support for the merge-base command
|
||||
- Adds stability to many commands
|
||||
- Command completion updates
|
||||
- Rename `init` to `.rc`
|
||||
- @grimmySwe++ @dzzh++ @jrosdahl++ @perlpunk++
|
||||
---
|
||||
version: 0.2.3
|
||||
date: Sun Aug 9 13:44:22 PDT 2015
|
||||
changes:
|
||||
- Fix issues #75 and #76
|
||||
---
|
||||
version: 0.2.2
|
||||
date: Wed Jul 22 09:45:13 PDT 2015
|
||||
changes:
|
||||
- Added the `init` subcommand
|
||||
- Applied doc fixes
|
||||
---
|
||||
version: 0.2.1
|
||||
date: Sat Mar 28 07:52:22 PDT 2015
|
||||
changes:
|
||||
- Allows subrepo clone to clone to an empty branch; fixes #26.
|
||||
- Refs in status
|
||||
- Empty parent set to 'none' in .gitrepo file.
|
||||
- Bug fixes
|
||||
---
|
||||
version: 0.2.0
|
||||
date: Sat Jan 24 06:22:05 PST 2015
|
||||
changes:
|
||||
- Massive overhaul
|
||||
- .gitrepo files remain the same so backwards compatible
|
||||
- Introduce the branch and commit subcommands
|
||||
- The checkout subcommand goes away
|
||||
- Operations work much smoother like normal Git flow
|
||||
- Much more testing
|
||||
- Better doc
|
||||
---
|
||||
version: 0.1.0
|
||||
date: Fri Feb 21 12:25:53 2014 -0800
|
||||
changes:
|
||||
- First version
|
||||
509
build/git-subrepo/Intro.pod
Normal file
509
build/git-subrepo/Intro.pod
Normal file
|
|
@ -0,0 +1,509 @@
|
|||
=pod
|
||||
|
||||
=for comment
|
||||
DO NOT EDIT. This Pod was generated by Swim v0.1.48.
|
||||
See http://github.com/ingydotnet/swim-pm#readme
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 Introducing Git Subrepos
|
||||
|
||||
There is a new git command called C<subrepo> that is meant to be a solid
|
||||
alternative to the C<submodule> and C<subtree> commands. All 3 of these
|
||||
commands allow you to include external repositories (pinned to specific
|
||||
commits) in your main repository. This is an often needed feature for project
|
||||
development under a source control system like Git. Unfortunately, the
|
||||
C<submodule> command is severely lacking, and the C<subtree> command (an
|
||||
attempt to make things better) is also very flawed. Fortunately, the
|
||||
C<subrepo> command is here to save the day.
|
||||
|
||||
This article will discuss how the previous commands work, and where they go
|
||||
wrong, while explaining how the new C<subrepo> command fixes the issues.
|
||||
|
||||
It should be noted that there are 3 distinct roles (ways people use repos)
|
||||
involved in discussing this topic:
|
||||
|
||||
=over
|
||||
|
||||
=item * B<owner> — The primary author and repo owner
|
||||
|
||||
=item * B<collaborators> — Other developers who contribute to the repo
|
||||
|
||||
=item * B<users> — People who simply use the repo software
|
||||
|
||||
=back
|
||||
|
||||
=head2 Introducing C<subrepo>
|
||||
|
||||
While the main point is to show how subrepo addresses the shortcomings
|
||||
of submodule and subtree, I'll start by giving a quick intro to the
|
||||
subrepo command.
|
||||
|
||||
Let's say that you have a project repo called 'freebird' and you want to have
|
||||
it include 2 other external repos, 'lynyrd' and 'skynyrd'. You would do the
|
||||
following:
|
||||
|
||||
git clone git@github.com/you/freebird
|
||||
cd freebird
|
||||
git subrepo clone git@github.com/you/lynyrd ext/lynyrd
|
||||
git subrepo clone git@github.com/you/skynyrd ext/skynyrd --branch=1975
|
||||
|
||||
What these commands do (at a high level) should be obvious. They "clone" (add)
|
||||
the repos content into the subdirectories you told them to. The details of
|
||||
what is happening to your repo will be discussed later, but adding new
|
||||
subrepos is easy. If you need to update the subrepos later:
|
||||
|
||||
git subrepo pull ext/lynyrd
|
||||
git subrepo pull ext/skynyrd --branch=1976
|
||||
|
||||
The lynyrd repo is tracking the upstream master branch, and you've changed the
|
||||
skynyrd subrepo to the 1976 branch. Since these subrepos are owned by 'you',
|
||||
you might want to change them in the context of your freebird repo. When
|
||||
things are working, you can push the subrepo changes back:
|
||||
|
||||
git subrepo push ext/lynyrd
|
||||
git subrepo push ext/skynyrd
|
||||
|
||||
Looks simple right? It's supposed to be. The intent of C<subrepo> is to do the
|
||||
right things, and to not cause problems.
|
||||
|
||||
Of course there's more to it under the hood, and that's what the rest of this
|
||||
article is about.
|
||||
|
||||
=head2 Git Submodules
|
||||
|
||||
Submodules tend to receive a lot of bad press. Here's some of it:
|
||||
|
||||
=over
|
||||
|
||||
=item * L<http://ayende.com/blog/4746/the-problem-with-git-submodules>
|
||||
|
||||
=item * L<http://somethingsinistral.net/blog/git-submodules-are-probably-not-the-answer/>
|
||||
|
||||
=item * L<http://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/>
|
||||
|
||||
=back
|
||||
|
||||
A quick recap of some of the good and bad things about submodules:
|
||||
|
||||
Good:
|
||||
|
||||
=over
|
||||
|
||||
=item * Use an external repo in a dedicated subdir of your project.
|
||||
|
||||
=item * Pin the external repo to a specific commit.
|
||||
|
||||
=item * The C<git-submodule> command is a core part of the Git project.
|
||||
|
||||
=back
|
||||
|
||||
Bad:
|
||||
|
||||
=over
|
||||
|
||||
=item * Users have to know a repo has submodules.
|
||||
|
||||
=item * Users have to get the subrepos manually.
|
||||
|
||||
=item * Pulling a repo with submodules won't pull in the new submodule changes.
|
||||
|
||||
=item * A submodule will break if the referenced repo goes away.
|
||||
|
||||
=item * A submodule will break if a forced push removes the referenced commit.
|
||||
|
||||
=item * Can't use different submodules/commits per main project branch.
|
||||
|
||||
=item * Can't "try out" a submodule on alternate branch.
|
||||
|
||||
=item * Main repo can be pushed upstream pointing to unpushed submod commits.
|
||||
|
||||
=item * Command capability differs across Git versions.
|
||||
|
||||
=item * Often need to change remote url, to push submodule changes upstream.
|
||||
|
||||
=item * Removing or renaming a submodule requires many steps.
|
||||
|
||||
=back
|
||||
|
||||
Internally, submodules are a real mess. They give the strong impression of
|
||||
being bolted on, well after Git was designed. Some commands are aware of the
|
||||
existence of submodules (although usually half-heartedly), and many commands
|
||||
are oblivious. For instance the git-clone command has a C<--recursive> option
|
||||
to clone all subrepos, but it's not a default, so you still need to be aware
|
||||
of the need. The git-checkout command does nothing with the submodules, even
|
||||
if they are intended to differ across branches.
|
||||
|
||||
Let's talk a bit about how submodules are implemented in Git. Information
|
||||
about them is stored in 3 different places (in the top level repo directory):
|
||||
|
||||
=over
|
||||
|
||||
=item * C<.gitmodules>
|
||||
|
||||
=item * C<.git/config>
|
||||
|
||||
=item * C<.git/modules> — The submodule repo's meta data (refs/objects)
|
||||
|
||||
=back
|
||||
|
||||
So some of the information lives in the repo history (.gitmodules), but other
|
||||
info (.git/) is only known to the local repo.
|
||||
|
||||
In addition, the submodule introduces a new low level concept, to the
|
||||
commitI<tree>blob graph. Normally a git tree object points to blob (file)
|
||||
objects and more tree (directory) objects. Submodules have tree objects point
|
||||
to B<commit> objects. While this seems clever and somewhat reasonable, it also
|
||||
means that every other git command (which was built on the super clean Git
|
||||
data model) has to be aware of this new possibility (and deal with it
|
||||
appropriately).
|
||||
|
||||
The point is that, while submodules are a real need, and a lot of work has
|
||||
gone into making them work decently, they are essentially a kludge to the Git
|
||||
model, and it is quite understandable why they haven't worked out as well as
|
||||
people would expect.
|
||||
|
||||
NOTE: Submodules I<are> getting better with each release of Git, but it's
|
||||
still an endless catch up game.
|
||||
|
||||
=head2 Git Subtrees
|
||||
|
||||
One day, someone decided to think different. Instead of pointing to external
|
||||
repos, why not just include them into the main repo (but also allow them to be
|
||||
pulled and pushed separately as needed)?
|
||||
|
||||
At first this may feel like a wasteful approach. Why keep other repos
|
||||
physically inside your main one? But if you think about it abstractly, what's
|
||||
the difference? You want your users and collaborators to have all this code
|
||||
because your project needs it. So why worry about how it happens? In the end,
|
||||
the choice is yours, but I've grown very comfortable with this concept and
|
||||
I'll try to justify it well. I should note that the first paragraph of the
|
||||
C<submodule> doc suggests considering this alternative.
|
||||
|
||||
The big win here is that you can do this using the existing git model. Nothing
|
||||
new is added. You are just adding commits to a history. You can do it
|
||||
different on every branch. You can merge branches sensibly.
|
||||
|
||||
The git-subtree command seems to have been inspired by Git's subtree merge
|
||||
strategy, which it uses internally, and possibly got its name from. A subtree
|
||||
merge allows you to take a completely separate Git history and make it be a
|
||||
subdirectory of your repo.
|
||||
|
||||
Adding a subtree was the easy part. All that needed to be done after that was
|
||||
to figure out a way to pull upstream changes and push local ones back
|
||||
upstream. And that's what the C<git-subtree> command does.
|
||||
|
||||
So what's the problem with git-subtree then?
|
||||
|
||||
Well unfortunately, it drops a few balls. The main problems come down to an
|
||||
overly complicated commandline UX, poor collaborator awareness, and a fragile
|
||||
and messy implementation.
|
||||
|
||||
Good:
|
||||
|
||||
=over
|
||||
|
||||
=item * Use an external repo in a dedicated subdir of your project.
|
||||
|
||||
=item * Pin the external repo to a specific commit.
|
||||
|
||||
=item * Users get everything with a normal clone command.
|
||||
|
||||
=item * Users don't need to know that subtrees are involved.
|
||||
|
||||
=item * Can use different submodules/commits per main project branch.
|
||||
|
||||
=item * Users don't need the subtree command. Only owners and collaborators.
|
||||
|
||||
=back
|
||||
|
||||
Bad:
|
||||
|
||||
=over
|
||||
|
||||
=item * The remote url and branch info is not saved (except in the history).
|
||||
|
||||
=item * Owners and collaborators have to enter the remote for every command.
|
||||
|
||||
=item * Collaborators aren't made aware that subtrees are involved.
|
||||
|
||||
=item * Pulled history is not squashed by default.
|
||||
|
||||
=item * Creates a messy historical view. (See below)
|
||||
|
||||
=item * Bash code is complicated.
|
||||
|
||||
=item * Only one test file. Currently is failing.
|
||||
|
||||
=back
|
||||
|
||||
As you can see, subtree makes quite a few things better, but after trying it
|
||||
for a while, the experience was more annoying than submodules. For example,
|
||||
consider this usage:
|
||||
|
||||
$ git subtree add --squash --prefix=foo git@github.com:my/thing mybranch
|
||||
# weeks go by…
|
||||
$ git subtree pull --squash --prefix=foo git@github.com:my/thing mybranch
|
||||
# time to push local subtree changes back upstream
|
||||
$ git subtree push --prefix=foo git@github.com:my/thing mybranch
|
||||
|
||||
The first thing you notice is the overly verbose syntax. It's justified in the
|
||||
first command, but in the other 2 commands I really don't want to have to
|
||||
remember what the remote and branch are that I'm using.
|
||||
|
||||
Moreover, my collaborators have no idea that subtrees are involved, let alone
|
||||
where they came from.
|
||||
|
||||
Consider the equivalent subrepo commands:
|
||||
|
||||
$ git subrepo clone git@github.com:my/thing foo -b mybranch
|
||||
$ git subrepo pull foo
|
||||
$ git subrepo push foo
|
||||
|
||||
Collaborators see a file called 'foo/.gitrepo', and know that the subdir is a
|
||||
subrepo. The file contains all the information needed by future commands
|
||||
applied to that subrepo.
|
||||
|
||||
=head2 Git Subrepos
|
||||
|
||||
Now is a good time to dive into the techinical aspects of the C<subrepo>
|
||||
command, but first let me explain how it came about.
|
||||
|
||||
As you may have surmised by now, I am the author of git-subrepo. I'd used
|
||||
submodules on and off for years, and when I became aware of subtree I gave it
|
||||
a try, but I quickly realized its problems. I decided maybe it could be
|
||||
improved. I decided to write down my expected commandline usage and my ideals
|
||||
of what it would and would not do. Then I set off to implement it. It's been a
|
||||
long road, but what I ended up with was even better than what I wanted from
|
||||
the start.
|
||||
|
||||
Let's review the Goods and Bads:
|
||||
|
||||
Good:
|
||||
|
||||
=over
|
||||
|
||||
=item * Use an external repo in a dedicated subdir of your project.
|
||||
|
||||
=item * Pin the external repo to a specific commit.
|
||||
|
||||
=item * Users get everything with a normal clone command.
|
||||
|
||||
=item * Users don't need to know that subrepos are involved.
|
||||
|
||||
=item * Can use different submodules/commits per main project branch.
|
||||
|
||||
=item * Meta info is kept in an obvious place.
|
||||
|
||||
=item * Everyone knows when a subdir is a subrepo.
|
||||
|
||||
=item * Commandline UX is minimal and intuitive.
|
||||
|
||||
=item * Pulled history is always squashed out locally.
|
||||
|
||||
=item * Pushed history is kept intact.
|
||||
|
||||
=item * Creates a clean historical view. (See below)
|
||||
|
||||
=item * Bash code is very simple and easy to follow.
|
||||
|
||||
=item * Comprehensive test suite. Currently passing on travis:
|
||||
|
||||
=back
|
||||
|
||||
=for html
|
||||
<a href="https://travis-ci.org/ingydotnet/git-subrepo"><img src="https://travis-ci.org/ingydotnet/git-subrepo.png" alt="git-subrepo"></a>
|
||||
|
||||
Bad:
|
||||
|
||||
=over
|
||||
|
||||
=item * --Subrepo is very new.-- (no longer true)
|
||||
|
||||
=item * --Not well tested in the wild.-- (no longer true)
|
||||
|
||||
=back
|
||||
|
||||
This review may seem somewhat slanted, but I honestly am not aware of any
|
||||
"bad" points that I'm not disclosing. That said, I am sure time will reveal
|
||||
bugs and shortcomings. Those can usually be fixed. Hopefully the B<model> is
|
||||
correct, because that's harder to fix down the road.
|
||||
|
||||
OK. So how does it all work?
|
||||
|
||||
There are 3 main commands: cloneI<pull>push. Let's start with the clone
|
||||
command. This is the easiest part. You give it a remote url, possibly a new
|
||||
subdir to put it, and possibly a remote branch to use. I say possibly, because
|
||||
the command can guess the subdir name (just like the git-clone command does),
|
||||
and the branch can be the upstream default branch.
|
||||
|
||||
Given this we do the following steps internally:
|
||||
|
||||
=over
|
||||
|
||||
=item * Fetch the remote content (for a specific refspec)
|
||||
|
||||
=item * Read the remote head tree into the index
|
||||
|
||||
=item * Checkout the index into the new subdir
|
||||
|
||||
=item * Create a new subrepo commit object for the subdir content
|
||||
|
||||
=item * Add a state file called .gitrepo to the new subrepo/subdir
|
||||
|
||||
=item * Amend the merge commit with this new file
|
||||
|
||||
=back
|
||||
|
||||
This process adds something like this to the top of your history:
|
||||
|
||||
* 9b6ddc9 git subrepo clone git@github.com:you/foo.git foo/
|
||||
* 37c61a5 Previous head commit of your repo
|
||||
|
||||
The entire history has been squashed down into one commit, and placed on
|
||||
top of your history. This is important as it keeps your history as clean
|
||||
as possible. You don't need to have the subrepo history in your main
|
||||
project, since it is immutably available elsewhere, and you have a pointer
|
||||
to that place.
|
||||
|
||||
The new foo/.gitrepo file looks like this:
|
||||
|
||||
[subrepo]
|
||||
remote = git@github.com:you/foo.git
|
||||
branch = master
|
||||
commit = 14c96c6931b41257b2d42b2edc67ddc659325823
|
||||
parent = 37c61a5a234f5dd6f5c2aec037509f50d3a79b8f
|
||||
cmdver = 0.1.0
|
||||
|
||||
It contains all the info needed now and later. Note that the repo url is the
|
||||
generally pushable form, rather than the publically readable (L<https://…)>
|
||||
form. This is the best practice. Users of your repo don't need access to this
|
||||
url, because the content is already in your repo. Only you and your
|
||||
collaborators need this url to pull/push in the future.
|
||||
|
||||
The next command is the pull command. Normally you just give it the subrepo's
|
||||
subdir path (although you can change the branch with -b), and it will get the
|
||||
other info from the subdir/.gitrepo file.
|
||||
|
||||
The pull command does these steps:
|
||||
|
||||
=over
|
||||
|
||||
=item * Fetch the upstream content
|
||||
|
||||
=item * Check if anything needs pulling
|
||||
|
||||
=item * Create a branch of local subrepo commits since last pull
|
||||
|
||||
=item * Rebase this branch onto the upstream commits
|
||||
|
||||
=item * Commit the HEAD of the rebased content
|
||||
|
||||
=item * Update/amend the .gitrepo file
|
||||
|
||||
=back
|
||||
|
||||
=head3 Clean History
|
||||
|
||||
I've talked a bit about clean history but let me show you a comparison between
|
||||
subrepo and subtree. Let's run this command sequence using both methods. Note
|
||||
the differences between I<both> the command syntax required, and the branch
|
||||
history produced.
|
||||
|
||||
Subrepo first:
|
||||
|
||||
$ git subrepo clone git@github.com:user/abc
|
||||
$ git subrepo clone git@github.com:user/def xyz
|
||||
$ git subrepo pull abc
|
||||
$ git subrepo pull xyz
|
||||
|
||||
The resulting history is:
|
||||
|
||||
* b1f60cc subrepo pull xyz
|
||||
* 4fb0276 subrepo pull abc
|
||||
* bcef2a0 subrepo clone git@github.com:user/def xyz
|
||||
* bebf0db subrepo clone git@github.com:user/abc
|
||||
* 64eeaa6 (origin/master, origin/HEAD) O HAI FREND
|
||||
|
||||
Compare that to B<subtree>. This:
|
||||
|
||||
$ git subtree add abc git@github.com:user/abc master
|
||||
$ git subtree add xyz git@github.com:user/def master
|
||||
$ git subtree pull abc git@github.com:user/abc master
|
||||
$ git subtree pull xyz git@github.com:user/def master
|
||||
|
||||
Produces this:
|
||||
|
||||
* 739e45a (HEAD, master) Merge commit '5f563469d886d53e19cb908b3a64e4229f88a2d1'
|
||||
|\
|
||||
| * 5f56346 Squashed 'xyz/' changes from 08c7421..365409f
|
||||
* | 641f5e5 Merge commit '8d88e90ce5f653ed2e7608a71b8693a2174ea62a'
|
||||
|\ \
|
||||
| * | 8d88e90 Squashed 'abc/' changes from 08c7421..365409f
|
||||
* | | 1703ed2 Merge commit '0e091b672c4bbbbf6bc4f6694c475d127ffa21eb' as 'xyz'
|
||||
|\ \ \
|
||||
| | |/
|
||||
| |/|
|
||||
| * | 0e091b6 Squashed 'xyz/' content from commit 08c7421
|
||||
| /
|
||||
* | 07b77e7 Merge commit 'cd2b30a0229d931979ed4436b995875ec563faea' as 'abc'
|
||||
|\ \
|
||||
| |/
|
||||
| * cd2b30a Squashed 'abc/' content from commit 08c7421
|
||||
* 64eeaa6 (origin/master, origin/HEAD) O HAI FREND
|
||||
|
||||
This was from a minimal case. Subtree history (when viewed this way at least)
|
||||
gets unreasonably ugly fast. Subrepo history, by contrast, always looks as
|
||||
clean as shown.
|
||||
|
||||
The final command, push, bascially just does the pull/rebase dance above
|
||||
described, and pushes the resulting history back. It does not squash the
|
||||
commits made locally, because it assumed that when you changed the local
|
||||
subrepo, you made messages that were intended to eventually be published
|
||||
back upstream.
|
||||
|
||||
=head2 Conflict Resolution
|
||||
|
||||
The commands described above can also be done "by hand". If something fails
|
||||
during a pull or push (generally in the rebasing) then the command will tell
|
||||
you what to do to finish up.
|
||||
|
||||
You might choose to do everything by hand, and do your own merging strategies.
|
||||
This is perfectly reasonable. The C<subrepo> command offers a few other helper
|
||||
commands to help you get the job done:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<fetch> - Fetch the upstream and create a C<< subrepo/remote/<subdir> >> ref.
|
||||
|
||||
=item * C<branch> - Create a branch of local subdir commits since the last pull, called C<< subrepo/<subdir> >>.
|
||||
|
||||
=item * C<commit> - Commit a merged branch's HEAD back into your repo.
|
||||
|
||||
=item * C<status> - Show lots of useful info about the current state of the subrepos.
|
||||
|
||||
=item * C<clean> - Remove branches, ref and remotes created by subrepo commands.
|
||||
|
||||
=item * C<help> - Read the complete documentation!
|
||||
|
||||
=back
|
||||
|
||||
=head2 Conclusion
|
||||
|
||||
Hopefully by now, you see that submodules are a painful choice with a dubious
|
||||
future, and that subtree, while a solid idea has many usage issues.
|
||||
|
||||
Give C<subrepo> a try. It's painless, easily revertable and just might be what
|
||||
the doctor ordered.
|
||||
|
||||
=head2 Reference Links
|
||||
|
||||
=over
|
||||
|
||||
=item * L<http://longair.net/blog/2010/06/02/git-submodules-explained/>
|
||||
|
||||
=item * L<http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/>
|
||||
|
||||
=back
|
||||
|
||||
=cut
|
||||
21
build/git-subrepo/License
Normal file
21
build/git-subrepo/License
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2020 Ingy döt Net
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
82
build/git-subrepo/Makefile
Normal file
82
build/git-subrepo/Makefile
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Make sure we have 'git' and it works OK:
|
||||
ifeq ($(shell which git),)
|
||||
$(error 'git' is not installed on this system)
|
||||
endif
|
||||
|
||||
# Set variables:
|
||||
NAME := git-subrepo
|
||||
LIB := lib/$(NAME)
|
||||
DOC := doc/$(NAME).swim
|
||||
MAN1 := man/man1
|
||||
EXT := $(LIB).d
|
||||
EXTS := $(shell find $(EXT) -type f) \
|
||||
$(shell find $(EXT) -type l)
|
||||
SHARE = share
|
||||
|
||||
# Install variables:
|
||||
PREFIX ?= /usr/local
|
||||
INSTALL_LIB ?= $(DESTDIR)$(shell git --exec-path)
|
||||
INSTALL_EXT ?= $(INSTALL_LIB)/$(NAME).d
|
||||
INSTALL_MAN1 ?= $(DESTDIR)$(PREFIX)/share/man/man1
|
||||
|
||||
# Basic targets:
|
||||
default: help
|
||||
|
||||
help:
|
||||
@echo 'Makefile rules:'
|
||||
@echo ''
|
||||
@echo 'test Run all tests'
|
||||
@echo 'install Install $(NAME)'
|
||||
@echo 'uninstall Uninstall $(NAME)'
|
||||
@echo 'env Show environment variables to set'
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
prove $(PROVEOPT:%=% )test/
|
||||
|
||||
# Install support:
|
||||
install:
|
||||
install -d -m 0755 $(INSTALL_LIB)/
|
||||
install -C -m 0755 $(LIB) $(INSTALL_LIB)/
|
||||
install -d -m 0755 $(INSTALL_EXT)/
|
||||
install -C -m 0755 $(EXTS) $(INSTALL_EXT)/
|
||||
install -d -m 0755 $(INSTALL_MAN1)/
|
||||
install -C -m 0644 $(MAN1)/$(NAME).1 $(INSTALL_MAN1)/
|
||||
|
||||
# Uninstall support:
|
||||
uninstall:
|
||||
rm -f $(INSTALL_LIB)/$(NAME)
|
||||
rm -fr $(INSTALL_EXT)
|
||||
rm -f $(INSTALL_MAN1)/$(NAME).1
|
||||
|
||||
env:
|
||||
@echo "export PATH=\"$$PWD/lib:\$$PATH\""
|
||||
@echo "export MANPATH=\"$$PWD/man:\$$MANPATH\""
|
||||
|
||||
# Doc rules:
|
||||
.PHONY: doc
|
||||
update: doc compgen
|
||||
|
||||
force:
|
||||
|
||||
doc: ReadMe.pod Intro.pod $(MAN1)/$(NAME).1
|
||||
perl pkg/bin/generate-help-functions.pl $(DOC) > \
|
||||
$(EXT)/help-functions.bash
|
||||
|
||||
ReadMe.pod: $(DOC) force
|
||||
swim --to=pod --wrap --complete $< > $@
|
||||
|
||||
Intro.pod: doc/intro-to-subrepo.swim force
|
||||
swim --to=pod --wrap --complete $< > $@
|
||||
|
||||
$(MAN1)/%.1: doc/%.swim Makefile force
|
||||
swim --to=man --wrap $< > $@
|
||||
|
||||
compgen: force
|
||||
perl pkg/bin/generate-completion.pl bash $(DOC) $(LIB) > \
|
||||
$(SHARE)/completion.bash
|
||||
perl pkg/bin/generate-completion.pl zsh $(DOC) $(LIB) > \
|
||||
$(SHARE)/zsh-completion/_git-subrepo
|
||||
|
||||
clean purge:
|
||||
rm -fr tmp
|
||||
28
build/git-subrepo/Meta
Normal file
28
build/git-subrepo/Meta
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
=meta: 0.0.2
|
||||
|
||||
name: git-subrepo
|
||||
version: 0.4.1
|
||||
abstract: Git Submodule Alternative
|
||||
homepage: https://github.com/ingydotnet/git-subrepo#readme
|
||||
license: MIT
|
||||
copyright: 2013-2020
|
||||
|
||||
author:
|
||||
name: Ingy döt Net
|
||||
email: ingy@ingy.net
|
||||
github: ingydotnet
|
||||
twitter: ingydotnet
|
||||
freenode: ingy
|
||||
homepage: http://ingy.net
|
||||
|
||||
requires:
|
||||
bash: 4.0.0
|
||||
git: 2.7.0
|
||||
test:
|
||||
cmd: make test
|
||||
install: make install
|
||||
|
||||
devel:
|
||||
git: git@github.org:ingydotnet/git-subrepo.git
|
||||
irc: irc.freenode.net/gitcommands
|
||||
bug: https://github.com/ingydotnet/git-subrepo/issues/
|
||||
698
build/git-subrepo/ReadMe.pod
Normal file
698
build/git-subrepo/ReadMe.pod
Normal file
|
|
@ -0,0 +1,698 @@
|
|||
=pod
|
||||
|
||||
=for comment
|
||||
DO NOT EDIT. This Pod was generated by Swim v0.1.48.
|
||||
See http://github.com/ingydotnet/swim-pm#readme
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 Name
|
||||
|
||||
git-subrepo - Git Submodule Alternative
|
||||
|
||||
=for html
|
||||
<a href="https://travis-ci.org/ingydotnet/git-subrepo"><img src="https://travis-ci.org/ingydotnet/git-subrepo.png" alt="git-subrepo"></a>
|
||||
|
||||
=head1 Synopsis
|
||||
|
||||
git subrepo -h # Help Overview
|
||||
|
||||
git subrepo clone <remote-url> [<subdir>]
|
||||
git subrepo init <subdir>
|
||||
git subrepo pull <subdir>
|
||||
git subrepo push <subdir>
|
||||
|
||||
git subrepo fetch <subdir>
|
||||
git subrepo branch <subdir>
|
||||
git subrepo commit <subdir>
|
||||
git subrepo config <subdir>
|
||||
|
||||
git subrepo status [<subdir>]
|
||||
git subrepo clean <subdir>
|
||||
|
||||
git subrepo help [<command> | --all]
|
||||
git subrepo version
|
||||
git subrepo upgrade
|
||||
|
||||
=head1 Description
|
||||
|
||||
This git command "clones" an external git repo into a subdirectory of your
|
||||
repo. Later on, upstream changes can be pulled in, and local changes can be
|
||||
pushed back. Simple.
|
||||
|
||||
=head1 Benefits
|
||||
|
||||
This command is an improvement from C<git-submodule> and C<git-subtree>; two
|
||||
other git commands with similar goals, but various problems.
|
||||
|
||||
It assumes there are 3 main roles of people interacting with a repo, and
|
||||
attempts to serve them all well:
|
||||
|
||||
=over
|
||||
|
||||
=item * B<owner> - The person who authors/owns/maintains a repo.
|
||||
|
||||
=item * B<users> - People who are just using/installing the repo.
|
||||
|
||||
=item * B<collaborators> - People who commit code to the repo and subrepos.
|
||||
|
||||
=back
|
||||
|
||||
The C<git-subrepo> command benefits these roles in the following ways:
|
||||
|
||||
=over
|
||||
|
||||
=item * Simple and intuitive commandline usage (with tab completion).
|
||||
|
||||
=item * Users get your repo and all your subrepos just by cloning your repo.
|
||||
|
||||
=item * Users do not need to install C<git-subrepo>, ever.
|
||||
|
||||
=item * Collaborators do not need to install unless they want to push/pull.
|
||||
|
||||
=item * Collaborators know when a subdir is a subrepo (it has a C<.gitrepo> file).
|
||||
|
||||
=item * The C<.gitrepo> file never gets pushed back to the subrepo upstream.
|
||||
|
||||
=item * Well named branches and remotes are generated for manual operations.
|
||||
|
||||
=item * Owners do not deal with the complications of keeping submodules in sync.
|
||||
|
||||
=item * Subrepo repositories can contain subrepos themselves.
|
||||
|
||||
=item * Branching with subrepos JustWorks™.
|
||||
|
||||
=item * Different branches can have different subrepos in different states, etc.
|
||||
|
||||
=item * Moving/renaming/deleting a subrepo subdir JustWorks™.
|
||||
|
||||
=item * You can C<init> an existing subdirectory into a subrepo.
|
||||
|
||||
=item * Your git history is kept squeaky clean.
|
||||
|
||||
=item * Upstream history (clone/pull) is condensed into a single commit.
|
||||
|
||||
=item * Pulls can use a C<merge>, C<rebase> or C<force> strategies.
|
||||
|
||||
=item * You can see the subrepo history with C<< git log subrepo/<subdir>/fetch >>.
|
||||
|
||||
=item * Commits pushed back upstream are B<not> condensed (by default).
|
||||
|
||||
=item * Trivial to try any subrepo operations and then reset back.
|
||||
|
||||
=item * No configuration required.
|
||||
|
||||
=item * Does not introduce history that messes up other git commands.
|
||||
|
||||
=item * Fixes known rebase failures with C<git-subtree>.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Installation
|
||||
|
||||
The best short answer is:
|
||||
|
||||
git clone https://github.com/ingydotnet/git-subrepo /path/to/git-subrepo
|
||||
echo 'source /path/to/git-subrepo/.rc' >> ~/.bashrc
|
||||
|
||||
The complete "Installation Instructions" can be found below.
|
||||
|
||||
Note: git-subrepo needs a git version (> 2.7) that supports worktree:s.
|
||||
|
||||
=head1 Commands
|
||||
|
||||
All the B<subrepo> commands use names of actual Git commands and try to do
|
||||
operations that are similar to their Git counterparts. They also attempt to
|
||||
give similar output in an attempt to make the subrepo usage intuitive to
|
||||
experienced Git users.
|
||||
|
||||
Please note that the commands are I<not> exact equivalents, and do not take
|
||||
all the same arguments. Keep reading…
|
||||
|
||||
=over
|
||||
|
||||
=item C<< git subrepo clone <repository> [<subdir>] [-b <branch>] [-f] [-m <msg>] [-e] [--method <merge|rebase>] >>
|
||||
|
||||
Add a repository as a subrepo in a subdir of your repository.
|
||||
|
||||
This is similar in feel to C<git clone>. You just specify the remote repo url,
|
||||
and optionally a sub-directory and/or branch name. The repo will be fetched
|
||||
and merged into the subdir.
|
||||
|
||||
The subrepo history is I<squashed> into a single commit that contains the
|
||||
reference information. This information is also stored in a special file
|
||||
called C<< <subdir>/.gitrepo >>. The presence of this file indicates that the
|
||||
directory is a subrepo.
|
||||
|
||||
All subsequent commands refer to the subrepo by the name of the
|
||||
I<subdir>. From the subdir, all the current information about the subrepo
|
||||
can be obtained.
|
||||
|
||||
The C<--force> option will "reclone" (completely replace) an existing subdir.
|
||||
|
||||
The C<--method> option will decide how the join process between branches are
|
||||
performed. The default option is merge.
|
||||
|
||||
The C<clone> command accepts the C<--branch=> C<--edit>, C<--force> and C<--
|
||||
message=> options.
|
||||
|
||||
=item C<< git subrepo init <subdir> [-r <remote>] [-b <branch>] [--method <merge|rebase>] >>
|
||||
|
||||
Turn an existing subdirectory into a subrepo.
|
||||
|
||||
If you want to expose a subdirectory of your project as a published subrepo,
|
||||
this command will do that. It will split out the content of a normal
|
||||
subdirectory into a branch and start tracking it as a subrepo. Afterwards your
|
||||
original repo will look exactly the same except that there will be a C<<
|
||||
<subdir>/.gitrepo >> file.
|
||||
|
||||
If you specify the C<--remote> (and optionally the C<--branch>) option, the
|
||||
values will be added to the C<< <subdir>/.gitrepo >> file. The C<--remote>
|
||||
option is the upstream URL, and the C<--branch> option is the upstream branch
|
||||
to push to. These values will be needed to do a C<git subrepo push> command,
|
||||
but they can be provided later on the C<push> command (and saved to C<<
|
||||
<subdir>/.gitrepo >> if you also specify the C<--update> option).
|
||||
|
||||
Note: You will need to create the empty upstream repo and push to it on your
|
||||
own, using C<< git subrepo push <subdir> >>.
|
||||
|
||||
The C<--method> option will decide how the join process between branches are
|
||||
performed. The default option is merge.
|
||||
|
||||
The C<init> command accepts the C<--branch=> and C<--remote=> options.
|
||||
|
||||
=item C<< git subrepo pull <subdir>|--all [-M|-R|-f] [-m <msg>] [-e] [-b <branch>] [-r <remote>] [-u] >>
|
||||
|
||||
Update the subrepo subdir with the latest upstream changes.
|
||||
|
||||
The C<pull> command fetches the latest content from the remote branch pointed
|
||||
to by the subrepo's C<.gitrepo> file, and then tries to merge the changes into
|
||||
the corresponding subdir. It does this by making a branch of the local commits
|
||||
to the subdir and then merging or rebasing (see below) it with the fetched
|
||||
upstream content. After the merge, the content of the new branch replaces your
|
||||
subdir, the C<.gitrepo> file is updated and a single 'pull' commit is added to
|
||||
your mainline history.
|
||||
|
||||
The C<pull> command will attempt to do the following commands in one go:
|
||||
|
||||
git subrepo fetch <subdir>
|
||||
git subrepo branch <subdir>
|
||||
git merge/rebase subrepo/<subdir>/fetch subrepo/<subdir>
|
||||
git subrepo commit <subdir>
|
||||
# Only needed for a consequential push:
|
||||
git update-ref refs/subrepo/<subdir>/pull subrepo/<subdir>
|
||||
|
||||
In other words, you could do all the above commands yourself, for the same
|
||||
effect. If any of the commands fail, subrepo will stop and tell you to finish
|
||||
this by hand. Generally a failure would be in the merge or rebase part, where
|
||||
conflicts can happen. Since Git has lots of ways to resolve conflicts to your
|
||||
personal tastes, the subrepo command defers to letting you do this by hand.
|
||||
|
||||
When pulling new data, the method selected in clone/init is used. This has no
|
||||
effect on the final result of the pull, since it becomes a single commit. But
|
||||
it does affect the resulting C<< subrepo/<subdir> >> branch, which is often
|
||||
used for a subrepo C<push> command. See 'push' below for more information. If
|
||||
you want to change the method you can use the C<config> command for this.
|
||||
|
||||
When you pull you can assume a fast-forward strategy (default) or you can
|
||||
specify a C<--rebase>, C<--merge> or C<--force> strategy. The latter is the
|
||||
same as a C<clone --force> operation, using the current remote and branch.
|
||||
|
||||
Like the C<clone> command, C<pull> will squash all the changes (since the last
|
||||
pull or clone) into one commit. This keeps your mainline history nice and
|
||||
clean. You can easily see the subrepo's history with the C<git log> command:
|
||||
|
||||
git log refs/subrepo/<subdir>/fetch
|
||||
|
||||
The set of commands used above are described in detail below.
|
||||
|
||||
The C<pull> command accepts the C<--all>, C<--branch=>, C<--edit>, C<--force>,
|
||||
C<--message=>, C<--remote=> and C<--update> options.
|
||||
|
||||
=item C<< git subrepo push <subdir>|--all [<branch>] [-r <remote>] [-b <branch>] [-M|-R] [-u] [-f] [-s] [-N] >>
|
||||
|
||||
Push a properly merged subrepo branch back upstream.
|
||||
|
||||
This command takes the subrepo branch from a successful pull command and
|
||||
pushes the history back to its designated remote and branch. You can also use
|
||||
the C<branch> command and merge things yourself before pushing if you want to
|
||||
(although that is probably a rare use case).
|
||||
|
||||
The C<push> command requires a branch that has been properly merged/rebased
|
||||
with the upstream HEAD (unless the upstream HEAD is empty, which is common
|
||||
when doing a first C<push> after an C<init>). That means the upstream HEAD is
|
||||
one of the commits in the branch.
|
||||
|
||||
By default the branch ref C<< refs/subrepo/<subdir>/pull >> will be pushed,
|
||||
but you can specify a (properly merged) branch to push.
|
||||
|
||||
After that, the C<push> command just checks that the branch contains the
|
||||
upstream HEAD and then pushes it upstream.
|
||||
|
||||
The C<--force> option will do a force push. Force pushes are typically
|
||||
discouraged. Only use this option if you fully understand it. (The C<--force>
|
||||
option will NOT check for a proper merge. ANY branch will be force pushed!)
|
||||
|
||||
The C<push> command accepts the C<--all>, C<--branch=>, C<--dry-run>, C<--
|
||||
force>, C<--merge>, C<--rebase>, C<--remote=>, C<--squash> and C<--
|
||||
update> options.
|
||||
|
||||
=item C<< git subrepo fetch <subdir>|--all [-r <remote>] [-b <branch>] >>
|
||||
|
||||
Fetch the remote/upstream content for a subrepo.
|
||||
|
||||
It will create a Git reference called C<< subrepo/<subdir>/fetch >> that
|
||||
points at the same commit as C<FETCH_HEAD>. It will also create a remote
|
||||
called C<< subrepo/<subdir> >>. These are temporary and you can easily remove
|
||||
them with the subrepo C<clean> command.
|
||||
|
||||
The C<fetch> command accepts the C<--all>, C<--branch=> and C<--
|
||||
remote=> options.
|
||||
|
||||
=item C<< git subrepo branch <subdir>|--all [-f] [-F] >>
|
||||
|
||||
Create a branch with local subrepo commits.
|
||||
|
||||
Scan the history of the mainline for all the commits that affect the C<subdir>
|
||||
and create a new branch from them called C<< subrepo/<subdir> >>.
|
||||
|
||||
This is useful for doing C<pull> and C<push> commands by hand.
|
||||
|
||||
Use the C<--force> option to write over an existing C<< subrepo/<subdir>
|
||||
>> branch.
|
||||
|
||||
The C<branch> command accepts the C<--all>, C<--fetch> and C<--force> options.
|
||||
|
||||
=item C<< git subrepo commit <subdir> [<subrepo-ref>] [-m <msg>] [-e] [-f] [-F] >>
|
||||
|
||||
Add subrepo branch to current history as a single commit.
|
||||
|
||||
This command is generally used after a hand-merge. You have done a C<subrepo
|
||||
branch> and merged (rebased) it with the upstream. This command takes the HEAD
|
||||
of that branch, puts its content into the subrepo subdir and adds a new commit
|
||||
for it to the top of your mainline history.
|
||||
|
||||
This command requires that the upstream HEAD be in the C<< subrepo/<subdir> >>
|
||||
branch history. That way the same branch can push upstream. Use the C<--force>
|
||||
option to commit anyway.
|
||||
|
||||
The C<commit> command accepts the C<--edit>, C<--fetch>, C<--force> and C<--
|
||||
message=> options.
|
||||
|
||||
=item C<< git subrepo status [<subdir>|--all|--ALL] [-F] [-q|-v] >>
|
||||
|
||||
Get the status of a subrepo. Uses the C<--all> option by default. If the C<--
|
||||
quiet> flag is used, just print the subrepo names, one per line.
|
||||
|
||||
The C<--verbose> option will show all the recent local and upstream commits.
|
||||
|
||||
Use C<--ALL> to show the subrepos of the subrepos (ie the
|
||||
"subsubrepos"), if any.
|
||||
|
||||
The C<status> command accepts the C<--all>, C<--ALL>, C<--fetch>, C<--quiet>
|
||||
and C<--verbose> options.
|
||||
|
||||
=item C<< git subrepo clean <subdir>|--all|--ALL [-f] >>
|
||||
|
||||
Remove artifacts created by C<fetch> and C<branch> commands.
|
||||
|
||||
The C<fetch> and C<branch> operations (and other commands that call them)
|
||||
create temporary things like refs, branches and remotes. This command removes
|
||||
all those things.
|
||||
|
||||
Use C<--force> to remove refs. Refs are not removed by default because they
|
||||
are sometimes needed between commands.
|
||||
|
||||
Use C<--all> to clean up after all the current subrepos. Sometimes you might
|
||||
change to a branch where a subrepo doesn't exist, and then C<--all> won't find
|
||||
it. Use C<--ALL> to remove any artifacts that were ever created by subrepo.
|
||||
|
||||
To remove ALL subrepo artifacts:
|
||||
|
||||
git subrepo clean --ALL --force
|
||||
|
||||
The C<clean> command accepts the C<--all>, C<--ALL>, and C<--force> options.
|
||||
|
||||
=item C<< git subrepo config <subdir> <option> [<value>] [-f] >>
|
||||
|
||||
Read or update configuration values in the subdir/.gitrepo file.
|
||||
|
||||
Because most of the values stored in the .gitrepo file are generated you
|
||||
will need to use C<--force> if you want to change anything else then the
|
||||
C<method> option.
|
||||
|
||||
Example to update the C<method> option for a subrepo:
|
||||
|
||||
git subrepo config foo method rebase
|
||||
|
||||
=item C<< git subrepo help [<command>|--all] >>
|
||||
|
||||
Same as C<git help subrepo>. Will launch the manpage. For the shorter usage,
|
||||
use C<git subrepo -h>.
|
||||
|
||||
Use C<< git subrepo help <command> >> to get help for a specific command. Use
|
||||
C<--all> to get a summary of all commands.
|
||||
|
||||
The C<help> command accepts the C<--all> option.
|
||||
|
||||
=item C<git subrepo version [-q|-v]>
|
||||
|
||||
This command will display version information about git-subrepo and its
|
||||
environment. For just the version number, use C<git subrepo --version>. Use
|
||||
C<--verbose> for more version info, and C<--quiet> for less.
|
||||
|
||||
The C<version> command accepts the C<--quiet> and C<--verbose> options.
|
||||
|
||||
=item C<git subrepo upgrade>
|
||||
|
||||
Upgrade the C<git-subrepo> software itself. This simply does a C<git pull>
|
||||
on the git repository that the code is running from. It only works if you
|
||||
are on the C<master> branch. It won't work if you installed C<git-subrepo>
|
||||
using C<make install>; in that case you'll need to C<make install> from the
|
||||
latest code.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Command Options
|
||||
|
||||
=over
|
||||
|
||||
=item C<-h>
|
||||
|
||||
Show a brief view of the commands and options.
|
||||
|
||||
=item C<--help>
|
||||
|
||||
Gives an overview of the help options available for the subrepo command.
|
||||
|
||||
=item C<--version>
|
||||
|
||||
Print the git-subrepo version. Just the version number. Try the C<version>
|
||||
command for more version info.
|
||||
|
||||
=item C<--all> (C<-a>)
|
||||
|
||||
If you have multiple subrepos, issue the command to all of them (if
|
||||
applicable).
|
||||
|
||||
=item C<--ALL> (C<-A>)
|
||||
|
||||
If you have subrepos that also have subrepos themselves, issue the command to
|
||||
ALL of them. Note that the C<--ALL> option only works for a subset of the
|
||||
commands that C<--all> works for.
|
||||
|
||||
=item C<< --branch=<branch-name> >> (C<< -b <branch-name> >>)
|
||||
|
||||
Use a different upstream branch-name than the remote HEAD or the one saved in
|
||||
C<.gitrepo> locally.
|
||||
|
||||
=item C<--dry-run> (C<-N>)
|
||||
|
||||
For the push command, do everything up until the push and then print out the
|
||||
actual C<git push> command needed to finish the operation.
|
||||
|
||||
=item C<--edit> (C<-e>)
|
||||
|
||||
Edit the commit message before committing.
|
||||
|
||||
=item C<--fetch> (C<-F>)
|
||||
|
||||
Use this option to fetch the upstream commits, before running the command.
|
||||
|
||||
=item C<--force> (C<-f>)
|
||||
|
||||
Use this option to force certain commands that fail in the general case.
|
||||
|
||||
NOTE: The C<--force> option means different things for different commands.
|
||||
Read the command specific doc for the exact meaning.
|
||||
|
||||
=item C<--merge> (C<-M>)
|
||||
|
||||
Use a C<merge> strategy to include upstream subrepo commits on a pull (or
|
||||
setup for push).
|
||||
|
||||
=item C<< --message=<message> >> (C<< -m <message> >>)
|
||||
|
||||
Specify your own commit message on the command line.
|
||||
|
||||
=item C<--rebase> (C<-R>)
|
||||
|
||||
Use a C<rebase> strategy to include upstream subrepo commits on a pull (or
|
||||
setup for push).
|
||||
|
||||
=item C<< --remote=<remote-url> >> (C<< -r <remote-url> >>)
|
||||
|
||||
Use a different remote-url than the one saved in C<.gitrepo> locally.
|
||||
|
||||
=item C<--squash> (C<-s>)
|
||||
|
||||
Squash all commits on a push into one new commit.
|
||||
|
||||
=item C<--update> (C<-u>)
|
||||
|
||||
If C<--branch> or C<--remote> are used, and the command updates the
|
||||
C<.gitrepo> file, include these values to the update.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Output Options
|
||||
|
||||
=over
|
||||
|
||||
=item C<--quiet> (C<-q>)
|
||||
|
||||
Print as little info as possible. Applicable to most commands.
|
||||
|
||||
=item C<--verbose> (C<-v>)
|
||||
|
||||
Print more information about the command execution and results. Applicable to
|
||||
most commands.
|
||||
|
||||
=item C<--debug> (C<-d>)
|
||||
|
||||
Show the actual git (and other) commands being executed under the hood.
|
||||
Applicable to most commands.
|
||||
|
||||
=item C<--DEBUG> (C<-x>)
|
||||
|
||||
Use the Bash C<set -x> option which prints every command before it is
|
||||
run. VERY noisy, but extremely useful in deep debugging. Applicable to
|
||||
all commands.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Environment Variables
|
||||
|
||||
The C<git-subrepo> command exports and honors some environment variables:
|
||||
|
||||
=over
|
||||
|
||||
=item C<GIT_SUBREPO_ROOT>
|
||||
|
||||
This is set by the C<.rc> file, if you use that method to install / enable C<git-
|
||||
subrepo>. It contains the path of the C<git-subrepo> repository.
|
||||
|
||||
=item C<GIT_SUBREPO_RUNNING>
|
||||
|
||||
This variable is exported when C<git-subrepo> is running. It is set to the pid
|
||||
of the C<git-subrepo> process that is running. Other processes, like git hooks
|
||||
for instance, can use this information to adjust accordingly.
|
||||
|
||||
=item C<GIT_SUBREPO_COMMAND>
|
||||
|
||||
This variable is exported when C<git-subrepo> is running. It is set to the
|
||||
name of the C<git-subrepo> subcommand that is running.
|
||||
|
||||
=item C<GIT_SUBREPO_PAGER>
|
||||
|
||||
Use this to specify the pager to use for long output commands. Defaults to
|
||||
C<$PAGER> or C<less>.
|
||||
|
||||
=item C<GIT_SUBREPO_QUIET>
|
||||
|
||||
Set this for quiet (C<-q>) output.
|
||||
|
||||
=item C<GIT_SUBREPO_VERBOSE>
|
||||
|
||||
Set this for verbose (C<-v>) output.
|
||||
|
||||
=item C<GIT_SUBREPO_DEBUG>
|
||||
|
||||
Set this for debugging (C<-d>) output.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Installation Instructions
|
||||
|
||||
There are currently 3 ways to install C<git-subrepo>. For all of them you need
|
||||
to get the source code from GitHub:
|
||||
|
||||
git clone https://github.com/ingydotnet/git-subrepo /path/to/git-subrepo
|
||||
|
||||
The first installation method is preferred: C<source> the C<.rc> file. Just
|
||||
add a line like this one to your shell startup script:
|
||||
|
||||
source /path/to/git-subrepo/.rc
|
||||
|
||||
That will modify your C<PATH> and C<MANPATH>, and also enable command
|
||||
completion.
|
||||
|
||||
The second method is to do these things by hand. This might afford you more
|
||||
control of your shell environment. Simply add the C<lib> and C<man>
|
||||
directories to your C<PATH> and C<MANPATH>:
|
||||
|
||||
export GIT_SUBREPO_ROOT="/path/to/git-subrepo"
|
||||
export PATH="/path/to/git-subrepo/lib:$PATH"
|
||||
export MANPATH="/path/to/git-subrepo/man:$MANPATH"
|
||||
|
||||
See below for info on how to turn on Command Completion.
|
||||
|
||||
The third method is a standard system install, which puts C<git-subrepo> next
|
||||
to your other git commands:
|
||||
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
This method does not account for upgrading and command completion yet.
|
||||
|
||||
=head2 Windows
|
||||
|
||||
This command is known to work in these Windows environments:
|
||||
|
||||
=over
|
||||
|
||||
=item * Git for Windows -- L<https://git-for-windows.github.io/>
|
||||
|
||||
=item * Babun -- L<http://babun.github.io/>
|
||||
|
||||
=item * Cygwin -- L<https://www.cygwin.com/>
|
||||
|
||||
=back
|
||||
|
||||
Let us know if there are others that it works (or doesn't work) in.
|
||||
|
||||
=head1 Testing
|
||||
|
||||
The C<git-subrepo> repository comes with a extensive test suite. You can
|
||||
run it with:
|
||||
|
||||
make test
|
||||
|
||||
or if you don't have C<make> on your system:
|
||||
|
||||
prove -v test
|
||||
|
||||
=head1 Upgrading
|
||||
|
||||
If you used the C<.rc> or C<PATH> method of installation, just run this to
|
||||
upgrade C<git-subrepo>:
|
||||
|
||||
git subrepo upgrade
|
||||
|
||||
Or (same thing):
|
||||
|
||||
cd /path/to/git-subrepo
|
||||
git pull
|
||||
|
||||
If you used C<make install> method, then run this again (after C<git pull>):
|
||||
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
=head1 Command Completion
|
||||
|
||||
The C<git subrepo> command supports C<< <TAB> >>-based command completion. If
|
||||
you don't use the C<.rc> script (see Installation, above), you'll need to
|
||||
enable this manually to use it.
|
||||
|
||||
=head2 In Bash
|
||||
|
||||
If your Bash setup does not already provide command completion for Git, you'll
|
||||
need to enable that first:
|
||||
|
||||
source <Git completion script>
|
||||
|
||||
On your system, the Git completion script might be found at any of the
|
||||
following locations (or somewhere else that we don't know about):
|
||||
|
||||
=over
|
||||
|
||||
=item * C</etc/bash_completion.d/git>
|
||||
|
||||
=item * C</usr/share/bash-completion/git>
|
||||
|
||||
=item * C</usr/share/bash-completion/completions/git>
|
||||
|
||||
=item * C</opt/local/share/bash-completion/completions/git>
|
||||
|
||||
=item * C</usr/local/etc/bash_completion.d/git>
|
||||
|
||||
=item * C<~/.homebrew/etc/bash_completion.d/git>
|
||||
|
||||
=back
|
||||
|
||||
In case you can't find any of these, this repository contains a copy of the
|
||||
Git completion script:
|
||||
|
||||
source /path/to/git-subrepo/share/git-completion.bash
|
||||
|
||||
Once Git completion is enabled (whether you needed to do that manually or
|
||||
not), you can turn on C<git-subrepo> completion with a command like this:
|
||||
|
||||
source /path/to/git-subrepo/share/completion.bash
|
||||
|
||||
=head2 In zsh
|
||||
|
||||
In the Z shell (zsh), you can manually enable C<git-subrepo> completion by
|
||||
adding the following line to your C<~/.zshrc>, B<before> the C<compinit>
|
||||
function is called:
|
||||
|
||||
fpath=('/path/to/git-subrepo/share/zsh-completion' $fpath)
|
||||
|
||||
=head1 Status
|
||||
|
||||
The git-subrepo command has been in use for well over a year and seems to get
|
||||
the job done. Development is still ongoing but mostly just for fixing bugs.
|
||||
|
||||
Trying subrepo out is simple and painless (this is not C<git submodule>).
|
||||
Nothing is permanent (if you do not push to shared remotes). ie You can always
|
||||
play around and reset back to the beginning without pain.
|
||||
|
||||
This command has a test suite (run C<make test>), but surely has many bugs. If
|
||||
you have expertise with Git and subcommands, please review the code, and file
|
||||
issues on anything that seems wrong.
|
||||
|
||||
If you want to chat about the C<git-subrepo> command, join C<#gitcommands> on
|
||||
C<irc.freenode.net>.
|
||||
|
||||
=head1 Notes
|
||||
|
||||
=over
|
||||
|
||||
=item * Works on POSIX systems: Linux, BSD, OSX, etc.
|
||||
|
||||
=item * Works on various Windows environments. See "Windows" section above.
|
||||
|
||||
=item * The C<git-subrepo> repo itself has 2 subrepos under the C<ext/> subdirectory.
|
||||
|
||||
=item * Written in (very modern) Bash, with full test suite. Take a look.
|
||||
|
||||
=item * A C<.gitrepo> file never is in the top level dir (next to a C<.git/> dir).
|
||||
|
||||
=back
|
||||
|
||||
=head1 Authors
|
||||
|
||||
=over
|
||||
|
||||
=item * Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
=item * Magnus Carlsson <grimmymail@gmail.com>
|
||||
|
||||
=back
|
||||
|
||||
=head1 License and Copyright
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2020 Ingy döt Net
|
||||
|
||||
=cut
|
||||
35
build/git-subrepo/doc/comparison.swim
Normal file
35
build/git-subrepo/doc/comparison.swim
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
= Comparing `submodule` and `subrepo`
|
||||
|
||||
This document compares Git's `submodule` command to the new `subrepo` command,
|
||||
with examples and discussion of all the common operations. I'll use the term
|
||||
"External" to mean the general concept of an external repo that might be used
|
||||
as a submodule or a subrepo.
|
||||
|
||||
= Overview
|
||||
|
||||
|
||||
|
||||
= Adding a new External
|
||||
|
||||
As an owner or collaborator, you have decided to add a new External to your
|
||||
repo:
|
||||
|
||||
- Submodule :: `git submodule add git@github.com/user/external`
|
||||
- Subtree :: `git subtree --squash --prefix=external git@github.com/user/external`
|
||||
- Subrepo :: `git subrepo clone git@github.com/user/external`
|
||||
|
||||
/…to be completed…/
|
||||
|
||||
= Updating from a changed External
|
||||
|
||||
= Pushing External changes upstream
|
||||
|
||||
= Moving/Renaming an External
|
||||
|
||||
= Making an External on a branch
|
||||
|
||||
= Changing the tracking branch of an External
|
||||
|
||||
= Removing an External
|
||||
|
||||
= Migration from One to the Other
|
||||
608
build/git-subrepo/doc/git-subrepo.swim
Normal file
608
build/git-subrepo/doc/git-subrepo.swim
Normal file
|
|
@ -0,0 +1,608 @@
|
|||
git-subrepo
|
||||
===========
|
||||
|
||||
Git Submodule Alternative
|
||||
|
||||
<badge travis ingydotnet/git-subrepo>
|
||||
|
||||
= Synopsis
|
||||
|
||||
git subrepo -h # Help Overview
|
||||
|
||||
git subrepo clone <remote-url> [<subdir>]
|
||||
git subrepo init <subdir>
|
||||
git subrepo pull <subdir>
|
||||
git subrepo push <subdir>
|
||||
|
||||
git subrepo fetch <subdir>
|
||||
git subrepo branch <subdir>
|
||||
git subrepo commit <subdir>
|
||||
git subrepo config <subdir>
|
||||
|
||||
git subrepo status [<subdir>]
|
||||
git subrepo clean <subdir>
|
||||
|
||||
git subrepo help [<command> | --all]
|
||||
git subrepo version
|
||||
git subrepo upgrade
|
||||
|
||||
= Description
|
||||
|
||||
This git command "clones" an external git repo into a subdirectory of your
|
||||
repo. Later on, upstream changes can be pulled in, and local changes can be
|
||||
pushed back. Simple.
|
||||
|
||||
= Benefits
|
||||
|
||||
This command is an improvement from `git-submodule` and `git-subtree`; two
|
||||
other git commands with similar goals, but various problems.
|
||||
|
||||
It assumes there are 3 main roles of people interacting with a repo, and
|
||||
attempts to serve them all well:
|
||||
|
||||
* *owner* - The person who authors\/owns\/maintains a repo.
|
||||
* *users* - People who are just using/installing the repo.
|
||||
* *collaborators* - People who commit code to the repo and subrepos.
|
||||
|
||||
The `git-subrepo` command benefits these roles in the following ways:
|
||||
|
||||
* Simple and intuitive commandline usage (with tab completion).
|
||||
* Users get your repo and all your subrepos just by cloning your repo.
|
||||
* Users do not need to install `git-subrepo`, ever.
|
||||
* Collaborators do not need to install unless they want to push/pull.
|
||||
* Collaborators know when a subdir is a subrepo (it has a `.gitrepo` file).
|
||||
* The `.gitrepo` file never gets pushed back to the subrepo upstream.
|
||||
* Well named branches and remotes are generated for manual operations.
|
||||
* Owners do not deal with the complications of keeping submodules in sync.
|
||||
* Subrepo repositories can contain subrepos themselves.
|
||||
* Branching with subrepos JustWorks™.
|
||||
* Different branches can have different subrepos in different states, etc.
|
||||
* Moving\/renaming\/deleting a subrepo subdir JustWorks™.
|
||||
* You can `init` an existing subdirectory into a subrepo.
|
||||
* Your git history is kept squeaky clean.
|
||||
* Upstream history (clone/pull) is condensed into a single commit.
|
||||
* Pulls can use a `merge`, `rebase` or `force` strategies.
|
||||
* You can see the subrepo history with `git log subrepo/<subdir>/fetch`.
|
||||
* Commits pushed back upstream are *not* condensed (by default).
|
||||
* Trivial to try any subrepo operations and then reset back.
|
||||
* No configuration required.
|
||||
* Does not introduce history that messes up other git commands.
|
||||
* Fixes known rebase failures with `git-subtree`.
|
||||
|
||||
= Installation
|
||||
|
||||
The best short answer is:
|
||||
|
||||
git clone https://github.com/ingydotnet/git-subrepo /path/to/git-subrepo
|
||||
echo 'source /path/to/git-subrepo/.rc' >> ~/.bashrc
|
||||
|
||||
The complete "Installation Instructions" can be found below.
|
||||
|
||||
Note: git-subrepo needs a git version (> 2.7) that supports worktree:s.
|
||||
|
||||
= Commands
|
||||
|
||||
All the *subrepo* commands use names of actual Git commands and try to do
|
||||
operations that are similar to their Git counterparts. They also attempt to
|
||||
give similar output in an attempt to make the subrepo usage intuitive to
|
||||
experienced Git users.
|
||||
|
||||
Please note that the commands are /not/ exact equivalents, and do not take all
|
||||
the same arguments. Keep reading…
|
||||
|
||||
- `git subrepo clone <repository> [<subdir>] [-b <branch>] [-f] [-m <msg>] [-e] [--method <merge|rebase>]`
|
||||
|
||||
Add a repository as a subrepo in a subdir of your repository.
|
||||
|
||||
This is similar in feel to `git clone`. You just specify the remote repo
|
||||
url, and optionally a sub-directory and/or branch name. The repo will be
|
||||
fetched and merged into the subdir.
|
||||
|
||||
The subrepo history is /squashed/ into a single commit that contains the
|
||||
reference information. This information is also stored in a special file
|
||||
called `<subdir>/.gitrepo`. The presence of this file indicates that the
|
||||
directory is a subrepo.
|
||||
|
||||
All subsequent commands refer to the subrepo by the name of the /subdir/.
|
||||
From the subdir, all the current information about the subrepo can be
|
||||
obtained.
|
||||
|
||||
The `--force` option will "reclone" (completely replace) an existing subdir.
|
||||
|
||||
The `--method` option will decide how the join process between branches are
|
||||
performed. The default option is merge.
|
||||
|
||||
The `clone` command accepts the `--branch=` `--edit`, `--force` and
|
||||
`--message=` options.
|
||||
|
||||
- `git subrepo init <subdir> [-r <remote>] [-b <branch>] [--method <merge|rebase>]`
|
||||
|
||||
Turn an existing subdirectory into a subrepo.
|
||||
|
||||
If you want to expose a subdirectory of your project as a published subrepo,
|
||||
this command will do that. It will split out the content of a normal
|
||||
subdirectory into a branch and start tracking it as a subrepo. Afterwards
|
||||
your original repo will look exactly the same except that there will be a
|
||||
`<subdir>/.gitrepo` file.
|
||||
|
||||
If you specify the `--remote` (and optionally the `--branch`) option, the
|
||||
values will be added to the `<subdir>/.gitrepo` file. The `--remote` option
|
||||
is the upstream URL, and the `--branch` option is the upstream branch to push
|
||||
to. These values will be needed to do a `git subrepo push` command, but they
|
||||
can be provided later on the `push` command (and saved to `<subdir>/.gitrepo`
|
||||
if you also specify the `--update` option).
|
||||
|
||||
Note: You will need to create the empty upstream repo and push to it on your
|
||||
own, using `git subrepo push <subdir>`.
|
||||
|
||||
The `--method` option will decide how the join process between branches
|
||||
are performed. The default option is merge.
|
||||
|
||||
The `init` command accepts the `--branch=` and `--remote=` options.
|
||||
|
||||
- `git subrepo pull <subdir>|--all [-M|-R|-f] [-m <msg>] [-e] [-b <branch>] [-r <remote>] [-u]`
|
||||
|
||||
Update the subrepo subdir with the latest upstream changes.
|
||||
|
||||
The `pull` command fetches the latest content from the remote branch pointed
|
||||
to by the subrepo's `.gitrepo` file, and then tries to merge the changes into
|
||||
the corresponding subdir. It does this by making a branch of the local
|
||||
commits to the subdir and then merging or rebasing (see below) it with the
|
||||
fetched upstream content. After the merge, the content of the new branch
|
||||
replaces your subdir, the `.gitrepo` file is updated and a single 'pull'
|
||||
commit is added to your mainline history.
|
||||
|
||||
The `pull` command will attempt to do the following commands in one go:
|
||||
|
||||
git subrepo fetch <subdir>
|
||||
git subrepo branch <subdir>
|
||||
git merge/rebase subrepo/<subdir>/fetch subrepo/<subdir>
|
||||
git subrepo commit <subdir>
|
||||
# Only needed for a consequential push:
|
||||
git update-ref refs/subrepo/<subdir>/pull subrepo/<subdir>
|
||||
|
||||
In other words, you could do all the above commands yourself, for the same
|
||||
effect. If any of the commands fail, subrepo will stop and tell you to finish
|
||||
this by hand. Generally a failure would be in the merge or rebase part, where
|
||||
conflicts can happen. Since Git has lots of ways to resolve conflicts to your
|
||||
personal tastes, the subrepo command defers to letting you do this by hand.
|
||||
|
||||
When pulling new data, the method selected in clone/init is used. This has
|
||||
no effect on the final result of the pull, since it becomes a single commit.
|
||||
But it does affect the resulting `subrepo/<subdir>` branch, which is often
|
||||
used for a subrepo `push` command. See 'push' below for more information.
|
||||
If you want to change the method you can use the `config` command for this.
|
||||
|
||||
When you pull you can assume a fast-forward strategy (default) or you can
|
||||
specify a `--rebase`, `--merge` or `--force` strategy. The latter is the same
|
||||
as a `clone --force` operation, using the current remote and branch.
|
||||
|
||||
Like the `clone` command, `pull` will squash all the changes (since the last
|
||||
pull or clone) into one commit. This keeps your mainline history nice and
|
||||
clean. You can easily see the subrepo's history with the `git log` command:
|
||||
|
||||
git log refs/subrepo/<subdir>/fetch
|
||||
|
||||
The set of commands used above are described in detail below.
|
||||
|
||||
The `pull` command accepts the `--all`, `--branch=`, `--edit`, `--force`,
|
||||
`--message=`, `--remote=` and `--update` options.
|
||||
|
||||
- `git subrepo push <subdir>|--all [<branch>] [-r <remote>] [-b <branch>] [-M|-R] [-u] [-f] [-s] [-N]`
|
||||
|
||||
Push a properly merged subrepo branch back upstream.
|
||||
|
||||
This command takes the subrepo branch from a successful pull command and
|
||||
pushes the history back to its designated remote and branch. You can also use
|
||||
the `branch` command and merge things yourself before pushing if you want to
|
||||
(although that is probably a rare use case).
|
||||
|
||||
The `push` command requires a branch that has been properly merged/rebased
|
||||
with the upstream HEAD (unless the upstream HEAD is empty, which is common
|
||||
when doing a first `push` after an `init`). That means the upstream HEAD is
|
||||
one of the commits in the branch.
|
||||
|
||||
By default the branch ref `refs/subrepo/<subdir>/pull` will be pushed, but
|
||||
you can specify a (properly merged) branch to push.
|
||||
|
||||
After that, the `push` command just checks that the branch contains the
|
||||
upstream HEAD and then pushes it upstream.
|
||||
|
||||
The `--force` option will do a force push. Force pushes are typically
|
||||
discouraged. Only use this option if you fully understand it. (The `--force`
|
||||
option will NOT check for a proper merge. ANY branch will be force pushed!)
|
||||
|
||||
The `push` command accepts the `--all`, `--branch=`, `--dry-run`, `--force`,
|
||||
`--merge`, `--rebase`, `--remote=`, `--squash` and `--update` options.
|
||||
|
||||
- `git subrepo fetch <subdir>|--all [-r <remote>] [-b <branch>]`
|
||||
|
||||
Fetch the remote/upstream content for a subrepo.
|
||||
|
||||
It will create a Git reference called `subrepo/<subdir>/fetch` that points at
|
||||
the same commit as `FETCH_HEAD`. It will also create a remote called
|
||||
`subrepo/<subdir>`. These are temporary and you can easily remove them with
|
||||
the subrepo `clean` command.
|
||||
|
||||
The `fetch` command accepts the `--all`, `--branch=` and `--remote=` options.
|
||||
|
||||
- `git subrepo branch <subdir>|--all [-f] [-F]`
|
||||
|
||||
Create a branch with local subrepo commits.
|
||||
|
||||
Scan the history of the mainline for all the commits that affect the `subdir`
|
||||
and create a new branch from them called `subrepo/<subdir>`.
|
||||
|
||||
This is useful for doing `pull` and `push` commands by hand.
|
||||
|
||||
Use the `--force` option to write over an existing `subrepo/<subdir>` branch.
|
||||
|
||||
The `branch` command accepts the `--all`, `--fetch` and `--force` options.
|
||||
|
||||
- `git subrepo commit <subdir> [<subrepo-ref>] [-m <msg>] [-e] [-f] [-F]`
|
||||
|
||||
Add subrepo branch to current history as a single commit.
|
||||
|
||||
This command is generally used after a hand-merge. You have done a `subrepo
|
||||
branch` and merged (rebased) it with the upstream. This command takes the
|
||||
HEAD of that branch, puts its content into the subrepo subdir and adds a new
|
||||
commit for it to the top of your mainline history.
|
||||
|
||||
This command requires that the upstream HEAD be in the `subrepo/<subdir>`
|
||||
branch history. That way the same branch can push upstream. Use the
|
||||
`--force` option to commit anyway.
|
||||
|
||||
The `commit` command accepts the `--edit`, `--fetch`, `--force` and
|
||||
`--message=` options.
|
||||
|
||||
- `git subrepo status [<subdir>|--all|--ALL] [-F] [-q|-v]`
|
||||
|
||||
Get the status of a subrepo. Uses the `--all` option by default. If the
|
||||
`--quiet` flag is used, just print the subrepo names, one per line.
|
||||
|
||||
The `--verbose` option will show all the recent local and upstream commits.
|
||||
|
||||
Use `--ALL` to show the subrepos of the subrepos (ie the "subsubrepos"), if
|
||||
any.
|
||||
|
||||
The `status` command accepts the `--all`, `--ALL`, `--fetch`, `--quiet` and
|
||||
`--verbose` options.
|
||||
|
||||
- `git subrepo clean <subdir>|--all|--ALL [-f]`
|
||||
|
||||
Remove artifacts created by `fetch` and `branch` commands.
|
||||
|
||||
The `fetch` and `branch` operations (and other commands that call them)
|
||||
create temporary things like refs, branches and remotes. This command
|
||||
removes all those things.
|
||||
|
||||
Use `--force` to remove refs. Refs are not removed by default because they
|
||||
are sometimes needed between commands.
|
||||
|
||||
Use `--all` to clean up after all the current subrepos. Sometimes you might
|
||||
change to a branch where a subrepo doesn't exist, and then `--all` won't find
|
||||
it. Use `--ALL` to remove any artifacts that were ever created by subrepo.
|
||||
|
||||
To remove ALL subrepo artifacts:
|
||||
|
||||
git subrepo clean --ALL --force
|
||||
|
||||
The `clean` command accepts the `--all`, `--ALL`, and `--force` options.
|
||||
|
||||
- `git subrepo config <subdir> <option> [<value>] [-f]`
|
||||
|
||||
Read or update configuration values in the subdir/.gitrepo file.
|
||||
|
||||
Because most of the values stored in the .gitrepo file are generated you
|
||||
will need to use `--force` if you want to change anything else then the
|
||||
`method` option.
|
||||
|
||||
Example to update the `method` option for a subrepo:
|
||||
|
||||
git subrepo config foo method rebase
|
||||
|
||||
- `git subrepo help [<command>|--all]`
|
||||
|
||||
Same as `git help subrepo`. Will launch the manpage. For the shorter usage,
|
||||
use `git subrepo -h`.
|
||||
|
||||
Use `git subrepo help <command>` to get help for a specific command. Use
|
||||
`--all` to get a summary of all commands.
|
||||
|
||||
The `help` command accepts the `--all` option.
|
||||
|
||||
- `git subrepo version [-q|-v]`
|
||||
|
||||
This command will display version information about git-subrepo and its
|
||||
environment. For just the version number, use `git subrepo --version`. Use
|
||||
`--verbose` for more version info, and `--quiet` for less.
|
||||
|
||||
The `version` command accepts the `--quiet` and `--verbose` options.
|
||||
|
||||
- `git subrepo upgrade`
|
||||
|
||||
Upgrade the `git-subrepo` software itself. This simply does a `git pull` on
|
||||
the git repository that the code is running from. It only works if you are on
|
||||
the `master` branch. It won't work if you installed `git-subrepo` using `make
|
||||
install`; in that case you'll need to `make install` from the latest code.
|
||||
|
||||
= Command Options
|
||||
|
||||
- `-h`
|
||||
|
||||
Show a brief view of the commands and options.
|
||||
|
||||
- `--help`
|
||||
|
||||
Gives an overview of the help options available for the subrepo command.
|
||||
|
||||
- `--version`
|
||||
|
||||
Print the git-subrepo version. Just the version number. Try the `version`
|
||||
command for more version info.
|
||||
|
||||
- `--all` (`-a`)
|
||||
|
||||
If you have multiple subrepos, issue the command to all of them (if
|
||||
applicable).
|
||||
|
||||
- `--ALL` (`-A`)
|
||||
|
||||
If you have subrepos that also have subrepos themselves, issue the command to
|
||||
ALL of them. Note that the `--ALL` option only works for a subset of the
|
||||
commands that `--all` works for.
|
||||
|
||||
- `--branch=<branch-name>` (`-b <branch-name>`)
|
||||
|
||||
Use a different upstream branch-name than the remote HEAD or the one saved in
|
||||
`.gitrepo` locally.
|
||||
|
||||
- `--dry-run` (`-N`)
|
||||
|
||||
For the push command, do everything up until the push and then print out the
|
||||
actual `git push` command needed to finish the operation.
|
||||
|
||||
- `--edit` (`-e`)
|
||||
|
||||
Edit the commit message before committing.
|
||||
|
||||
- `--fetch` (`-F`)
|
||||
|
||||
Use this option to fetch the upstream commits, before running the command.
|
||||
|
||||
- `--force` (`-f`)
|
||||
|
||||
Use this option to force certain commands that fail in the general case.
|
||||
|
||||
NOTE: The `--force` option means different things for different commands.
|
||||
Read the command specific doc for the exact meaning.
|
||||
|
||||
- `--merge` (`-M`)
|
||||
|
||||
Use a `merge` strategy to include upstream subrepo commits on a pull (or
|
||||
setup for push).
|
||||
|
||||
- `--message=<message>` (`-m <message>`)
|
||||
|
||||
Specify your own commit message on the command line.
|
||||
|
||||
- `--rebase` (`-R`)
|
||||
|
||||
Use a `rebase` strategy to include upstream subrepo commits on a pull (or
|
||||
setup for push).
|
||||
|
||||
- `--remote=<remote-url>` (`-r <remote-url>`)
|
||||
|
||||
Use a different remote-url than the one saved in `.gitrepo` locally.
|
||||
|
||||
- `--squash` (`-s`)
|
||||
|
||||
Squash all commits on a push into one new commit.
|
||||
|
||||
- `--update` (`-u`)
|
||||
|
||||
If `--branch` or `--remote` are used, and the command updates the `.gitrepo`
|
||||
file, include these values to the update.
|
||||
|
||||
= Output Options
|
||||
|
||||
- `--quiet` (`-q`)
|
||||
|
||||
Print as little info as possible. Applicable to most commands.
|
||||
|
||||
- `--verbose` (`-v`)
|
||||
|
||||
Print more information about the command execution and results. Applicable
|
||||
to most commands.
|
||||
|
||||
- `--debug` (`-d`)
|
||||
|
||||
Show the actual git (and other) commands being executed under the hood.
|
||||
Applicable to most commands.
|
||||
|
||||
- `--DEBUG` (`-x`)
|
||||
|
||||
Use the Bash `set -x` option which prints every command before it is run.
|
||||
VERY noisy, but extremely useful in deep debugging. Applicable to all
|
||||
commands.
|
||||
|
||||
= Environment Variables
|
||||
|
||||
The `git-subrepo` command exports and honors some environment variables:
|
||||
|
||||
- `GIT_SUBREPO_ROOT`
|
||||
|
||||
This is set by the `.rc` file, if you use that method to install / enable
|
||||
`git-subrepo`. It contains the path of the `git-subrepo` repository.
|
||||
|
||||
- `GIT_SUBREPO_RUNNING`
|
||||
|
||||
This variable is exported when `git-subrepo` is running. It is set to the pid
|
||||
of the `git-subrepo` process that is running. Other processes, like git hooks
|
||||
for instance, can use this information to adjust accordingly.
|
||||
|
||||
- `GIT_SUBREPO_COMMAND`
|
||||
|
||||
This variable is exported when `git-subrepo` is running. It is set to the
|
||||
name of the `git-subrepo` subcommand that is running.
|
||||
|
||||
- `GIT_SUBREPO_PAGER`
|
||||
|
||||
Use this to specify the pager to use for long output commands. Defaults to
|
||||
`$PAGER` or `less`.
|
||||
|
||||
- `GIT_SUBREPO_QUIET`
|
||||
|
||||
Set this for quiet (`-q`) output.
|
||||
|
||||
- `GIT_SUBREPO_VERBOSE`
|
||||
|
||||
Set this for verbose (`-v`) output.
|
||||
|
||||
- `GIT_SUBREPO_DEBUG`
|
||||
|
||||
Set this for debugging (`-d`) output.
|
||||
|
||||
= Installation Instructions
|
||||
|
||||
There are currently 3 ways to install `git-subrepo`. For all of them you need
|
||||
to get the source code from GitHub:
|
||||
|
||||
git clone https://github.com/ingydotnet/git-subrepo /path/to/git-subrepo
|
||||
|
||||
The first installation method is preferred: `source` the `.rc` file. Just add a
|
||||
line like this one to your shell startup script:
|
||||
|
||||
source /path/to/git-subrepo/.rc
|
||||
|
||||
That will modify your `PATH` and `MANPATH`, and also enable command completion.
|
||||
|
||||
The second method is to do these things by hand. This might afford you more
|
||||
control of your shell environment. Simply add the `lib` and `man` directories
|
||||
to your `PATH` and `MANPATH`:
|
||||
|
||||
export GIT_SUBREPO_ROOT="/path/to/git-subrepo"
|
||||
export PATH="/path/to/git-subrepo/lib:$PATH"
|
||||
export MANPATH="/path/to/git-subrepo/man:$MANPATH"
|
||||
|
||||
See below for info on how to turn on Command Completion.
|
||||
|
||||
The third method is a standard system install, which puts `git-subrepo` next to
|
||||
your other git commands:
|
||||
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
This method does not account for upgrading and command completion yet.
|
||||
|
||||
== Windows
|
||||
|
||||
This command is known to work in these Windows environments:
|
||||
|
||||
* Git for Windows -- https://git-for-windows.github.io/
|
||||
* Babun -- http://babun.github.io/
|
||||
* Cygwin -- https://www.cygwin.com/
|
||||
|
||||
Let us know if there are others that it works (or doesn't work) in.
|
||||
|
||||
= Testing
|
||||
|
||||
The `git-subrepo` repository comes with a extensive test suite. You can run it
|
||||
with:
|
||||
|
||||
make test
|
||||
|
||||
or if you don't have `make` on your system:
|
||||
|
||||
prove -v test
|
||||
|
||||
= Upgrading
|
||||
|
||||
If you used the `.rc` or `PATH` method of installation, just run this to
|
||||
upgrade `git-subrepo`:
|
||||
|
||||
git subrepo upgrade
|
||||
|
||||
Or (same thing):
|
||||
|
||||
cd /path/to/git-subrepo
|
||||
git pull
|
||||
|
||||
If you used `make install` method, then run this again (after `git pull`):
|
||||
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
= Command Completion
|
||||
|
||||
The `git subrepo` command supports `<TAB>`-based command completion. If you
|
||||
don't use the `.rc` script (see Installation, above), you'll need to enable
|
||||
this manually to use it.
|
||||
|
||||
== In Bash
|
||||
|
||||
If your Bash setup does not already provide command completion for Git, you'll
|
||||
need to enable that first:
|
||||
|
||||
source <Git completion script>
|
||||
|
||||
On your system, the Git completion script might be found at any of the
|
||||
following locations (or somewhere else that we don't know about):
|
||||
|
||||
* `/etc/bash_completion.d/git`
|
||||
* `/usr/share/bash-completion/git`
|
||||
* `/usr/share/bash-completion/completions/git`
|
||||
* `/opt/local/share/bash-completion/completions/git`
|
||||
* `/usr/local/etc/bash_completion.d/git`
|
||||
* `~/.homebrew/etc/bash_completion.d/git`
|
||||
|
||||
In case you can't find any of these, this repository contains a copy of the
|
||||
Git completion script:
|
||||
|
||||
source /path/to/git-subrepo/share/git-completion.bash
|
||||
|
||||
Once Git completion is enabled (whether you needed to do that manually or
|
||||
not), you can turn on `git-subrepo` completion with a command like this:
|
||||
|
||||
source /path/to/git-subrepo/share/completion.bash
|
||||
|
||||
== In zsh
|
||||
|
||||
In the Z shell (zsh), you can manually enable `git-subrepo` completion by
|
||||
adding the following line to your `~/.zshrc`, *before* the `compinit` function
|
||||
is called:
|
||||
|
||||
fpath=('/path/to/git-subrepo/share/zsh-completion' $fpath)
|
||||
|
||||
= Status
|
||||
|
||||
The git-subrepo command has been in use for well over a year and seems to get
|
||||
the job done. Development is still ongoing but mostly just for fixing bugs.
|
||||
|
||||
Trying subrepo out is simple and painless (this is not `git submodule`).
|
||||
Nothing is permanent (if you do not push to shared remotes). ie You can always
|
||||
play around and reset back to the beginning without pain.
|
||||
|
||||
This command has a test suite (run `make test`), but surely has many bugs. If
|
||||
you have expertise with Git and subcommands, please review the code, and file
|
||||
issues on anything that seems wrong.
|
||||
|
||||
If you want to chat about the `git-subrepo` command, join `#gitcommands` on
|
||||
`irc.freenode.net`.
|
||||
|
||||
= Notes
|
||||
|
||||
* Works on POSIX systems: Linux, BSD, OSX, etc.
|
||||
* Works on various Windows environments. See "Windows" section above.
|
||||
* The `git-subrepo` repo itself has 2 subrepos under the `ext/` subdirectory.
|
||||
* Written in (very modern) Bash, with full test suite. Take a look.
|
||||
* A `.gitrepo` file never is in the top level dir (next to a `.git/` dir).
|
||||
|
||||
= Authors
|
||||
|
||||
* Ingy döt Net <ingy@ingy.net>
|
||||
* Magnus Carlsson <grimmymail@gmail.com>
|
||||
|
||||
= License and Copyright
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013-2020 Ingy döt Net
|
||||
387
build/git-subrepo/doc/intro-to-subrepo.swim
Normal file
387
build/git-subrepo/doc/intro-to-subrepo.swim
Normal file
|
|
@ -0,0 +1,387 @@
|
|||
= Introducing Git Subrepos
|
||||
|
||||
There is a new git command called `subrepo` that is meant to be a solid
|
||||
alternative to the `submodule` and `subtree` commands. All 3 of these commands
|
||||
allow you to include external repositories (pinned to specific commits) in
|
||||
your main repository. This is an often needed feature for project development
|
||||
under a source control system like Git. Unfortunately, the `submodule` command
|
||||
is severely lacking, and the `subtree` command (an attempt to make things
|
||||
better) is also very flawed. Fortunately, the `subrepo` command is here to
|
||||
save the day.
|
||||
|
||||
This article will discuss how the previous commands work, and where they go
|
||||
wrong, while explaining how the new `subrepo` command fixes the issues.
|
||||
|
||||
It should be noted that there are 3 distinct roles (ways people use repos)
|
||||
involved in discussing this topic:
|
||||
|
||||
* *owner* — The primary author and repo owner
|
||||
* *collaborators* — Other developers who contribute to the repo
|
||||
* *users* — People who simply use the repo software
|
||||
|
||||
== Introducing `subrepo`
|
||||
|
||||
While the main point is to show how subrepo addresses the shortcomings of
|
||||
submodule and subtree, I'll start by giving a quick intro to the subrepo
|
||||
command.
|
||||
|
||||
Let's say that you have a project repo called 'freebird' and you want to have
|
||||
it include 2 other external repos, 'lynyrd' and 'skynyrd'. You would do the
|
||||
following:
|
||||
|
||||
git clone git@github.com/you/freebird
|
||||
cd freebird
|
||||
git subrepo clone git@github.com/you/lynyrd ext/lynyrd
|
||||
git subrepo clone git@github.com/you/skynyrd ext/skynyrd --branch=1975
|
||||
|
||||
What these commands do (at a high level) should be obvious. They "clone"
|
||||
(add) the repos content into the subdirectories you told them to. The details
|
||||
of what is happening to your repo will be discussed later, but adding new
|
||||
subrepos is easy. If you need to update the subrepos later:
|
||||
|
||||
git subrepo pull ext/lynyrd
|
||||
git subrepo pull ext/skynyrd --branch=1976
|
||||
|
||||
The lynyrd repo is tracking the upstream master branch, and you've changed the
|
||||
skynyrd subrepo to the 1976 branch. Since these subrepos are owned by 'you',
|
||||
you might want to change them in the context of your freebird repo. When
|
||||
things are working, you can push the subrepo changes back:
|
||||
|
||||
git subrepo push ext/lynyrd
|
||||
git subrepo push ext/skynyrd
|
||||
|
||||
Looks simple right? It's supposed to be. The intent of `subrepo` is to do the
|
||||
right things, and to not cause problems.
|
||||
|
||||
Of course there's more to it under the hood, and that's what the rest of this
|
||||
article is about.
|
||||
|
||||
== Git Submodules
|
||||
|
||||
Submodules tend to receive a lot of bad press. Here's some of it:
|
||||
|
||||
* http://ayende.com/blog/4746/the-problem-with-git-submodules
|
||||
* http://somethingsinistral.net/blog/git-submodules-are-probably-not-the-answer/
|
||||
* http://codingkilledthecat.wordpress.com/2012/04/28/why-your-company-shouldnt-use-git-submodules/
|
||||
|
||||
A quick recap of some of the good and bad things about submodules:
|
||||
|
||||
Good:
|
||||
|
||||
* Use an external repo in a dedicated subdir of your project.
|
||||
* Pin the external repo to a specific commit.
|
||||
* The `git-submodule` command is a core part of the Git project.
|
||||
|
||||
Bad:
|
||||
|
||||
* Users have to know a repo has submodules.
|
||||
* Users have to get the subrepos manually.
|
||||
* Pulling a repo with submodules won't pull in the new submodule changes.
|
||||
* A submodule will break if the referenced repo goes away.
|
||||
* A submodule will break if a forced push removes the referenced commit.
|
||||
* Can't use different submodules/commits per main project branch.
|
||||
* Can't "try out" a submodule on alternate branch.
|
||||
* Main repo can be pushed upstream pointing to unpushed submod commits.
|
||||
* Command capability differs across Git versions.
|
||||
* Often need to change remote url, to push submodule changes upstream.
|
||||
* Removing or renaming a submodule requires many steps.
|
||||
|
||||
Internally, submodules are a real mess. They give the strong impression of
|
||||
being bolted on, well after Git was designed. Some commands are aware of the
|
||||
existence of submodules (although usually half-heartedly), and many commands
|
||||
are oblivious. For instance the git-clone command has a `--recursive` option
|
||||
to clone all subrepos, but it's not a default, so you still need to be aware
|
||||
of the need. The git-checkout command does nothing with the submodules, even
|
||||
if they are intended to differ across branches.
|
||||
|
||||
Let's talk a bit about how submodules are implemented in Git. Information
|
||||
about them is stored in 3 different places (in the top level repo directory):
|
||||
|
||||
* `.gitmodules`
|
||||
* `.git/config`
|
||||
* `.git/modules` — The submodule repo's meta data (refs/objects)
|
||||
|
||||
So some of the information lives in the repo history (.gitmodules), but other
|
||||
info (.git/) is only known to the local repo.
|
||||
|
||||
In addition, the submodule introduces a new low level concept, to the
|
||||
commit/tree/blob graph. Normally a git tree object points to blob (file)
|
||||
objects and more tree (directory) objects. Submodules have tree objects point
|
||||
to *commit* objects. While this seems clever and somewhat reasonable, it also
|
||||
means that every other git command (which was built on the super clean Git
|
||||
data model) has to be aware of this new possibility (and deal with it
|
||||
appropriately).
|
||||
|
||||
The point is that, while submodules are a real need, and a lot of work has
|
||||
gone into making them work decently, they are essentially a kludge to the Git
|
||||
model, and it is quite understandable why they haven't worked out as well as
|
||||
people would expect.
|
||||
|
||||
NOTE: Submodules /are/ getting better with each release of Git, but it's still
|
||||
an endless catch up game.
|
||||
|
||||
== Git Subtrees
|
||||
|
||||
One day, someone decided to think different. Instead of pointing to external
|
||||
repos, why not just include them into the main repo (but also allow them to be
|
||||
pulled and pushed separately as needed)?
|
||||
|
||||
At first this may feel like a wasteful approach. Why keep other repos
|
||||
physically inside your main one? But if you think about it abstractly, what's
|
||||
the difference? You want your users and collaborators to have all this code
|
||||
because your project needs it. So why worry about how it happens? In the end,
|
||||
the choice is yours, but I've grown very comfortable with this concept and
|
||||
I'll try to justify it well. I should note that the first paragraph of the
|
||||
`submodule` doc suggests considering this alternative.
|
||||
|
||||
The big win here is that you can do this using the existing git model.
|
||||
Nothing new is added. You are just adding commits to a history. You can do it
|
||||
different on every branch. You can merge branches sensibly.
|
||||
|
||||
The git-subtree command seems to have been inspired by Git's subtree merge
|
||||
strategy, which it uses internally, and possibly got its name from. A subtree
|
||||
merge allows you to take a completely separate Git history and make it be a
|
||||
subdirectory of your repo.
|
||||
|
||||
Adding a subtree was the easy part. All that needed to be done after that was
|
||||
to figure out a way to pull upstream changes and push local ones back
|
||||
upstream. And that's what the `git-subtree` command does.
|
||||
|
||||
So what's the problem with git-subtree then?
|
||||
|
||||
Well unfortunately, it drops a few balls. The main problems come down to an
|
||||
overly complicated commandline UX, poor collaborator awareness, and a fragile
|
||||
and messy implementation.
|
||||
|
||||
Good:
|
||||
|
||||
* Use an external repo in a dedicated subdir of your project.
|
||||
* Pin the external repo to a specific commit.
|
||||
* Users get everything with a normal clone command.
|
||||
* Users don't need to know that subtrees are involved.
|
||||
* Can use different submodules/commits per main project branch.
|
||||
* Users don't need the subtree command. Only owners and collaborators.
|
||||
|
||||
Bad:
|
||||
* The remote url and branch info is not saved (except in the history).
|
||||
* Owners and collaborators have to enter the remote for every command.
|
||||
* Collaborators aren't made aware that subtrees are involved.
|
||||
* Pulled history is not squashed by default.
|
||||
* Creates a messy historical view. (See below)
|
||||
* Bash code is complicated.
|
||||
* Only one test file. Currently is failing.
|
||||
|
||||
As you can see, subtree makes quite a few things better, but after trying it
|
||||
for a while, the experience was more annoying than submodules. For example,
|
||||
consider this usage:
|
||||
|
||||
$ git subtree add --squash --prefix=foo git@github.com:my/thing mybranch
|
||||
# weeks go by…
|
||||
$ git subtree pull --squash --prefix=foo git@github.com:my/thing mybranch
|
||||
# time to push local subtree changes back upstream
|
||||
$ git subtree push --prefix=foo git@github.com:my/thing mybranch
|
||||
|
||||
The first thing you notice is the overly verbose syntax. It's justified in the
|
||||
first command, but in the other 2 commands I really don't want to have to
|
||||
remember what the remote and branch are that I'm using.
|
||||
|
||||
Moreover, my collaborators have no idea that subtrees are involved, let alone
|
||||
where they came from.
|
||||
|
||||
Consider the equivalent subrepo commands:
|
||||
|
||||
$ git subrepo clone git@github.com:my/thing foo -b mybranch
|
||||
$ git subrepo pull foo
|
||||
$ git subrepo push foo
|
||||
|
||||
Collaborators see a file called 'foo/.gitrepo', and know that the subdir is a
|
||||
subrepo. The file contains all the information needed by future commands
|
||||
applied to that subrepo.
|
||||
|
||||
== Git Subrepos
|
||||
|
||||
Now is a good time to dive into the techinical aspects of the `subrepo`
|
||||
command, but first let me explain how it came about.
|
||||
|
||||
As you may have surmised by now, I am the author of git-subrepo. I'd used
|
||||
submodules on and off for years, and when I became aware of subtree I gave it
|
||||
a try, but I quickly realized its problems. I decided maybe it could be
|
||||
improved. I decided to write down my expected commandline usage and my ideals
|
||||
of what it would and would not do. Then I set off to implement it. It's been a
|
||||
long road, but what I ended up with was even better than what I wanted from
|
||||
the start.
|
||||
|
||||
Let's review the Goods and Bads:
|
||||
|
||||
Good:
|
||||
|
||||
* Use an external repo in a dedicated subdir of your project.
|
||||
* Pin the external repo to a specific commit.
|
||||
* Users get everything with a normal clone command.
|
||||
* Users don't need to know that subrepos are involved.
|
||||
* Can use different submodules/commits per main project branch.
|
||||
* Meta info is kept in an obvious place.
|
||||
* Everyone knows when a subdir is a subrepo.
|
||||
* Commandline UX is minimal and intuitive.
|
||||
* Pulled history is always squashed out locally.
|
||||
* Pushed history is kept intact.
|
||||
* Creates a clean historical view. (See below)
|
||||
* Bash code is very simple and easy to follow.
|
||||
* Comprehensive test suite. Currently passing on travis:
|
||||
|
||||
<badge travis ingydotnet/git-subrepo>
|
||||
|
||||
Bad:
|
||||
|
||||
* --Subrepo is very new.-- (no longer true)
|
||||
* --Not well tested in the wild.-- (no longer true)
|
||||
|
||||
This review may seem somewhat slanted, but I honestly am not aware of any
|
||||
"bad" points that I'm not disclosing. That said, I am sure time will reveal
|
||||
bugs and shortcomings. Those can usually be fixed. Hopefully the *model* is
|
||||
correct, because that's harder to fix down the road.
|
||||
|
||||
OK. So how does it all work?
|
||||
|
||||
There are 3 main commands: clone/pull/push. Let's start with the clone
|
||||
command. This is the easiest part. You give it a remote url, possibly a new
|
||||
subdir to put it, and possibly a remote branch to use. I say possibly, because
|
||||
the command can guess the subdir name (just like the git-clone command does),
|
||||
and the branch can be the upstream default branch.
|
||||
|
||||
Given this we do the following steps internally:
|
||||
|
||||
* Fetch the remote content (for a specific refspec)
|
||||
* Read the remote head tree into the index
|
||||
* Checkout the index into the new subdir
|
||||
* Create a new subrepo commit object for the subdir content
|
||||
* Add a state file called .gitrepo to the new subrepo/subdir
|
||||
* Amend the merge commit with this new file
|
||||
|
||||
This process adds something like this to the top of your history:
|
||||
|
||||
* 9b6ddc9 git subrepo clone git@github.com:you/foo.git foo/
|
||||
* 37c61a5 Previous head commit of your repo
|
||||
|
||||
The entire history has been squashed down into one commit, and placed on top of
|
||||
your history. This is important as it keeps your history as clean as possible.
|
||||
You don't need to have the subrepo history in your main project, since it is
|
||||
immutably available elsewhere, and you have a pointer to that place.
|
||||
|
||||
The new foo/.gitrepo file looks like this:
|
||||
|
||||
[subrepo]
|
||||
remote = git@github.com:you/foo.git
|
||||
branch = master
|
||||
commit = 14c96c6931b41257b2d42b2edc67ddc659325823
|
||||
parent = 37c61a5a234f5dd6f5c2aec037509f50d3a79b8f
|
||||
cmdver = 0.1.0
|
||||
|
||||
It contains all the info needed now and later. Note that the repo url is the
|
||||
generally pushable form, rather than the publically readable (https://…) form.
|
||||
This is the best practice. Users of your repo don't need access to this url,
|
||||
because the content is already in your repo. Only you and your collaborators
|
||||
need this url to pull/push in the future.
|
||||
|
||||
The next command is the pull command. Normally you just give it the subrepo's
|
||||
subdir path (although you can change the branch with -b), and it will get the
|
||||
other info from the subdir/.gitrepo file.
|
||||
|
||||
The pull command does these steps:
|
||||
|
||||
* Fetch the upstream content
|
||||
* Check if anything needs pulling
|
||||
* Create a branch of local subrepo commits since last pull
|
||||
* Rebase this branch onto the upstream commits
|
||||
* Commit the HEAD of the rebased content
|
||||
* Update/amend the .gitrepo file
|
||||
|
||||
=== Clean History
|
||||
|
||||
I've talked a bit about clean history but let me show you a comparison between
|
||||
subrepo and subtree. Let's run this command sequence using both methods. Note
|
||||
the differences between /both/ the command syntax required, and the branch
|
||||
history produced.
|
||||
|
||||
Subrepo first:
|
||||
|
||||
$ git subrepo clone git@github.com:user/abc
|
||||
$ git subrepo clone git@github.com:user/def xyz
|
||||
$ git subrepo pull abc
|
||||
$ git subrepo pull xyz
|
||||
|
||||
The resulting history is:
|
||||
|
||||
* b1f60cc subrepo pull xyz
|
||||
* 4fb0276 subrepo pull abc
|
||||
* bcef2a0 subrepo clone git@github.com:user/def xyz
|
||||
* bebf0db subrepo clone git@github.com:user/abc
|
||||
* 64eeaa6 (origin/master, origin/HEAD) O HAI FREND
|
||||
|
||||
Compare that to *subtree*. This:
|
||||
|
||||
$ git subtree add abc git@github.com:user/abc master
|
||||
$ git subtree add xyz git@github.com:user/def master
|
||||
$ git subtree pull abc git@github.com:user/abc master
|
||||
$ git subtree pull xyz git@github.com:user/def master
|
||||
|
||||
Produces this:
|
||||
|
||||
* 739e45a (HEAD, master) Merge commit '5f563469d886d53e19cb908b3a64e4229f88a2d1'
|
||||
|\
|
||||
| * 5f56346 Squashed 'xyz/' changes from 08c7421..365409f
|
||||
* | 641f5e5 Merge commit '8d88e90ce5f653ed2e7608a71b8693a2174ea62a'
|
||||
|\ \
|
||||
| * | 8d88e90 Squashed 'abc/' changes from 08c7421..365409f
|
||||
* | | 1703ed2 Merge commit '0e091b672c4bbbbf6bc4f6694c475d127ffa21eb' as 'xyz'
|
||||
|\ \ \
|
||||
| | |/
|
||||
| |/|
|
||||
| * | 0e091b6 Squashed 'xyz/' content from commit 08c7421
|
||||
| /
|
||||
* | 07b77e7 Merge commit 'cd2b30a0229d931979ed4436b995875ec563faea' as 'abc'
|
||||
|\ \
|
||||
| |/
|
||||
| * cd2b30a Squashed 'abc/' content from commit 08c7421
|
||||
* 64eeaa6 (origin/master, origin/HEAD) O HAI FREND
|
||||
|
||||
This was from a minimal case. Subtree history (when viewed this way at least)
|
||||
gets unreasonably ugly fast. Subrepo history, by contrast, always looks as
|
||||
clean as shown.
|
||||
|
||||
The final command, push, bascially just does the pull/rebase dance above
|
||||
described, and pushes the resulting history back. It does not squash the
|
||||
commits made locally, because it assumed that when you changed the local
|
||||
subrepo, you made messages that were intended to eventually be published back
|
||||
upstream.
|
||||
|
||||
== Conflict Resolution
|
||||
|
||||
The commands described above can also be done "by hand". If something fails
|
||||
during a pull or push (generally in the rebasing) then the command will tell
|
||||
you what to do to finish up.
|
||||
|
||||
You might choose to do everything by hand, and do your own merging strategies.
|
||||
This is perfectly reasonable. The `subrepo` command offers a few other helper
|
||||
commands to help you get the job done:
|
||||
|
||||
* `fetch` - Fetch the upstream and create a `subrepo/remote/<subdir>` ref.
|
||||
* `branch` - Create a branch of local subdir commits since the last pull,
|
||||
called `subrepo/<subdir>`.
|
||||
* `commit` - Commit a merged branch's HEAD back into your repo.
|
||||
* `status` - Show lots of useful info about the current state of the subrepos.
|
||||
* `clean` - Remove branches, ref and remotes created by subrepo commands.
|
||||
* `help` - Read the complete documentation!
|
||||
|
||||
== Conclusion
|
||||
|
||||
Hopefully by now, you see that submodules are a painful choice with a dubious
|
||||
future, and that subtree, while a solid idea has many usage issues.
|
||||
|
||||
Give `subrepo` a try. It's painless, easily revertable and just might be what
|
||||
the doctor ordered.
|
||||
|
||||
== Reference Links
|
||||
|
||||
* http://longair.net/blog/2010/06/02/git-submodules-explained/
|
||||
* http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
|
||||
11
build/git-subrepo/ext/bashplus/.gitrepo
Normal file
11
build/git-subrepo/ext/bashplus/.gitrepo
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:ingydotnet/bashplus.git
|
||||
branch = master
|
||||
commit = d9183af6f46946fabdef1dd8f37824c042a378f8
|
||||
parent = 9b8f13e94677b2680a33ad204bebadcdb1ff9081
|
||||
cmdver = 0.3.0
|
||||
6
build/git-subrepo/ext/bashplus/.travis.yml
Normal file
6
build/git-subrepo/ext/bashplus/.travis.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# C language gives closest shell env.
|
||||
language: c
|
||||
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- PROVEOPT=-v make test
|
||||
15
build/git-subrepo/ext/bashplus/Changes
Normal file
15
build/git-subrepo/ext/bashplus/Changes
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
version: 0.0.7
|
||||
date: Sat Jan 23 16:28:59 PST 2016
|
||||
changes:
|
||||
- Update tooling, and copyright
|
||||
---
|
||||
version: 0.0.6
|
||||
date: Fri Jan 23 21:05:15 PST 2015
|
||||
changes:
|
||||
- Update tooling, and copyright
|
||||
---
|
||||
version: 0.0.1
|
||||
date: Sun Oct 27 19:07:51 PDT 2013
|
||||
changes:
|
||||
- First release.
|
||||
21
build/git-subrepo/ext/bashplus/License
Normal file
21
build/git-subrepo/ext/bashplus/License
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright © 2013-2016 Ingy döt Net
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the ‘Software’), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
45
build/git-subrepo/ext/bashplus/Makefile
Normal file
45
build/git-subrepo/ext/bashplus/Makefile
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
ifeq ($(MAKECMDGOALS),install)
|
||||
ifeq "$(shell bpan version 2>/dev/null)" ""
|
||||
$(error 'BPAN not installed. See http://bpan.org')
|
||||
endif
|
||||
endif
|
||||
|
||||
NAME := bash+
|
||||
LIB := lib/$(NAME).bash
|
||||
DOC := doc/$(NAME).swim
|
||||
MAN1 := man/man1
|
||||
MAN3 := man/man3
|
||||
|
||||
INSTALL_LIB ?= $(shell bpan env BPAN_LIB)
|
||||
INSTALL_DIR ?= test
|
||||
INSTALL_MAN1 ?= $(shell bpan env BPAN_MAN1)
|
||||
INSTALL_MAN3 ?= $(shell bpan env BPAN_MAN3)
|
||||
|
||||
default: help
|
||||
|
||||
help:
|
||||
@echo 'Rules: test, install, doc'
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
prove $(PROVEOPT:%=% )test/
|
||||
|
||||
install:
|
||||
install -C -d -m 0755 $(INSTALL_LIB)/$(INSTALL_DIR)/
|
||||
install -C -m 0755 $(LIB) $(INSTALL_LIB)/$(INSTALL_DIR)/
|
||||
install -C -d -m 0755 $(INSTALL_MAN1)/
|
||||
install -C -d -m 0755 $(INSTALL_MAN3)/
|
||||
install -C -m 0644 $(MAN1)/$(NAME).1 $(INSTALL_MAN1)/
|
||||
install -C -m 0644 $(MAN3)/$(NAME).3 $(INSTALL_MAN3)/
|
||||
|
||||
.PHONY: doc
|
||||
doc: ReadMe.pod $(MAN1)/$(NAME).1 $(MAN3)/$(NAME).3
|
||||
|
||||
ReadMe.pod: $(DOC)
|
||||
swim --to=pod --complete --wrap $< > $@
|
||||
|
||||
$(MAN1)/%.1: doc/%.swim
|
||||
swim --to=man $< > $@
|
||||
|
||||
$(MAN3)/%.3: doc/%.swim
|
||||
swim --to=man $< > $@
|
||||
28
build/git-subrepo/ext/bashplus/Meta
Normal file
28
build/git-subrepo/ext/bashplus/Meta
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
=meta: 0.0.2
|
||||
|
||||
name: bashplus
|
||||
version: 0.0.7
|
||||
abstract: Modern Bash Programming
|
||||
homepage: http://bpan.org/package/bashplus/
|
||||
|
||||
license: MIT
|
||||
copyright: 2013-2016
|
||||
author:
|
||||
name: Ingy döt Net
|
||||
email: ingy@ingy.net
|
||||
github: ingydotnet
|
||||
twitter: ingydotnet
|
||||
freenode: ingy
|
||||
homepage: http://ingy.net
|
||||
|
||||
requires:
|
||||
bash: 3.2.0
|
||||
test:
|
||||
cmd: make test
|
||||
install:
|
||||
cmd: make install
|
||||
|
||||
devel:
|
||||
git: git@github.org/ingydotnet/bashplus
|
||||
irc: irc.freenode.net/bpan
|
||||
bug: https://github.com/ingydotnet/bashplus/issues/
|
||||
77
build/git-subrepo/ext/bashplus/ReadMe.pod
Normal file
77
build/git-subrepo/ext/bashplus/ReadMe.pod
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
=pod
|
||||
|
||||
=for comment
|
||||
DO NOT EDIT. This Pod was generated by Swim v0.1.41.
|
||||
See http://github.com/ingydotnet/swim-pm#readme
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 Name
|
||||
|
||||
Bash+(1) - Modern Bash Programming
|
||||
|
||||
=for html
|
||||
<a href="https://travis-ci.org/ingydotnet/bashplus"><img src="https://travis-ci.org/ingydotnet/bashplus.png" alt="bashplus"></a>
|
||||
|
||||
=head1 Synopsis
|
||||
|
||||
source bash+ :std :array
|
||||
|
||||
use Foo::Bar this that
|
||||
|
||||
Array.new args "$@"
|
||||
|
||||
if args.empty?; then
|
||||
die "I need args!"
|
||||
fi
|
||||
|
||||
Foo::Bar.new foo args
|
||||
|
||||
this is awesome # <= this is a real command! (You just imported it)
|
||||
|
||||
=head1 Description
|
||||
|
||||
Bash+ is just Bash... B<plus> some libraries that can make Bash programming a
|
||||
lot nicer.
|
||||
|
||||
=for comment # Installation
|
||||
|
||||
Get the source code from GitHub:
|
||||
|
||||
git clone git@github.com:ingydotnet/bashplus
|
||||
|
||||
Then run:
|
||||
|
||||
make test
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
=head1 Usage
|
||||
|
||||
For now look at some libraries the use Bash+:
|
||||
|
||||
=over
|
||||
|
||||
=item * L<https://github.com/ingydotnet/git-hub>
|
||||
|
||||
=item * L<https://github.com/ingydotnet/json-bash>
|
||||
|
||||
=item * L<https://github.com/ingydotnet/test-more-bash>
|
||||
|
||||
=back
|
||||
|
||||
=head1 Status
|
||||
|
||||
If you are interested in chatting about this, C</join #bpan> on
|
||||
irc.freenode.net.
|
||||
|
||||
=head1 Author
|
||||
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
=head1 Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT).
|
||||
|
||||
=cut
|
||||
43
build/git-subrepo/ext/bashplus/bin/bash+
Normal file
43
build/git-subrepo/ext/bashplus/bin/bash+
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env bash
|
||||
#------------------------------------------------------------------------------
|
||||
# Bash+ - Modern Bash Programming
|
||||
#
|
||||
# Copyright (c) 2013-2016 Ingy döt Net
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
set -e
|
||||
shopt -s compat31&>/dev/null||:
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Determine how `bash+` was called, and do the right thing:
|
||||
#------------------------------------------------------------------------------
|
||||
if [ "${BASH_SOURCE[0]}" != "$0" ]; then
|
||||
# 'bash+' is being sourced:
|
||||
[[ "${BASH_SOURCE[0]}" =~ /bin/bash\\+$ ]] || {
|
||||
echo "Invalid Bash+ path '${BASH_SOURCE[0]}'" 2> /dev/null
|
||||
exit 1
|
||||
}
|
||||
source "${BASH_SOURCE[0]%/bin/*}"/lib/bash+.bash || return $?
|
||||
bash+:import "$@"
|
||||
return $?
|
||||
else
|
||||
if [ $# -eq 1 -a "$1" == --version ]; then
|
||||
echo 'bash+ version 0.0.7'
|
||||
else
|
||||
cat <<...
|
||||
|
||||
Greetings modern Bash programmer. Welcome to Bash+!
|
||||
|
||||
Bash+ is framework that makes Bash programming more like Ruby and Perl.
|
||||
|
||||
See: https://github.com/bpan-org/bashplus
|
||||
|
||||
If you got here trying to use bash+ in a program, you need to source it:
|
||||
|
||||
source bash+
|
||||
|
||||
Happy Bash Hacking!
|
||||
|
||||
...
|
||||
fi
|
||||
fi
|
||||
61
build/git-subrepo/ext/bashplus/doc/bash+.swim
Normal file
61
build/git-subrepo/ext/bashplus/doc/bash+.swim
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
Bash+(1)
|
||||
========
|
||||
|
||||
Modern Bash Programming
|
||||
|
||||
<badge travis ingydotnet/bashplus>
|
||||
|
||||
= Synopsis
|
||||
|
||||
source bash+ :std :array
|
||||
|
||||
use Foo::Bar this that
|
||||
|
||||
Array.new args "$@"
|
||||
|
||||
if args.empty?; then
|
||||
die "I need args!"
|
||||
fi
|
||||
|
||||
Foo::Bar.new foo args
|
||||
|
||||
this is awesome # <= this is a real command! (You just imported it)
|
||||
|
||||
= Description
|
||||
|
||||
Bash+ is just Bash... *plus* some libraries that can make Bash programming a
|
||||
lot nicer.
|
||||
|
||||
## Installation
|
||||
|
||||
Get the source code from GitHub:
|
||||
|
||||
git clone git@github.com:ingydotnet/bashplus
|
||||
|
||||
Then run:
|
||||
|
||||
make test
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
= Usage
|
||||
|
||||
For now look at some libraries the use Bash+:
|
||||
|
||||
* https://github.com/ingydotnet/git-hub
|
||||
* https://github.com/ingydotnet/json-bash
|
||||
* https://github.com/ingydotnet/test-more-bash
|
||||
|
||||
= Status
|
||||
|
||||
If you are interested in chatting about this, `/join #bpan` on
|
||||
irc.freenode.net.
|
||||
|
||||
= Author
|
||||
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
= Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT).
|
||||
134
build/git-subrepo/ext/bashplus/man/man1/bash+.1
Normal file
134
build/git-subrepo/ext/bashplus/man/man1/bash+.1
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{
|
||||
. if \nF \{
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "Bash+(1) 1"
|
||||
.TH Bash+(1) 1 "January 2016" "Generated by Swim v0.1.41" "Modern Bash Programming"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH "Name"
|
||||
.IX Header "Name"
|
||||
Bash+(1) \- Modern Bash Programming
|
||||
.SH "Synopsis"
|
||||
.IX Header "Synopsis"
|
||||
.Vb 1
|
||||
\& source bash+ :std :array
|
||||
\&
|
||||
\& use Foo::Bar this that
|
||||
\&
|
||||
\& Array.new args "$@"
|
||||
\&
|
||||
\& if args.empty?; then
|
||||
\& die "I need args!"
|
||||
\& fi
|
||||
\&
|
||||
\& Foo::Bar.new foo args
|
||||
\&
|
||||
\& this is awesome # <= this is a real command! (You just imported it)
|
||||
.Ve
|
||||
.SH "Description"
|
||||
.IX Header "Description"
|
||||
Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
|
||||
.PP
|
||||
Get the source code from GitHub:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& git clone git@github.com:ingydotnet/bashplus
|
||||
.Ve
|
||||
.PP
|
||||
Then run:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& make test
|
||||
\& make install # Possibly with \*(Aqsudo\*(Aq
|
||||
.Ve
|
||||
.SH "Usage"
|
||||
.IX Header "Usage"
|
||||
For now look at some libraries the use Bash+:
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/git\-hub>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/json\-bash>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/test\-more\-bash>
|
||||
.SH "Status"
|
||||
.IX Header "Status"
|
||||
If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
|
||||
.SH "Author"
|
||||
.IX Header "Author"
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
.SH "Copyright & License"
|
||||
.IX Header "Copyright & License"
|
||||
Copyright 2013\-2016. Ingy döt Net.
|
||||
.PP
|
||||
The \s-1MIT\s0 License (\s-1MIT\s0).
|
||||
134
build/git-subrepo/ext/bashplus/man/man3/bash+.3
Normal file
134
build/git-subrepo/ext/bashplus/man/man3/bash+.3
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{
|
||||
. if \nF \{
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "Bash+(1) 1"
|
||||
.TH Bash+(1) 1 "January 2016" "Generated by Swim v0.1.41" "Modern Bash Programming"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH "Name"
|
||||
.IX Header "Name"
|
||||
Bash+(1) \- Modern Bash Programming
|
||||
.SH "Synopsis"
|
||||
.IX Header "Synopsis"
|
||||
.Vb 1
|
||||
\& source bash+ :std :array
|
||||
\&
|
||||
\& use Foo::Bar this that
|
||||
\&
|
||||
\& Array.new args "$@"
|
||||
\&
|
||||
\& if args.empty?; then
|
||||
\& die "I need args!"
|
||||
\& fi
|
||||
\&
|
||||
\& Foo::Bar.new foo args
|
||||
\&
|
||||
\& this is awesome # <= this is a real command! (You just imported it)
|
||||
.Ve
|
||||
.SH "Description"
|
||||
.IX Header "Description"
|
||||
Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
|
||||
.PP
|
||||
Get the source code from GitHub:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& git clone git@github.com:ingydotnet/bashplus
|
||||
.Ve
|
||||
.PP
|
||||
Then run:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& make test
|
||||
\& make install # Possibly with \*(Aqsudo\*(Aq
|
||||
.Ve
|
||||
.SH "Usage"
|
||||
.IX Header "Usage"
|
||||
For now look at some libraries the use Bash+:
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/git\-hub>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/json\-bash>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/test\-more\-bash>
|
||||
.SH "Status"
|
||||
.IX Header "Status"
|
||||
If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
|
||||
.SH "Author"
|
||||
.IX Header "Author"
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
.SH "Copyright & License"
|
||||
.IX Header "Copyright & License"
|
||||
Copyright 2013\-2016. Ingy döt Net.
|
||||
.PP
|
||||
The \s-1MIT\s0 License (\s-1MIT\s0).
|
||||
12
build/git-subrepo/ext/bashplus/test/base.t
Normal file
12
build/git-subrepo/ext/bashplus/test/base.t
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+ :std
|
||||
|
||||
ok $? '`source bash+` works'
|
||||
|
||||
is "$BASHPLUS_VERSION" '0.0.7' 'BASHPLUS_VERSION is 0.0.7'
|
||||
|
||||
done_testing 2
|
||||
22
build/git-subrepo/ext/bashplus/test/fcopy.t
Normal file
22
build/git-subrepo/ext/bashplus/test/fcopy.t
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+
|
||||
|
||||
foo() {
|
||||
echo O HAI
|
||||
}
|
||||
|
||||
like "$(type bar 2>&1)" 'bar: not found' \
|
||||
'bar is not yet a function'
|
||||
|
||||
bash+:fcopy foo bar
|
||||
|
||||
type -t bar &>/dev/null
|
||||
ok $? 'bar is now a function'
|
||||
is "$(type foo | tail -n+3)" "$(type bar | tail -n+3)" \
|
||||
'Copy matches original'
|
||||
|
||||
done_testing 3
|
||||
18
build/git-subrepo/ext/bashplus/test/source-bash+-std.t
Normal file
18
build/git-subrepo/ext/bashplus/test/source-bash+-std.t
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+ :std
|
||||
|
||||
ok "`bash+:can use`" 'use is imported'
|
||||
ok "`bash+:can die`" 'die is imported'
|
||||
ok "`bash+:can warn`" 'warn is imported'
|
||||
|
||||
ok "`! bash+:can import`" 'import is not imported'
|
||||
ok "`! bash+:can main`" 'main is not imported'
|
||||
ok "`! bash+:can fcopy`" 'fcopy is not imported'
|
||||
ok "`! bash+:can findlib`" 'findlib is not imported'
|
||||
ok "`! bash+:can can`" 'can is not imported'
|
||||
|
||||
done_testing 8
|
||||
23
build/git-subrepo/ext/bashplus/test/source-bash+.t
Normal file
23
build/git-subrepo/ext/bashplus/test/source-bash+.t
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+
|
||||
|
||||
functions=(
|
||||
use
|
||||
import
|
||||
fcopy
|
||||
findlib
|
||||
die
|
||||
warn
|
||||
can
|
||||
)
|
||||
|
||||
for f in ${functions[@]}; do
|
||||
is "$(type -t "bash+:$f")" function \
|
||||
"bash+:$f is a function"
|
||||
done
|
||||
|
||||
done_testing 7
|
||||
70
build/git-subrepo/ext/bashplus/test/test.bash
Normal file
70
build/git-subrepo/ext/bashplus/test/test.bash
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# This is a tiny version of test-more-bash that I use here. test-more-bash uses
|
||||
# bash+, so I want to avoid the circular dependency. This little guy does
|
||||
# 80-90% what test-more-bash does, with minimal code. It's a good example of
|
||||
# how nice Bash can be.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
plan() {
|
||||
echo "1..$1"
|
||||
}
|
||||
|
||||
pass() {
|
||||
let run=run+1
|
||||
echo "ok $run${1:+ - $1}"
|
||||
}
|
||||
|
||||
fail() {
|
||||
let run=run+1
|
||||
echo "not ok $run${1:+ - $1}"
|
||||
}
|
||||
|
||||
is() {
|
||||
if [ "$1" == "$2" ]; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
diag "Got: $1"
|
||||
diag "Want: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
ok() {
|
||||
(exit ${1:-$?}) &&
|
||||
pass "$2" ||
|
||||
fail "$2"
|
||||
}
|
||||
|
||||
like() {
|
||||
if [[ "$1" =~ "$2" ]]; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
diag "Got: $1"
|
||||
diag "Like: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
unlike() {
|
||||
if [[ ! "$1" =~ "$2" ]]; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
diag "Got: $1"
|
||||
diag "Dont: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
done_testing() {
|
||||
echo "1..${1:-$run}"
|
||||
}
|
||||
|
||||
diag() {
|
||||
echo "# ${1//$'\n'/$'\n'# }" >&2
|
||||
}
|
||||
|
||||
note() {
|
||||
echo "# ${1//$'\n'/$'\n'# }"
|
||||
}
|
||||
19
build/git-subrepo/ext/bashplus/test/use.t
Normal file
19
build/git-subrepo/ext/bashplus/test/use.t
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+ :std can
|
||||
|
||||
BASHLIB=test/lib
|
||||
|
||||
use Foo::Bar
|
||||
ok $? 'use Foo::Bar - works'
|
||||
ok "`can Foo::Bar:baz`" 'Function Foo::Bar:baz exists'
|
||||
is "$Foo__Bar_VERSION" 1.2.3 '$Foo__Bar_VERSION == 1.2.3'
|
||||
|
||||
output=`use Foo::Foo Boo Booo`
|
||||
ok $? 'use Foo::Foo Boo Booo - works'
|
||||
is "$output" Boo---Booo 'Correct import called'
|
||||
|
||||
done_testing 5
|
||||
11
build/git-subrepo/ext/test-more-bash/.gitrepo
Normal file
11
build/git-subrepo/ext/test-more-bash/.gitrepo
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:ingydotnet/test-more-bash.git
|
||||
branch = master
|
||||
commit = 24a6cceabff4d62a5fd25b8945bab6f618fb0b88
|
||||
parent = 69e22c2e7f6aeadfecb8b00d57c976958da03733
|
||||
cmdver = 0.3.0
|
||||
6
build/git-subrepo/ext/test-more-bash/.travis.yml
Normal file
6
build/git-subrepo/ext/test-more-bash/.travis.yml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# C language gives closest shell env.
|
||||
language: c
|
||||
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- PROVEOPT=-v make test
|
||||
15
build/git-subrepo/ext/test-more-bash/Changes
Normal file
15
build/git-subrepo/ext/test-more-bash/Changes
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
version: 0.0.3
|
||||
date: Sat Jan 23 16:39:20 PST 2016
|
||||
changes:
|
||||
- Make up to date
|
||||
---
|
||||
version: 0.0.2
|
||||
date: Fri Jan 23 21:26:18 PST 2015
|
||||
changes:
|
||||
- Make up to date
|
||||
---
|
||||
version: 0.0.1
|
||||
date: Sun Oct 27 22:53:10 PDT 2013
|
||||
changes:
|
||||
- First release.
|
||||
21
build/git-subrepo/ext/test-more-bash/License
Normal file
21
build/git-subrepo/ext/test-more-bash/License
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright © 2013-2016. Ingy döt Net.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the ‘Software’), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
20
build/git-subrepo/ext/test-more-bash/Makefile
Normal file
20
build/git-subrepo/ext/test-more-bash/Makefile
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
NAME := test-more
|
||||
DOC := doc/$(NAME).swim
|
||||
MAN3 := man/man3
|
||||
|
||||
default: help
|
||||
|
||||
help:
|
||||
@echo 'Rules: test, doc'
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
prove $(PROVEOPT:%=% )test/
|
||||
|
||||
doc: ReadMe.pod $(MAN3)/$(NAME).3
|
||||
|
||||
ReadMe.pod: $(DOC)
|
||||
swim --to=pod --complete --wrap $< > $@
|
||||
|
||||
$(MAN3)/%.3: doc/%.swim
|
||||
swim --to=man $< > $@
|
||||
30
build/git-subrepo/ext/test-more-bash/Meta
Normal file
30
build/git-subrepo/ext/test-more-bash/Meta
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
=meta: 0.0.2
|
||||
|
||||
name: test-more
|
||||
version: 0.0.3
|
||||
abstract: TAP Testing for Bash
|
||||
homepage: http://bpan.org/package/test-more/
|
||||
|
||||
license: MIT
|
||||
copyright: 2013-2016
|
||||
author:
|
||||
name: Ingy döt Net
|
||||
email: ingy@ingy.net
|
||||
github: ingydotnet
|
||||
twitter: ingydotnet
|
||||
freenode: ingy
|
||||
homepage: http://ingy.net
|
||||
|
||||
requires:
|
||||
bash: 3.2.0
|
||||
bashplus: 0.0.7
|
||||
test-tap: 0.0.4
|
||||
test:
|
||||
cmd: make test
|
||||
install:
|
||||
cmd: make install
|
||||
|
||||
devel:
|
||||
git: git@github.org/ingydotnet/test-more-bash.git
|
||||
irc: irc.freenode.net#bpan
|
||||
bug: https://github.com/ingydotnet/test-more-bash/issues/
|
||||
115
build/git-subrepo/ext/test-more-bash/ReadMe.pod
Normal file
115
build/git-subrepo/ext/test-more-bash/ReadMe.pod
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
=pod
|
||||
|
||||
=for comment
|
||||
DO NOT EDIT. This Pod was generated by Swim v0.1.41.
|
||||
See http://github.com/ingydotnet/swim-pm#readme
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 Name
|
||||
|
||||
Test::More - TAP Testing for Bash
|
||||
|
||||
=for html
|
||||
<a href="https://travis-ci.org/ingydotnet/test-more-bash"><img src="https://travis-ci.org/ingydotnet/test-more-bash.png" alt="test-more-bash"></a>
|
||||
|
||||
=head1 Synopsis
|
||||
|
||||
Write a test file like this. Maybe call it C<test/test.t>:
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TEST_MORE_PATH="/path/to/test-more-bash"
|
||||
BASHLIB="`
|
||||
find $TEST_MORE_PATH -type d |
|
||||
grep -E '/(bin|lib)$' |
|
||||
xargs -n1 printf "%s:"`"
|
||||
PATH="$BASHLIB$PATH"
|
||||
|
||||
source bash+ :std
|
||||
|
||||
use Test::More
|
||||
|
||||
plan tests 8
|
||||
|
||||
some-command
|
||||
ok $? 'some-command is ok'
|
||||
|
||||
# or:
|
||||
ok "`some-command`" 'some-command is ok'
|
||||
|
||||
pass 'This will always pass'
|
||||
|
||||
fail 'This will always fail'
|
||||
|
||||
is `echo foo` 'foo' 'foo is foo'
|
||||
|
||||
isnt foo bar "foo isn't bar"
|
||||
|
||||
like food foo 'food is like foo'
|
||||
|
||||
unlike team I "There's no 'I' in 'team'"
|
||||
|
||||
diag "A message for stderr"
|
||||
|
||||
note "A message for stdout"
|
||||
|
||||
Run the test with C<prove> like this:
|
||||
|
||||
prove test/test.t
|
||||
|
||||
Prove knows it's Bash from the first line (the hashbang), and it just works.
|
||||
|
||||
=head1 Description
|
||||
|
||||
Test::More is the tried and true testing library for Perl. It uses TAP (the
|
||||
Test Anything Protocol). This is the same thing for Bash. For the most part it
|
||||
should work exactly the same.
|
||||
|
||||
=head1 Methods
|
||||
|
||||
This is the basic usage:
|
||||
|
||||
=over
|
||||
|
||||
=item * C<plan tests $count>
|
||||
|
||||
=item * C<ok $status_code "$label">
|
||||
|
||||
=item * C<pass "$label">
|
||||
|
||||
=item * C<fail "$label">
|
||||
|
||||
=item * C<is "$got" "$want" "label">
|
||||
|
||||
=item * C<isnt "$got" "$unwanted" "$label">
|
||||
|
||||
=item * C<like "$got" "$regex" "$label">
|
||||
|
||||
=item * C<unlike "$got" "$regex" "$label">
|
||||
|
||||
=item * C<diag "$message">
|
||||
|
||||
=item * C<note "$message">
|
||||
|
||||
=item * C<done_testing $count>
|
||||
|
||||
=item * C<plan skip_all "$reason">
|
||||
|
||||
=item * C<BAIL_OUT "$reason">
|
||||
|
||||
=back
|
||||
|
||||
More detailed info coming soon.
|
||||
|
||||
=head1 Author
|
||||
|
||||
Ingy döt Net <ingy@bpan.org>
|
||||
|
||||
=head1 Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
=cut
|
||||
89
build/git-subrepo/ext/test-more-bash/doc/test-more.swim
Normal file
89
build/git-subrepo/ext/test-more-bash/doc/test-more.swim
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
Test::More
|
||||
==========
|
||||
|
||||
TAP Testing for Bash
|
||||
|
||||
<badge travis ingydotnet/test-more-bash>
|
||||
|
||||
= Synopsis
|
||||
|
||||
Write a test file like this. Maybe call it `test/test.t`:
|
||||
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TEST_MORE_PATH="/path/to/test-more-bash"
|
||||
BASHLIB="`
|
||||
find $TEST_MORE_PATH -type d |
|
||||
grep -E '/(bin|lib)$' |
|
||||
xargs -n1 printf "%s:"`"
|
||||
PATH="$BASHLIB$PATH"
|
||||
|
||||
source bash+ :std
|
||||
|
||||
use Test::More
|
||||
|
||||
plan tests 8
|
||||
|
||||
some-command
|
||||
ok $? 'some-command is ok'
|
||||
|
||||
# or:
|
||||
ok "`some-command`" 'some-command is ok'
|
||||
|
||||
pass 'This will always pass'
|
||||
|
||||
fail 'This will always fail'
|
||||
|
||||
is `echo foo` 'foo' 'foo is foo'
|
||||
|
||||
isnt foo bar "foo isn't bar"
|
||||
|
||||
like food foo 'food is like foo'
|
||||
|
||||
unlike team I "There's no 'I' in 'team'"
|
||||
|
||||
diag "A message for stderr"
|
||||
|
||||
note "A message for stdout"
|
||||
|
||||
Run the test with `prove` like this:
|
||||
|
||||
prove test/test.t
|
||||
|
||||
Prove knows it's Bash from the first line (the hashbang), and it just works.
|
||||
|
||||
= Description
|
||||
|
||||
Test::More is the tried and true testing library for Perl. It uses TAP (the
|
||||
Test Anything Protocol). This is the same thing for Bash. For the most part it
|
||||
should work exactly the same.
|
||||
|
||||
= Methods
|
||||
|
||||
This is the basic usage:
|
||||
|
||||
* `plan tests $count`
|
||||
* `ok $status_code "$label"`
|
||||
* `pass "$label"`
|
||||
* `fail "$label"`
|
||||
* `is "$got" "$want" "label"`
|
||||
* `isnt "$got" "$unwanted" "$label"`
|
||||
* `like "$got" "$regex" "$label"`
|
||||
* `unlike "$got" "$regex" "$label"`
|
||||
* `diag "$message"`
|
||||
* `note "$message"`
|
||||
* `done_testing $count`
|
||||
* `plan skip_all "$reason"`
|
||||
* `BAIL_OUT "$reason"`
|
||||
|
||||
More detailed info coming soon.
|
||||
|
||||
= Author
|
||||
|
||||
Ingy döt Net <ingy@bpan.org>
|
||||
|
||||
= Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT)
|
||||
11
build/git-subrepo/ext/test-more-bash/ext/bashplus/.gitrepo
Normal file
11
build/git-subrepo/ext/test-more-bash/ext/bashplus/.gitrepo
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:ingydotnet/bashplus.git
|
||||
branch = master
|
||||
commit = d9183af6f46946fabdef1dd8f37824c042a378f8
|
||||
parent = 05a1bddbe237bbf2c390048c80ca70d4f66c6a37
|
||||
cmdver = 0.3.0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# C language gives closest shell env.
|
||||
language: c
|
||||
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- PROVEOPT=-v make test
|
||||
15
build/git-subrepo/ext/test-more-bash/ext/bashplus/Changes
Normal file
15
build/git-subrepo/ext/test-more-bash/ext/bashplus/Changes
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
version: 0.0.7
|
||||
date: Sat Jan 23 16:28:59 PST 2016
|
||||
changes:
|
||||
- Update tooling, and copyright
|
||||
---
|
||||
version: 0.0.6
|
||||
date: Fri Jan 23 21:05:15 PST 2015
|
||||
changes:
|
||||
- Update tooling, and copyright
|
||||
---
|
||||
version: 0.0.1
|
||||
date: Sun Oct 27 19:07:51 PDT 2013
|
||||
changes:
|
||||
- First release.
|
||||
21
build/git-subrepo/ext/test-more-bash/ext/bashplus/License
Normal file
21
build/git-subrepo/ext/test-more-bash/ext/bashplus/License
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright © 2013-2016 Ingy döt Net
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the ‘Software’), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
45
build/git-subrepo/ext/test-more-bash/ext/bashplus/Makefile
Normal file
45
build/git-subrepo/ext/test-more-bash/ext/bashplus/Makefile
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
ifeq ($(MAKECMDGOALS),install)
|
||||
ifeq "$(shell bpan version 2>/dev/null)" ""
|
||||
$(error 'BPAN not installed. See http://bpan.org')
|
||||
endif
|
||||
endif
|
||||
|
||||
NAME := bash+
|
||||
LIB := lib/$(NAME).bash
|
||||
DOC := doc/$(NAME).swim
|
||||
MAN1 := man/man1
|
||||
MAN3 := man/man3
|
||||
|
||||
INSTALL_LIB ?= $(shell bpan env BPAN_LIB)
|
||||
INSTALL_DIR ?= test
|
||||
INSTALL_MAN1 ?= $(shell bpan env BPAN_MAN1)
|
||||
INSTALL_MAN3 ?= $(shell bpan env BPAN_MAN3)
|
||||
|
||||
default: help
|
||||
|
||||
help:
|
||||
@echo 'Rules: test, install, doc'
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
prove $(PROVEOPT:%=% )test/
|
||||
|
||||
install:
|
||||
install -C -d -m 0755 $(INSTALL_LIB)/$(INSTALL_DIR)/
|
||||
install -C -m 0755 $(LIB) $(INSTALL_LIB)/$(INSTALL_DIR)/
|
||||
install -C -d -m 0755 $(INSTALL_MAN1)/
|
||||
install -C -d -m 0755 $(INSTALL_MAN3)/
|
||||
install -C -m 0644 $(MAN1)/$(NAME).1 $(INSTALL_MAN1)/
|
||||
install -C -m 0644 $(MAN3)/$(NAME).3 $(INSTALL_MAN3)/
|
||||
|
||||
.PHONY: doc
|
||||
doc: ReadMe.pod $(MAN1)/$(NAME).1 $(MAN3)/$(NAME).3
|
||||
|
||||
ReadMe.pod: $(DOC)
|
||||
swim --to=pod --complete --wrap $< > $@
|
||||
|
||||
$(MAN1)/%.1: doc/%.swim
|
||||
swim --to=man $< > $@
|
||||
|
||||
$(MAN3)/%.3: doc/%.swim
|
||||
swim --to=man $< > $@
|
||||
28
build/git-subrepo/ext/test-more-bash/ext/bashplus/Meta
Normal file
28
build/git-subrepo/ext/test-more-bash/ext/bashplus/Meta
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
=meta: 0.0.2
|
||||
|
||||
name: bashplus
|
||||
version: 0.0.7
|
||||
abstract: Modern Bash Programming
|
||||
homepage: http://bpan.org/package/bashplus/
|
||||
|
||||
license: MIT
|
||||
copyright: 2013-2016
|
||||
author:
|
||||
name: Ingy döt Net
|
||||
email: ingy@ingy.net
|
||||
github: ingydotnet
|
||||
twitter: ingydotnet
|
||||
freenode: ingy
|
||||
homepage: http://ingy.net
|
||||
|
||||
requires:
|
||||
bash: 3.2.0
|
||||
test:
|
||||
cmd: make test
|
||||
install:
|
||||
cmd: make install
|
||||
|
||||
devel:
|
||||
git: git@github.org/ingydotnet/bashplus
|
||||
irc: irc.freenode.net/bpan
|
||||
bug: https://github.com/ingydotnet/bashplus/issues/
|
||||
77
build/git-subrepo/ext/test-more-bash/ext/bashplus/ReadMe.pod
Normal file
77
build/git-subrepo/ext/test-more-bash/ext/bashplus/ReadMe.pod
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
=pod
|
||||
|
||||
=for comment
|
||||
DO NOT EDIT. This Pod was generated by Swim v0.1.41.
|
||||
See http://github.com/ingydotnet/swim-pm#readme
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 Name
|
||||
|
||||
Bash+(1) - Modern Bash Programming
|
||||
|
||||
=for html
|
||||
<a href="https://travis-ci.org/ingydotnet/bashplus"><img src="https://travis-ci.org/ingydotnet/bashplus.png" alt="bashplus"></a>
|
||||
|
||||
=head1 Synopsis
|
||||
|
||||
source bash+ :std :array
|
||||
|
||||
use Foo::Bar this that
|
||||
|
||||
Array.new args "$@"
|
||||
|
||||
if args.empty?; then
|
||||
die "I need args!"
|
||||
fi
|
||||
|
||||
Foo::Bar.new foo args
|
||||
|
||||
this is awesome # <= this is a real command! (You just imported it)
|
||||
|
||||
=head1 Description
|
||||
|
||||
Bash+ is just Bash... B<plus> some libraries that can make Bash programming a
|
||||
lot nicer.
|
||||
|
||||
=for comment # Installation
|
||||
|
||||
Get the source code from GitHub:
|
||||
|
||||
git clone git@github.com:ingydotnet/bashplus
|
||||
|
||||
Then run:
|
||||
|
||||
make test
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
=head1 Usage
|
||||
|
||||
For now look at some libraries the use Bash+:
|
||||
|
||||
=over
|
||||
|
||||
=item * L<https://github.com/ingydotnet/git-hub>
|
||||
|
||||
=item * L<https://github.com/ingydotnet/json-bash>
|
||||
|
||||
=item * L<https://github.com/ingydotnet/test-more-bash>
|
||||
|
||||
=back
|
||||
|
||||
=head1 Status
|
||||
|
||||
If you are interested in chatting about this, C</join #bpan> on
|
||||
irc.freenode.net.
|
||||
|
||||
=head1 Author
|
||||
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
=head1 Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT).
|
||||
|
||||
=cut
|
||||
43
build/git-subrepo/ext/test-more-bash/ext/bashplus/bin/bash+
Normal file
43
build/git-subrepo/ext/test-more-bash/ext/bashplus/bin/bash+
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/usr/bin/env bash
|
||||
#------------------------------------------------------------------------------
|
||||
# Bash+ - Modern Bash Programming
|
||||
#
|
||||
# Copyright (c) 2013-2016 Ingy döt Net
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
set -e
|
||||
shopt -s compat31&>/dev/null||:
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Determine how `bash+` was called, and do the right thing:
|
||||
#------------------------------------------------------------------------------
|
||||
if [ "${BASH_SOURCE[0]}" != "$0" ]; then
|
||||
# 'bash+' is being sourced:
|
||||
[[ "${BASH_SOURCE[0]}" =~ /bin/bash\\+$ ]] || {
|
||||
echo "Invalid Bash+ path '${BASH_SOURCE[0]}'" 2> /dev/null
|
||||
exit 1
|
||||
}
|
||||
source "${BASH_SOURCE[0]%/bin/*}"/lib/bash+.bash || return $?
|
||||
bash+:import "$@"
|
||||
return $?
|
||||
else
|
||||
if [ $# -eq 1 -a "$1" == --version ]; then
|
||||
echo 'bash+ version 0.0.7'
|
||||
else
|
||||
cat <<...
|
||||
|
||||
Greetings modern Bash programmer. Welcome to Bash+!
|
||||
|
||||
Bash+ is framework that makes Bash programming more like Ruby and Perl.
|
||||
|
||||
See: https://github.com/bpan-org/bashplus
|
||||
|
||||
If you got here trying to use bash+ in a program, you need to source it:
|
||||
|
||||
source bash+
|
||||
|
||||
Happy Bash Hacking!
|
||||
|
||||
...
|
||||
fi
|
||||
fi
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
Bash+(1)
|
||||
========
|
||||
|
||||
Modern Bash Programming
|
||||
|
||||
<badge travis ingydotnet/bashplus>
|
||||
|
||||
= Synopsis
|
||||
|
||||
source bash+ :std :array
|
||||
|
||||
use Foo::Bar this that
|
||||
|
||||
Array.new args "$@"
|
||||
|
||||
if args.empty?; then
|
||||
die "I need args!"
|
||||
fi
|
||||
|
||||
Foo::Bar.new foo args
|
||||
|
||||
this is awesome # <= this is a real command! (You just imported it)
|
||||
|
||||
= Description
|
||||
|
||||
Bash+ is just Bash... *plus* some libraries that can make Bash programming a
|
||||
lot nicer.
|
||||
|
||||
## Installation
|
||||
|
||||
Get the source code from GitHub:
|
||||
|
||||
git clone git@github.com:ingydotnet/bashplus
|
||||
|
||||
Then run:
|
||||
|
||||
make test
|
||||
make install # Possibly with 'sudo'
|
||||
|
||||
= Usage
|
||||
|
||||
For now look at some libraries the use Bash+:
|
||||
|
||||
* https://github.com/ingydotnet/git-hub
|
||||
* https://github.com/ingydotnet/json-bash
|
||||
* https://github.com/ingydotnet/test-more-bash
|
||||
|
||||
= Status
|
||||
|
||||
If you are interested in chatting about this, `/join #bpan` on
|
||||
irc.freenode.net.
|
||||
|
||||
= Author
|
||||
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
= Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT).
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{
|
||||
. if \nF \{
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "Bash+(1) 1"
|
||||
.TH Bash+(1) 1 "January 2016" "Generated by Swim v0.1.41" "Modern Bash Programming"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH "Name"
|
||||
.IX Header "Name"
|
||||
Bash+(1) \- Modern Bash Programming
|
||||
.SH "Synopsis"
|
||||
.IX Header "Synopsis"
|
||||
.Vb 1
|
||||
\& source bash+ :std :array
|
||||
\&
|
||||
\& use Foo::Bar this that
|
||||
\&
|
||||
\& Array.new args "$@"
|
||||
\&
|
||||
\& if args.empty?; then
|
||||
\& die "I need args!"
|
||||
\& fi
|
||||
\&
|
||||
\& Foo::Bar.new foo args
|
||||
\&
|
||||
\& this is awesome # <= this is a real command! (You just imported it)
|
||||
.Ve
|
||||
.SH "Description"
|
||||
.IX Header "Description"
|
||||
Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
|
||||
.PP
|
||||
Get the source code from GitHub:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& git clone git@github.com:ingydotnet/bashplus
|
||||
.Ve
|
||||
.PP
|
||||
Then run:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& make test
|
||||
\& make install # Possibly with \*(Aqsudo\*(Aq
|
||||
.Ve
|
||||
.SH "Usage"
|
||||
.IX Header "Usage"
|
||||
For now look at some libraries the use Bash+:
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/git\-hub>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/json\-bash>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/test\-more\-bash>
|
||||
.SH "Status"
|
||||
.IX Header "Status"
|
||||
If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
|
||||
.SH "Author"
|
||||
.IX Header "Author"
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
.SH "Copyright & License"
|
||||
.IX Header "Copyright & License"
|
||||
Copyright 2013\-2016. Ingy döt Net.
|
||||
.PP
|
||||
The \s-1MIT\s0 License (\s-1MIT\s0).
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{
|
||||
. if \nF \{
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "Bash+(1) 1"
|
||||
.TH Bash+(1) 1 "January 2016" "Generated by Swim v0.1.41" "Modern Bash Programming"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH "Name"
|
||||
.IX Header "Name"
|
||||
Bash+(1) \- Modern Bash Programming
|
||||
.SH "Synopsis"
|
||||
.IX Header "Synopsis"
|
||||
.Vb 1
|
||||
\& source bash+ :std :array
|
||||
\&
|
||||
\& use Foo::Bar this that
|
||||
\&
|
||||
\& Array.new args "$@"
|
||||
\&
|
||||
\& if args.empty?; then
|
||||
\& die "I need args!"
|
||||
\& fi
|
||||
\&
|
||||
\& Foo::Bar.new foo args
|
||||
\&
|
||||
\& this is awesome # <= this is a real command! (You just imported it)
|
||||
.Ve
|
||||
.SH "Description"
|
||||
.IX Header "Description"
|
||||
Bash+ is just Bash... \fBplus\fR some libraries that can make Bash programming a lot nicer.
|
||||
.PP
|
||||
Get the source code from GitHub:
|
||||
.PP
|
||||
.Vb 1
|
||||
\& git clone git@github.com:ingydotnet/bashplus
|
||||
.Ve
|
||||
.PP
|
||||
Then run:
|
||||
.PP
|
||||
.Vb 2
|
||||
\& make test
|
||||
\& make install # Possibly with \*(Aqsudo\*(Aq
|
||||
.Ve
|
||||
.SH "Usage"
|
||||
.IX Header "Usage"
|
||||
For now look at some libraries the use Bash+:
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/git\-hub>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/json\-bash>
|
||||
.IP "\(bu" 4
|
||||
<https://github.com/ingydotnet/test\-more\-bash>
|
||||
.SH "Status"
|
||||
.IX Header "Status"
|
||||
If you are interested in chatting about this, \f(CW\*(C`/join #bpan\*(C'\fR on irc.freenode.net.
|
||||
.SH "Author"
|
||||
.IX Header "Author"
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
.SH "Copyright & License"
|
||||
.IX Header "Copyright & License"
|
||||
Copyright 2013\-2016. Ingy döt Net.
|
||||
.PP
|
||||
The \s-1MIT\s0 License (\s-1MIT\s0).
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+ :std
|
||||
|
||||
ok $? '`source bash+` works'
|
||||
|
||||
is "$BASHPLUS_VERSION" '0.0.7' 'BASHPLUS_VERSION is 0.0.7'
|
||||
|
||||
done_testing 2
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+
|
||||
|
||||
foo() {
|
||||
echo O HAI
|
||||
}
|
||||
|
||||
like "$(type bar 2>&1)" 'bar: not found' \
|
||||
'bar is not yet a function'
|
||||
|
||||
bash+:fcopy foo bar
|
||||
|
||||
type -t bar &>/dev/null
|
||||
ok $? 'bar is now a function'
|
||||
is "$(type foo | tail -n+3)" "$(type bar | tail -n+3)" \
|
||||
'Copy matches original'
|
||||
|
||||
done_testing 3
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+ :std
|
||||
|
||||
ok "`bash+:can use`" 'use is imported'
|
||||
ok "`bash+:can die`" 'die is imported'
|
||||
ok "`bash+:can warn`" 'warn is imported'
|
||||
|
||||
ok "`! bash+:can import`" 'import is not imported'
|
||||
ok "`! bash+:can main`" 'main is not imported'
|
||||
ok "`! bash+:can fcopy`" 'fcopy is not imported'
|
||||
ok "`! bash+:can findlib`" 'findlib is not imported'
|
||||
ok "`! bash+:can can`" 'can is not imported'
|
||||
|
||||
done_testing 8
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+
|
||||
|
||||
functions=(
|
||||
use
|
||||
import
|
||||
fcopy
|
||||
findlib
|
||||
die
|
||||
warn
|
||||
can
|
||||
)
|
||||
|
||||
for f in ${functions[@]}; do
|
||||
is "$(type -t "bash+:$f")" function \
|
||||
"bash+:$f is a function"
|
||||
done
|
||||
|
||||
done_testing 7
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# This is a tiny version of test-more-bash that I use here. test-more-bash uses
|
||||
# bash+, so I want to avoid the circular dependency. This little guy does
|
||||
# 80-90% what test-more-bash does, with minimal code. It's a good example of
|
||||
# how nice Bash can be.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
plan() {
|
||||
echo "1..$1"
|
||||
}
|
||||
|
||||
pass() {
|
||||
let run=run+1
|
||||
echo "ok $run${1:+ - $1}"
|
||||
}
|
||||
|
||||
fail() {
|
||||
let run=run+1
|
||||
echo "not ok $run${1:+ - $1}"
|
||||
}
|
||||
|
||||
is() {
|
||||
if [ "$1" == "$2" ]; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
diag "Got: $1"
|
||||
diag "Want: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
ok() {
|
||||
(exit ${1:-$?}) &&
|
||||
pass "$2" ||
|
||||
fail "$2"
|
||||
}
|
||||
|
||||
like() {
|
||||
if [[ "$1" =~ "$2" ]]; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
diag "Got: $1"
|
||||
diag "Like: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
unlike() {
|
||||
if [[ ! "$1" =~ "$2" ]]; then
|
||||
pass "$3"
|
||||
else
|
||||
fail "$3"
|
||||
diag "Got: $1"
|
||||
diag "Dont: $2"
|
||||
fi
|
||||
}
|
||||
|
||||
done_testing() {
|
||||
echo "1..${1:-$run}"
|
||||
}
|
||||
|
||||
diag() {
|
||||
echo "# ${1//$'\n'/$'\n'# }" >&2
|
||||
}
|
||||
|
||||
note() {
|
||||
echo "# ${1//$'\n'/$'\n'# }"
|
||||
}
|
||||
19
build/git-subrepo/ext/test-more-bash/ext/bashplus/test/use.t
Normal file
19
build/git-subrepo/ext/test-more-bash/ext/bashplus/test/use.t
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source test/test.bash
|
||||
|
||||
PATH=$PWD/bin:$PATH
|
||||
source bash+ :std can
|
||||
|
||||
BASHLIB=test/lib
|
||||
|
||||
use Foo::Bar
|
||||
ok $? 'use Foo::Bar - works'
|
||||
ok "`can Foo::Bar:baz`" 'Function Foo::Bar:baz exists'
|
||||
is "$Foo__Bar_VERSION" 1.2.3 '$Foo__Bar_VERSION == 1.2.3'
|
||||
|
||||
output=`use Foo::Foo Boo Booo`
|
||||
ok $? 'use Foo::Foo Boo Booo - works'
|
||||
is "$output" Boo---Booo 'Correct import called'
|
||||
|
||||
done_testing 5
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
; DO NOT EDIT (unless you know what you are doing)
|
||||
;
|
||||
; This subdirectory is a git "subrepo", and this file is maintained by the
|
||||
; git-subrepo command. See https://github.com/git-commands/git-subrepo#readme
|
||||
;
|
||||
[subrepo]
|
||||
remote = git@github.com:ingydotnet/test-tap-bash.git
|
||||
branch = master
|
||||
commit = 7890df93f13e684715750a2d6a608e7e79671ca4
|
||||
parent = 3faca582ee96a320b5675ad67b47ad0f16730446
|
||||
cmdver = 0.3.0
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# C language gives closest shell env.
|
||||
language: c
|
||||
|
||||
script:
|
||||
- git submodule update --init --recursive
|
||||
- PROVEOPT=-v make test
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
---
|
||||
version: 0.0.4
|
||||
date: Sat Jan 23 16:32:22 PST 2016
|
||||
changes:
|
||||
- Make up to date.
|
||||
---
|
||||
version: 0.0.3
|
||||
date: Fri Jan 23 21:39:39 PST 2015
|
||||
changes:
|
||||
- Make up to date.
|
||||
---
|
||||
version: 0.0.1
|
||||
date: Sun Oct 27 23:02:11 PDT 2013
|
||||
changes:
|
||||
- First release.
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright © 2013-2016. Ingy döt Net.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the ‘Software’), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
ifeq ($(MAKECMDGOALS),install)
|
||||
ifeq "$(shell bpan version 2>/dev/null)" ""
|
||||
$(error 'BPAN not installed. See http://bpan.org')
|
||||
endif
|
||||
endif
|
||||
|
||||
NAME := test-tap
|
||||
LIB := lib/test/tap.bash
|
||||
MAN3 := man/man3
|
||||
|
||||
INSTALL_LIB ?= $(shell bpan env BPAN_LIB)
|
||||
INSTALL_DIR ?= test
|
||||
INSTALL_MAN3 ?= $(shell bpan env BPAN_MAN3)
|
||||
|
||||
default: help
|
||||
|
||||
help:
|
||||
@echo 'Rules: test, install, doc'
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
prove $(PROVEOPT:%=% )test/
|
||||
|
||||
install:
|
||||
install -C -d -m 0755 $(INSTALL_LIB)/$(INSTALL_DIR)/
|
||||
install -C -m 0755 $(LIB) $(INSTALL_LIB)/$(INSTALL_DIR)/
|
||||
install -C -d -m 0755 $(INSTALL_MAN3)/
|
||||
install -C -m 0644 $(MAN3)/$(NAME).3 $(INSTALL_MAN3)/
|
||||
|
||||
.PHONY: doc
|
||||
doc: ReadMe.pod $(MAN3)/$(NAME).3
|
||||
|
||||
ReadMe.pod: doc/test-tap.swim
|
||||
swim --to=pod --complete --wrap $< > $@
|
||||
|
||||
man/man3/%.3: doc/%.swim
|
||||
swim --to=man $< > $@
|
||||
28
build/git-subrepo/ext/test-more-bash/ext/test-tap-bash/Meta
Normal file
28
build/git-subrepo/ext/test-more-bash/ext/test-tap-bash/Meta
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
=meta: 0.0.2
|
||||
|
||||
name: test-tap
|
||||
version: 0.0.4
|
||||
abstract: TAP Test Base for Bash
|
||||
homepage: http://bpan.org/package/test-tap/
|
||||
|
||||
license: MIT
|
||||
copyright: 2013-2016
|
||||
author:
|
||||
name: Ingy döt Net
|
||||
email: ingy@ingy.net
|
||||
github: ingydotnet
|
||||
twitter: ingydotnet
|
||||
freenode: ingy
|
||||
homepage: http://ingy.net
|
||||
|
||||
requires:
|
||||
bash: 3.2.0
|
||||
test:
|
||||
cmd: make test
|
||||
install:
|
||||
cmd: make install
|
||||
|
||||
devel:
|
||||
git: git@github.org/ingydotnet/test-tap-bash.git
|
||||
irc: irc.freenode.net/bpan
|
||||
bug: https://github.com/ingydotnet/test-tap-bash/issues/
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
=pod
|
||||
|
||||
=for comment
|
||||
DO NOT EDIT. This Pod was generated by Swim v0.1.41.
|
||||
See http://github.com/ingydotnet/swim-pm#readme
|
||||
|
||||
=encoding utf8
|
||||
|
||||
=head1 Name
|
||||
|
||||
Test::Tap - TAP Test Base for Bash
|
||||
|
||||
=for html
|
||||
<a href="https://travis-ci.org/ingydotnet/test-tap-bash"><img src="https://travis-ci.org/ingydotnet/test-tap-bash.png" alt="test-tap-bash"></a>
|
||||
|
||||
=head1 Synopsis
|
||||
|
||||
source test/tap.bash
|
||||
|
||||
Test::Tap:plan tests 1
|
||||
|
||||
pass 'Everything is OK!'
|
||||
|
||||
=head1 Description
|
||||
|
||||
This is a TAP testing base class for Bash. It has all the basic TAP functions,
|
||||
and works properly from a TAP harness, like the C<prove> utility.
|
||||
|
||||
test-tap-bash is used as the base for test-more-bash, which is what you want
|
||||
if you are writing tests in bash.
|
||||
|
||||
See: L<https://github.com/ingydotnet/test-more-bash/>
|
||||
|
||||
=head1 Functions
|
||||
|
||||
=over
|
||||
|
||||
=item C<Test::Tap:init>
|
||||
|
||||
Must be called first for every test file/process.
|
||||
|
||||
=item C<Test::Tap::plan>
|
||||
|
||||
Used to set the plan.
|
||||
|
||||
=back
|
||||
|
||||
=head1 TODO
|
||||
|
||||
=over
|
||||
|
||||
=item * Finish this doc.
|
||||
|
||||
=back
|
||||
|
||||
=head1 Author
|
||||
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
=head1 Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT).
|
||||
|
||||
=cut
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
Test::Tap
|
||||
=========
|
||||
|
||||
TAP Test Base for Bash
|
||||
|
||||
<badge travis ingydotnet/test-tap-bash>
|
||||
|
||||
= Synopsis
|
||||
|
||||
source test/tap.bash
|
||||
|
||||
Test::Tap:plan tests 1
|
||||
|
||||
pass 'Everything is OK!'
|
||||
|
||||
= Description
|
||||
|
||||
This is a TAP testing base class for Bash. It has all the basic TAP functions,
|
||||
and works properly from a TAP harness, like the `prove` utility.
|
||||
|
||||
test-tap-bash is used as the base for test-more-bash, which is what you want
|
||||
if you are writing tests in bash.
|
||||
|
||||
See: https://github.com/ingydotnet/test-more-bash/
|
||||
|
||||
= Functions
|
||||
|
||||
- `Test::Tap:init`
|
||||
|
||||
Must be called first for every test file/process.
|
||||
|
||||
- `Test::Tap::plan`
|
||||
|
||||
Used to set the plan.
|
||||
|
||||
= TODO
|
||||
|
||||
* Finish this doc.
|
||||
|
||||
= Author
|
||||
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
|
||||
= Copyright & License
|
||||
|
||||
Copyright 2013-2016. Ingy döt Net.
|
||||
|
||||
The MIT License (MIT).
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
.\" Automatically generated by Pod::Man 2.27 (Pod::Simple 3.28)
|
||||
.\"
|
||||
.\" Standard preamble:
|
||||
.\" ========================================================================
|
||||
.de Sp \" Vertical space (when we can't use .PP)
|
||||
.if t .sp .5v
|
||||
.if n .sp
|
||||
..
|
||||
.de Vb \" Begin verbatim text
|
||||
.ft CW
|
||||
.nf
|
||||
.ne \\$1
|
||||
..
|
||||
.de Ve \" End verbatim text
|
||||
.ft R
|
||||
.fi
|
||||
..
|
||||
.\" Set up some character translations and predefined strings. \*(-- will
|
||||
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
|
||||
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
|
||||
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
|
||||
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
|
||||
.\" nothing in troff, for use with C<>.
|
||||
.tr \(*W-
|
||||
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
|
||||
.ie n \{\
|
||||
. ds -- \(*W-
|
||||
. ds PI pi
|
||||
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
|
||||
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
|
||||
. ds L" ""
|
||||
. ds R" ""
|
||||
. ds C` ""
|
||||
. ds C' ""
|
||||
'br\}
|
||||
.el\{\
|
||||
. ds -- \|\(em\|
|
||||
. ds PI \(*p
|
||||
. ds L" ``
|
||||
. ds R" ''
|
||||
. ds C`
|
||||
. ds C'
|
||||
'br\}
|
||||
.\"
|
||||
.\" Escape single quotes in literal strings from groff's Unicode transform.
|
||||
.ie \n(.g .ds Aq \(aq
|
||||
.el .ds Aq '
|
||||
.\"
|
||||
.\" If the F register is turned on, we'll generate index entries on stderr for
|
||||
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
|
||||
.\" entries marked with X<> in POD. Of course, you'll have to process the
|
||||
.\" output yourself in some meaningful fashion.
|
||||
.\"
|
||||
.\" Avoid warning from groff about undefined register 'F'.
|
||||
.de IX
|
||||
..
|
||||
.nr rF 0
|
||||
.if \n(.g .if rF .nr rF 1
|
||||
.if (\n(rF:(\n(.g==0)) \{
|
||||
. if \nF \{
|
||||
. de IX
|
||||
. tm Index:\\$1\t\\n%\t"\\$2"
|
||||
..
|
||||
. if !\nF==2 \{
|
||||
. nr % 0
|
||||
. nr F 2
|
||||
. \}
|
||||
. \}
|
||||
.\}
|
||||
.rr rF
|
||||
.\" ========================================================================
|
||||
.\"
|
||||
.IX Title "Test::Tap 1"
|
||||
.TH Test::Tap 1 "January 2016" "Generated by Swim v0.1.41" "\s-1TAP\s0 Test Base for Bash"
|
||||
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
|
||||
.\" way too many mistakes in technical documents.
|
||||
.if n .ad l
|
||||
.nh
|
||||
.SH "Name"
|
||||
.IX Header "Name"
|
||||
Test::Tap \- \s-1TAP\s0 Test Base for Bash
|
||||
.SH "Synopsis"
|
||||
.IX Header "Synopsis"
|
||||
.Vb 1
|
||||
\& source test/tap.bash
|
||||
\&
|
||||
\& Test::Tap:plan tests 1
|
||||
\&
|
||||
\& pass \*(AqEverything is OK!\*(Aq
|
||||
.Ve
|
||||
.SH "Description"
|
||||
.IX Header "Description"
|
||||
This is a \s-1TAP\s0 testing base class for Bash. It has all the basic \s-1TAP\s0 functions, and works properly from a \s-1TAP\s0 harness, like the \f(CW\*(C`prove\*(C'\fR utility.
|
||||
.PP
|
||||
test-tap-bash is used as the base for test-more-bash, which is what you want if you are writing tests in bash.
|
||||
.PP
|
||||
See: <https://github.com/ingydotnet/test\-more\-bash/>
|
||||
.SH "Functions"
|
||||
.IX Header "Functions"
|
||||
.ie n .IP """Test::Tap:init""" 4
|
||||
.el .IP "\f(CWTest::Tap:init\fR" 4
|
||||
.IX Item "Test::Tap:init"
|
||||
Must be called first for every test file/process.
|
||||
.ie n .IP """Test::Tap::plan""" 4
|
||||
.el .IP "\f(CWTest::Tap::plan\fR" 4
|
||||
.IX Item "Test::Tap::plan"
|
||||
Used to set the plan.
|
||||
.SH "TODO"
|
||||
.IX Header "TODO"
|
||||
.IP "\(bu" 4
|
||||
Finish this doc.
|
||||
.SH "Author"
|
||||
.IX Header "Author"
|
||||
Written by Ingy döt Net <ingy@ingy.net>
|
||||
.SH "Copyright & License"
|
||||
.IX Header "Copyright & License"
|
||||
Copyright 2013\-2016. Ingy döt Net.
|
||||
.PP
|
||||
The \s-1MIT\s0 License (\s-1MIT\s0).
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source test/helper.bash
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init tests 1
|
||||
|
||||
output=$(prove -v test/test/{b,f}ail.t 2>&1)
|
||||
|
||||
test-helper:like \
|
||||
"$output" \
|
||||
'Bailout called. Further testing stopped: Get me outta here' \
|
||||
'Test::Tap:BAIL_OUT works'
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init
|
||||
|
||||
Test::Tap:pass one
|
||||
Test::Tap:pass two
|
||||
|
||||
Test::Tap:done_testing
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source test/helper.bash
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init tests 2
|
||||
|
||||
output="$(prove -v test/test/fail.t 2>&1)"
|
||||
|
||||
# echo "# >>>${output//$'\n'/$'\n'# }<<<" >&2
|
||||
|
||||
test-helper:like \
|
||||
"$output" \
|
||||
'not ok 1 - I am a failure' \
|
||||
'Test::Tap:fail works'
|
||||
|
||||
test-helper:like \
|
||||
"$output" \
|
||||
'Failed 1/1 subtests' \
|
||||
'Proper summary'
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source test/helper.bash
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init tests 1
|
||||
|
||||
output="$(prove -v test/test/fail_fast.t 2>&1)"
|
||||
|
||||
# echo ">>>$output<<<" >&2
|
||||
|
||||
test-helper:like \
|
||||
"$output" \
|
||||
'Further testing stopped: Bailing out on status=1' \
|
||||
'Test::Tap:BAIL_OUT works'
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
test-helper:like() {
|
||||
local got=$1 regex=$2 label=$3
|
||||
if [[ "$got" =~ "$regex" ]]; then
|
||||
Test::Tap:pass "$label"
|
||||
else
|
||||
Test::Tap:fail "$label"
|
||||
Test::Tap:diag "Got: '$got'"
|
||||
fi
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init tests 3
|
||||
|
||||
Test::Tap:pass 'pass 1 - with label'
|
||||
Test::Tap:pass
|
||||
Test::Tap:pass 'pass 3 - 2 has no label'
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init
|
||||
Test::Tap:plan tests 3
|
||||
|
||||
for n in 1 2 3; do
|
||||
Test::Tap:pass "Test #$n"
|
||||
done
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
source test/helper.bash
|
||||
source lib/test/tap.bash
|
||||
|
||||
Test::Tap:init tests 4
|
||||
|
||||
for s in plan init; do
|
||||
output=$(prove test/test/skip-all-$s.t)
|
||||
|
||||
test-helper:like \
|
||||
"$output" \
|
||||
"skipped: Test for skip_all from $s" \
|
||||
"skip_all from $s: it works"
|
||||
|
||||
test-helper:like \
|
||||
"$output" \
|
||||
'Result: NOTESTS' \
|
||||
"skip_all from $s: No tests run"
|
||||
done
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue