mirror of
https://github.com/josegonzalez/python-github-backup.git
synced 2025-12-05 16:18:02 +01:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2340a02fc6 | ||
|
|
cafff4ae80 | ||
|
|
3193d120e5 | ||
|
|
da4b29a2d6 | ||
|
|
d05c96ecef | ||
|
|
c86163bfe6 | ||
|
|
eff6e36974 | ||
|
|
63e458bafb | ||
|
|
57ab5ce1a2 | ||
|
|
d148f9b900 | ||
|
|
89ee22c2be | ||
|
|
9e472b74e6 | ||
|
|
4b459f9af8 | ||
|
|
b70ea87db7 | ||
|
|
f8be34562b | ||
|
|
ec05204aa9 | ||
|
|
628f2cbf73 | ||
|
|
38bf438d2f | ||
|
|
899cf42b57 | ||
|
|
b5972aaaf0 | ||
|
|
d860f369e9 | ||
|
|
77ab1bda15 | ||
|
|
4a4a317331 | ||
|
|
5a8e1ac275 | ||
|
|
0de341eab4 | ||
|
|
b0130fdf94 | ||
|
|
b49f399037 | ||
|
|
321414d352 | ||
|
|
413d4381cc | ||
|
|
0110ea40ed | ||
|
|
8d2ef2f528 | ||
|
|
1a79f755a5 | ||
|
|
abf45d5b54 | ||
|
|
fd33037b1c | ||
|
|
87dab293ed | ||
|
|
0244af4e05 | ||
|
|
eca9f0f7df | ||
|
|
ef88248c41 | ||
|
|
0a4decfb3b |
191
CHANGES.rst
191
CHANGES.rst
@@ -1,63 +1,140 @@
|
|||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
0.17.0 (2018-02-20)
|
0.23.0 (2019-06-04)
|
||||||
|
-------------------
|
||||||
|
------------------------
|
||||||
|
- Avoid to crash in case of HTTP 502 error. [Gael de Chalendar]
|
||||||
|
|
||||||
|
Survive also on socket.error connections like on HTTPError or URLError.
|
||||||
|
|
||||||
|
This should solve issue #110.
|
||||||
|
|
||||||
|
|
||||||
|
0.22.2 (2019-02-21)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
Fix
|
||||||
|
~~~
|
||||||
|
- Warn instead of error. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
|
Refs #106
|
||||||
|
|
||||||
|
|
||||||
|
0.22.1 (2019-02-21)
|
||||||
|
-------------------
|
||||||
|
- Log URL error https://github.com/josegonzalez/python-github-
|
||||||
|
backup/issues/105. [JOHN STETIC]
|
||||||
|
|
||||||
|
|
||||||
|
0.22.0 (2019-02-01)
|
||||||
|
-------------------
|
||||||
|
- Remove unnecessary sys.exit call. [W. Harrison Wright]
|
||||||
|
- Add org check to avoid incorrect log output. [W. Harrison Wright]
|
||||||
|
- Fix accidental system exit with better logging strategy. [W. Harrison
|
||||||
|
Wright]
|
||||||
|
|
||||||
|
|
||||||
|
0.21.1 (2018-12-25)
|
||||||
|
-------------------
|
||||||
|
- Mark options which are not included in --all. [Bernd]
|
||||||
|
|
||||||
|
As discussed in Issue #100
|
||||||
|
|
||||||
|
|
||||||
|
0.21.0 (2018-11-28)
|
||||||
|
-------------------
|
||||||
|
- Correctly download repos when user arg != authenticated user. [W.
|
||||||
|
Harrison Wright]
|
||||||
|
|
||||||
|
|
||||||
|
0.20.1 (2018-09-29)
|
||||||
|
-------------------
|
||||||
|
- Clone the specified user's gists, not the authenticated user. [W.
|
||||||
|
Harrison Wright]
|
||||||
|
- Clone the specified user's starred repos, not the authenticated user.
|
||||||
|
[W. Harrison Wright]
|
||||||
|
|
||||||
|
|
||||||
|
0.20.0 (2018-03-24)
|
||||||
|
-------------------
|
||||||
|
- Chore: drop Python 2.6. [Jose Diaz-Gonzalez]
|
||||||
|
- Feat: simplify release script. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
|
|
||||||
|
0.19.2 (2018-03-24)
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Fix
|
||||||
|
~~~
|
||||||
|
- Cleanup pep8 violations. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
|
|
||||||
|
0.19.0 (2018-03-24)
|
||||||
|
-------------------
|
||||||
|
- Add additional output for the current request. [Robin Gloster]
|
||||||
|
|
||||||
|
This is useful to have some progress indication for huge repositories.
|
||||||
|
- Add option to backup additional PR details. [Robin Gloster]
|
||||||
|
|
||||||
|
Some payload is only included when requesting a single pull request
|
||||||
|
- Mark string as binary in comparison for skip_existing. [Johannes
|
||||||
|
Bornhold]
|
||||||
|
|
||||||
|
Found out that the flag "--skip-existing" did not work out as expected on Python
|
||||||
|
3.6. Tracked it down to the comparison which has to be against a string of bytes
|
||||||
|
in Python3.
|
||||||
|
|
||||||
|
|
||||||
|
0.18.0 (2018-02-22)
|
||||||
|
-------------------
|
||||||
|
- Add option to fetch followers/following JSON data. [Stephen Greene]
|
||||||
|
|
||||||
|
|
||||||
|
0.17.0 (2018-02-20)
|
||||||
|
-------------------
|
||||||
- Short circuit gists backup process. [W. Harrison Wright]
|
- Short circuit gists backup process. [W. Harrison Wright]
|
||||||
|
|
||||||
- Formatting. [W. Harrison Wright]
|
- Formatting. [W. Harrison Wright]
|
||||||
|
|
||||||
- Add ability to backup gists. [W. Harrison Wright]
|
- Add ability to backup gists. [W. Harrison Wright]
|
||||||
|
|
||||||
|
|
||||||
0.16.0 (2018-01-22)
|
0.16.0 (2018-01-22)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Change option to --all-starred. [W. Harrison Wright]
|
- Change option to --all-starred. [W. Harrison Wright]
|
||||||
|
|
||||||
- JK don't update documentation. [W. Harrison Wright]
|
- JK don't update documentation. [W. Harrison Wright]
|
||||||
|
|
||||||
- Put starred clone repoistories under a new option. [W. Harrison
|
- Put starred clone repoistories under a new option. [W. Harrison
|
||||||
Wright]
|
Wright]
|
||||||
|
|
||||||
- Add comment. [W. Harrison Wright]
|
- Add comment. [W. Harrison Wright]
|
||||||
|
|
||||||
- Add ability to clone starred repos. [W. Harrison Wright]
|
- Add ability to clone starred repos. [W. Harrison Wright]
|
||||||
|
|
||||||
|
|
||||||
0.14.1 (2017-10-11)
|
0.14.1 (2017-10-11)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Fix arg not defined error. [Edward Pfremmer]
|
- Fix arg not defined error. [Edward Pfremmer]
|
||||||
|
|
||||||
Ref: https://github.com/josegonzalez/python-github-backup/issues/69
|
|
||||||
|
|
||||||
0.14.0 (2017-10-11)
|
0.14.0 (2017-10-11)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Added a check to see if git-lfs is installed when doing an LFS clone.
|
- Added a check to see if git-lfs is installed when doing an LFS clone.
|
||||||
[pieterclaerhout]
|
[pieterclaerhout]
|
||||||
|
|
||||||
- Added support for LFS clones. [pieterclaerhout]
|
- Added support for LFS clones. [pieterclaerhout]
|
||||||
|
|
||||||
- Add pypi info to readme. [Albert Wang]
|
- Add pypi info to readme. [Albert Wang]
|
||||||
|
|
||||||
- Explicitly support python 3 in package description. [Albert Wang]
|
- Explicitly support python 3 in package description. [Albert Wang]
|
||||||
|
|
||||||
- Add couple examples to help new users. [Yusuf Tran]
|
- Add couple examples to help new users. [Yusuf Tran]
|
||||||
|
|
||||||
|
|
||||||
0.13.2 (2017-05-06)
|
0.13.2 (2017-05-06)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Fix remotes while updating repository. [Dima Gerasimov]
|
- Fix remotes while updating repository. [Dima Gerasimov]
|
||||||
|
|
||||||
|
|
||||||
0.13.1 (2017-04-11)
|
0.13.1 (2017-04-11)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Fix error when repository has no updated_at value. [Nicolai Ehemann]
|
- Fix error when repository has no updated_at value. [Nicolai Ehemann]
|
||||||
|
|
||||||
|
|
||||||
0.13.0 (2017-04-05)
|
0.13.0 (2017-04-05)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Add OS check for OSX specific keychain args. [Martin O'Reilly]
|
- Add OS check for OSX specific keychain args. [Martin O'Reilly]
|
||||||
|
|
||||||
Keychain arguments are only supported on Mac OSX.
|
Keychain arguments are only supported on Mac OSX.
|
||||||
@@ -66,8 +143,6 @@ Changelog
|
|||||||
error message rather than a "No password item matching the
|
error message rather than a "No password item matching the
|
||||||
provided name and account could be found in the osx keychain"
|
provided name and account could be found in the osx keychain"
|
||||||
error message
|
error message
|
||||||
|
|
||||||
|
|
||||||
- Add support for storing PAT in OSX keychain. [Martin O'Reilly]
|
- Add support for storing PAT in OSX keychain. [Martin O'Reilly]
|
||||||
|
|
||||||
Added additional optional arguments and README guidance for storing
|
Added additional optional arguments and README guidance for storing
|
||||||
@@ -77,62 +152,48 @@ Changelog
|
|||||||
|
|
||||||
0.12.1 (2017-03-27)
|
0.12.1 (2017-03-27)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Avoid remote branch name churn. [Chris Adams]
|
- Avoid remote branch name churn. [Chris Adams]
|
||||||
|
|
||||||
This avoids the backup output having lots of "[new branch]" messages
|
This avoids the backup output having lots of "[new branch]" messages
|
||||||
because removing the old remote name removed all of the existing branch
|
because removing the old remote name removed all of the existing branch
|
||||||
references.
|
references.
|
||||||
|
|
||||||
|
|
||||||
- Fix detection of bare git directories. [Andrzej Maczuga]
|
- Fix detection of bare git directories. [Andrzej Maczuga]
|
||||||
|
|
||||||
|
|
||||||
0.12.0 (2016-11-22)
|
0.12.0 (2016-11-22)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Fix
|
Fix
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
- Properly import version from github_backup package. [Jose Diaz-
|
- Properly import version from github_backup package. [Jose Diaz-
|
||||||
Gonzalez]
|
Gonzalez]
|
||||||
|
|
||||||
- Support alternate git status output. [Jose Diaz-Gonzalez]
|
- Support alternate git status output. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
Other
|
Other
|
||||||
~~~~~
|
~~~~~
|
||||||
|
|
||||||
- Pep8: E501 line too long (83 > 79 characters) [Jose Diaz-Gonzalez]
|
- Pep8: E501 line too long (83 > 79 characters) [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Pep8: E128 continuation line under-indented for visual indent. [Jose
|
- Pep8: E128 continuation line under-indented for visual indent. [Jose
|
||||||
Diaz-Gonzalez]
|
Diaz-Gonzalez]
|
||||||
|
|
||||||
- Support archivization using bare git clones. [Andrzej Maczuga]
|
- Support archivization using bare git clones. [Andrzej Maczuga]
|
||||||
|
|
||||||
- Fix typo, 3x. [Terrell Russell]
|
- Fix typo, 3x. [Terrell Russell]
|
||||||
|
|
||||||
|
|
||||||
0.11.0 (2016-10-26)
|
0.11.0 (2016-10-26)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Support --token file:///home/user/token.txt (fixes gh-51) [Björn
|
- Support --token file:///home/user/token.txt (fixes gh-51) [Björn
|
||||||
Dahlgren]
|
Dahlgren]
|
||||||
|
|
||||||
- Fix some linting. [Albert Wang]
|
- Fix some linting. [Albert Wang]
|
||||||
|
|
||||||
- Fix byte/string conversion for python 3. [Albert Wang]
|
- Fix byte/string conversion for python 3. [Albert Wang]
|
||||||
|
|
||||||
- Support python 3. [Albert Wang]
|
- Support python 3. [Albert Wang]
|
||||||
|
|
||||||
- Encode special characters in password. [Remi Rampin]
|
- Encode special characters in password. [Remi Rampin]
|
||||||
|
|
||||||
- Don't pretend program name is "Github Backup" [Remi Rampin]
|
- Don't pretend program name is "Github Backup" [Remi Rampin]
|
||||||
|
|
||||||
- Don't install over insecure connection. [Remi Rampin]
|
- Don't install over insecure connection. [Remi Rampin]
|
||||||
|
|
||||||
The git:// protocol is unauthenticated and unencrypted, and no longer advertised by GitHub. Using HTTPS shouldn't impact performance.
|
The git:// protocol is unauthenticated and unencrypted, and no longer advertised by GitHub. Using HTTPS shouldn't impact performance.
|
||||||
|
|
||||||
|
|
||||||
0.10.3 (2016-08-21)
|
0.10.3 (2016-08-21)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Fixes #29. [Jonas Michel]
|
- Fixes #29. [Jonas Michel]
|
||||||
|
|
||||||
Reporting an error when the user's rate limit is exceeded causes
|
Reporting an error when the user's rate limit is exceeded causes
|
||||||
@@ -140,8 +201,6 @@ Other
|
|||||||
sleep. Instead of generating an explicit error we just want to
|
sleep. Instead of generating an explicit error we just want to
|
||||||
inform the user that the script is going to sleep until their rate
|
inform the user that the script is going to sleep until their rate
|
||||||
limit count resets.
|
limit count resets.
|
||||||
|
|
||||||
|
|
||||||
- Fixes #29. [Jonas Michel]
|
- Fixes #29. [Jonas Michel]
|
||||||
|
|
||||||
The errors list was not being cleared out after resuming a backup
|
The errors list was not being cleared out after resuming a backup
|
||||||
@@ -152,14 +211,13 @@ Other
|
|||||||
|
|
||||||
0.10.2 (2016-08-21)
|
0.10.2 (2016-08-21)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Add a note regarding git version requirement. [Jose Diaz-Gonzalez]
|
- Add a note regarding git version requirement. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
Closes #37
|
Closes #37
|
||||||
|
|
||||||
|
|
||||||
0.10.0 (2016-08-18)
|
0.10.0 (2016-08-18)
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
- Implement incremental updates. [Robert Bradshaw]
|
- Implement incremental updates. [Robert Bradshaw]
|
||||||
|
|
||||||
Guarded with an --incremental flag.
|
Guarded with an --incremental flag.
|
||||||
@@ -172,12 +230,11 @@ Other
|
|||||||
|
|
||||||
0.9.0 (2016-03-29)
|
0.9.0 (2016-03-29)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Fix cloning private repos with basic auth or token. [Kazuki Suda]
|
- Fix cloning private repos with basic auth or token. [Kazuki Suda]
|
||||||
|
|
||||||
|
|
||||||
0.8.0 (2016-02-14)
|
0.8.0 (2016-02-14)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Don't store issues which are actually pull requests. [Enrico Tröger]
|
- Don't store issues which are actually pull requests. [Enrico Tröger]
|
||||||
|
|
||||||
This prevents storing pull requests twice since the Github API returns
|
This prevents storing pull requests twice since the Github API returns
|
||||||
@@ -188,43 +245,31 @@ Other
|
|||||||
|
|
||||||
0.7.0 (2016-02-02)
|
0.7.0 (2016-02-02)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Softly fail if not able to read hooks. [Albert Wang]
|
- Softly fail if not able to read hooks. [Albert Wang]
|
||||||
|
|
||||||
- Add note about 2-factor auth. [Albert Wang]
|
- Add note about 2-factor auth. [Albert Wang]
|
||||||
|
|
||||||
- Make user repository search go through endpoint capable of reading
|
- Make user repository search go through endpoint capable of reading
|
||||||
private repositories. [Albert Wang]
|
private repositories. [Albert Wang]
|
||||||
|
|
||||||
- Prompt for password if only username given. [Alex Hall]
|
- Prompt for password if only username given. [Alex Hall]
|
||||||
|
|
||||||
|
|
||||||
0.6.0 (2015-11-10)
|
0.6.0 (2015-11-10)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Force proper remote url. [Jose Diaz-Gonzalez]
|
- Force proper remote url. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Improve error handling in case of HTTP errors. [Enrico Tröger]
|
- Improve error handling in case of HTTP errors. [Enrico Tröger]
|
||||||
|
|
||||||
In case of a HTTP status code 404, the returned 'r' was never assigned.
|
In case of a HTTP status code 404, the returned 'r' was never assigned.
|
||||||
In case of URL errors which are not timeouts, we probably should bail
|
In case of URL errors which are not timeouts, we probably should bail
|
||||||
out.
|
out.
|
||||||
|
|
||||||
|
|
||||||
- Add --hooks to also include web hooks into the backup. [Enrico Tröger]
|
- Add --hooks to also include web hooks into the backup. [Enrico Tröger]
|
||||||
|
|
||||||
- Create the user specified output directory if it does not exist.
|
- Create the user specified output directory if it does not exist.
|
||||||
[Enrico Tröger]
|
[Enrico Tröger]
|
||||||
|
|
||||||
Fixes #17.
|
Fixes #17.
|
||||||
|
|
||||||
|
|
||||||
- Add missing auth argument to _get_response() [Enrico Tröger]
|
- Add missing auth argument to _get_response() [Enrico Tröger]
|
||||||
|
|
||||||
When running unauthenticated and Github starts rate-limiting the client,
|
When running unauthenticated and Github starts rate-limiting the client,
|
||||||
github-backup crashes because the used auth variable in _get_response()
|
github-backup crashes because the used auth variable in _get_response()
|
||||||
was not available. This change should fix it.
|
was not available. This change should fix it.
|
||||||
|
|
||||||
|
|
||||||
- Add repository URL to error message for non-existing repositories.
|
- Add repository URL to error message for non-existing repositories.
|
||||||
[Enrico Tröger]
|
[Enrico Tröger]
|
||||||
|
|
||||||
@@ -235,40 +280,28 @@ Other
|
|||||||
|
|
||||||
0.5.0 (2015-10-10)
|
0.5.0 (2015-10-10)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Add release script. [Jose Diaz-Gonzalez]
|
- Add release script. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Refactor to both simplify codepath as well as follow PEP8 standards.
|
- Refactor to both simplify codepath as well as follow PEP8 standards.
|
||||||
[Jose Diaz-Gonzalez]
|
[Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Retry 3 times when the connection times out. [Mathijs Jonker]
|
- Retry 3 times when the connection times out. [Mathijs Jonker]
|
||||||
|
|
||||||
- Made unicode output defalut. [Kirill Grushetsky]
|
- Made unicode output defalut. [Kirill Grushetsky]
|
||||||
|
|
||||||
- Import alphabetised. [Kirill Grushetsky]
|
- Import alphabetised. [Kirill Grushetsky]
|
||||||
|
|
||||||
- Preserve Unicode characters in the output file. [Kirill Grushetsky]
|
- Preserve Unicode characters in the output file. [Kirill Grushetsky]
|
||||||
|
|
||||||
Added option to preserve Unicode characters in the output file
|
Added option to preserve Unicode characters in the output file
|
||||||
|
|
||||||
- Josegonzales/python-github-backup#12 Added backup of labels and
|
- Josegonzales/python-github-backup#12 Added backup of labels and
|
||||||
milestones. [aensley]
|
milestones. [aensley]
|
||||||
|
|
||||||
- Fixed indent. [Mathijs Jonker]
|
- Fixed indent. [Mathijs Jonker]
|
||||||
|
|
||||||
- Skip unitialized repo's. [mjonker-embed]
|
- Skip unitialized repo's. [mjonker-embed]
|
||||||
|
|
||||||
These gave me errors which caused mails from crontab.
|
These gave me errors which caused mails from crontab.
|
||||||
|
|
||||||
- Added prefer-ssh. [mjonker-embed]
|
- Added prefer-ssh. [mjonker-embed]
|
||||||
|
|
||||||
Was needed for my back-up setup, code includes this but readme wasn't updated
|
Was needed for my back-up setup, code includes this but readme wasn't updated
|
||||||
|
|
||||||
- Retry API requests which failed due to rate-limiting. [Chris Adams]
|
- Retry API requests which failed due to rate-limiting. [Chris Adams]
|
||||||
|
|
||||||
This allows operation to continue, albeit at a slower pace,
|
This allows operation to continue, albeit at a slower pace,
|
||||||
if you have enough data to trigger the API rate limits
|
if you have enough data to trigger the API rate limits
|
||||||
|
|
||||||
- Logging_subprocess: always log when a command fails. [Chris Adams]
|
- Logging_subprocess: always log when a command fails. [Chris Adams]
|
||||||
|
|
||||||
Previously git clones could fail without any indication
|
Previously git clones could fail without any indication
|
||||||
@@ -278,21 +311,15 @@ Other
|
|||||||
Now a non-zero return code will always output a message to
|
Now a non-zero return code will always output a message to
|
||||||
stderr and will display the executed command so it can be
|
stderr and will display the executed command so it can be
|
||||||
rerun for troubleshooting.
|
rerun for troubleshooting.
|
||||||
|
|
||||||
|
|
||||||
- Switch to using ssh_url. [Chris Adams]
|
- Switch to using ssh_url. [Chris Adams]
|
||||||
|
|
||||||
The previous commit used the wrong URL for a private repo. This was
|
The previous commit used the wrong URL for a private repo. This was
|
||||||
masked by the lack of error loging in logging_subprocess (which will be
|
masked by the lack of error loging in logging_subprocess (which will be
|
||||||
in a separate branch)
|
in a separate branch)
|
||||||
|
|
||||||
|
|
||||||
- Add an option to prefer checkouts over SSH. [Chris Adams]
|
- Add an option to prefer checkouts over SSH. [Chris Adams]
|
||||||
|
|
||||||
This is really useful with private repos to avoid being nagged
|
This is really useful with private repos to avoid being nagged
|
||||||
for credentials for every repository
|
for credentials for every repository
|
||||||
|
|
||||||
|
|
||||||
- Add pull request support. [Kevin Laude]
|
- Add pull request support. [Kevin Laude]
|
||||||
|
|
||||||
Back up reporitory pull requests by passing the --include-pulls
|
Back up reporitory pull requests by passing the --include-pulls
|
||||||
@@ -304,8 +331,6 @@ Other
|
|||||||
|
|
||||||
Pull requests are automatically backed up when the --all argument is
|
Pull requests are automatically backed up when the --all argument is
|
||||||
uesd.
|
uesd.
|
||||||
|
|
||||||
|
|
||||||
- Add GitHub Enterprise support. [Kevin Laude]
|
- Add GitHub Enterprise support. [Kevin Laude]
|
||||||
|
|
||||||
Pass the -H or --github-host argument with a GitHub Enterprise hostname
|
Pass the -H or --github-host argument with a GitHub Enterprise hostname
|
||||||
@@ -315,35 +340,21 @@ Other
|
|||||||
|
|
||||||
0.2.0 (2014-09-22)
|
0.2.0 (2014-09-22)
|
||||||
------------------
|
------------------
|
||||||
|
|
||||||
- Add support for retrieving repositories. Closes #1. [Jose Diaz-
|
- Add support for retrieving repositories. Closes #1. [Jose Diaz-
|
||||||
Gonzalez]
|
Gonzalez]
|
||||||
|
|
||||||
- Fix PEP8 violations. [Jose Diaz-Gonzalez]
|
- Fix PEP8 violations. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Add authorization to header only if specified by user. [Ioannis
|
- Add authorization to header only if specified by user. [Ioannis
|
||||||
Filippidis]
|
Filippidis]
|
||||||
|
|
||||||
- Fill out readme more. [Jose Diaz-Gonzalez]
|
- Fill out readme more. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Fix import. [Jose Diaz-Gonzalez]
|
- Fix import. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Properly name readme. [Jose Diaz-Gonzalez]
|
- Properly name readme. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create MANIFEST.in. [Jose Diaz-Gonzalez]
|
- Create MANIFEST.in. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create .gitignore. [Jose Diaz-Gonzalez]
|
- Create .gitignore. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create setup.py. [Jose Diaz-Gonzalez]
|
- Create setup.py. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create requirements.txt. [Jose Diaz-Gonzalez]
|
- Create requirements.txt. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create __init__.py. [Jose Diaz-Gonzalez]
|
- Create __init__.py. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create LICENSE.txt. [Jose Diaz-Gonzalez]
|
- Create LICENSE.txt. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create README.md. [Jose Diaz-Gonzalez]
|
- Create README.md. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
- Create github-backup. [Jose Diaz-Gonzalez]
|
- Create github-backup. [Jose Diaz-Gonzalez]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
24
README.rst
24
README.rst
@@ -28,12 +28,12 @@ Usage
|
|||||||
CLI Usage is as follows::
|
CLI Usage is as follows::
|
||||||
|
|
||||||
github-backup [-h] [-u USERNAME] [-p PASSWORD] [-t TOKEN]
|
github-backup [-h] [-u USERNAME] [-p PASSWORD] [-t TOKEN]
|
||||||
[-o OUTPUT_DIRECTORY] [-i] [--starred] [--watched]
|
[-o OUTPUT_DIRECTORY] [-i] [--starred] [--all-starred]
|
||||||
[--all] [--issues] [--issue-comments] [--issue-events]
|
[--watched] [--followers] [--following] [--all]
|
||||||
[--pulls] [--pull-comments] [--pull-commits] [--labels]
|
[--issues] [--issue-comments] [--issue-events] [--pulls]
|
||||||
[--hooks] [--milestones] [--repositories] [--bare] [--lfs]
|
[--pull-comments] [--pull-commits] [--labels] [--hooks]
|
||||||
[--wikis] [--skip-existing] [--all-starred]
|
[--milestones] [--repositories] [--bare] [--lfs]
|
||||||
[--gists] [--starred-gists]
|
[--wikis] [--gists] [--starred-gists] [--skip-existing]
|
||||||
[-L [LANGUAGES [LANGUAGES ...]]] [-N NAME_REGEX]
|
[-L [LANGUAGES [LANGUAGES ...]]] [-N NAME_REGEX]
|
||||||
[-H GITHUB_HOST] [-O] [-R REPOSITORY] [-P] [-F]
|
[-H GITHUB_HOST] [-O] [-R REPOSITORY] [-P] [-F]
|
||||||
[--prefer-ssh] [-v]
|
[--prefer-ssh] [-v]
|
||||||
@@ -54,12 +54,16 @@ CLI Usage is as follows::
|
|||||||
password for basic auth. If a username is given but
|
password for basic auth. If a username is given but
|
||||||
not a password, the password will be prompted for.
|
not a password, the password will be prompted for.
|
||||||
-t TOKEN, --token TOKEN
|
-t TOKEN, --token TOKEN
|
||||||
personal access or OAuth token
|
personal access or OAuth token, or path to token
|
||||||
|
(file://...)
|
||||||
-o OUTPUT_DIRECTORY, --output-directory OUTPUT_DIRECTORY
|
-o OUTPUT_DIRECTORY, --output-directory OUTPUT_DIRECTORY
|
||||||
directory at which to backup the repositories
|
directory at which to backup the repositories
|
||||||
-i, --incremental incremental backup
|
-i, --incremental incremental backup
|
||||||
--starred include JSON output of starred repositories in backup
|
--starred include JSON output of starred repositories in backup
|
||||||
|
--all-starred include starred repositories in backup
|
||||||
--watched include watched repositories in backup
|
--watched include watched repositories in backup
|
||||||
|
--followers include JSON output of followers in backup
|
||||||
|
--following include JSON output of following users in backup
|
||||||
--all include everything in backup
|
--all include everything in backup
|
||||||
--issues include issues in backup
|
--issues include issues in backup
|
||||||
--issue-comments include issue comments in backup
|
--issue-comments include issue comments in backup
|
||||||
@@ -73,12 +77,12 @@ CLI Usage is as follows::
|
|||||||
--milestones include milestones in backup
|
--milestones include milestones in backup
|
||||||
--repositories include repository clone in backup
|
--repositories include repository clone in backup
|
||||||
--bare clone bare repositories
|
--bare clone bare repositories
|
||||||
--lfs clone LFS repositories (requires Git LFS to be installed, https://git-lfs.github.com)
|
--lfs clone LFS repositories (requires Git LFS to be
|
||||||
|
installed, https://git-lfs.github.com)
|
||||||
--wikis include wiki clone in backup
|
--wikis include wiki clone in backup
|
||||||
--skip-existing skip project if a backup directory exists
|
|
||||||
--all-starred include starred repositories in backup
|
|
||||||
--gists include gists in backup
|
--gists include gists in backup
|
||||||
--starred-gists include starred gists in backup
|
--starred-gists include starred gists in backup
|
||||||
|
--skip-existing skip project if a backup directory exists
|
||||||
-L [LANGUAGES [LANGUAGES ...]], --languages [LANGUAGES [LANGUAGES ...]]
|
-L [LANGUAGES [LANGUAGES ...]], --languages [LANGUAGES [LANGUAGES ...]]
|
||||||
only allow these languages
|
only allow these languages
|
||||||
-N NAME_REGEX, --name-regex NAME_REGEX
|
-N NAME_REGEX, --name-regex NAME_REGEX
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
import socket
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import base64
|
import base64
|
||||||
@@ -40,16 +41,17 @@ FNULL = open(os.devnull, 'w')
|
|||||||
|
|
||||||
|
|
||||||
def log_error(message):
|
def log_error(message):
|
||||||
if type(message) == str:
|
"""
|
||||||
message = [message]
|
Log message (str) or messages (List[str]) to stderr and exit with status 1
|
||||||
|
"""
|
||||||
for msg in message:
|
log_warning(message)
|
||||||
sys.stderr.write("{0}\n".format(msg))
|
|
||||||
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
def log_info(message):
|
def log_info(message):
|
||||||
|
"""
|
||||||
|
Log message (str) or messages (List[str]) to stdout
|
||||||
|
"""
|
||||||
if type(message) == str:
|
if type(message) == str:
|
||||||
message = [message]
|
message = [message]
|
||||||
|
|
||||||
@@ -57,6 +59,17 @@ def log_info(message):
|
|||||||
sys.stdout.write("{0}\n".format(msg))
|
sys.stdout.write("{0}\n".format(msg))
|
||||||
|
|
||||||
|
|
||||||
|
def log_warning(message):
|
||||||
|
"""
|
||||||
|
Log message (str) or messages (List[str]) to stderr
|
||||||
|
"""
|
||||||
|
if type(message) == str:
|
||||||
|
message = [message]
|
||||||
|
|
||||||
|
for msg in message:
|
||||||
|
sys.stderr.write("{0}\n".format(msg))
|
||||||
|
|
||||||
|
|
||||||
def logging_subprocess(popenargs,
|
def logging_subprocess(popenargs,
|
||||||
logger,
|
logger,
|
||||||
stdout_log_level=logging.DEBUG,
|
stdout_log_level=logging.DEBUG,
|
||||||
@@ -163,15 +176,23 @@ def parse_args():
|
|||||||
parser.add_argument('--all-starred',
|
parser.add_argument('--all-starred',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='all_starred',
|
dest='all_starred',
|
||||||
help='include starred repositories in backup')
|
help='include starred repositories in backup [*]')
|
||||||
parser.add_argument('--watched',
|
parser.add_argument('--watched',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_watched',
|
dest='include_watched',
|
||||||
help='include watched repositories in backup')
|
help='include JSON output of watched repositories in backup')
|
||||||
|
parser.add_argument('--followers',
|
||||||
|
action='store_true',
|
||||||
|
dest='include_followers',
|
||||||
|
help='include JSON output of followers in backup')
|
||||||
|
parser.add_argument('--following',
|
||||||
|
action='store_true',
|
||||||
|
dest='include_following',
|
||||||
|
help='include JSON output of following users in backup')
|
||||||
parser.add_argument('--all',
|
parser.add_argument('--all',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_everything',
|
dest='include_everything',
|
||||||
help='include everything in backup')
|
help='include everything in backup (not including [*])')
|
||||||
parser.add_argument('--issues',
|
parser.add_argument('--issues',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_issues',
|
dest='include_issues',
|
||||||
@@ -196,6 +217,10 @@ def parse_args():
|
|||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_pull_commits',
|
dest='include_pull_commits',
|
||||||
help='include pull request commits in backup')
|
help='include pull request commits in backup')
|
||||||
|
parser.add_argument('--pull-details',
|
||||||
|
action='store_true',
|
||||||
|
dest='include_pull_details',
|
||||||
|
help='include more pull request details in backup [*]')
|
||||||
parser.add_argument('--labels',
|
parser.add_argument('--labels',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_labels',
|
dest='include_labels',
|
||||||
@@ -219,7 +244,7 @@ def parse_args():
|
|||||||
parser.add_argument('--lfs',
|
parser.add_argument('--lfs',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='lfs_clone',
|
dest='lfs_clone',
|
||||||
help='clone LFS repositories (requires Git LFS to be installed, https://git-lfs.github.com)')
|
help='clone LFS repositories (requires Git LFS to be installed, https://git-lfs.github.com) [*]')
|
||||||
parser.add_argument('--wikis',
|
parser.add_argument('--wikis',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_wiki',
|
dest='include_wiki',
|
||||||
@@ -227,11 +252,11 @@ def parse_args():
|
|||||||
parser.add_argument('--gists',
|
parser.add_argument('--gists',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_gists',
|
dest='include_gists',
|
||||||
help='include gists in backup')
|
help='include gists in backup [*]')
|
||||||
parser.add_argument('--starred-gists',
|
parser.add_argument('--starred-gists',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='include_starred_gists',
|
dest='include_starred_gists',
|
||||||
help='include starred gists in backup')
|
help='include starred gists in backup [*]')
|
||||||
parser.add_argument('--skip-existing',
|
parser.add_argument('--skip-existing',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='skip_existing',
|
dest='skip_existing',
|
||||||
@@ -261,11 +286,11 @@ def parse_args():
|
|||||||
parser.add_argument('-P', '--private',
|
parser.add_argument('-P', '--private',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='private',
|
dest='private',
|
||||||
help='include private repositories')
|
help='include private repositories [*]')
|
||||||
parser.add_argument('-F', '--fork',
|
parser.add_argument('-F', '--fork',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
dest='fork',
|
dest='fork',
|
||||||
help='include forked repositories')
|
help='include forked repositories [*]')
|
||||||
parser.add_argument('--prefer-ssh',
|
parser.add_argument('--prefer-ssh',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Clone repositories using SSH instead of HTTPS')
|
help='Clone repositories using SSH instead of HTTPS')
|
||||||
@@ -291,12 +316,12 @@ def get_auth(args, encode=True):
|
|||||||
if platform.system() != 'Darwin':
|
if platform.system() != 'Darwin':
|
||||||
log_error("Keychain arguments are only supported on Mac OSX")
|
log_error("Keychain arguments are only supported on Mac OSX")
|
||||||
try:
|
try:
|
||||||
with open(os.devnull,'w') as devnull:
|
with open(os.devnull, 'w') as devnull:
|
||||||
token = (subprocess.check_output([
|
token = (subprocess.check_output([
|
||||||
'security','find-generic-password',
|
'security', 'find-generic-password',
|
||||||
'-s',args.osx_keychain_item_name,
|
'-s', args.osx_keychain_item_name,
|
||||||
'-a',args.osx_keychain_item_account,
|
'-a', args.osx_keychain_item_account,
|
||||||
'-w' ], stderr=devnull).strip())
|
'-w'], stderr=devnull).strip())
|
||||||
auth = token + ':' + 'x-oauth-basic'
|
auth = token + ':' + 'x-oauth-basic'
|
||||||
except:
|
except:
|
||||||
log_error('No password item matching the provided name and account could be found in the osx keychain.')
|
log_error('No password item matching the provided name and account could be found in the osx keychain.')
|
||||||
@@ -380,6 +405,16 @@ def retrieve_data(args, template, query_args=None, single_request=False):
|
|||||||
|
|
||||||
status_code = int(r.getcode())
|
status_code = int(r.getcode())
|
||||||
|
|
||||||
|
retries = 0
|
||||||
|
while retries < 3 and status_code == 502:
|
||||||
|
print('API request returned HTTP 502: Bad Gateway. Retrying in 5 seconds')
|
||||||
|
retries += 1
|
||||||
|
time.sleep(5)
|
||||||
|
request = _construct_request(per_page, page, query_args, template, auth) # noqa
|
||||||
|
r, errors = _get_response(request, auth, template)
|
||||||
|
|
||||||
|
status_code = int(r.getcode())
|
||||||
|
|
||||||
if status_code != 200:
|
if status_code != 200:
|
||||||
template = 'API request returned HTTP {0}: {1}'
|
template = 'API request returned HTTP {0}: {1}'
|
||||||
errors.append(template.format(status_code, r.reason))
|
errors.append(template.format(status_code, r.reason))
|
||||||
@@ -421,7 +456,13 @@ def _get_response(request, auth, template):
|
|||||||
except HTTPError as exc:
|
except HTTPError as exc:
|
||||||
errors, should_continue = _request_http_error(exc, auth, errors) # noqa
|
errors, should_continue = _request_http_error(exc, auth, errors) # noqa
|
||||||
r = exc
|
r = exc
|
||||||
except URLError:
|
except URLError as e:
|
||||||
|
log_warning(e.reason)
|
||||||
|
should_continue = _request_url_error(template, retry_timeout)
|
||||||
|
if not should_continue:
|
||||||
|
raise
|
||||||
|
except socket.error as e:
|
||||||
|
log_warning(e.strerror)
|
||||||
should_continue = _request_url_error(template, retry_timeout)
|
should_continue = _request_url_error(template, retry_timeout)
|
||||||
if not should_continue:
|
if not should_continue:
|
||||||
raise
|
raise
|
||||||
@@ -442,6 +483,7 @@ def _construct_request(per_page, page, query_args, template, auth):
|
|||||||
request = Request(template + '?' + querystring)
|
request = Request(template + '?' + querystring)
|
||||||
if auth is not None:
|
if auth is not None:
|
||||||
request.add_header('Authorization', 'Basic '.encode('ascii') + auth)
|
request.add_header('Authorization', 'Basic '.encode('ascii') + auth)
|
||||||
|
log_info('Requesting {}?{}'.format(template, querystring))
|
||||||
return request
|
return request
|
||||||
|
|
||||||
|
|
||||||
@@ -490,18 +532,32 @@ def _request_url_error(template, retry_timeout):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def get_authenticated_user(args):
|
||||||
|
template = 'https://{0}/user'.format(get_github_api_host(args))
|
||||||
|
data = retrieve_data(args, template, single_request=True)
|
||||||
|
return data[0]
|
||||||
|
|
||||||
|
|
||||||
def check_git_lfs_install():
|
def check_git_lfs_install():
|
||||||
exit_code = subprocess.call(['git', 'lfs', 'version'])
|
exit_code = subprocess.call(['git', 'lfs', 'version'])
|
||||||
if exit_code != 0:
|
if exit_code != 0:
|
||||||
log_error('The argument --lfs requires you to have Git LFS installed.\nYou can get it from https://git-lfs.github.com.')
|
log_error('The argument --lfs requires you to have Git LFS installed.\nYou can get it from https://git-lfs.github.com.')
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
|
|
||||||
def retrieve_repositories(args):
|
def retrieve_repositories(args, authenticated_user):
|
||||||
log_info('Retrieving repositories')
|
log_info('Retrieving repositories')
|
||||||
single_request = False
|
single_request = False
|
||||||
template = 'https://{0}/user/repos'.format(
|
if args.user == authenticated_user['login']:
|
||||||
get_github_api_host(args))
|
# we must use the /user/repos API to be able to access private repos
|
||||||
|
template = 'https://{0}/user/repos'.format(
|
||||||
|
get_github_api_host(args))
|
||||||
|
else:
|
||||||
|
if args.private and not args.organization:
|
||||||
|
log_warning('Authenticated user is different from user being backed up, thus private repositories cannot be accessed')
|
||||||
|
template = 'https://{0}/users/{1}/repos'.format(
|
||||||
|
get_github_api_host(args),
|
||||||
|
args.user)
|
||||||
|
|
||||||
if args.organization:
|
if args.organization:
|
||||||
template = 'https://{0}/orgs/{1}/repos'.format(
|
template = 'https://{0}/orgs/{1}/repos'.format(
|
||||||
get_github_api_host(args),
|
get_github_api_host(args),
|
||||||
@@ -517,7 +573,7 @@ def retrieve_repositories(args):
|
|||||||
repos = retrieve_data(args, template, single_request=single_request)
|
repos = retrieve_data(args, template, single_request=single_request)
|
||||||
|
|
||||||
if args.all_starred:
|
if args.all_starred:
|
||||||
starred_template = 'https://{0}/user/starred'.format(get_github_api_host(args))
|
starred_template = 'https://{0}/users/{1}/starred'.format(get_github_api_host(args), args.user)
|
||||||
starred_repos = retrieve_data(args, starred_template, single_request=False)
|
starred_repos = retrieve_data(args, starred_template, single_request=False)
|
||||||
# flag each repo as starred for downstream processing
|
# flag each repo as starred for downstream processing
|
||||||
for item in starred_repos:
|
for item in starred_repos:
|
||||||
@@ -525,7 +581,7 @@ def retrieve_repositories(args):
|
|||||||
repos.extend(starred_repos)
|
repos.extend(starred_repos)
|
||||||
|
|
||||||
if args.include_gists:
|
if args.include_gists:
|
||||||
gists_template = 'https://{0}/gists'.format(get_github_api_host(args))
|
gists_template = 'https://{0}/users/{1}/gists'.format(get_github_api_host(args), args.user)
|
||||||
gists = retrieve_data(args, gists_template, single_request=False)
|
gists = retrieve_data(args, gists_template, single_request=False)
|
||||||
# flag each repo as a gist for downstream processing
|
# flag each repo as a gist for downstream processing
|
||||||
for item in gists:
|
for item in gists:
|
||||||
@@ -717,23 +773,35 @@ def backup_pulls(args, repo_cwd, repository, repos_template):
|
|||||||
pulls = {}
|
pulls = {}
|
||||||
_pulls_template = '{0}/{1}/pulls'.format(repos_template,
|
_pulls_template = '{0}/{1}/pulls'.format(repos_template,
|
||||||
repository['full_name'])
|
repository['full_name'])
|
||||||
|
query_args = {
|
||||||
|
'filter': 'all',
|
||||||
|
'state': 'all',
|
||||||
|
'sort': 'updated',
|
||||||
|
'direction': 'desc',
|
||||||
|
}
|
||||||
|
|
||||||
pull_states = ['open', 'closed']
|
if not args.include_pull_details:
|
||||||
for pull_state in pull_states:
|
pull_states = ['open', 'closed']
|
||||||
query_args = {
|
for pull_state in pull_states:
|
||||||
'filter': 'all',
|
query_args['state'] = pull_state
|
||||||
'state': pull_state,
|
# It'd be nice to be able to apply the args.since filter here...
|
||||||
'sort': 'updated',
|
_pulls = retrieve_data(args,
|
||||||
'direction': 'desc',
|
_pulls_template,
|
||||||
}
|
query_args=query_args)
|
||||||
|
for pull in _pulls:
|
||||||
# It'd be nice to be able to apply the args.since filter here...
|
if not args.since or pull['updated_at'] >= args.since:
|
||||||
|
pulls[pull['number']] = pull
|
||||||
|
else:
|
||||||
_pulls = retrieve_data(args,
|
_pulls = retrieve_data(args,
|
||||||
_pulls_template,
|
_pulls_template,
|
||||||
query_args=query_args)
|
query_args=query_args)
|
||||||
for pull in _pulls:
|
for pull in _pulls:
|
||||||
if not args.since or pull['updated_at'] >= args.since:
|
if not args.since or pull['updated_at'] >= args.since:
|
||||||
pulls[pull['number']] = pull
|
pulls[pull['number']] = retrieve_data(
|
||||||
|
args,
|
||||||
|
_pulls_template + '/{}'.format(pull['number']),
|
||||||
|
single_request=True
|
||||||
|
)
|
||||||
|
|
||||||
log_info('Saving {0} pull requests to disk'.format(
|
log_info('Saving {0} pull requests to disk'.format(
|
||||||
len(list(pulls.keys()))))
|
len(list(pulls.keys()))))
|
||||||
@@ -823,7 +891,7 @@ def fetch_repository(name,
|
|||||||
clone_exists = subprocess.check_output(['git',
|
clone_exists = subprocess.check_output(['git',
|
||||||
'rev-parse',
|
'rev-parse',
|
||||||
'--is-bare-repository'],
|
'--is-bare-repository'],
|
||||||
cwd=local_dir) == "true\n"
|
cwd=local_dir) == b"true\n"
|
||||||
else:
|
else:
|
||||||
clone_exists = False
|
clone_exists = False
|
||||||
else:
|
else:
|
||||||
@@ -886,21 +954,37 @@ def backup_account(args, output_directory):
|
|||||||
account_cwd = os.path.join(output_directory, 'account')
|
account_cwd = os.path.join(output_directory, 'account')
|
||||||
|
|
||||||
if args.include_starred or args.include_everything:
|
if args.include_starred or args.include_everything:
|
||||||
output_file = '{0}/starred.json'.format(account_cwd)
|
output_file = "{0}/starred.json".format(account_cwd)
|
||||||
template = "https://{0}/users/{1}/starred"
|
template = "https://{0}/users/{1}/starred".format(get_github_api_host(args), args.user)
|
||||||
template = template.format(get_github_api_host(args), args.user)
|
|
||||||
_backup_data(args,
|
_backup_data(args,
|
||||||
'starred repositories',
|
"starred repositories",
|
||||||
template,
|
template,
|
||||||
output_file,
|
output_file,
|
||||||
account_cwd)
|
account_cwd)
|
||||||
|
|
||||||
if args.include_watched or args.include_everything:
|
if args.include_watched or args.include_everything:
|
||||||
output_file = '{0}/watched.json'.format(account_cwd)
|
output_file = "{0}/watched.json".format(account_cwd)
|
||||||
template = "https://{0}/users/{1}/subscriptions"
|
template = "https://{0}/users/{1}/subscriptions".format(get_github_api_host(args), args.user)
|
||||||
template = template.format(get_github_api_host(args), args.user)
|
|
||||||
_backup_data(args,
|
_backup_data(args,
|
||||||
'watched repositories',
|
"watched repositories",
|
||||||
|
template,
|
||||||
|
output_file,
|
||||||
|
account_cwd)
|
||||||
|
|
||||||
|
if args.include_followers or args.include_everything:
|
||||||
|
output_file = "{0}/followers.json".format(account_cwd)
|
||||||
|
template = "https://{0}/users/{1}/followers".format(get_github_api_host(args), args.user)
|
||||||
|
_backup_data(args,
|
||||||
|
"followers",
|
||||||
|
template,
|
||||||
|
output_file,
|
||||||
|
account_cwd)
|
||||||
|
|
||||||
|
if args.include_following or args.include_everything:
|
||||||
|
output_file = "{0}/following.json".format(account_cwd)
|
||||||
|
template = "https://{0}/users/{1}/following".format(get_github_api_host(args), args.user)
|
||||||
|
_backup_data(args,
|
||||||
|
"following",
|
||||||
template,
|
template,
|
||||||
output_file,
|
output_file,
|
||||||
account_cwd)
|
account_cwd)
|
||||||
@@ -940,7 +1024,8 @@ def main():
|
|||||||
|
|
||||||
log_info('Backing up user {0} to {1}'.format(args.user, output_directory))
|
log_info('Backing up user {0} to {1}'.format(args.user, output_directory))
|
||||||
|
|
||||||
repositories = retrieve_repositories(args)
|
authenticated_user = get_authenticated_user(args)
|
||||||
|
repositories = retrieve_repositories(args, authenticated_user)
|
||||||
repositories = filter_repositories(args, repositories)
|
repositories = filter_repositories(args, repositories)
|
||||||
backup_repositories(args, output_directory, repositories)
|
backup_repositories(args, output_directory, repositories)
|
||||||
backup_account(args, output_directory)
|
backup_account(args, output_directory)
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
__version__ = '0.17.0'
|
__version__ = '0.23.0'
|
||||||
|
|||||||
9
release
9
release
@@ -1,8 +1,13 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -eo pipefail; [[ $RELEASE_TRACE ]] && set -x
|
set -eo pipefail; [[ $RELEASE_TRACE ]] && set -x
|
||||||
|
|
||||||
PACKAGE_NAME='github-backup'
|
if [[ ! -f setup.py ]]; then
|
||||||
INIT_PACKAGE_NAME='github_backup'
|
echo -e "${RED}WARNING: Missing setup.py${COLOR_OFF}\n"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PACKAGE_NAME="$(cat setup.py | grep "name='" | head | cut -d "'" -f2)"
|
||||||
|
INIT_PACKAGE_NAME="$(echo "${PACKAGE_NAME//-/_}")"
|
||||||
PUBLIC="true"
|
PUBLIC="true"
|
||||||
|
|
||||||
# Colors
|
# Colors
|
||||||
|
|||||||
1
setup.py
1
setup.py
@@ -37,7 +37,6 @@ setup(
|
|||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
'Topic :: System :: Archiving :: Backup',
|
'Topic :: System :: Archiving :: Backup',
|
||||||
'License :: OSI Approved :: MIT License',
|
'License :: OSI Approved :: MIT License',
|
||||||
'Programming Language :: Python :: 2.6',
|
|
||||||
'Programming Language :: Python :: 2.7',
|
'Programming Language :: Python :: 2.7',
|
||||||
'Programming Language :: Python :: 3.5',
|
'Programming Language :: Python :: 3.5',
|
||||||
'Programming Language :: Python :: 3.6',
|
'Programming Language :: Python :: 3.6',
|
||||||
|
|||||||
Reference in New Issue
Block a user