new --entity command line arg to replace --file

This commit is contained in:
Alan Hamlett 2015-08-29 18:14:07 -07:00
parent 92350ff8a0
commit 7656b5365d
5 changed files with 42 additions and 29 deletions

View file

@ -1,4 +1,4 @@
usage: wakatime [-h] --file file [--key KEY] [--write] [--plugin PLUGIN] usage: wakatime [-h] [--entity FILE] [--key KEY] [--write] [--plugin PLUGIN]
[--time time] [--lineno LINENO] [--cursorpos CURSORPOS] [--time time] [--lineno LINENO] [--cursorpos CURSORPOS]
[--entitytype ENTITY_TYPE] [--proxy PROXY] [--project PROJECT] [--entitytype ENTITY_TYPE] [--proxy PROXY] [--project PROJECT]
[--alternate-project ALTERNATE_PROJECT] [--hostname HOSTNAME] [--alternate-project ALTERNATE_PROJECT] [--hostname HOSTNAME]
@ -10,7 +10,8 @@ Common interface for the WakaTime api.
optional arguments: optional arguments:
-h, --help show this help message and exit -h, --help show this help message and exit
--file file absolute path to file for current heartbeat --entity FILE absolute path to file for the heartbeat; can also be a
url, domain, or app when --entitytype is not file
--key KEY your wakatime api key; uses api_key from --key KEY your wakatime api key; uses api_key from
~/.wakatime.conf by default ~/.wakatime.conf by default
--write when set, tells api this heartbeat was triggered from --write when set, tells api this heartbeat was triggered from
@ -24,7 +25,7 @@ optional arguments:
optional cursor position in the current file optional cursor position in the current file
--entitytype ENTITY_TYPE --entitytype ENTITY_TYPE
entity type for this heartbeat. can be one of "file", entity type for this heartbeat. can be one of "file",
"url", or "domain"; defaults to file. "url", "domain", or "app"; defaults to file.
--proxy PROXY optional https proxy url; for example: --proxy PROXY optional https proxy url; for example:
https://user:pass@localhost:8080 https://user:pass@localhost:8080
--project PROJECT optional project name --project PROJECT optional project name

View file

@ -1,4 +1,4 @@
usage: wakatime [-h] --file file [--key KEY] [--write] [--plugin PLUGIN] usage: wakatime [-h] [--entity FILE] [--key KEY] [--write] [--plugin PLUGIN]
[--time time] [--lineno LINENO] [--cursorpos CURSORPOS] [--time time] [--lineno LINENO] [--cursorpos CURSORPOS]
[--entitytype ENTITY_TYPE] [--proxy PROXY] [--project PROJECT] [--entitytype ENTITY_TYPE] [--proxy PROXY] [--project PROJECT]
[--alternate-project ALTERNATE_PROJECT] [--hostname HOSTNAME] [--alternate-project ALTERNATE_PROJECT] [--hostname HOSTNAME]

View file

@ -40,11 +40,11 @@ class CustomEncoder(json.JSONEncoder):
class JsonFormatter(logging.Formatter): class JsonFormatter(logging.Formatter):
def setup(self, timestamp, isWrite, targetFile, version, plugin, verbose, def setup(self, timestamp, isWrite, entity, version, plugin, verbose,
warnings=False): warnings=False):
self.timestamp = timestamp self.timestamp = timestamp
self.isWrite = isWrite self.isWrite = isWrite
self.targetFile = targetFile self.entity = entity
self.version = version self.version = version
self.plugin = plugin self.plugin = plugin
self.verbose = verbose self.verbose = verbose
@ -61,7 +61,7 @@ class JsonFormatter(logging.Formatter):
data['caller'] = record.pathname data['caller'] = record.pathname
data['lineno'] = record.lineno data['lineno'] = record.lineno
data['isWrite'] = self.isWrite data['isWrite'] = self.isWrite
data['file'] = self.targetFile data['file'] = self.entity
if not self.isWrite: if not self.isWrite:
del data['isWrite'] del data['isWrite']
data['level'] = record.levelname data['level'] = record.levelname
@ -89,7 +89,7 @@ def setup_logging(args, version):
formatter.setup( formatter.setup(
timestamp=args.timestamp, timestamp=args.timestamp,
isWrite=args.isWrite, isWrite=args.isWrite,
targetFile=args.targetFile, entity=args.entity,
version=version, version=version,
plugin=args.plugin, plugin=args.plugin,
verbose=args.verbose, verbose=args.verbose,
@ -104,7 +104,7 @@ def setup_logging(args, version):
formatter.setup( formatter.setup(
timestamp=args.timestamp, timestamp=args.timestamp,
isWrite=args.isWrite, isWrite=args.isWrite,
targetFile=args.targetFile, entity=args.entity,
version=version, version=version,
plugin=args.plugin, plugin=args.plugin,
verbose=args.verbose, verbose=args.verbose,
@ -116,7 +116,7 @@ def setup_logging(args, version):
warnings_formatter.setup( warnings_formatter.setup(
timestamp=args.timestamp, timestamp=args.timestamp,
isWrite=args.isWrite, isWrite=args.isWrite,
targetFile=args.targetFile, entity=args.entity,
version=version, version=version,
plugin=args.plugin, plugin=args.plugin,
verbose=args.verbose, verbose=args.verbose,

View file

@ -53,7 +53,11 @@ log = logging.getLogger('WakaTime')
class FileAction(argparse.Action): class FileAction(argparse.Action):
def __call__(self, parser, namespace, values, option_string=None): def __call__(self, parser, namespace, values, option_string=None):
try:
if os.path.isfile(values):
values = os.path.realpath(values) values = os.path.realpath(values)
except:
pass
setattr(namespace, self.dest, values) setattr(namespace, self.dest, values)
@ -88,9 +92,12 @@ def parseArguments():
# define supported command line arguments # define supported command line arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='Common interface for the WakaTime api.') description='Common interface for the WakaTime api.')
parser.add_argument('--file', dest='targetFile', metavar='file', parser.add_argument('--entity', dest='entity', metavar='FILE',
action=FileAction, required=True, action=FileAction,
help='absolute path to file for current heartbeat') help='absolute path to file for the heartbeat; can also be a '+
'url, domain, or app when --entitytype is not file')
parser.add_argument('--file', dest='file', action=FileAction,
help=argparse.SUPPRESS)
parser.add_argument('--key', dest='key', parser.add_argument('--key', dest='key',
help='your wakatime api key; uses api_key from '+ help='your wakatime api key; uses api_key from '+
'~/.wakatime.conf by default') '~/.wakatime.conf by default')
@ -111,7 +118,7 @@ def parseArguments():
help='optional cursor position in the current file') help='optional cursor position in the current file')
parser.add_argument('--entitytype', dest='entity_type', parser.add_argument('--entitytype', dest='entity_type',
help='entity type for this heartbeat. can be one of "file", '+ help='entity type for this heartbeat. can be one of "file", '+
'"url", or "domain"; defaults to file.') '"url", "domain", or "app"; defaults to file.')
parser.add_argument('--proxy', dest='proxy', parser.add_argument('--proxy', dest='proxy',
help='optional https proxy url; for example: '+ help='optional https proxy url; for example: '+
'https://user:pass@localhost:8080') 'https://user:pass@localhost:8080')
@ -170,6 +177,11 @@ def parseArguments():
parser.error('Missing api key') parser.error('Missing api key')
if not args.entity_type: if not args.entity_type:
args.entity_type = 'file' args.entity_type = 'file'
if not args.entity:
if args.file:
args.entity = args.file
else:
parser.error('argument --entity is required')
if not args.exclude: if not args.exclude:
args.exclude = [] args.exclude = []
if configs.has_option('settings', 'ignore'): if configs.has_option('settings', 'ignore'):
@ -213,13 +225,13 @@ def parseArguments():
return args, configs return args, configs
def should_exclude(fileName, include, exclude): def should_exclude(entity, include, exclude):
if fileName is not None and fileName.strip() != '': if entity is not None and entity.strip() != '':
try: try:
for pattern in include: for pattern in include:
try: try:
compiled = re.compile(pattern, re.IGNORECASE) compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(fileName): if compiled.search(entity):
return False return False
except re.error as ex: except re.error as ex:
log.warning(u('Regex error ({msg}) for include pattern: {pattern}').format( log.warning(u('Regex error ({msg}) for include pattern: {pattern}').format(
@ -232,7 +244,7 @@ def should_exclude(fileName, include, exclude):
for pattern in exclude: for pattern in exclude:
try: try:
compiled = re.compile(pattern, re.IGNORECASE) compiled = re.compile(pattern, re.IGNORECASE)
if compiled.search(fileName): if compiled.search(entity):
return pattern return pattern
except re.error as ex: except re.error as ex:
log.warning(u('Regex error ({msg}) for exclude pattern: {pattern}').format( log.warning(u('Regex error ({msg}) for exclude pattern: {pattern}').format(
@ -264,7 +276,7 @@ def get_user_agent(plugin):
return user_agent return user_agent
def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None, targetFile=None, def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None, entity=None,
timestamp=None, isWrite=None, plugin=None, offline=None, entity_type='file', timestamp=None, isWrite=None, plugin=None, offline=None, entity_type='file',
hidefilenames=None, proxy=None, api_url=None, **kwargs): hidefilenames=None, proxy=None, api_url=None, **kwargs):
"""Sends heartbeat as POST request to WakaTime api server. """Sends heartbeat as POST request to WakaTime api server.
@ -275,10 +287,10 @@ def send_heartbeat(project=None, branch=None, hostname=None, stats={}, key=None,
log.debug('Sending heartbeat to api at %s' % api_url) log.debug('Sending heartbeat to api at %s' % api_url)
data = { data = {
'time': timestamp, 'time': timestamp,
'entity': targetFile, 'entity': entity,
'type': entity_type, 'type': entity_type,
} }
if hidefilenames and targetFile is not None and entity_type == 'file': if hidefilenames and entity is not None and entity_type == 'file':
extension = u(os.path.splitext(data['entity'])[1]) extension = u(os.path.splitext(data['entity'])[1])
data['entity'] = u('HIDDEN{0}').format(extension) data['entity'] = u('HIDDEN{0}').format(extension)
if stats.get('lines'): if stats.get('lines'):
@ -390,16 +402,16 @@ def execute(argv):
setup_logging(args, __version__) setup_logging(args, __version__)
exclude = should_exclude(args.targetFile, args.include, args.exclude) exclude = should_exclude(args.entity, args.include, args.exclude)
if exclude is not False: if exclude is not False:
log.debug(u('File not logged because matches exclude pattern: {pattern}').format( log.debug(u('Skipping because matches exclude pattern: {pattern}').format(
pattern=u(exclude), pattern=u(exclude),
)) ))
return 0 return 0
if args.entity_type != 'file' or os.path.isfile(args.targetFile): if args.entity_type != 'file' or os.path.isfile(args.entity):
stats = get_file_stats(args.targetFile, entity_type=args.entity_type, stats = get_file_stats(args.entity, entity_type=args.entity_type,
lineno=args.lineno, cursorpos=args.cursorpos) lineno=args.lineno, cursorpos=args.cursorpos)
project = args.project or args.alternate_project project = args.project or args.alternate_project
@ -421,7 +433,7 @@ def execute(argv):
break break
sent = send_heartbeat( sent = send_heartbeat(
project=heartbeat['project'], project=heartbeat['project'],
targetFile=heartbeat['file'], entity=heartbeat['entity'],
timestamp=heartbeat['time'], timestamp=heartbeat['time'],
branch=heartbeat['branch'], branch=heartbeat['branch'],
hostname=kwargs['hostname'], hostname=kwargs['hostname'],

View file

@ -50,7 +50,7 @@ def get_project_info(configs, args):
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(args.targetFile, configs=plugin_configs) project = plugin_cls(args.entity, configs=plugin_configs)
if project.process(): if project.process():
project_name = project_name or project.name() project_name = project_name or project.name()
branch_name = project.branch() branch_name = project.branch()
@ -66,7 +66,7 @@ def get_project_info(configs, args):
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(args.targetFile, configs=plugin_configs) project = plugin_cls(args.entity, configs=plugin_configs)
if project.process(): if project.process():
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()