mirror of
https://github.com/ejwa/gitinspector.git
synced 2024-11-16 00:28:25 +01:00
Implemented validation and printing of all supplied repositories (#24).
Upon start-up, now directly passes all supplied paths to git in order to check if all of them point to a valid git repository. The clone.create() function now returns a list of Repository instances, containing the name and location of the repository. This is later used in the gitinspector module to execute and parse the repository. format.output_header(...) now takes a list of Repository instances. Thanks to this, each output format can print every supplied repository.
This commit is contained in:
parent
01bdbfaba1
commit
d5106a7302
3 changed files with 60 additions and 28 deletions
|
@ -18,27 +18,41 @@
|
||||||
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
|
# along with gitinspector. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
from collections import namedtuple
|
||||||
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
|
|
||||||
|
try:
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
except:
|
||||||
|
from urlparse import urlparse
|
||||||
|
|
||||||
__cloned_paths__ = []
|
__cloned_paths__ = []
|
||||||
|
|
||||||
def create(url):
|
def create(url):
|
||||||
if url.startswith("file://") or url.startswith("git://") or url.startswith("http://") or \
|
class Repository(object):
|
||||||
url.startswith("https://") or url.startswith("ssh://"):
|
def __init__(self, name, location):
|
||||||
location = tempfile.mkdtemp(suffix=".gitinspector")
|
self.name = name
|
||||||
git_clone = subprocess.Popen(["git", "clone", url, location], bufsize=1, stdout=sys.stderr)
|
self.location = location
|
||||||
|
|
||||||
|
parsed_url = urlparse(url)
|
||||||
|
|
||||||
|
if parsed_url.scheme == "file" or parsed_url.scheme == "git" or parsed_url.scheme == "http" or \
|
||||||
|
parsed_url.scheme == "https" or parsed_url.scheme == "ssh":
|
||||||
|
path = tempfile.mkdtemp(suffix=".gitinspector")
|
||||||
|
git_clone = subprocess.Popen(["git", "clone", url, path], bufsize=1, stdout=sys.stderr)
|
||||||
git_clone.wait()
|
git_clone.wait()
|
||||||
|
|
||||||
if git_clone.returncode != 0:
|
if git_clone.returncode != 0:
|
||||||
sys.exit(git_clone.returncode)
|
sys.exit(git_clone.returncode)
|
||||||
|
|
||||||
__cloned_paths__.append(location)
|
__cloned_paths__.append(path)
|
||||||
return location
|
return Repository(os.path.basename(parsed_url.path), path)
|
||||||
|
|
||||||
return url
|
return Repository(None, os.path.abspath(url))
|
||||||
|
|
||||||
def delete():
|
def delete():
|
||||||
for path in __cloned_paths__:
|
for path in __cloned_paths__:
|
||||||
|
|
|
@ -24,6 +24,7 @@ import os
|
||||||
import textwrap
|
import textwrap
|
||||||
import time
|
import time
|
||||||
import zipfile
|
import zipfile
|
||||||
|
from .localization import N_
|
||||||
from . import basedir, localization, terminal, version
|
from . import basedir, localization, terminal, version
|
||||||
|
|
||||||
__available_formats__ = ["html", "htmlembedded", "json", "text", "xml"]
|
__available_formats__ = ["html", "htmlembedded", "json", "text", "xml"]
|
||||||
|
@ -59,7 +60,12 @@ def __get_zip_file_content__(name, file_name="/html/flot.zip"):
|
||||||
zip_file.close()
|
zip_file.close()
|
||||||
return content.decode("utf-8", "replace")
|
return content.decode("utf-8", "replace")
|
||||||
|
|
||||||
def output_header(repo):
|
INFO_ONE_REPOSITORY = N_("Statistical information for the repository '{0}' was gathered on {1}.")
|
||||||
|
INFO_MANY_REPOSITORIES = N_("Statistical information for the repositories '{0}' was gathered on {1}.")
|
||||||
|
|
||||||
|
def output_header(repos):
|
||||||
|
repos_string = ", ".join([repo.name for repo in repos])
|
||||||
|
|
||||||
if __selected_format__ == "html" or __selected_format__ == "htmlembedded":
|
if __selected_format__ == "html" or __selected_format__ == "htmlembedded":
|
||||||
base = basedir.get_basedir()
|
base = basedir.get_basedir()
|
||||||
html_header = __output_html_template__(base + "/html/html.header")
|
html_header = __output_html_template__(base + "/html/html.header")
|
||||||
|
@ -80,7 +86,7 @@ def output_header(repo):
|
||||||
else:
|
else:
|
||||||
jquery_js = " src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js\">"
|
jquery_js = " src=\"https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js\">"
|
||||||
|
|
||||||
print(html_header.format(title=_("Repository statistics for {0}").format(os.path.basename(repo)),
|
print(html_header.format(title=_("Repository statistics for '{0}'").format(repo_string),
|
||||||
jquery=jquery_js,
|
jquery=jquery_js,
|
||||||
jquery_tablesorter=tablesorter_js,
|
jquery_tablesorter=tablesorter_js,
|
||||||
jquery_flot=flot_js,
|
jquery_flot=flot_js,
|
||||||
|
@ -91,8 +97,8 @@ def output_header(repo):
|
||||||
" for git repositories.").format(
|
" for git repositories.").format(
|
||||||
"<a href=\"https://github.com/ejwa/gitinspector\">gitinspector</a>",
|
"<a href=\"https://github.com/ejwa/gitinspector\">gitinspector</a>",
|
||||||
version.__version__),
|
version.__version__),
|
||||||
repo_text=_("Statistical information for the repository '{0}' was gathered on {1}.").format(
|
repos_text=_(INFO_ONE_REPOSITORY if len(repos) <= 1 else INFO_MANY_REPOSITORIES).format(
|
||||||
os.path.basename(repo), localization.get_date()),
|
repos_string, localization.get_date()),
|
||||||
show_minor_authors=_("Show minor authors"),
|
show_minor_authors=_("Show minor authors"),
|
||||||
hide_minor_authors=_("Hide minor authors"),
|
hide_minor_authors=_("Hide minor authors"),
|
||||||
show_minor_rows=_("Show rows with minor work"),
|
show_minor_rows=_("Show rows with minor work"),
|
||||||
|
@ -102,11 +108,11 @@ def output_header(repo):
|
||||||
elif __selected_format__ == "xml":
|
elif __selected_format__ == "xml":
|
||||||
print("<gitinspector>")
|
print("<gitinspector>")
|
||||||
print("\t<version>" + version.__version__ + "</version>")
|
print("\t<version>" + version.__version__ + "</version>")
|
||||||
print("\t<repository>" + os.path.basename(repo) + "</repository>")
|
print("\t<repository>" + repos_string + "</repository>")
|
||||||
print("\t<report-date>" + time.strftime("%Y/%m/%d") + "</report-date>")
|
print("\t<report-date>" + time.strftime("%Y/%m/%d") + "</report-date>")
|
||||||
else:
|
else:
|
||||||
print(textwrap.fill(_("Statistical information for the repository '{0}' was gathered on {1}.").format(
|
print(textwrap.fill(_(INFO_ONE_REPOSITORY if len(repos) <= 1 else INFO_MANY_REPOSITORIES).format(
|
||||||
os.path.basename(repo), localization.get_date()), width=terminal.get_size()[0]))
|
repos_string, localization.get_date()), width=terminal.get_size()[0]))
|
||||||
|
|
||||||
def output_footer():
|
def output_footer():
|
||||||
if __selected_format__ == "html" or __selected_format__ == "htmlembedded":
|
if __selected_format__ == "html" or __selected_format__ == "htmlembedded":
|
||||||
|
|
|
@ -60,15 +60,12 @@ class Runner(object):
|
||||||
terminal.skip_escapes(not sys.stdout.isatty())
|
terminal.skip_escapes(not sys.stdout.isatty())
|
||||||
terminal.set_stdout_encoding()
|
terminal.set_stdout_encoding()
|
||||||
previous_directory = os.getcwd()
|
previous_directory = os.getcwd()
|
||||||
|
|
||||||
summed_blames = None
|
summed_blames = None
|
||||||
summed_changes = None
|
summed_changes = None
|
||||||
summed_metrics = None
|
summed_metrics = None
|
||||||
|
|
||||||
for repo in repos:
|
for repo in repos:
|
||||||
os.chdir(previous_directory)
|
os.chdir(repo.location)
|
||||||
os.chdir(repo)
|
|
||||||
absolute_path = basedir.get_basedir_git()
|
|
||||||
changes = Changes(self.hard)
|
changes = Changes(self.hard)
|
||||||
summed_blames = Blame(self.hard, self.useweeks, changes) + summed_blames
|
summed_blames = Blame(self.hard, self.useweeks, changes) + summed_blames
|
||||||
summed_changes = changes + summed_changes
|
summed_changes = changes + summed_changes
|
||||||
|
@ -78,10 +75,10 @@ class Runner(object):
|
||||||
|
|
||||||
if sys.stdout.isatty() and format.is_interactive_format():
|
if sys.stdout.isatty() and format.is_interactive_format():
|
||||||
terminal.clear_row()
|
terminal.clear_row()
|
||||||
|
else:
|
||||||
|
os.chdir(previous_directory)
|
||||||
|
|
||||||
os.chdir(absolute_path)
|
format.output_header(repos)
|
||||||
|
|
||||||
format.output_header(absolute_path)
|
|
||||||
outputable.output(ChangesOutput(changes))
|
outputable.output(ChangesOutput(changes))
|
||||||
|
|
||||||
if changes.get_commits():
|
if changes.get_commits():
|
||||||
|
@ -109,6 +106,24 @@ def __check_python_version__():
|
||||||
python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1])
|
python_version = str(sys.version_info[0]) + "." + str(sys.version_info[1])
|
||||||
sys.exit(_("gitinspector requires at least Python 2.6 to run (version {0} was found).").format(python_version))
|
sys.exit(_("gitinspector requires at least Python 2.6 to run (version {0} was found).").format(python_version))
|
||||||
|
|
||||||
|
def __get_validated_git_repos__(repos_relative):
|
||||||
|
if not repos_relative:
|
||||||
|
repos_relative = "."
|
||||||
|
|
||||||
|
repos = []
|
||||||
|
|
||||||
|
#Try to clone the repos or return the same directory and bail out.
|
||||||
|
for repo in repos_relative:
|
||||||
|
cloned_repo = clone.create(repo)
|
||||||
|
basedir_path = basedir.get_basedir_git(cloned_repo.location)
|
||||||
|
|
||||||
|
if cloned_repo.name == None:
|
||||||
|
cloned_repo.name = os.path.basename(basedir_path)
|
||||||
|
|
||||||
|
repos.append(cloned_repo)
|
||||||
|
|
||||||
|
return repos
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
terminal.check_terminal_encoding()
|
terminal.check_terminal_encoding()
|
||||||
terminal.set_stdin_encoding()
|
terminal.set_stdin_encoding()
|
||||||
|
@ -121,13 +136,10 @@ def main():
|
||||||
"hard:true", "help", "list-file-types:true", "localize-output:true",
|
"hard:true", "help", "list-file-types:true", "localize-output:true",
|
||||||
"metrics:true", "responsibilities:true", "since=", "grading:true",
|
"metrics:true", "responsibilities:true", "since=", "grading:true",
|
||||||
"timeline:true", "until=", "version", "weeks:true"])
|
"timeline:true", "until=", "version", "weeks:true"])
|
||||||
|
repos = __get_validated_git_repos__(set(args))
|
||||||
|
|
||||||
#Try to clone the repos or return the same directory and bail out.
|
#We need the repos above to be set before we read the git config.
|
||||||
for repo in args:
|
GitConfig(run, repos[-1].location).read()
|
||||||
repos.append(clone.create(repo))
|
|
||||||
|
|
||||||
#We need the repo above to be set before we read the git config.
|
|
||||||
GitConfig(run, repos[-1] if len(repos) > 0 else ".", len(repos) > 1).read()
|
|
||||||
clear_x_on_next_pass = True
|
clear_x_on_next_pass = True
|
||||||
|
|
||||||
for o, a in opts:
|
for o, a in opts:
|
||||||
|
@ -190,7 +202,7 @@ def main():
|
||||||
filtering.add(a)
|
filtering.add(a)
|
||||||
|
|
||||||
__check_python_version__()
|
__check_python_version__()
|
||||||
run.process(["."] if repos == [] else repos)
|
run.process(repos)
|
||||||
|
|
||||||
except (filtering.InvalidRegExpError, format.InvalidFormatError, optval.InvalidOptionArgument, getopt.error) as exception:
|
except (filtering.InvalidRegExpError, format.InvalidFormatError, optval.InvalidOptionArgument, getopt.error) as exception:
|
||||||
print(sys.argv[0], "\b:", exception.msg, file=sys.stderr)
|
print(sys.argv[0], "\b:", exception.msg, file=sys.stderr)
|
||||||
|
|
Loading…
Reference in a new issue