git-project-core-plugins 0.0.21__tar.gz → 0.0.22__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.
- git_project_core_plugins-0.0.22/.git +1 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/PKG-INFO +3 -3
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/_version.py +2 -2
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/__init__.py +27 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/branch.py +222 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/clone.py +98 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/common.py +22 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/config.py +169 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/help.py +298 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/init.py +74 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/run.py +399 -0
- git_project_core_plugins-0.0.22/build/lib/git_project_core_plugins/worktree.py +643 -0
- git_project_core_plugins-0.0.22/docs/README-template.rst +104 -0
- git_project_core_plugins-0.0.22/gen-readme.py +55 -0
- git_project_core_plugins-0.0.22/gen-readme.py~ +2 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/PKG-INFO +493 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/SOURCES.txt +21 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/dependency_links.txt +1 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/entry_points.txt +9 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/not-zip-safe +1 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/requires.txt +3 -0
- git_project_core_plugins-0.0.22/git_project_core_plugins.egg-info/top_level.txt +1 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/requirements.txt +1 -1
- git_project_core_plugins-0.0.22/src/git_project_core_plugins/artifact.py +323 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/branch.py +3 -0
- git_project_core_plugins-0.0.22/src/git_project_core_plugins/worktree.py +684 -0
- git_project_core_plugins-0.0.21/src/git_project_core_plugins/worktree.py → git_project_core_plugins-0.0.22/src/git_project_core_plugins/worktree.py~ +1 -1
- git_project_core_plugins-0.0.22/test.out +38 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_artifact.py +1 -1
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_branch.py +4 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_run.py +16 -16
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_worktree.py +27 -9
- git_project_core_plugins-0.0.21/.#test.out +0 -1
- git_project_core_plugins-0.0.21/.git +0 -1
- git_project_core_plugins-0.0.21/docs/authors.rst~ +0 -36
- git_project_core_plugins-0.0.21/docs/changelog.rst~ +0 -39
- git_project_core_plugins-0.0.21/docs/conf.py~ +0 -57
- git_project_core_plugins-0.0.21/docs/index.rst~ +0 -46
- git_project_core_plugins-0.0.21/docs/intro.rst~ +0 -29
- git_project_core_plugins-0.0.21/pyproject.toml~ +0 -260
- git_project_core_plugins-0.0.21/requirements.txt~ +0 -22
- git_project_core_plugins-0.0.21/test.out +0 -1804
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/COPYING +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/MANIFEST.in +0 -0
- {git_project_core_plugins-0.0.21/src → git_project_core_plugins-0.0.22/build/lib}/git_project_core_plugins/artifact.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/Makefile +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/authors.rst +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/changelog.rst +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/conf.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/index.rst +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/intro.rst +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/license.rst +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/docs/make.bat +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/pyproject.toml +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/__init__.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/clone.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/common.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/config.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/help.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/init.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/src/git_project_core_plugins/run.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/common.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/conftest.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_clone.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_config.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_help.py +0 -0
- {git_project_core_plugins-0.0.21 → git_project_core_plugins-0.0.22}/tests/test_init.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
gitdir: /Users/dag/projects/git-project-core-plugins/.git/worktrees/master/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: git-project-core-plugins
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.22
|
|
4
4
|
Summary: The extensible stupid project manager - core functionality
|
|
5
5
|
Author-email: "David A. Greene" <dag@obbligato.org>
|
|
6
6
|
License-Expression: AGPL-3.0-or-later
|
|
@@ -13,7 +13,7 @@ Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or l
|
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.9
|
|
14
14
|
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
15
15
|
Requires-Python: >=3
|
|
16
|
-
Requires-Dist: git-project>=0.0.
|
|
16
|
+
Requires-Dist: git-project>=0.0.27
|
|
17
17
|
Requires-Dist: progressbar
|
|
18
18
|
Provides-Extra: test
|
|
19
19
|
Requires-Dist: git-project; extra == 'test'
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2020 David A. Greene
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
# the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
# version.
|
|
9
|
+
#
|
|
10
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
13
|
+
# details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License along with
|
|
16
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
from .artifact import Artifact, ArtifactPlugin
|
|
20
|
+
from .branch import BranchPlugin
|
|
21
|
+
from .run import RunPlugin
|
|
22
|
+
from .clone import ClonePlugin
|
|
23
|
+
from .common import add_plugin_version_argument
|
|
24
|
+
from .config import ConfigPlugin
|
|
25
|
+
from .help import Help, HelpPlugin
|
|
26
|
+
from .init import InitPlugin
|
|
27
|
+
from .worktree import Worktree, WorktreePlugin
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2020 David A. Greene
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
# the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
# version.
|
|
9
|
+
#
|
|
10
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
13
|
+
# details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License along with
|
|
16
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
"""A plugin to add a 'branch' command to git-project. The branch command allows
|
|
20
|
+
query of branch status with respect to the project and pruning of 'finished'
|
|
21
|
+
branches.
|
|
22
|
+
|
|
23
|
+
Summary:
|
|
24
|
+
|
|
25
|
+
git-project branch status [<pattern>]
|
|
26
|
+
git-project branch prune [--no-ask] [<pattern>]
|
|
27
|
+
|
|
28
|
+
"""
|
|
29
|
+
from git_project import Git, RunnableConfigObject, Plugin
|
|
30
|
+
from git_project import add_top_level_command, Project, GitProjectException
|
|
31
|
+
|
|
32
|
+
from git_project_core_plugins.common import add_plugin_version_argument
|
|
33
|
+
|
|
34
|
+
import getpass
|
|
35
|
+
|
|
36
|
+
def query_yes_no(question, default="yes"):
|
|
37
|
+
"""Ask a yes/no question via input() and return their answer.
|
|
38
|
+
|
|
39
|
+
"question" is a string that is presented to the user.
|
|
40
|
+
"default" is the presumed answer if the user just hits <Enter>.
|
|
41
|
+
It must be "yes" (the default), "no" or None (meaning
|
|
42
|
+
an answer is required of the user).
|
|
43
|
+
|
|
44
|
+
The "answer" return value is True for "yes" or False for "no".
|
|
45
|
+
"""
|
|
46
|
+
valid = {"yes": True, "y": True, "ye": True,
|
|
47
|
+
"no": False, "n": False}
|
|
48
|
+
if default is None:
|
|
49
|
+
prompt = " [y/n] "
|
|
50
|
+
elif default == "yes":
|
|
51
|
+
prompt = " [Y/n] "
|
|
52
|
+
elif default == "no":
|
|
53
|
+
prompt = " [y/N] "
|
|
54
|
+
else:
|
|
55
|
+
raise ValueError("invalid default answer: '%s'" % default)
|
|
56
|
+
|
|
57
|
+
while True:
|
|
58
|
+
sys.stdout.write(question + prompt)
|
|
59
|
+
choice = input().lower()
|
|
60
|
+
if default is not None and choice == '':
|
|
61
|
+
return valid[default]
|
|
62
|
+
elif choice in valid:
|
|
63
|
+
return valid[choice]
|
|
64
|
+
else:
|
|
65
|
+
sys.stdout.write("Please respond with 'yes' or 'no' "
|
|
66
|
+
"(or 'y' or 'n').\n")
|
|
67
|
+
|
|
68
|
+
def command_branch_status(git, gitproject, project, clargs):
|
|
69
|
+
"""Implement git-project branch status."""
|
|
70
|
+
ref = clargs.name_or_ref
|
|
71
|
+
|
|
72
|
+
if not ref:
|
|
73
|
+
if clargs.all_user:
|
|
74
|
+
ref = 'refs/heads/user/' + getpass.getuser()
|
|
75
|
+
elif clargs.all:
|
|
76
|
+
ref = 'refs/heads'
|
|
77
|
+
else:
|
|
78
|
+
raise GitProjectException('merged requires branch name, pattern, --all-user or --all')
|
|
79
|
+
else:
|
|
80
|
+
if not ref.startswith('refs/'):
|
|
81
|
+
ref = 'refs/heads/' + ref
|
|
82
|
+
|
|
83
|
+
target = clargs.target if clargs.target else None
|
|
84
|
+
|
|
85
|
+
branch_width = 45
|
|
86
|
+
status_width = 8
|
|
87
|
+
separator_width = branch_width + 2 * status_width - (status_width - len('merged'))
|
|
88
|
+
|
|
89
|
+
print('-' * separator_width)
|
|
90
|
+
print('{:<{branch_width}s}{:<{status_width}s}{:<{status_width}s}'.
|
|
91
|
+
format('branch', 'merged', 'pushed',
|
|
92
|
+
branch_width=branch_width, status_width=status_width))
|
|
93
|
+
print('-' * separator_width)
|
|
94
|
+
|
|
95
|
+
for branch in git.iterrefnames([ref]):
|
|
96
|
+
merge_status = 'no'
|
|
97
|
+
if target:
|
|
98
|
+
merge_status = 'yes' if git.branch_is_merged(branch, target) else 'no'
|
|
99
|
+
else:
|
|
100
|
+
merge_status = 'yes' if project.branch_is_merged(branch) else 'no'
|
|
101
|
+
|
|
102
|
+
push_status = 'yes' if project.branch_is_pushed(branch) else 'no'
|
|
103
|
+
|
|
104
|
+
print('{:<{branch_width}s}{:<{status_width}s}{:<{status_width}s}'.
|
|
105
|
+
format(branch[:branch_width-2], merge_status, push_status,
|
|
106
|
+
branch_width=branch_width, status_width=status_width))
|
|
107
|
+
print('-' * separator_width)
|
|
108
|
+
|
|
109
|
+
def command_branch_prune(git, gitproject, project, clargs):
|
|
110
|
+
"""Implement git-project branch prune."""
|
|
111
|
+
ref = clargs.name_or_ref
|
|
112
|
+
if not ref:
|
|
113
|
+
if clargs.all_user:
|
|
114
|
+
ref = 'refs/heads/user/' + getpass.getuser()
|
|
115
|
+
else:
|
|
116
|
+
raise GitProjectException('Prune requires branch name, pattern or --all-user')
|
|
117
|
+
else:
|
|
118
|
+
ref = Git.branch_name_to_refname(ref)
|
|
119
|
+
|
|
120
|
+
branch_width = 45
|
|
121
|
+
status_width = 15
|
|
122
|
+
separator_width = branch_width + 2 * status_width
|
|
123
|
+
|
|
124
|
+
print('-' * separator_width)
|
|
125
|
+
print('{:<{branch_width}s}{:<{status_width}s}{:<{status_width}s}'.
|
|
126
|
+
format('branch', 'local status', 'remote status',
|
|
127
|
+
branch_width=branch_width, status_width=status_width))
|
|
128
|
+
print('-' * separator_width)
|
|
129
|
+
|
|
130
|
+
for branch in git.iterrefnames([ref]):
|
|
131
|
+
status = 'merged' if project.branch_is_merged(branch) else 'unmerged'
|
|
132
|
+
|
|
133
|
+
print('{:<{branch_width}s}{:<{status_width}s}'.
|
|
134
|
+
format(branch[:branch_width-2], status,
|
|
135
|
+
branch_width=branch_width, status_width=status_width))
|
|
136
|
+
if clargs.force or status == 'merged':
|
|
137
|
+
if clargs.no_ask or query_yes_no('Prune?', default=None):
|
|
138
|
+
project.prune_branch(branch)
|
|
139
|
+
|
|
140
|
+
class BranchPlugin(Plugin):
|
|
141
|
+
"""
|
|
142
|
+
The branch command queries the status of branches against known project
|
|
143
|
+
branches and provides methods to prune old branches.
|
|
144
|
+
|
|
145
|
+
Summary:
|
|
146
|
+
|
|
147
|
+
git <project> branch status [--all] [<refish>]
|
|
148
|
+
git <project> branch prune [--force] [--no-ask]
|
|
149
|
+
|
|
150
|
+
The branch status command checks the given <refish> (or all local branches
|
|
151
|
+
with the --all option) against the project-configured branches. The command
|
|
152
|
+
outputs a table of branches and whether they are merged to a project branch
|
|
153
|
+
and/or pushed to a remote. For example:
|
|
154
|
+
|
|
155
|
+
git <project> config --add branch release
|
|
156
|
+
git <project> branch status mybranch
|
|
157
|
+
|
|
158
|
+
The report will show whether mybranch is merged to the release or master
|
|
159
|
+
branches (master is always a configured project branch) and whether the
|
|
160
|
+
commit pointed to mybranch is pushed to a remote.
|
|
161
|
+
|
|
162
|
+
The branch prune command computes the same information and if the branch is
|
|
163
|
+
merged to a project branch and that project branch is pushed to a remote,
|
|
164
|
+
will ask whether mybranch should be deleted. If the user indicates yes,
|
|
165
|
+
both the local mybranch and its remote counterpart, if any, will be deleted.
|
|
166
|
+
|
|
167
|
+
With --force, branches will be pruneed regardless of merge/push status.
|
|
168
|
+
With --no-ask branch prune operates in batch mode, assuming all merged and
|
|
169
|
+
pushed branches should be pruned.
|
|
170
|
+
|
|
171
|
+
See also:
|
|
172
|
+
|
|
173
|
+
config
|
|
174
|
+
|
|
175
|
+
"""
|
|
176
|
+
def __init__(self):
|
|
177
|
+
super().__init__('branch')
|
|
178
|
+
|
|
179
|
+
def add_arguments(self,
|
|
180
|
+
git,
|
|
181
|
+
gitproject,
|
|
182
|
+
project,
|
|
183
|
+
parser_manager,
|
|
184
|
+
plugin_manager):
|
|
185
|
+
"""Add arguments for 'git project branch.'"""
|
|
186
|
+
# branch
|
|
187
|
+
branch_parser = add_top_level_command(parser_manager,
|
|
188
|
+
'branch',
|
|
189
|
+
'branch',
|
|
190
|
+
help='Manipulate branches')
|
|
191
|
+
|
|
192
|
+
add_plugin_version_argument(branch_parser)
|
|
193
|
+
|
|
194
|
+
branch_subparser = parser_manager.add_subparser(branch_parser,
|
|
195
|
+
'branch_command',
|
|
196
|
+
help='branch commands')
|
|
197
|
+
|
|
198
|
+
# branch status
|
|
199
|
+
branch_status_parser = parser_manager.add_parser(branch_subparser,
|
|
200
|
+
'status',
|
|
201
|
+
'branch-status',
|
|
202
|
+
help='Show branch status')
|
|
203
|
+
|
|
204
|
+
branch_status_parser.set_defaults(func=command_branch_status)
|
|
205
|
+
|
|
206
|
+
branch_status_parser.add_argument('name_or_ref', nargs='?', help='Branch or pattern to filter branches')
|
|
207
|
+
branch_status_parser.add_argument('target', nargs='?', help='Target branch to check against')
|
|
208
|
+
branch_status_parser.add_argument('--all', action='store_true', help='Show all branches')
|
|
209
|
+
branch_status_parser.add_argument('--all-user', action='store_true', help='Show all user\'s branches')
|
|
210
|
+
|
|
211
|
+
# branch prune
|
|
212
|
+
branch_prune_parser = parser_manager.add_parser(branch_subparser,
|
|
213
|
+
'prune',
|
|
214
|
+
'branch-prune',
|
|
215
|
+
help='Delete merged branches')
|
|
216
|
+
|
|
217
|
+
branch_prune_parser.set_defaults(func=command_branch_prune)
|
|
218
|
+
|
|
219
|
+
branch_prune_parser.add_argument('name_or_ref', nargs='?', help='Branch name or pattern to filter branches')
|
|
220
|
+
branch_prune_parser.add_argument('--all-user', action='store_true', help='Prune all user\'s branches')
|
|
221
|
+
branch_prune_parser.add_argument('--force', action='store_true', help='Prune even if unmerged')
|
|
222
|
+
branch_prune_parser.add_argument('--no-ask', action='store_true', help='Do not ask before pruning')
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2020 David A. Greene
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
# the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
# version.
|
|
9
|
+
#
|
|
10
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
13
|
+
# details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License along with
|
|
16
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
"""A plugin to add a 'clone' command to git-project. The clone command clones a
|
|
20
|
+
repository and optionally initializes a master worktree environment.
|
|
21
|
+
|
|
22
|
+
Summary:
|
|
23
|
+
|
|
24
|
+
git-project clone <url> [path] [--bare] [--no-master-worktree]
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from git_project import add_top_level_command, Plugin
|
|
29
|
+
|
|
30
|
+
from git_project_core_plugins.common import add_plugin_version_argument
|
|
31
|
+
|
|
32
|
+
import getpass
|
|
33
|
+
import os
|
|
34
|
+
from pathlib import Path
|
|
35
|
+
import pygit2
|
|
36
|
+
|
|
37
|
+
def command_clone(git, gitproject, project, clargs):
|
|
38
|
+
"""Implement git-project clone"""
|
|
39
|
+
gitdir = git.clone(clargs.url,
|
|
40
|
+
path=clargs.path if hasattr(clargs, 'path') else None,
|
|
41
|
+
bare=clargs.bare)
|
|
42
|
+
|
|
43
|
+
# Now that we have a repository, add sensible project defaults. We know
|
|
44
|
+
# there is no existing project in the config file since we just cloned.
|
|
45
|
+
# This will have the effect of adding a project section.
|
|
46
|
+
project.set_defaults()
|
|
47
|
+
|
|
48
|
+
return gitdir
|
|
49
|
+
|
|
50
|
+
class ClonePlugin(Plugin):
|
|
51
|
+
"""
|
|
52
|
+
The clone command clones a repository.
|
|
53
|
+
|
|
54
|
+
Summary:
|
|
55
|
+
|
|
56
|
+
git <project> clone <url> [<path>] [--bare]
|
|
57
|
+
|
|
58
|
+
By itself clone has just the very basic funcionality of the built-in git
|
|
59
|
+
clone command. Plugins may add options to give the clone command more
|
|
60
|
+
features. For example, the woktree command adds a --worktree option to have
|
|
61
|
+
clone create a ``worktree layout.''
|
|
62
|
+
|
|
63
|
+
See also:
|
|
64
|
+
|
|
65
|
+
worktree
|
|
66
|
+
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
def __init__(self):
|
|
70
|
+
super().__init__('clone')
|
|
71
|
+
|
|
72
|
+
def add_arguments(self,
|
|
73
|
+
git,
|
|
74
|
+
gitproject,
|
|
75
|
+
project,
|
|
76
|
+
parser_manager,
|
|
77
|
+
plugin_manager):
|
|
78
|
+
"""Add arguments for 'git-project clone.'"""
|
|
79
|
+
# clone
|
|
80
|
+
clone_parser = add_top_level_command(parser_manager,
|
|
81
|
+
'clone',
|
|
82
|
+
'clone',
|
|
83
|
+
help='Clone project')
|
|
84
|
+
|
|
85
|
+
add_plugin_version_argument(clone_parser)
|
|
86
|
+
|
|
87
|
+
clone_parser.set_defaults(func=command_clone)
|
|
88
|
+
|
|
89
|
+
clone_parser.add_argument('url',
|
|
90
|
+
help='URL to clone')
|
|
91
|
+
|
|
92
|
+
clone_parser.add_argument('path',
|
|
93
|
+
nargs='?',
|
|
94
|
+
help='Local repository location')
|
|
95
|
+
|
|
96
|
+
clone_parser.add_argument('--bare',
|
|
97
|
+
action='store_true',
|
|
98
|
+
help='Clone a bare repository')
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2020 David A. Greene
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
# the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
# version.
|
|
9
|
+
#
|
|
10
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
13
|
+
# details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License along with
|
|
16
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
from git_project.commandline import add_version_argument
|
|
20
|
+
|
|
21
|
+
def add_plugin_version_argument(parser):
|
|
22
|
+
add_version_argument(parser, 'git-project-core-plugins')
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
#
|
|
3
|
+
# Copyright 2020 David A. Greene
|
|
4
|
+
#
|
|
5
|
+
# This program is free software: you can redistribute it and/or modify it under
|
|
6
|
+
# the terms of the GNU General Public License as published by the Free Software
|
|
7
|
+
# Foundation, either version 3 of the License, or (at your option) any later
|
|
8
|
+
# version.
|
|
9
|
+
#
|
|
10
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
11
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
12
|
+
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
13
|
+
# details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License along with
|
|
16
|
+
# this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
#
|
|
18
|
+
|
|
19
|
+
"""A plugin to add a 'config' command to git-project. The config command sets
|
|
20
|
+
project-wide git configuration values and prints their values to stdout.
|
|
21
|
+
|
|
22
|
+
Summary:
|
|
23
|
+
|
|
24
|
+
git-project config <key> [--unset] [<value>]
|
|
25
|
+
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
from git_project import ConfigObject, RunnableConfigObject
|
|
29
|
+
from git_project import Plugin, Project, GitProjectException
|
|
30
|
+
|
|
31
|
+
from git_project_core_plugins.common import add_plugin_version_argument
|
|
32
|
+
|
|
33
|
+
def command_config(git, gitproject, project, clargs):
|
|
34
|
+
"""Implement git-project config."""
|
|
35
|
+
getter = clargs.getter
|
|
36
|
+
exister = clargs.exister
|
|
37
|
+
classname = clargs.classname
|
|
38
|
+
|
|
39
|
+
subsection = None
|
|
40
|
+
if hasattr(clargs, 'subsection'):
|
|
41
|
+
subsection = clargs.subsection
|
|
42
|
+
|
|
43
|
+
ident = None
|
|
44
|
+
if hasattr(clargs, 'ident'):
|
|
45
|
+
ident = clargs.ident
|
|
46
|
+
|
|
47
|
+
if not exister(git, project.get_section(), subsection, ident):
|
|
48
|
+
if ident:
|
|
49
|
+
raise GitProjectException(f'{classname} \'{ident}\' does not exist')
|
|
50
|
+
else:
|
|
51
|
+
raise GitProjectException(f'No {classname} configured')
|
|
52
|
+
|
|
53
|
+
configitem = getter(git, project, ident) if ident else getter(git, project.get_section())
|
|
54
|
+
|
|
55
|
+
if clargs.value:
|
|
56
|
+
if clargs.unset:
|
|
57
|
+
configitem.rm_item(clargs.name, clargs.value)
|
|
58
|
+
else:
|
|
59
|
+
if clargs.add:
|
|
60
|
+
configitem.add_item(clargs.name, clargs.value)
|
|
61
|
+
else:
|
|
62
|
+
setattr(configitem, clargs.name, clargs.value)
|
|
63
|
+
elif clargs.unset:
|
|
64
|
+
delattr(configitem, clargs.name)
|
|
65
|
+
else:
|
|
66
|
+
value = getattr(configitem, clargs.name)
|
|
67
|
+
print(value)
|
|
68
|
+
|
|
69
|
+
class ConfigPlugin(Plugin):
|
|
70
|
+
"""
|
|
71
|
+
The config command manages git config settings under the <project> section.
|
|
72
|
+
|
|
73
|
+
Summary:
|
|
74
|
+
|
|
75
|
+
git <project> config [--add] [--unset] <name> [<value>]
|
|
76
|
+
|
|
77
|
+
The config command operates much like git's built-in config command, except
|
|
78
|
+
all configuration keys are prefixed with <project>, keeping values under a
|
|
79
|
+
single project namespace. This is a convenient way to store parameters for
|
|
80
|
+
other commands. For example:
|
|
81
|
+
|
|
82
|
+
git <project> config builddir /path/to/build
|
|
83
|
+
git <project> add run build "make BUILDDIR={builddir} all"
|
|
84
|
+
|
|
85
|
+
Configuration kays may have their values substituted into other
|
|
86
|
+
configuration values via the {key} specifier. Special commands like build
|
|
87
|
+
perform the substitution recursively, so configuration vaalues may contain
|
|
88
|
+
substitutions of other configuration values which themselves contain
|
|
89
|
+
substitutions, and so on. Importantly, substitution only happens when
|
|
90
|
+
commands are run. Commands should document whether or not they perform
|
|
91
|
+
substitutions.
|
|
92
|
+
|
|
93
|
+
A git config ``sub-section'' may be substituted with its identifier. For
|
|
94
|
+
example:
|
|
95
|
+
|
|
96
|
+
git <project> worktree add myworktree
|
|
97
|
+
git <project> config builddir /path/to/{worktree}/build
|
|
98
|
+
|
|
99
|
+
Here, myworktree is the identifier of a specific worktree sub-section. If
|
|
100
|
+
myworktree is the currently active worktree (that is, the current directory
|
|
101
|
+
is under the myworktree root), then ``myworktree'' will substitute for
|
|
102
|
+
{woktree}.
|
|
103
|
+
|
|
104
|
+
See also:
|
|
105
|
+
|
|
106
|
+
run
|
|
107
|
+
worktree
|
|
108
|
+
|
|
109
|
+
"""
|
|
110
|
+
def __init__(self):
|
|
111
|
+
super().__init__('config')
|
|
112
|
+
|
|
113
|
+
def _add_config_parser(self, cls, project, parser_manager):
|
|
114
|
+
command = cls.get_managing_command()
|
|
115
|
+
config_key = command + '-config' if command else 'config'
|
|
116
|
+
config_parser = parser_manager.find_parser(config_key)
|
|
117
|
+
|
|
118
|
+
if not config_parser:
|
|
119
|
+
# Create a config parser under the managing command.
|
|
120
|
+
command_subparser_key = command + '-command' if command else 'command'
|
|
121
|
+
command_subparser = parser_manager.find_subparser(command_subparser_key)
|
|
122
|
+
if not command_subparser:
|
|
123
|
+
# This plugin doesn't have subcommands, so don't add one.
|
|
124
|
+
return
|
|
125
|
+
|
|
126
|
+
config_help = 'Configure ' + command if command else 'Configure git-project'
|
|
127
|
+
config_parser = parser_manager.add_parser(command_subparser,
|
|
128
|
+
'config',
|
|
129
|
+
config_key,
|
|
130
|
+
help=config_help)
|
|
131
|
+
|
|
132
|
+
config_parser.set_defaults(func=command_config)
|
|
133
|
+
config_parser.set_defaults(getter=cls.get)
|
|
134
|
+
config_parser.set_defaults(exister=cls.exists)
|
|
135
|
+
config_parser.set_defaults(classname=cls.__name__)
|
|
136
|
+
|
|
137
|
+
if hasattr(cls, 'subsection'):
|
|
138
|
+
config_parser.set_defaults(subsection=cls.subsection())
|
|
139
|
+
config_parser.add_argument('ident', help=f'{cls.__name__} to modify')
|
|
140
|
+
|
|
141
|
+
if not command:
|
|
142
|
+
# This is the top-level 'config' command.
|
|
143
|
+
add_plugin_version_argument(config_parser)
|
|
144
|
+
|
|
145
|
+
config_parser.add_argument('name', help='Property name')
|
|
146
|
+
config_parser.add_argument('value', nargs='?', help='Property value to set')
|
|
147
|
+
config_parser.add_argument('--add', action='store_true',
|
|
148
|
+
help='Add a value to a property')
|
|
149
|
+
config_parser.add_argument('--unset', action='store_true',
|
|
150
|
+
help='Remove a value from a property')
|
|
151
|
+
|
|
152
|
+
def add_arguments(self,
|
|
153
|
+
git,
|
|
154
|
+
gitproject,
|
|
155
|
+
project,
|
|
156
|
+
parser_manager,
|
|
157
|
+
plugin_manager):
|
|
158
|
+
"""Add arguments for 'git-project config'"""
|
|
159
|
+
self._add_config_parser(Project, project, parser_manager)
|
|
160
|
+
|
|
161
|
+
def modify_arguments(self, git, gitproject, project, parser_manager, plugin_manager):
|
|
162
|
+
"""Modify arguments for 'git-project config.'"""
|
|
163
|
+
|
|
164
|
+
# Find all plugins with classes that derive from ConfigObject and add
|
|
165
|
+
# config commands to them.
|
|
166
|
+
for plugin in plugin_manager.iterplugins():
|
|
167
|
+
for cls in plugin.iterclasses():
|
|
168
|
+
if (issubclass(cls, ConfigObject)):
|
|
169
|
+
self._add_config_parser(cls, project, parser_manager)
|