Add --exclude-unknown-project arg and corresponding config
This commit is contained in:
parent
f2b8776e21
commit
3e47f77f47
11 changed files with 118 additions and 18 deletions
4
tests/samples/configs/exclude_unknown_project.cfg
Normal file
4
tests/samples/configs/exclude_unknown_project.cfg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
[settings]
|
||||||
|
debug = false
|
||||||
|
api_key = 1090a6ae-855f-4be7-b8fb-3edbaf1aa3ec
|
||||||
|
exclude_unknown_project = true
|
|
@ -15,5 +15,6 @@ no_ssl_verify = false
|
||||||
timeout = abc
|
timeout = abc
|
||||||
api_url = https://localhost:0/api/v1/heartbeats
|
api_url = https://localhost:0/api/v1/heartbeats
|
||||||
hostname = fromcfgfile
|
hostname = fromcfgfile
|
||||||
|
exclude_unknown_project = false
|
||||||
[git]
|
[git]
|
||||||
submodules_disabled =
|
submodules_disabled =
|
||||||
|
|
|
@ -4,8 +4,8 @@ usage: wakatime [-h] [--entity FILE] [--key KEY] [--write] [--plugin PLUGIN]
|
||||||
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
||||||
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
||||||
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
||||||
[--exclude EXCLUDE] [--include INCLUDE]
|
[--exclude EXCLUDE] [--exclude-unknown-project]
|
||||||
[--include-only-with-project-file] [--extra-heartbeats]
|
[--include INCLUDE] [--include-only-with-project-file]
|
||||||
[--log-file LOG_FILE] [--api-url API_URL] [--timeout TIMEOUT]
|
[--extra-heartbeats] [--log-file LOG_FILE] [--api-url API_URL]
|
||||||
[--config CONFIG] [--verbose] [--version]
|
[--timeout TIMEOUT] [--config CONFIG] [--verbose] [--version]
|
||||||
wakatime: error: Missing api key. Find your api key from wakatime.com/settings/api-key.
|
wakatime: error: Missing api key. Find your api key from wakatime.com/settings/api-key.
|
||||||
|
|
|
@ -4,8 +4,8 @@ usage: wakatime [-h] [--entity FILE] [--key KEY] [--write] [--plugin PLUGIN]
|
||||||
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
||||||
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
||||||
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
||||||
[--exclude EXCLUDE] [--include INCLUDE]
|
[--exclude EXCLUDE] [--exclude-unknown-project]
|
||||||
[--include-only-with-project-file] [--extra-heartbeats]
|
[--include INCLUDE] [--include-only-with-project-file]
|
||||||
[--log-file LOG_FILE] [--api-url API_URL] [--timeout TIMEOUT]
|
[--extra-heartbeats] [--log-file LOG_FILE] [--api-url API_URL]
|
||||||
[--config CONFIG] [--verbose] [--version]
|
[--timeout TIMEOUT] [--config CONFIG] [--verbose] [--version]
|
||||||
wakatime: error: Missing api key. Find your api key from wakatime.com/settings/api-key.
|
wakatime: error: Missing api key. Find your api key from wakatime.com/settings/api-key.
|
||||||
|
|
|
@ -4,8 +4,8 @@ usage: wakatime [-h] [--entity FILE] [--key KEY] [--write] [--plugin PLUGIN]
|
||||||
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
||||||
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
||||||
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
||||||
[--exclude EXCLUDE] [--include INCLUDE]
|
[--exclude EXCLUDE] [--exclude-unknown-project]
|
||||||
[--include-only-with-project-file] [--extra-heartbeats]
|
[--include INCLUDE] [--include-only-with-project-file]
|
||||||
[--log-file LOG_FILE] [--api-url API_URL] [--timeout TIMEOUT]
|
[--extra-heartbeats] [--log-file LOG_FILE] [--api-url API_URL]
|
||||||
[--config CONFIG] [--verbose] [--version]
|
[--timeout TIMEOUT] [--config CONFIG] [--verbose] [--version]
|
||||||
wakatime: error: argument --timeout: invalid int value: 'abc'
|
wakatime: error: argument --timeout: invalid int value: 'abc'
|
||||||
|
|
|
@ -4,10 +4,10 @@ usage: wakatime [-h] [--entity FILE] [--key KEY] [--write] [--plugin PLUGIN]
|
||||||
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
[--proxy PROXY] [--no-ssl-verify] [--project PROJECT]
|
||||||
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
[--alternate-project ALTERNATE_PROJECT] [--language LANGUAGE]
|
||||||
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
[--hostname HOSTNAME] [--disable-offline] [--hide-filenames]
|
||||||
[--exclude EXCLUDE] [--include INCLUDE]
|
[--exclude EXCLUDE] [--exclude-unknown-project]
|
||||||
[--include-only-with-project-file] [--extra-heartbeats]
|
[--include INCLUDE] [--include-only-with-project-file]
|
||||||
[--log-file LOG_FILE] [--api-url API_URL] [--timeout TIMEOUT]
|
[--extra-heartbeats] [--log-file LOG_FILE] [--api-url API_URL]
|
||||||
[--config CONFIG] [--verbose] [--version]
|
[--timeout TIMEOUT] [--config CONFIG] [--verbose] [--version]
|
||||||
|
|
||||||
Common interface for the WakaTime api.
|
Common interface for the WakaTime api.
|
||||||
|
|
||||||
|
@ -51,6 +51,9 @@ optional arguments:
|
||||||
--hide-filenames Obfuscate filenames. Will not send file names to api.
|
--hide-filenames Obfuscate filenames. Will not send file names to api.
|
||||||
--exclude EXCLUDE Filename patterns to exclude from logging. POSIX regex
|
--exclude EXCLUDE Filename patterns to exclude from logging. POSIX regex
|
||||||
syntax. Can be used more than once.
|
syntax. Can be used more than once.
|
||||||
|
--exclude-unknown-project
|
||||||
|
When set, any activity where the project cannot be
|
||||||
|
detected will be ignored.
|
||||||
--include INCLUDE Filename patterns to log. When used in combination
|
--include INCLUDE Filename patterns to log. When used in combination
|
||||||
with --exclude, files matching include will still be
|
with --exclude, files matching include will still be
|
||||||
logged. POSIX regex syntax. Can be used more than
|
logged. POSIX regex syntax. Can be used more than
|
||||||
|
|
|
@ -1026,6 +1026,34 @@ class ArgumentsTestCase(TestCase):
|
||||||
self.assertOfflineHeartbeatsSynced()
|
self.assertOfflineHeartbeatsSynced()
|
||||||
self.assertSessionCacheSaved()
|
self.assertSessionCacheSaved()
|
||||||
|
|
||||||
|
@log_capture()
|
||||||
|
def test_exclude_unknown_project_arg(self, logs):
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
response = Response()
|
||||||
|
response.status_code = 0
|
||||||
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
|
with TemporaryDirectory() as tempdir:
|
||||||
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
||||||
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
||||||
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
||||||
|
config = 'tests/samples/configs/good_config.cfg'
|
||||||
|
|
||||||
|
args = ['--file', entity, '--config', config, '--exclude-unknown-project', '--verbose', '--log-file', '~/.wakatime.log']
|
||||||
|
retval = execute(args)
|
||||||
|
self.assertEquals(retval, SUCCESS)
|
||||||
|
self.assertNothingPrinted()
|
||||||
|
actual = self.getLogOutput(logs)
|
||||||
|
expected = 'WakaTime DEBUG Skipping because project unknown.'
|
||||||
|
self.assertEquals(actual, expected)
|
||||||
|
|
||||||
|
self.assertHeartbeatNotSent()
|
||||||
|
|
||||||
|
self.assertHeartbeatNotSavedOffline()
|
||||||
|
self.assertOfflineHeartbeatsSynced()
|
||||||
|
self.assertSessionCacheUntouched()
|
||||||
|
|
||||||
@log_capture()
|
@log_capture()
|
||||||
def test_uses_wakatime_home_env_variable(self, logs):
|
def test_uses_wakatime_home_env_variable(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
|
@ -515,6 +515,34 @@ class ConfigsTestCase(TestCase):
|
||||||
self.assertOfflineHeartbeatsSynced()
|
self.assertOfflineHeartbeatsSynced()
|
||||||
self.assertSessionCacheUntouched()
|
self.assertSessionCacheUntouched()
|
||||||
|
|
||||||
|
@log_capture()
|
||||||
|
def test_exclude_file_because_project_unknown(self, logs):
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
response = Response()
|
||||||
|
response.status_code = 0
|
||||||
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
|
with TemporaryDirectory() as tempdir:
|
||||||
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
||||||
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
||||||
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
||||||
|
config = 'tests/samples/configs/exclude_unknown_project.cfg'
|
||||||
|
|
||||||
|
args = ['--file', entity, '--config', config, '--verbose', '--log-file', '~/.wakatime.log']
|
||||||
|
retval = execute(args)
|
||||||
|
self.assertEquals(retval, SUCCESS)
|
||||||
|
self.assertNothingPrinted()
|
||||||
|
actual = self.getLogOutput(logs)
|
||||||
|
expected = 'WakaTime DEBUG Skipping because project unknown.'
|
||||||
|
self.assertEquals(actual, expected)
|
||||||
|
|
||||||
|
self.assertHeartbeatNotSent()
|
||||||
|
|
||||||
|
self.assertHeartbeatNotSavedOffline()
|
||||||
|
self.assertOfflineHeartbeatsSynced()
|
||||||
|
self.assertSessionCacheUntouched()
|
||||||
|
|
||||||
@log_capture()
|
@log_capture()
|
||||||
def test_include_file_with_project_file(self, logs):
|
def test_include_file_with_project_file(self, logs):
|
||||||
logging.disable(logging.NOTSET)
|
logging.disable(logging.NOTSET)
|
||||||
|
|
|
@ -17,7 +17,7 @@ from wakatime.constants import API_ERROR, SUCCESS
|
||||||
from wakatime.exceptions import NotYetImplemented
|
from wakatime.exceptions import NotYetImplemented
|
||||||
from wakatime.projects.base import BaseProject
|
from wakatime.projects.base import BaseProject
|
||||||
from wakatime.projects.git import Git
|
from wakatime.projects.git import Git
|
||||||
from .utils import ANY, DynamicIterable, TestCase, CustomResponse, mock, json
|
from .utils import ANY, DynamicIterable, TestCase, TemporaryDirectory, CustomResponse, mock, json
|
||||||
|
|
||||||
|
|
||||||
class ProjectTestCase(TestCase):
|
class ProjectTestCase(TestCase):
|
||||||
|
@ -630,3 +630,24 @@ class ProjectTestCase(TestCase):
|
||||||
|
|
||||||
self.assertNothingPrinted()
|
self.assertNothingPrinted()
|
||||||
self.assertNothingLogged(logs)
|
self.assertNothingLogged(logs)
|
||||||
|
|
||||||
|
@log_capture()
|
||||||
|
def test_exclude_unknown_project_when_project_detected(self, logs):
|
||||||
|
logging.disable(logging.NOTSET)
|
||||||
|
|
||||||
|
response = Response()
|
||||||
|
response.status_code = 0
|
||||||
|
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||||
|
|
||||||
|
with TemporaryDirectory() as tempdir:
|
||||||
|
entity = 'tests/samples/codefiles/emptyfile.txt'
|
||||||
|
shutil.copy(entity, os.path.join(tempdir, 'emptyfile.txt'))
|
||||||
|
entity = os.path.realpath(os.path.join(tempdir, 'emptyfile.txt'))
|
||||||
|
config = 'tests/samples/configs/exclude_unknown_project.cfg'
|
||||||
|
|
||||||
|
args = ['--file', entity, '--project', 'proj-arg', '--config', config, '--log-file', '~/.wakatime.log']
|
||||||
|
execute(args)
|
||||||
|
|
||||||
|
self.assertNothingPrinted()
|
||||||
|
self.assertNothingLogged(logs)
|
||||||
|
self.assertEquals('proj-arg', self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['project'])
|
||||||
|
|
|
@ -136,6 +136,10 @@ def parse_arguments():
|
||||||
parser.add_argument('--exclude', dest='exclude', action='append',
|
parser.add_argument('--exclude', dest='exclude', action='append',
|
||||||
help='Filename patterns to exclude from logging. ' +
|
help='Filename patterns to exclude from logging. ' +
|
||||||
'POSIX regex syntax. Can be used more than once.')
|
'POSIX regex syntax. Can be used more than once.')
|
||||||
|
parser.add_argument('--exclude-unknown-project',
|
||||||
|
dest='exclude_unknown_project', action='store_true',
|
||||||
|
help='When set, any activity where the project ' +
|
||||||
|
'cannot be detected will be ignored.')
|
||||||
parser.add_argument('--include', dest='include', action='append',
|
parser.add_argument('--include', dest='include', action='append',
|
||||||
help='Filename patterns to log. When used in ' +
|
help='Filename patterns to log. When used in ' +
|
||||||
'combination with --exclude, files matching ' +
|
'combination with --exclude, files matching ' +
|
||||||
|
@ -144,7 +148,7 @@ def parse_arguments():
|
||||||
parser.add_argument('--include-only-with-project-file',
|
parser.add_argument('--include-only-with-project-file',
|
||||||
dest='include_only_with_project_file',
|
dest='include_only_with_project_file',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
help='Disables tracking folders unless they contain '+
|
help='Disables tracking folders unless they contain ' +
|
||||||
'a .wakatime-project file. Defaults to false.')
|
'a .wakatime-project file. Defaults to false.')
|
||||||
parser.add_argument('--ignore', dest='ignore', action='append',
|
parser.add_argument('--ignore', dest='ignore', action='append',
|
||||||
help=argparse.SUPPRESS)
|
help=argparse.SUPPRESS)
|
||||||
|
@ -243,6 +247,8 @@ def parse_arguments():
|
||||||
args.include.append(pattern)
|
args.include.append(pattern)
|
||||||
except TypeError: # pragma: nocover
|
except TypeError: # pragma: nocover
|
||||||
pass
|
pass
|
||||||
|
if not args.exclude_unknown_project and configs.has_option('settings', 'exclude_unknown_project'):
|
||||||
|
args.exclude_unknown_project = configs.getboolean('settings', 'exclude_unknown_project')
|
||||||
if not args.hide_filenames and args.hidefilenames:
|
if not args.hide_filenames and args.hidefilenames:
|
||||||
args.hide_filenames = args.hidefilenames
|
args.hide_filenames = args.hidefilenames
|
||||||
if args.hide_filenames:
|
if args.hide_filenames:
|
||||||
|
|
|
@ -94,6 +94,10 @@ class Heartbeat(object):
|
||||||
self.project = project
|
self.project = project
|
||||||
self.branch = branch
|
self.branch = branch
|
||||||
|
|
||||||
|
if self._excluded_by_unknown_project():
|
||||||
|
self.skip = u('Skipping because project unknown.')
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
stats = get_file_stats(self.entity,
|
stats = get_file_stats(self.entity,
|
||||||
entity_type=self.type,
|
entity_type=self.type,
|
||||||
|
@ -210,6 +214,11 @@ class Heartbeat(object):
|
||||||
def _excluded_by_pattern(self):
|
def _excluded_by_pattern(self):
|
||||||
return should_exclude(self.entity, self.args.include, self.args.exclude)
|
return should_exclude(self.entity, self.args.include, self.args.exclude)
|
||||||
|
|
||||||
|
def _excluded_by_unknown_project(self):
|
||||||
|
if self.project:
|
||||||
|
return False
|
||||||
|
return self.args.exclude_unknown_project
|
||||||
|
|
||||||
def _excluded_by_missing_project_file(self):
|
def _excluded_by_missing_project_file(self):
|
||||||
if not self.args.include_only_with_project_file:
|
if not self.args.include_only_with_project_file:
|
||||||
return False
|
return False
|
||||||
|
|
Loading…
Reference in a new issue