upgrade wakatime-cli to v12.0.0

This commit is contained in:
Alan Hamlett 2019-06-23 18:56:57 -07:00
parent 67d8b0d24f
commit 32c0cb5a97
4 changed files with 92 additions and 46 deletions

View File

@ -1,7 +1,7 @@
__title__ = 'wakatime' __title__ = 'wakatime'
__description__ = 'Common interface to the WakaTime api.' __description__ = 'Common interface to the WakaTime api.'
__url__ = 'https://github.com/wakatime/wakatime' __url__ = 'https://github.com/wakatime/wakatime'
__version_info__ = ('11', '0', '0') __version_info__ = ('12', '0', '0')
__version__ = '.'.join(__version_info__) __version__ = '.'.join(__version_info__)
__author__ = 'Alan Hamlett' __author__ = 'Alan Hamlett'
__author_email__ = 'alan@wakatime.com' __author_email__ = 'alan@wakatime.com'

View File

@ -153,6 +153,10 @@ def parse_arguments():
'folder name as the project, a ' + 'folder name as the project, a ' +
'.wakatime-project file is created with a ' + '.wakatime-project file is created with a ' +
'random project name.') 'random project name.')
parser.add_argument('--hide-branch-names', dest='hide_branch_names',
action='store_true',
help='Obfuscate branch names. Will not send revision ' +
'control branch names to api.')
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.')
@ -294,8 +298,9 @@ def parse_arguments():
pass pass
if not args.exclude_unknown_project and configs.has_option('settings', 'exclude_unknown_project'): if not args.exclude_unknown_project and configs.has_option('settings', 'exclude_unknown_project'):
args.exclude_unknown_project = configs.getboolean('settings', 'exclude_unknown_project') args.exclude_unknown_project = configs.getboolean('settings', 'exclude_unknown_project')
boolean_or_list('hide_file_names', args, configs, alternative_names=['hide_filenames', 'hidefilenames']) _boolean_or_list('hide_file_names', args, configs, alternative_names=['hide_filenames', 'hidefilenames'])
boolean_or_list('hide_project_names', args, configs, alternative_names=['hide_projectnames', 'hideprojectnames']) _boolean_or_list('hide_project_names', args, configs, alternative_names=['hide_projectnames', 'hideprojectnames'])
_boolean_or_list('hide_branch_names', args, configs, alternative_names=['hide_branchnames', 'hidebranchnames'], default=None)
if args.offline_deprecated: if args.offline_deprecated:
args.offline = False args.offline = False
if args.offline and configs.has_option('settings', 'offline'): if args.offline and configs.has_option('settings', 'offline'):
@ -340,7 +345,7 @@ def parse_arguments():
return args, configs return args, configs
def boolean_or_list(config_name, args, configs, alternative_names=[]): def _boolean_or_list(config_name, args, configs, alternative_names=[], default=[]):
"""Get a boolean or list of regexes from args and configs.""" """Get a boolean or list of regexes from args and configs."""
# when argument flag present, set to wildcard regex # when argument flag present, set to wildcard regex
@ -349,7 +354,7 @@ def boolean_or_list(config_name, args, configs, alternative_names=[]):
setattr(args, config_name, ['.*']) setattr(args, config_name, ['.*'])
return return
setattr(args, config_name, []) setattr(args, config_name, default)
option = None option = None
alternative_names.insert(0, config_name) alternative_names.insert(0, config_name)
@ -361,7 +366,11 @@ def boolean_or_list(config_name, args, configs, alternative_names=[]):
if option is not None: if option is not None:
if option.strip().lower() == 'true': if option.strip().lower() == 'true':
setattr(args, config_name, ['.*']) setattr(args, config_name, ['.*'])
elif option.strip().lower() != 'false': elif option.strip().lower() == 'false':
setattr(args, config_name, [])
else:
for pattern in option.split("\n"): for pattern in option.split("\n"):
if pattern.strip() != '': if pattern.strip() != '':
if not getattr(args, config_name):
setattr(args, config_name, [])
getattr(args, config_name).append(pattern) getattr(args, config_name).append(pattern)

View File

@ -43,7 +43,15 @@ class Heartbeat(object):
cursorpos = None cursorpos = None
user_agent = None user_agent = None
_sensitive = ('dependencies', 'lines', 'lineno', 'cursorpos', 'branch') _sensitive_when_hiding_filename = (
'dependencies',
'lines',
'lineno',
'cursorpos',
)
_sensitive_when_hiding_branch = (
'branch',
)
def __init__(self, data, args, configs, _clone=None): def __init__(self, data, args, configs, _clone=None):
if not data: if not data:
@ -141,21 +149,24 @@ class Heartbeat(object):
Returns a Heartbeat. Returns a Heartbeat.
""" """
if not self.args.hide_file_names:
return self
if self.entity is None: if self.entity is None:
return self return self
if self.type != 'file': if self.type != 'file':
return self return self
if self.should_obfuscate_filename(): if self._should_obfuscate_filename():
self._sanitize_metadata() self._sanitize_metadata(keys=self._sensitive_when_hiding_filename)
if self._should_obfuscate_branch(default=True):
self._sanitize_metadata(keys=self._sensitive_when_hiding_branch)
extension = u(os.path.splitext(self.entity)[1]) extension = u(os.path.splitext(self.entity)[1])
self.entity = u('HIDDEN{0}').format(extension) self.entity = u('HIDDEN{0}').format(extension)
elif self.should_obfuscate_project(): elif self.should_obfuscate_project():
self._sanitize_metadata() self._sanitize_metadata(keys=self._sensitive_when_hiding_filename)
if self._should_obfuscate_branch(default=True):
self._sanitize_metadata(keys=self._sensitive_when_hiding_branch)
elif self._should_obfuscate_branch():
self._sanitize_metadata(keys=self._sensitive_when_hiding_branch)
return self return self
@ -193,22 +204,6 @@ class Heartbeat(object):
is_write=self.is_write, is_write=self.is_write,
) )
def should_obfuscate_filename(self):
"""Returns True if hide_file_names is true or the entity file path
matches one in the list of obfuscated file paths."""
for pattern in self.args.hide_file_names:
try:
compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(self.entity):
return True
except re.error as ex:
log.warning(u('Regex error ({msg}) for hide_file_names pattern: {pattern}').format(
msg=u(ex),
pattern=u(pattern),
))
return False
def should_obfuscate_project(self): def should_obfuscate_project(self):
"""Returns True if hide_project_names is true or the entity file path """Returns True if hide_project_names is true or the entity file path
matches one in the list of obfuscated project paths.""" matches one in the list of obfuscated project paths."""
@ -223,6 +218,49 @@ class Heartbeat(object):
msg=u(ex), msg=u(ex),
pattern=u(pattern), pattern=u(pattern),
)) ))
return False
def _should_obfuscate_filename(self):
"""Returns True if hide_file_names is true or the entity file path
matches one in the list of obfuscated file paths."""
for pattern in self.args.hide_file_names:
try:
compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(self.entity):
return True
except re.error as ex:
log.warning(u('Regex error ({msg}) for hide_file_names pattern: {pattern}').format(
msg=u(ex),
pattern=u(pattern),
))
return False
def _should_obfuscate_branch(self, default=False):
"""Returns True if hide_file_names is true or the entity file path
matches one in the list of obfuscated file paths."""
# when project names or file names are hidden and hide_branch_names is
# not set, we default to hiding branch names along with file/project.
if default and self.args.hide_branch_names is None:
return True
if not self.branch or not self.args.hide_branch_names:
return False
for pattern in self.args.hide_branch_names:
try:
compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(self.entity) or compiled.search(self.branch):
return True
except re.error as ex:
log.warning(u('Regex error ({msg}) for hide_branch_names pattern: {pattern}').format(
msg=u(ex),
pattern=u(pattern),
))
return False return False
def _unicode(self, value): def _unicode(self, value):
@ -333,8 +371,8 @@ class Heartbeat(object):
return False return False
return find_project_file(self.entity) is None return find_project_file(self.entity) is None
def _sanitize_metadata(self): def _sanitize_metadata(self, keys=[]):
for key in self._sensitive: for key in keys:
setattr(self, key, None) setattr(self, key, None)
def __repr__(self): def __repr__(self):

View File

@ -69,8 +69,6 @@ def get_project_info(configs, heartbeat, data):
project_name = data.get('project') or heartbeat.args.project project_name = data.get('project') or heartbeat.args.project
hide_project = heartbeat.should_obfuscate_project() hide_project = heartbeat.should_obfuscate_project()
if hide_project and project_name is not None:
return project_name, None
if project_name is None or branch_name is None: if project_name is None or branch_name is None:
@ -78,13 +76,18 @@ def get_project_info(configs, heartbeat, data):
plugin_name = plugin_cls.__name__.lower() plugin_name = plugin_cls.__name__.lower()
plugin_configs = get_configs_for_plugin(plugin_name, configs) plugin_configs = get_configs_for_plugin(plugin_name, configs)
project = plugin_cls(heartbeat.entity, configs=plugin_configs) project = plugin_cls(heartbeat.entity, configs=plugin_configs)
if project.process(): if project.process():
if not hide_project:
project_name = project_name or project.name() project_name = project_name or project.name()
branch_name = branch_name or project.branch() branch_name = branch_name or project.branch()
if hide_project: break
branch_name = None
if project_name is None:
if not hide_project:
project_name = data.get('alternate_project') or heartbeat.args.alternate_project
else:
project_name = generate_project_name() project_name = generate_project_name()
project_file = os.path.join(project.folder(), '.wakatime-project') project_file = os.path.join(project.folder(), '.wakatime-project')
try: try:
@ -92,10 +95,6 @@ def get_project_info(configs, heartbeat, data):
fh.write(project_name) fh.write(project_name)
except IOError: except IOError:
project_name = None project_name = None
break
if project_name is None and not hide_project:
project_name = data.get('alternate_project') or heartbeat.args.alternate_project
return project_name, branch_name return project_name, branch_name