githubtakeout 0.1.10__tar.gz → 0.1.12__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {githubtakeout-0.1.10/src/githubtakeout.egg-info → githubtakeout-0.1.12}/PKG-INFO +35 -39
- githubtakeout-0.1.12/README.md +103 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/pyproject.toml +36 -7
- {githubtakeout-0.1.10 → githubtakeout-0.1.12/src/githubtakeout.egg-info}/PKG-INFO +35 -39
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.py +60 -59
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/progress.py +7 -5
- githubtakeout-0.1.10/README.md +0 -107
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/LICENSE +0 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/setup.cfg +0 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.egg-info/SOURCES.txt +0 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.egg-info/dependency_links.txt +0 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.egg-info/entry_points.txt +0 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.egg-info/requires.txt +0 -0
- {githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.egg-info/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: githubtakeout
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.12
|
|
4
|
+
Summary: Backup and archive Git Repos and Gists from GitHub
|
|
5
5
|
Author: Corey Goldberg
|
|
6
6
|
Maintainer: Corey Goldberg
|
|
7
7
|
License-Expression: MIT
|
|
@@ -25,7 +25,7 @@ Dynamic: license-file
|
|
|
25
25
|
|
|
26
26
|
# githubtakeout
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Backup and archive Git Repos and Gists from GitHub
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -38,32 +38,30 @@ Dynamic: license-file
|
|
|
38
38
|
|
|
39
39
|
## About:
|
|
40
40
|
|
|
41
|
-
`githubtakeout` is a data export tool for
|
|
42
|
-
It clones a user's repos and creates an archive
|
|
41
|
+
`githubtakeout` is a data export tool for backing up and archiving Git
|
|
42
|
+
repositories hosted on GitHub. It clones a user's repos and creates an archive
|
|
43
|
+
of each.
|
|
43
44
|
|
|
44
|
-
It supports public/private repos and public/secret gists. By default, it
|
|
45
|
-
commit history or branches (`.git` directory), or Gist
|
|
46
|
-
with command line options).
|
|
45
|
+
It supports public/private repos and public/secret gists. By default, it
|
|
46
|
+
doesn't save commit history or branches (`.git` directory), or Gist
|
|
47
|
+
repositories (both can be enabled with command line options).
|
|
47
48
|
|
|
48
|
-
When you run the program, archives of your repos will be saved in a directory
|
|
49
|
-
`backups` inside your current working directory, unless a different
|
|
50
|
-
using the `--dir` option.
|
|
49
|
+
When you run the program, archives of your repos will be saved in a directory
|
|
50
|
+
named `backups` inside your current working directory, unless a different
|
|
51
|
+
location is specified using the `--dir` option.
|
|
51
52
|
|
|
52
|
-
Archives are saved in compressed zip format (`.zip`) by default
|
|
53
|
-
as tarballs (`.tar.gz`) using the `--format=tar` option
|
|
53
|
+
Archives are saved in compressed zip format (`.zip`) by default. You can also
|
|
54
|
+
save as tarballs (`.tar.gz`) using the `--format=tar` option, or skip archiving
|
|
55
|
+
using the `--format=none` option.
|
|
54
56
|
|
|
55
57
|
## Requirements:
|
|
56
58
|
|
|
57
59
|
- Python 3.12+
|
|
58
60
|
- Git 1.7+
|
|
59
|
-
- Python packages:
|
|
60
|
-
- [GitPython][pypi-gitpython]
|
|
61
|
-
- [PyGithub][pypi-pygithub]
|
|
62
|
-
- [rich][pypi-rich]
|
|
63
61
|
|
|
64
62
|
## Installation:
|
|
65
63
|
|
|
66
|
-
Install from [PyPI][
|
|
64
|
+
#### Install from [PyPI][pypi-githubtakeout]:
|
|
67
65
|
|
|
68
66
|
```
|
|
69
67
|
pip install githubtakeout
|
|
@@ -71,46 +69,48 @@ pip install githubtakeout
|
|
|
71
69
|
|
|
72
70
|
## Authentication:
|
|
73
71
|
|
|
74
|
-
By default, `githubtakeout` will only retrieve an account's public repos. To
|
|
75
|
-
you need to authenticate.
|
|
72
|
+
By default, `githubtakeout` will only retrieve an account's public repos. To
|
|
73
|
+
access private repos and secret gists, you need to authenticate.
|
|
76
74
|
|
|
77
|
-
First, you must create a [personal access token][github-pat] on Github (either
|
|
78
|
-
access token). Once you have a token, you
|
|
75
|
+
First, you must create a [personal access token][github-pat] on Github (either
|
|
76
|
+
a fine-grained or classic personal access token). Once you have a token, you
|
|
77
|
+
can set the `GITHUB_TOKEN` environment variable:
|
|
79
78
|
|
|
80
79
|
```
|
|
81
80
|
$ export GITHUB_TOKEN=<access token>
|
|
82
81
|
```
|
|
83
82
|
|
|
84
|
-
If you prefer to be prompted for your token each time you run the program, use
|
|
83
|
+
If you prefer to be prompted for your token each time you run the program, use
|
|
84
|
+
the `--token` argument.
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
## CLI Options:
|
|
87
87
|
|
|
88
88
|
```
|
|
89
|
-
usage: githubtakeout [-h] [--dir DIR] [--format {tar,zip}] [--gists] [--history] [--list] [--token] username
|
|
89
|
+
usage: githubtakeout [-h] [--dir DIR] [--format {tar,zip,none}] [--gists] [--history] [--list] [--token] username
|
|
90
90
|
|
|
91
91
|
positional arguments:
|
|
92
|
-
username
|
|
92
|
+
username github username
|
|
93
93
|
|
|
94
94
|
options:
|
|
95
|
-
-h, --help
|
|
96
|
-
--dir DIR
|
|
97
|
-
--format {tar,zip} archive format (default: zip)
|
|
98
|
-
--gists
|
|
99
|
-
--history
|
|
100
|
-
--list
|
|
101
|
-
--token
|
|
95
|
+
-h, --help show this help message and exit
|
|
96
|
+
--dir DIR output directory (default: .)
|
|
97
|
+
--format {tar,zip,none} archive format (default: zip)
|
|
98
|
+
--gists include gists
|
|
99
|
+
--history include commit history and branches (.git directory)
|
|
100
|
+
--list list repos only
|
|
101
|
+
--token prompt for auth token
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
## Usage Examples:
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
#### Install from PyPI with pipx, Run:
|
|
107
107
|
|
|
108
108
|
```
|
|
109
109
|
pipx install githubtakeout
|
|
110
110
|
githubtakeout <github username>
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
#### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
|
|
114
114
|
|
|
115
115
|
```
|
|
116
116
|
git clone git@github.com:cgoldberg/githubtakeout.git
|
|
@@ -121,12 +121,8 @@ pip install .
|
|
|
121
121
|
githubtakeout <github username>
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
|
|
125
124
|
[github-home]: https://github.com/cgoldberg
|
|
126
125
|
[github-repo]: https://github.com/cgoldberg/sudokubot
|
|
127
126
|
[github-pat]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
|
|
128
127
|
[pypi-githubtakeout]: https://pypi.org/project/githubtakeout
|
|
129
|
-
[pypi-gitpython]: https://pypi.org/project/GitPython
|
|
130
|
-
[pypi-pygithub]: https://pypi.org/project/PyGithub
|
|
131
|
-
[pypi-rich]: https://pypi.org/project/rich
|
|
132
128
|
[mit-license]: https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# githubtakeout
|
|
2
|
+
|
|
3
|
+
## Backup and archive Git Repos and Gists from GitHub
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
- Copyright (c) 2015-2025 [Corey Goldberg][github-home]
|
|
8
|
+
- Development: [GitHub][github-repo]
|
|
9
|
+
- Download/Install: [PyPI][pypi-githubtakeout]
|
|
10
|
+
- License: [MIT][mit-license]
|
|
11
|
+
|
|
12
|
+
----
|
|
13
|
+
|
|
14
|
+
## About:
|
|
15
|
+
|
|
16
|
+
`githubtakeout` is a data export tool for backing up and archiving Git
|
|
17
|
+
repositories hosted on GitHub. It clones a user's repos and creates an archive
|
|
18
|
+
of each.
|
|
19
|
+
|
|
20
|
+
It supports public/private repos and public/secret gists. By default, it
|
|
21
|
+
doesn't save commit history or branches (`.git` directory), or Gist
|
|
22
|
+
repositories (both can be enabled with command line options).
|
|
23
|
+
|
|
24
|
+
When you run the program, archives of your repos will be saved in a directory
|
|
25
|
+
named `backups` inside your current working directory, unless a different
|
|
26
|
+
location is specified using the `--dir` option.
|
|
27
|
+
|
|
28
|
+
Archives are saved in compressed zip format (`.zip`) by default. You can also
|
|
29
|
+
save as tarballs (`.tar.gz`) using the `--format=tar` option, or skip archiving
|
|
30
|
+
using the `--format=none` option.
|
|
31
|
+
|
|
32
|
+
## Requirements:
|
|
33
|
+
|
|
34
|
+
- Python 3.12+
|
|
35
|
+
- Git 1.7+
|
|
36
|
+
|
|
37
|
+
## Installation:
|
|
38
|
+
|
|
39
|
+
#### Install from [PyPI][pypi-githubtakeout]:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
pip install githubtakeout
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Authentication:
|
|
46
|
+
|
|
47
|
+
By default, `githubtakeout` will only retrieve an account's public repos. To
|
|
48
|
+
access private repos and secret gists, you need to authenticate.
|
|
49
|
+
|
|
50
|
+
First, you must create a [personal access token][github-pat] on Github (either
|
|
51
|
+
a fine-grained or classic personal access token). Once you have a token, you
|
|
52
|
+
can set the `GITHUB_TOKEN` environment variable:
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
$ export GITHUB_TOKEN=<access token>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
If you prefer to be prompted for your token each time you run the program, use
|
|
59
|
+
the `--token` argument.
|
|
60
|
+
|
|
61
|
+
## CLI Options:
|
|
62
|
+
|
|
63
|
+
```
|
|
64
|
+
usage: githubtakeout [-h] [--dir DIR] [--format {tar,zip,none}] [--gists] [--history] [--list] [--token] username
|
|
65
|
+
|
|
66
|
+
positional arguments:
|
|
67
|
+
username github username
|
|
68
|
+
|
|
69
|
+
options:
|
|
70
|
+
-h, --help show this help message and exit
|
|
71
|
+
--dir DIR output directory (default: .)
|
|
72
|
+
--format {tar,zip,none} archive format (default: zip)
|
|
73
|
+
--gists include gists
|
|
74
|
+
--history include commit history and branches (.git directory)
|
|
75
|
+
--list list repos only
|
|
76
|
+
--token prompt for auth token
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Usage Examples:
|
|
80
|
+
|
|
81
|
+
#### Install from PyPI with pipx, Run:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
pipx install githubtakeout
|
|
85
|
+
githubtakeout <github username>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
#### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
git clone git@github.com:cgoldberg/githubtakeout.git
|
|
92
|
+
cd ./githubtakeout
|
|
93
|
+
python3 -m venv venv
|
|
94
|
+
source venv/bin/activate
|
|
95
|
+
pip install .
|
|
96
|
+
githubtakeout <github username>
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
[github-home]: https://github.com/cgoldberg
|
|
100
|
+
[github-repo]: https://github.com/cgoldberg/sudokubot
|
|
101
|
+
[github-pat]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
|
|
102
|
+
[pypi-githubtakeout]: https://pypi.org/project/githubtakeout
|
|
103
|
+
[mit-license]: https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE
|
|
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "githubtakeout"
|
|
7
|
-
version = "0.1.
|
|
8
|
-
description = "
|
|
7
|
+
version = "0.1.12"
|
|
8
|
+
description = "Backup and archive Git Repos and Gists from GitHub"
|
|
9
9
|
license = "MIT"
|
|
10
10
|
license-files = ["LICENSE"]
|
|
11
11
|
authors = [{name = "Corey Goldberg"}]
|
|
@@ -35,22 +35,51 @@ homepage = "https://github.com/cgoldberg/githubtakeout"
|
|
|
35
35
|
source = "https://github.com/cgoldberg/githubtakeout"
|
|
36
36
|
download = "https://pypi.org/project/githubtakeout"
|
|
37
37
|
|
|
38
|
+
[dependency-groups]
|
|
39
|
+
dev = [
|
|
40
|
+
"tox",
|
|
41
|
+
]
|
|
42
|
+
lint = [
|
|
43
|
+
"black",
|
|
44
|
+
"refurb",
|
|
45
|
+
"ruff",
|
|
46
|
+
]
|
|
47
|
+
validate = [
|
|
48
|
+
"packaging",
|
|
49
|
+
"validate-pyproject",
|
|
50
|
+
]
|
|
51
|
+
|
|
38
52
|
[tool.setuptools]
|
|
39
53
|
package-dir = {"" = "src"}
|
|
40
54
|
|
|
41
55
|
[tool.black]
|
|
42
|
-
line-length =
|
|
43
|
-
target-version = [
|
|
56
|
+
line-length = 120
|
|
57
|
+
target-version = [
|
|
58
|
+
"py312", "py313"
|
|
59
|
+
]
|
|
44
60
|
|
|
45
61
|
[tool.ruff]
|
|
46
|
-
line-length =
|
|
62
|
+
line-length = 120
|
|
47
63
|
respect-gitignore = true
|
|
48
64
|
target-version = "py312"
|
|
49
65
|
|
|
50
66
|
[tool.ruff.lint]
|
|
51
|
-
|
|
67
|
+
select = [
|
|
68
|
+
"D", "E", "F", "I", "PT", "RUF", "TID", "W"
|
|
69
|
+
]
|
|
70
|
+
extend-ignore = [
|
|
71
|
+
"D100", "D101", "D102", "D103", "D104", "D105", "D106", "D107", "D203",
|
|
72
|
+
"D205", "D211", "D213", "D400", "D401", "RUF012"
|
|
73
|
+
]
|
|
52
74
|
fixable = ["ALL"]
|
|
53
75
|
|
|
54
76
|
[tool.ruff.format]
|
|
55
77
|
docstring-code-format = true
|
|
56
|
-
docstring-code-line-length =
|
|
78
|
+
docstring-code-line-length = 120
|
|
79
|
+
|
|
80
|
+
[tool.refurb]
|
|
81
|
+
python_version = "3.9"
|
|
82
|
+
enable_all = true
|
|
83
|
+
disable = [
|
|
84
|
+
"FURB104", "FURB107", "FURB147", "FURB173", "FURB183", "FURB184"
|
|
85
|
+
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: githubtakeout
|
|
3
|
-
Version: 0.1.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.1.12
|
|
4
|
+
Summary: Backup and archive Git Repos and Gists from GitHub
|
|
5
5
|
Author: Corey Goldberg
|
|
6
6
|
Maintainer: Corey Goldberg
|
|
7
7
|
License-Expression: MIT
|
|
@@ -25,7 +25,7 @@ Dynamic: license-file
|
|
|
25
25
|
|
|
26
26
|
# githubtakeout
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Backup and archive Git Repos and Gists from GitHub
|
|
29
29
|
|
|
30
30
|
---
|
|
31
31
|
|
|
@@ -38,32 +38,30 @@ Dynamic: license-file
|
|
|
38
38
|
|
|
39
39
|
## About:
|
|
40
40
|
|
|
41
|
-
`githubtakeout` is a data export tool for
|
|
42
|
-
It clones a user's repos and creates an archive
|
|
41
|
+
`githubtakeout` is a data export tool for backing up and archiving Git
|
|
42
|
+
repositories hosted on GitHub. It clones a user's repos and creates an archive
|
|
43
|
+
of each.
|
|
43
44
|
|
|
44
|
-
It supports public/private repos and public/secret gists. By default, it
|
|
45
|
-
commit history or branches (`.git` directory), or Gist
|
|
46
|
-
with command line options).
|
|
45
|
+
It supports public/private repos and public/secret gists. By default, it
|
|
46
|
+
doesn't save commit history or branches (`.git` directory), or Gist
|
|
47
|
+
repositories (both can be enabled with command line options).
|
|
47
48
|
|
|
48
|
-
When you run the program, archives of your repos will be saved in a directory
|
|
49
|
-
`backups` inside your current working directory, unless a different
|
|
50
|
-
using the `--dir` option.
|
|
49
|
+
When you run the program, archives of your repos will be saved in a directory
|
|
50
|
+
named `backups` inside your current working directory, unless a different
|
|
51
|
+
location is specified using the `--dir` option.
|
|
51
52
|
|
|
52
|
-
Archives are saved in compressed zip format (`.zip`) by default
|
|
53
|
-
as tarballs (`.tar.gz`) using the `--format=tar` option
|
|
53
|
+
Archives are saved in compressed zip format (`.zip`) by default. You can also
|
|
54
|
+
save as tarballs (`.tar.gz`) using the `--format=tar` option, or skip archiving
|
|
55
|
+
using the `--format=none` option.
|
|
54
56
|
|
|
55
57
|
## Requirements:
|
|
56
58
|
|
|
57
59
|
- Python 3.12+
|
|
58
60
|
- Git 1.7+
|
|
59
|
-
- Python packages:
|
|
60
|
-
- [GitPython][pypi-gitpython]
|
|
61
|
-
- [PyGithub][pypi-pygithub]
|
|
62
|
-
- [rich][pypi-rich]
|
|
63
61
|
|
|
64
62
|
## Installation:
|
|
65
63
|
|
|
66
|
-
Install from [PyPI][
|
|
64
|
+
#### Install from [PyPI][pypi-githubtakeout]:
|
|
67
65
|
|
|
68
66
|
```
|
|
69
67
|
pip install githubtakeout
|
|
@@ -71,46 +69,48 @@ pip install githubtakeout
|
|
|
71
69
|
|
|
72
70
|
## Authentication:
|
|
73
71
|
|
|
74
|
-
By default, `githubtakeout` will only retrieve an account's public repos. To
|
|
75
|
-
you need to authenticate.
|
|
72
|
+
By default, `githubtakeout` will only retrieve an account's public repos. To
|
|
73
|
+
access private repos and secret gists, you need to authenticate.
|
|
76
74
|
|
|
77
|
-
First, you must create a [personal access token][github-pat] on Github (either
|
|
78
|
-
access token). Once you have a token, you
|
|
75
|
+
First, you must create a [personal access token][github-pat] on Github (either
|
|
76
|
+
a fine-grained or classic personal access token). Once you have a token, you
|
|
77
|
+
can set the `GITHUB_TOKEN` environment variable:
|
|
79
78
|
|
|
80
79
|
```
|
|
81
80
|
$ export GITHUB_TOKEN=<access token>
|
|
82
81
|
```
|
|
83
82
|
|
|
84
|
-
If you prefer to be prompted for your token each time you run the program, use
|
|
83
|
+
If you prefer to be prompted for your token each time you run the program, use
|
|
84
|
+
the `--token` argument.
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
## CLI Options:
|
|
87
87
|
|
|
88
88
|
```
|
|
89
|
-
usage: githubtakeout [-h] [--dir DIR] [--format {tar,zip}] [--gists] [--history] [--list] [--token] username
|
|
89
|
+
usage: githubtakeout [-h] [--dir DIR] [--format {tar,zip,none}] [--gists] [--history] [--list] [--token] username
|
|
90
90
|
|
|
91
91
|
positional arguments:
|
|
92
|
-
username
|
|
92
|
+
username github username
|
|
93
93
|
|
|
94
94
|
options:
|
|
95
|
-
-h, --help
|
|
96
|
-
--dir DIR
|
|
97
|
-
--format {tar,zip} archive format (default: zip)
|
|
98
|
-
--gists
|
|
99
|
-
--history
|
|
100
|
-
--list
|
|
101
|
-
--token
|
|
95
|
+
-h, --help show this help message and exit
|
|
96
|
+
--dir DIR output directory (default: .)
|
|
97
|
+
--format {tar,zip,none} archive format (default: zip)
|
|
98
|
+
--gists include gists
|
|
99
|
+
--history include commit history and branches (.git directory)
|
|
100
|
+
--list list repos only
|
|
101
|
+
--token prompt for auth token
|
|
102
102
|
```
|
|
103
103
|
|
|
104
104
|
## Usage Examples:
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
#### Install from PyPI with pipx, Run:
|
|
107
107
|
|
|
108
108
|
```
|
|
109
109
|
pipx install githubtakeout
|
|
110
110
|
githubtakeout <github username>
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
#### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
|
|
114
114
|
|
|
115
115
|
```
|
|
116
116
|
git clone git@github.com:cgoldberg/githubtakeout.git
|
|
@@ -121,12 +121,8 @@ pip install .
|
|
|
121
121
|
githubtakeout <github username>
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
|
|
125
124
|
[github-home]: https://github.com/cgoldberg
|
|
126
125
|
[github-repo]: https://github.com/cgoldberg/sudokubot
|
|
127
126
|
[github-pat]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
|
|
128
127
|
[pypi-githubtakeout]: https://pypi.org/project/githubtakeout
|
|
129
|
-
[pypi-gitpython]: https://pypi.org/project/GitPython
|
|
130
|
-
[pypi-pygithub]: https://pypi.org/project/PyGithub
|
|
131
|
-
[pypi-rich]: https://pypi.org/project/rich
|
|
132
128
|
[mit-license]: https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
# Corey Goldberg
|
|
1
|
+
# Copyright (c) 2015-2025 Corey Goldberg
|
|
2
2
|
# License: MIT
|
|
3
3
|
|
|
4
|
-
"""
|
|
4
|
+
"""Backup and archive Git Repos and Gists from GitHub."""
|
|
5
5
|
|
|
6
6
|
import argparse
|
|
7
7
|
import getpass
|
|
@@ -22,7 +22,7 @@ import github
|
|
|
22
22
|
|
|
23
23
|
from progress import GitProgress
|
|
24
24
|
|
|
25
|
-
ARCHIVE_FORMATS = ("tar", "zip")
|
|
25
|
+
ARCHIVE_FORMATS = ("tar", "zip", "none")
|
|
26
26
|
|
|
27
27
|
logging.basicConfig(level=logging.INFO, format="%(message)s")
|
|
28
28
|
logger = logging.getLogger(__name__)
|
|
@@ -32,7 +32,7 @@ def convert_size(size_bytes):
|
|
|
32
32
|
if size_bytes == 0:
|
|
33
33
|
return "0 B"
|
|
34
34
|
size_name = ("B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB")
|
|
35
|
-
i =
|
|
35
|
+
i = math.floor(math.log(size_bytes, 1024))
|
|
36
36
|
p = math.pow(1024, i)
|
|
37
37
|
s = round(size_bytes / p, 2)
|
|
38
38
|
return f"{s} {size_name[i]}"
|
|
@@ -52,6 +52,8 @@ def add_creds(url, username, token):
|
|
|
52
52
|
def archive(local_repo_dir, archive_format="zip", is_gist=False):
|
|
53
53
|
if archive_format not in ARCHIVE_FORMATS:
|
|
54
54
|
raise ValueError(f"{archive_format} is not a valid archive format")
|
|
55
|
+
if archive_format == "none":
|
|
56
|
+
return None
|
|
55
57
|
base_name = os.path.basename(local_repo_dir)
|
|
56
58
|
extension = "tar.gz" if archive_format == "tar" else archive_format
|
|
57
59
|
archive_name = f"{base_name}.{extension}"
|
|
@@ -101,9 +103,7 @@ def clone(repo_url, local_repo_dir, include_history):
|
|
|
101
103
|
pass
|
|
102
104
|
|
|
103
105
|
|
|
104
|
-
def clone_and_archive_repo(
|
|
105
|
-
repo_url, local_repo_dir, archive_format, include_history, is_gist=False
|
|
106
|
-
):
|
|
106
|
+
def clone_and_archive_repo(repo_url, local_repo_dir, archive_format, include_history, is_gist=False):
|
|
107
107
|
def remove_readonly(func, path, _):
|
|
108
108
|
# This is necessary so rmtree() doesn't fail if there are any readonly
|
|
109
109
|
# dirs/files when trying to delete. This seems to happen after cloning on
|
|
@@ -134,45 +134,26 @@ def clone_and_archive_repo(
|
|
|
134
134
|
except FileNotFoundError:
|
|
135
135
|
pass
|
|
136
136
|
archive_path = archive(local_repo_dir, archive_format, is_gist)
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
if archive_path:
|
|
138
|
+
size = convert_size(os.path.getsize(archive_path))
|
|
139
|
+
logger.info(f"archive size: {size}")
|
|
140
|
+
logger.info("deleting repo")
|
|
141
|
+
try:
|
|
142
|
+
# delete repo after archive is created
|
|
143
|
+
shutil.rmtree(local_repo_dir, onexc=remove_readonly)
|
|
144
|
+
except FileNotFoundError:
|
|
145
|
+
pass
|
|
145
146
|
elapsed = default_timer() - start
|
|
146
147
|
base_name = os.path.basename(local_repo_dir)
|
|
147
148
|
logger.info(f"successfully backed up '{base_name}' repo in {elapsed:.3f} secs\n")
|
|
148
149
|
|
|
149
150
|
|
|
150
|
-
def
|
|
151
|
-
if
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
sys.exit("error: auth token cannot be empty")
|
|
151
|
+
def get_repos(username, token, include_gists):
|
|
152
|
+
if token is not None:
|
|
153
|
+
# you need to be authenticated and then call the API
|
|
154
|
+
# with no username to get public and private repos
|
|
155
155
|
auth = github.Auth.Token(token)
|
|
156
156
|
gh = github.Github(auth=auth)
|
|
157
|
-
else:
|
|
158
|
-
token = os.getenv("GITHUB_TOKEN")
|
|
159
|
-
if token is not None:
|
|
160
|
-
auth = github.Auth.Token(token)
|
|
161
|
-
gh = github.Github(auth=auth)
|
|
162
|
-
else:
|
|
163
|
-
gh = github.Github()
|
|
164
|
-
if token is None:
|
|
165
|
-
try:
|
|
166
|
-
user = gh.get_user(username)
|
|
167
|
-
except github.GithubException as e:
|
|
168
|
-
if e.data["status"] == "404":
|
|
169
|
-
sys.exit(f"error: user '{username}' not found")
|
|
170
|
-
else:
|
|
171
|
-
raise e
|
|
172
|
-
repos = user.get_repos()
|
|
173
|
-
else:
|
|
174
|
-
# you need to be authenticated and then call the API
|
|
175
|
-
# with no username to get private repos
|
|
176
157
|
user = gh.get_user()
|
|
177
158
|
repos = user.get_repos(affiliation="owner")
|
|
178
159
|
try:
|
|
@@ -183,8 +164,31 @@ def get_user(username, prompt_token):
|
|
|
183
164
|
sys.exit(f"error: invalid auth token for user '{username}'")
|
|
184
165
|
else:
|
|
185
166
|
raise e
|
|
186
|
-
|
|
187
|
-
|
|
167
|
+
else:
|
|
168
|
+
gh = github.Github()
|
|
169
|
+
try:
|
|
170
|
+
user = gh.get_user(username)
|
|
171
|
+
except github.GithubException as e:
|
|
172
|
+
if e.data["status"] == "404":
|
|
173
|
+
sys.exit(f"error: user '{username}' not found")
|
|
174
|
+
else:
|
|
175
|
+
raise e
|
|
176
|
+
repos = user.get_repos()
|
|
177
|
+
if include_gists:
|
|
178
|
+
gists = user.get_gists()
|
|
179
|
+
else:
|
|
180
|
+
gists = None
|
|
181
|
+
return repos, gists
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def get_token(prompt_for_token):
|
|
185
|
+
if prompt_for_token:
|
|
186
|
+
token = getpass.getpass("Token:")
|
|
187
|
+
if not token:
|
|
188
|
+
sys.exit("error: auth token cannot be empty")
|
|
189
|
+
else:
|
|
190
|
+
token = os.getenv("GITHUB_TOKEN")
|
|
191
|
+
return token
|
|
188
192
|
|
|
189
193
|
|
|
190
194
|
def run(
|
|
@@ -194,10 +198,11 @@ def run(
|
|
|
194
198
|
include_gists,
|
|
195
199
|
include_history,
|
|
196
200
|
list_only,
|
|
197
|
-
|
|
201
|
+
prompt_for_token,
|
|
198
202
|
):
|
|
199
203
|
working_dir = os.path.join(base_dir, "backups")
|
|
200
|
-
|
|
204
|
+
token = get_token(prompt_for_token)
|
|
205
|
+
repos, gists = get_repos(username, token, include_gists)
|
|
201
206
|
num_repos = repos.totalCount
|
|
202
207
|
if not list_only:
|
|
203
208
|
logger.info(f"creating archives in: {working_dir}\n")
|
|
@@ -209,7 +214,7 @@ def run(
|
|
|
209
214
|
logger.info(url)
|
|
210
215
|
else:
|
|
211
216
|
clone_and_archive_repo(url, local_repo_dir, archive_format, include_history)
|
|
212
|
-
if
|
|
217
|
+
if gists is not None:
|
|
213
218
|
num_gists = gists.totalCount
|
|
214
219
|
logger.info("")
|
|
215
220
|
logger.info(f"found {num_gists} gists for user '{username}'\n")
|
|
@@ -219,20 +224,22 @@ def run(
|
|
|
219
224
|
if list_only:
|
|
220
225
|
logger.info(url)
|
|
221
226
|
else:
|
|
222
|
-
clone_and_archive_repo(
|
|
223
|
-
url, local_repo_dir, archive_format, include_history, is_gist=True
|
|
224
|
-
)
|
|
227
|
+
clone_and_archive_repo(url, local_repo_dir, archive_format, include_history, is_gist=True)
|
|
225
228
|
|
|
226
229
|
|
|
227
230
|
def main():
|
|
228
231
|
if sys.version_info < (3, 12):
|
|
229
232
|
sys.exit("sorry, this program requires Python 3.12+")
|
|
230
|
-
|
|
233
|
+
|
|
234
|
+
def formatter(prog):
|
|
235
|
+
return argparse.HelpFormatter(prog, max_help_position=30)
|
|
236
|
+
|
|
237
|
+
parser = argparse.ArgumentParser(formatter_class=formatter)
|
|
231
238
|
parser.add_argument("username", help="github username")
|
|
232
239
|
parser.add_argument(
|
|
233
240
|
"--dir",
|
|
234
241
|
default=os.getcwd(),
|
|
235
|
-
help="output directory (default:
|
|
242
|
+
help="output directory (default: .)",
|
|
236
243
|
)
|
|
237
244
|
parser.add_argument(
|
|
238
245
|
"--format",
|
|
@@ -240,21 +247,15 @@ def main():
|
|
|
240
247
|
default="zip",
|
|
241
248
|
help="archive format (default: %(default)s)",
|
|
242
249
|
)
|
|
243
|
-
parser.add_argument(
|
|
244
|
-
"--gists", action="store_true", default=False, help="include gists"
|
|
245
|
-
)
|
|
250
|
+
parser.add_argument("--gists", action="store_true", default=False, help="include gists")
|
|
246
251
|
parser.add_argument(
|
|
247
252
|
"--history",
|
|
248
253
|
action="store_true",
|
|
249
254
|
default=False,
|
|
250
255
|
help="include commit history and branches (.git directory)",
|
|
251
256
|
)
|
|
252
|
-
parser.add_argument(
|
|
253
|
-
|
|
254
|
-
)
|
|
255
|
-
parser.add_argument(
|
|
256
|
-
"--token", action="store_true", default=False, help="prompt for auth token"
|
|
257
|
-
)
|
|
257
|
+
parser.add_argument("--list", action="store_true", default=False, help="list repos only")
|
|
258
|
+
parser.add_argument("--token", action="store_true", default=False, help="prompt for auth token")
|
|
258
259
|
args = parser.parse_args()
|
|
259
260
|
try:
|
|
260
261
|
run(
|
|
@@ -264,7 +265,7 @@ def main():
|
|
|
264
265
|
include_gists=args.gists,
|
|
265
266
|
include_history=args.history,
|
|
266
267
|
list_only=args.list,
|
|
267
|
-
|
|
268
|
+
prompt_for_token=args.token,
|
|
268
269
|
)
|
|
269
270
|
except KeyboardInterrupt:
|
|
270
271
|
sys.exit("\nexiting program ...")
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
# Copyright (c) 2025 Corey Goldberg
|
|
2
|
+
# License: MIT
|
|
3
|
+
# adapted from: https://stackoverflow.com/a/71285627/16148
|
|
4
|
+
|
|
5
|
+
"""Progress bar for cloning Git repos."""
|
|
6
|
+
|
|
1
7
|
import git
|
|
2
8
|
from rich import console, progress
|
|
3
9
|
|
|
4
|
-
# adapted from: https://stackoverflow.com/a/71285627/16148
|
|
5
|
-
|
|
6
10
|
|
|
7
11
|
class GitProgress(git.RemoteProgress):
|
|
8
12
|
OP_CODES = [
|
|
@@ -16,9 +20,7 @@ class GitProgress(git.RemoteProgress):
|
|
|
16
20
|
"RESOLVING",
|
|
17
21
|
"WRITING",
|
|
18
22
|
]
|
|
19
|
-
OP_CODE_MAP = {
|
|
20
|
-
getattr(git.RemoteProgress, _op_code): _op_code for _op_code in OP_CODES
|
|
21
|
-
}
|
|
23
|
+
OP_CODE_MAP = {getattr(git.RemoteProgress, _op_code): _op_code for _op_code in OP_CODES}
|
|
22
24
|
|
|
23
25
|
def __init__(self):
|
|
24
26
|
super().__init__()
|
githubtakeout-0.1.10/README.md
DELETED
|
@@ -1,107 +0,0 @@
|
|
|
1
|
-
# githubtakeout
|
|
2
|
-
|
|
3
|
-
## Archive Git Repos and Gists from GitHub
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
- Copyright (c) 2015-2025 [Corey Goldberg][github-home]
|
|
8
|
-
- Development: [GitHub][github-repo]
|
|
9
|
-
- Download/Install: [PyPI][pypi-githubtakeout]
|
|
10
|
-
- License: [MIT][mit-license]
|
|
11
|
-
|
|
12
|
-
----
|
|
13
|
-
|
|
14
|
-
## About:
|
|
15
|
-
|
|
16
|
-
`githubtakeout` is a data export tool for archiving Git repositories hosted on GitHub.
|
|
17
|
-
It clones a user's repos and creates an archive of each.
|
|
18
|
-
|
|
19
|
-
It supports public/private repos and public/secret gists. By default, it doesn't save
|
|
20
|
-
commit history or branches (`.git` directory), or Gist repositories (both can be enabled
|
|
21
|
-
with command line options).
|
|
22
|
-
|
|
23
|
-
When you run the program, archives of your repos will be saved in a directory named
|
|
24
|
-
`backups` inside your current working directory, unless a different location is specified
|
|
25
|
-
using the `--dir` option.
|
|
26
|
-
|
|
27
|
-
Archives are saved in compressed zip format (`.zip`) by default, but can also be saved
|
|
28
|
-
as tarballs (`.tar.gz`) using the `--format=tar` option.
|
|
29
|
-
|
|
30
|
-
## Requirements:
|
|
31
|
-
|
|
32
|
-
- Python 3.12+
|
|
33
|
-
- Git 1.7+
|
|
34
|
-
- Python packages:
|
|
35
|
-
- [GitPython][pypi-gitpython]
|
|
36
|
-
- [PyGithub][pypi-pygithub]
|
|
37
|
-
- [rich][pypi-rich]
|
|
38
|
-
|
|
39
|
-
## Installation:
|
|
40
|
-
|
|
41
|
-
Install from [PyPI][pypyi-githubtakeout]:
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
pip install githubtakeout
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Authentication:
|
|
48
|
-
|
|
49
|
-
By default, `githubtakeout` will only retrieve an account's public repos. To access private repos and secret gists,
|
|
50
|
-
you need to authenticate.
|
|
51
|
-
|
|
52
|
-
First, you must create a [personal access token][github-pat] on Github (either a fine-grained or classic personal
|
|
53
|
-
access token). Once you have a token, you can set the `GITHUB_TOKEN` environment variable:
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
$ export GITHUB_TOKEN=<access token>
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
If you prefer to be prompted for your token each time you run the program, use the `--token` argument.
|
|
60
|
-
|
|
61
|
-
### CLI Options:
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
usage: githubtakeout [-h] [--dir DIR] [--format {tar,zip}] [--gists] [--history] [--list] [--token] username
|
|
65
|
-
|
|
66
|
-
positional arguments:
|
|
67
|
-
username github username
|
|
68
|
-
|
|
69
|
-
options:
|
|
70
|
-
-h, --help show this help message and exit
|
|
71
|
-
--dir DIR output directory (default: ./)
|
|
72
|
-
--format {tar,zip} archive format (default: zip)
|
|
73
|
-
--gists include gists
|
|
74
|
-
--history include commit history and branches (.git directory)
|
|
75
|
-
--list list repos only
|
|
76
|
-
--token prompt for auth token
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Usage Examples:
|
|
80
|
-
|
|
81
|
-
### Install from PyPI with pipx, Run:
|
|
82
|
-
|
|
83
|
-
```
|
|
84
|
-
pipx install githubtakeout
|
|
85
|
-
githubtakeout <github username>
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
### Clone Repo, Create/Activate Virtual Environment, Install from Source, Run:
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
git clone git@github.com:cgoldberg/githubtakeout.git
|
|
92
|
-
cd ./githubtakeout
|
|
93
|
-
python3 -m venv venv
|
|
94
|
-
source venv/bin/activate
|
|
95
|
-
pip install .
|
|
96
|
-
githubtakeout <github username>
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
[github-home]: https://github.com/cgoldberg
|
|
101
|
-
[github-repo]: https://github.com/cgoldberg/sudokubot
|
|
102
|
-
[github-pat]: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
|
|
103
|
-
[pypi-githubtakeout]: https://pypi.org/project/githubtakeout
|
|
104
|
-
[pypi-gitpython]: https://pypi.org/project/GitPython
|
|
105
|
-
[pypi-pygithub]: https://pypi.org/project/PyGithub
|
|
106
|
-
[pypi-rich]: https://pypi.org/project/rich
|
|
107
|
-
[mit-license]: https://raw.githubusercontent.com/cgoldberg/githubtakeout/refs/heads/master/LICENSE
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{githubtakeout-0.1.10 → githubtakeout-0.1.12}/src/githubtakeout.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|