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']
|
dependencies = self.patched['wakatime.offlinequeue.Queue.push'].call_args[0][0]['dependencies']
|
||||||
self.assertListsEqual(dependencies, expected_dependencies)
|
self.assertListsEqual(dependencies, expected_dependencies)
|
||||||
self.patched['wakatime.offlinequeue.Queue.pop'].assert_not_called()
|
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