detect dependencies from golang files
This commit is contained in:
parent
caafe3dcb6
commit
23dc803446
3 changed files with 157 additions and 0 deletions
24
tests/samples/codefiles/go.go
Normal file
24
tests/samples/codefiles/go.go
Normal file
|
@ -0,0 +1,24 @@
|
|||
package main
|
||||
|
||||
// list every possible way of importing to try and break dependency detection
|
||||
// http://learngowith.me/alternate-ways-of-importing-packages/
|
||||
|
||||
import "fmt"
|
||||
import "compress/gzip"
|
||||
import "github.com/golang/example/stringutil"
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
)
|
||||
import newname "oldname"
|
||||
import . "direct"
|
||||
import _ "supress"
|
||||
import (
|
||||
"foobar"
|
||||
. "math"
|
||||
_ "image/gif"
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello, World!")
|
||||
}
|
|
@ -439,3 +439,59 @@ class DependenciesTestCase(utils.TestCase):
|
|||
dependencies = self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['dependencies']
|
||||
self.assertListsEqual(dependencies, expected_dependencies)
|
||||
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
||||
|
||||
def test_go_dependencies_detected(self):
|
||||
response = Response()
|
||||
response.status_code = 0
|
||||
self.patched['wakatime.packages.requests.adapters.HTTPAdapter.send'].return_value = response
|
||||
|
||||
now = u(int(time.time()))
|
||||
entity = 'tests/samples/codefiles/go.go'
|
||||
config = 'tests/samples/configs/good_config.cfg'
|
||||
|
||||
args = ['--file', entity, '--config', config, '--time', now]
|
||||
|
||||
retval = execute(args)
|
||||
self.assertEquals(retval, 102)
|
||||
self.assertEquals(sys.stdout.getvalue(), '')
|
||||
self.assertEquals(sys.stderr.getvalue(), '')
|
||||
|
||||
self.patched['wakatime.session_cache.SessionCache.get'].assert_called_once_with()
|
||||
self.patched['wakatime.session_cache.SessionCache.delete'].assert_called_once_with()
|
||||
self.patched['wakatime.session_cache.SessionCache.save'].assert_not_called()
|
||||
|
||||
heartbeat = {
|
||||
'language': u('Go'),
|
||||
'lines': 24,
|
||||
'entity': os.path.realpath(entity),
|
||||
'project': u(os.path.basename(os.path.realpath('.'))),
|
||||
'dependencies': ANY,
|
||||
'branch': os.environ.get('TRAVIS_COMMIT', ANY),
|
||||
'time': float(now),
|
||||
'type': 'file',
|
||||
}
|
||||
stats = {
|
||||
u('cursorpos'): None,
|
||||
u('dependencies'): ANY,
|
||||
u('language'): u('Go'),
|
||||
u('lineno'): None,
|
||||
u('lines'): 24,
|
||||
}
|
||||
expected_dependencies = [
|
||||
'"compress/gzip"',
|
||||
'"direct"',
|
||||
'"foobar"',
|
||||
'"github.com/golang/example/stringutil"',
|
||||
'"image/gif"',
|
||||
'"log"',
|
||||
'"math"',
|
||||
'"oldname"',
|
||||
'"os"',
|
||||
'"supress"',
|
||||
]
|
||||
|
||||
self.patched['wakatime.offlinequeue.Queue.push'].assert_called_once_with(heartbeat, ANY, None)
|
||||
dependencies = self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['dependencies']
|
||||
self.assertListsEqual(dependencies, expected_dependencies)
|
||||
self.assertEquals(stats, json.loads(self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][1]))
|
||||
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
||||
|
|
77
wakatime/dependencies/go.py
Normal file
77
wakatime/dependencies/go.py
Normal file
|
@ -0,0 +1,77 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
wakatime.languages.go
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Parse dependencies from Go code.
|
||||
|
||||
:copyright: (c) 2016 Alan Hamlett.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
|
||||
from . import TokenParser
|
||||
|
||||
|
||||
class GoParser(TokenParser):
|
||||
state = None
|
||||
parens = 0
|
||||
aliases = 0
|
||||
exclude = [
|
||||
r'^"fmt"$',
|
||||
]
|
||||
|
||||
def parse(self):
|
||||
for index, token, content in self.tokens:
|
||||
self._process_token(token, content)
|
||||
return self.dependencies
|
||||
|
||||
def _process_token(self, token, content):
|
||||
if self.partial(token) == 'Namespace':
|
||||
self._process_namespace(token, content)
|
||||
elif self.partial(token) == 'Punctuation':
|
||||
self._process_punctuation(token, content)
|
||||
elif self.partial(token) == 'String':
|
||||
self._process_string(token, content)
|
||||
elif self.partial(token) == 'Text':
|
||||
self._process_text(token, content)
|
||||
elif self.partial(token) == 'Other':
|
||||
self._process_other(token, content)
|
||||
else:
|
||||
self._process_misc(token, content)
|
||||
|
||||
def _process_namespace(self, token, content):
|
||||
self.state = content
|
||||
self.parens = 0
|
||||
self.aliases = 0
|
||||
|
||||
def _process_string(self, token, content):
|
||||
if self.state == 'import':
|
||||
self.append(content, truncate=False)
|
||||
|
||||
def _process_punctuation(self, token, content):
|
||||
if content == '(':
|
||||
self.parens += 1
|
||||
elif content == ')':
|
||||
self.parens -= 1
|
||||
elif content == '.':
|
||||
self.aliases += 1
|
||||
else:
|
||||
self.state = None
|
||||
|
||||
def _process_text(self, token, content):
|
||||
if self.state == 'import':
|
||||
if content == "\n" and self.parens <= 0:
|
||||
self.state = None
|
||||
self.parens = 0
|
||||
self.aliases = 0
|
||||
else:
|
||||
self.state = None
|
||||
|
||||
def _process_other(self, token, content):
|
||||
if self.state == 'import':
|
||||
self.aliases += 1
|
||||
else:
|
||||
self.state = None
|
||||
|
||||
def _process_misc(self, token, content):
|
||||
self.state = None
|
Loading…
Reference in a new issue