diff --git a/wakatime/project.py b/wakatime/project.py index 0dd23cd..4d33635 100644 --- a/wakatime/project.py +++ b/wakatime/project.py @@ -30,6 +30,6 @@ PLUGINS = [ def find_project(path): for plugin in PLUGINS: project = plugin(path) - if project.config: + if project.process(): return project return BaseProject(path) diff --git a/wakatime/projects/base.py b/wakatime/projects/base.py index bf2f6ef..728a7f8 100644 --- a/wakatime/projects/base.py +++ b/wakatime/projects/base.py @@ -16,32 +16,39 @@ import os log = logging.getLogger(__name__) -class BaseProject(): +class BaseProject(object): + """ Parent project class only + used when no valid project can + be found for the current path. + """ def __init__(self, path): self.path = path - self.config = self.findConfig(path) - - def name(self): - base = self.base() - if base: - return os.path.basename(base) - return None def type(self): + """ Returns None if this is the base class. + Returns the type of project if this is a + valid project. + """ type = self.__class__.__name__.lower() if type == 'baseproject': type = None return type - def base(self): - if self.config: - return os.path.dirname(self.config) + def process(self): + """ Processes self.path into a project and + returns True if project is valid, otherwise + returns False. + """ + return False + + def name(self): + """ Returns the project's name. + """ return None def tags(self): - tags = [] - return tags - - def findConfig(self, path): - return '' + """ Returns an array of tag strings for the + path and/or project. + """ + return [] diff --git a/wakatime/projects/git.py b/wakatime/projects/git.py index b1c6519..00cf1f4 100644 --- a/wakatime/projects/git.py +++ b/wakatime/projects/git.py @@ -11,13 +11,10 @@ import logging import os +from subprocess import Popen, PIPE from .base import BaseProject - -try: - from collections import OrderedDict -except ImportError: - from ..packages.ordereddict import OrderedDict +from ..packages.ordereddict import OrderedDict log = logging.getLogger(__name__) @@ -25,21 +22,54 @@ log = logging.getLogger(__name__) class Git(BaseProject): - def base(self): + def process(self): + self.config = self._find_config(self.path) if self.config: - return os.path.dirname(os.path.dirname(self.config)) + return True + return False + + def name(self): + base = self._project_base() + if base: + return os.path.basename(base) return None def tags(self): tags = [] if self.config: - sections = self.parseConfig() + base = self._project_base() + if base: + tags.append(base) + sections = self._parse_config() for section in sections: if section.split(' ', 1)[0] == 'remote' and 'url' in sections[section]: tags.append(sections[section]['url']) + branch = self._current_branch() + if branch is not None: + tags.append(branch) return tags - def findConfig(self, path): + def _project_base(self): + if self.config: + return os.path.dirname(os.path.dirname(self.config)) + return None + + def _current_branch(self): + stdout = None + try: + stdout, stderr = Popen([ + 'git', 'branch', '--no-color', '--list' + ], stdout=PIPE, cwd=self._project_base()).communicate() + except OSError: + pass + if stdout: + for line in stdout.splitlines(): + line = line.split(' ', 1) + if line[0] == '*': + return line[1] + return None + + def _find_config(self, path): path = os.path.realpath(path) if os.path.isfile(path): path = os.path.split(path)[0] @@ -48,9 +78,9 @@ class Git(BaseProject): split_path = os.path.split(path) if split_path[1] == '': return None - return self.findConfig(split_path[0]) + return self._find_config(split_path[0]) - def parseConfig(self): + def _parse_config(self): sections = {} try: f = open(self.config, 'r') diff --git a/wakatime/projects/mercurial.py b/wakatime/projects/mercurial.py index 6be3030..7d9b2ae 100644 --- a/wakatime/projects/mercurial.py +++ b/wakatime/projects/mercurial.py @@ -20,9 +20,11 @@ log = logging.getLogger(__name__) class Mercurial(BaseProject): - def base(self): - return super(Mercurial, self).base() + def process(self): + return False + + def name(self): + return None def tags(self): - tags = [] - return tags + return [] diff --git a/wakatime/projects/subversion.py b/wakatime/projects/subversion.py index a876885..35d834d 100644 --- a/wakatime/projects/subversion.py +++ b/wakatime/projects/subversion.py @@ -11,8 +11,10 @@ import logging import os +from subprocess import Popen, PIPE from .base import BaseProject +from ..packages.ordereddict import OrderedDict log = logging.getLogger(__name__) @@ -20,9 +22,42 @@ log = logging.getLogger(__name__) class Subversion(BaseProject): - def base(self): - return super(Subversion, self).base() + def process(self): + self.info = self._get_info() + if 'Repository Root' in self.info: + return True + return False + + def name(self): + return self.info['Repository Root'].split('/')[-1] + + def _get_info(self): + info = OrderedDict() + stdout = None + try: + stdout, stderr = Popen([ + 'svn', 'info', os.path.realpath(self.path) + ], stdout=PIPE).communicate() + except OSError: + pass + else: + if stdout: + interesting = [ + 'Repository Root', + 'Repository UUID', + 'URL', + ] + for line in stdout.splitlines(): + line = line.split(': ', 1) + if line[0] in interesting: + info[line[0]] = line[1] + return info def tags(self): tags = [] + for key in self.info: + if key == 'Repository UUID': + tags.append(self.info[key]) + if key == 'URL': + tags.append(os.path.dirname(self.info[key])) return tags