From 615fa5cdac2c42fbfcd1bfbc6a6b6cace86af301 Mon Sep 17 00:00:00 2001 From: Alan Hamlett Date: Mon, 18 Apr 2016 21:34:00 +0200 Subject: [PATCH] support regex patterns in projectmap config section --- tests/samples/configs/project_map.cfg | 2 + .../projects/project_map42/emptyfile.txt | 0 tests/test_project.py | 29 +++++++++----- wakatime/projects/projectmap.py | 40 ++++++++++--------- 4 files changed, 43 insertions(+), 28 deletions(-) create mode 100644 tests/samples/projects/project_map42/emptyfile.txt diff --git a/tests/samples/configs/project_map.cfg b/tests/samples/configs/project_map.cfg index b76ce1d..7480710 100644 --- a/tests/samples/configs/project_map.cfg +++ b/tests/samples/configs/project_map.cfg @@ -2,3 +2,5 @@ debug = false api_key = 1234 [projectmap] +samples/projects/proj.{3}_map/ = proj-map +samples/projects/project_map(\d+)/ = proj-map{0} diff --git a/tests/samples/projects/project_map42/emptyfile.txt b/tests/samples/projects/project_map42/emptyfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_project.py b/tests/test_project.py index 8f90bef..6ccf81c 100644 --- a/tests/test_project.py +++ b/tests/test_project.py @@ -160,18 +160,27 @@ class LanguagesTestCase(utils.TestCase): response.status_code = 0 self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response - with tempfile.NamedTemporaryFile() as fh: - now = u(int(time.time())) - entity = 'tests/samples/projects/project_map/emptyfile.txt' + now = u(int(time.time())) + entity = 'tests/samples/projects/project_map/emptyfile.txt' + config = 'tests/samples/configs/project_map.cfg' - fh.write(open('tests/samples/configs/project_map.cfg').read().encode('utf-8')) - fh.write('{0} = proj-map'.format(os.path.realpath(os.path.dirname(os.path.dirname(entity)))).encode('utf-8')) - fh.flush() + args = ['--file', entity, '--config', config, '--time', now] - config = fh.name + execute(args) - args = ['--file', entity, '--config', config, '--time', now] + self.assertEquals('proj-map', self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['project']) - execute(args) + def test_project_map_group_usage(self): + response = Response() + response.status_code = 0 + self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response - self.assertEquals('proj-map', self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['project']) + now = u(int(time.time())) + entity = 'tests/samples/projects/project_map42/emptyfile.txt' + config = 'tests/samples/configs/project_map.cfg' + + args = ['--file', entity, '--config', config, '--time', now] + + execute(args) + + self.assertEquals('proj-map42', self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['project']) diff --git a/wakatime/projects/projectmap.py b/wakatime/projects/projectmap.py index f6b4fc2..5591a11 100644 --- a/wakatime/projects/projectmap.py +++ b/wakatime/projects/projectmap.py @@ -3,18 +3,18 @@ wakatime.projects.projectmap ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Use the ~/.wakatime.cfg file to set custom project names by - recursively matching folder paths. - Project maps go under the [projectmap] config section. + Use the ~/.wakatime.cfg file to set custom project names by matching files + with regex patterns. Project maps go under the [projectmap] config section. For example: [projectmap] /home/user/projects/foo = new project name - /home/user/projects/bar = project2 + /home/user/projects/bar(\d+)/ = project{0} Will result in file `/home/user/projects/foo/src/main.c` to have - project name `new project name`. + project name `new project name` and file `/home/user/projects/bar42/main.c` + to have project name `project42`. :copyright: (c) 2013 Alan Hamlett. :license: BSD, see LICENSE for more details. @@ -22,6 +22,7 @@ import logging import os +import re from .base import BaseProject from ..compat import u @@ -42,20 +43,23 @@ class ProjectMap(BaseProject): def _find_project(self, path): path = os.path.realpath(path) - if os.path.isfile(path): - path = os.path.split(path)[0] - if self._configs.get(path.lower()): - return self._configs.get(path.lower()) - if self._configs.get('%s/' % path.lower()): # pragma: nocover - return self._configs.get('%s/' % path.lower()) - if self._configs.get('%s\\' % path.lower()): # pragma: nocover - return self._configs.get('%s\\' % path.lower()) + try: + for pattern, new_proj_name in self._configs.items(): + try: + compiled = re.compile(pattern, re.IGNORECASE) + match = compiled.search(path) + if match: + return new_proj_name.format(*match.groups()) + except re.error as ex: + log.warning(u('Regex error ({msg}) for projectmap pattern: {pattern}').format( + msg=u(ex), + pattern=u(pattern), + )) + except TypeError: # pragma: nocover + pass - split_path = os.path.split(path) - if split_path[1] == '': - return None # pragma: nocover - return self._find_project(split_path[0]) + return None def branch(self): return None @@ -63,4 +67,4 @@ class ProjectMap(BaseProject): def name(self): if self.project: return u(self.project) - return None # pragma: nocover + return None