Repository: deis/deis

Issue:
feat(*): add `make test-style` target
That way we can run `go vet`, `flake8`, etc. on each component. This should also be run against against each PR on ci.deis.io so that our code follows code style best practices :)



Discussion:

Resolving patch:
diff --git a/client/deis.py b/client/deis.py
--- a/client/deis.py
+++ b/client/deis.py
@@ -318,7 +318,7 @@ def readable_datetime(datetime_str):
         else:
             return "{}{}ago".format(hour_str, min_str)
     # if it happened yesterday, say "yesterday at 3:23 pm"
-    yesterday = now + relativedelta.relativedelta(days= -1)
+    yesterday = now + relativedelta.relativedelta(days=-1)
     if delta.days <= 2 and dt.day == yesterday.day:
         return dt.strftime("Yesterday at %X")
     # otherwise return locale-specific date/time format
@@ -1033,12 +1033,13 @@ def clusters_update(self, args):
             if k == 'auth' and args.get('--auth') is not None:
                 auth_path = os.path.expanduser(args['--auth'])
                 if not os.path.exists(auth_path):
-                    print('Path to authentication credentials does not exist: {}'.format(auth_path))
+                    print(
+                        "Path to authentication credentials does not exist: {}".format(auth_path))
                     sys.exit(1)
                 with open(auth_path) as f:
                     data = f.read()
                 body.update({'auth': base64.b64encode(data)})
-            else :
+            else:
                 v = args.get(arg)
                 if v:
                     body.update({k: v})
@@ -1176,7 +1177,8 @@ def config_unset(self, args):
         try:
             progress = TextProgress()
             progress.start()
-            response = self._dispatch('post', "/api/apps/{}/config".format(app), json.dumps(body))
+            response = self._dispatch(
+                'post', "/api/apps/{}/config".format(app), json.dumps(body))
         finally:
             progress.cancel()
             progress.join()
@@ -1230,10 +1232,8 @@ def config_pull(self, args):
         if response.status_code == requests.codes.ok:  # @UndefinedVariable
             config = json.loads(response.json()['values'])
             for k, v in config.items():
-                if interactive:
-                    confirm = raw_input('overwrite {} with {}? (y/N) '.format(k, v))
-                    if confirm == 'y':
-                        env_dict[k] = v
+                if interactive and raw_input("overwrite {} with {}? (y/N) ".format(k, v)) == 'y':
+                    env_dict[k] = v
                 if k in env_dict and not overwrite:
                     continue
                 env_dict[k] = v
@@ -1284,7 +1284,8 @@ def domains_add(self, args):
         try:
             progress = TextProgress()
             progress.start()
-            response = self._dispatch('post', "/api/apps/{app}/domains".format(app=app), json.dumps(body))
+            response = self._dispatch(
+                'post', "/api/apps/{app}/domains".format(app=app), json.dumps(body))
         finally:
             progress.cancel()
             progress.join()
@@ -1316,7 +1317,8 @@ def domains_remove(self, args):
         try:
             progress = TextProgress()
             progress.start()
-            response = self._dispatch('delete', "/api/apps/{app}/domains/{domain}".format(**locals()))
+            response = self._dispatch(
+                'delete', "/api/apps/{app}/domains/{domain}".format(**locals()))
         finally:
             progress.cancel()
             progress.join()
diff --git a/controller/api/models.py b/controller/api/models.py
--- a/controller/api/models.py
+++ b/controller/api/models.py
@@ -186,7 +186,7 @@ def deploy(self, release, initial=False):
             elif release.build.dockerfile and not release.build.procfile:
                 self.structure = {'cmd': 1}
             # if a procfile exists without a web entry, assume docker workflow
-            elif release.build.procfile and not 'web' in release.build.procfile:
+            elif release.build.procfile and 'web' not in release.build.procfile:
                 self.structure = {'cmd': 1}
             # default to heroku workflow
             else:
@@ -206,7 +206,7 @@ def scale(self, **kwargs):  # noqa
         for container_type in requested_containers.keys():
             if container_type == 'cmd':
                 continue  # allow docker cmd types in case we don't have the image source
-            if not container_type in available_process_types:
+            if container_type not in available_process_types:
                 raise EnvironmentError(
                     'Container type {} does not exist in application'.format(container_type))
         msg = 'Containers scaled ' + ' '.join(
diff --git a/controller/scheduler/coreos.py b/controller/scheduler/coreos.py
--- a/controller/scheduler/coreos.py
+++ b/controller/scheduler/coreos.py
@@ -11,7 +11,9 @@
 if not os.path.exists(ROOT_DIR):
     os.mkdir(ROOT_DIR)
 
-MATCH = re.compile('(?P<app>[a-z0-9-]+)_?(?P<version>v[0-9]+)?\.?(?P<c_type>[a-z]+)?.(?P<c_num>[0-9]+)')
+MATCH = re.compile(
+    '(?P<app>[a-z0-9-]+)_?(?P<version>v[0-9]+)?\.?(?P<c_type>[a-z]+)?.(?P<c_num>[0-9]+)')
+
 
 class FleetClient(object):
 
@@ -76,15 +78,15 @@ def _create_container(self, name, image, command, template, env, **kwargs):
         # prepare memory limit for the container type
         mem = kwargs.get('memory', {}).get(l['c_type'], None)
         if mem:
-          l.update({'memory': '-m {}'.format(mem.lower())})
+            l.update({'memory': '-m {}'.format(mem.lower())})
         else:
-          l.update({'memory': ''})
+            l.update({'memory': ''})
         # prepare memory limit for the container type
         cpu = kwargs.get('cpu', {}).get(l['c_type'], None)
         if cpu:
-          l.update({'cpu': '-c {}'.format(cpu)})
+            l.update({'cpu': '-c {}'.format(cpu)})
         else:
-          l.update({'cpu': ''})
+            l.update({'cpu': ''})
         env.update({'FLEETW_UNIT': name + '.service'})
         # construct unit from template
         unit = template.format(**l)
@@ -148,7 +150,7 @@ def _wait_for_announcer(self, name, env):
         # we bump to 20 minutes here to match the timeout on the router and in the app unit files
         for _ in range(1200):
             status = subprocess.check_output(
-                "fleetctl.sh list-units --no-legend --fields unit,sub | grep {name}-announce.service | awk '{{print $2}}'".format(**locals()),
+                "fleetctl.sh list-units --no-legend --fields unit,sub | grep {name}-announce.service | awk '{{print $2}}'".format(**locals()),  # noqa
                 shell=True, env=env).strip('\n')
             if status == 'running':
                 break
@@ -246,7 +248,7 @@ def attach(self, name):
 ExecStart=/bin/sh -c "IMAGE=$(etcdctl get /deis/registry/host 2>&1):$(etcdctl get /deis/registry/port 2>&1)/{image}; port=$(docker inspect -f '{{{{range $k, $v := .ContainerConfig.ExposedPorts }}}}{{{{$k}}}}{{{{end}}}}' $IMAGE | cut -d/ -f1) ; docker run --name {name} {memory} {cpu} -P -e PORT=$port $IMAGE {command}"
 ExecStop=/usr/bin/docker rm -f {name}
 TimeoutStartSec=20m
-"""
+"""  # noqa
 
 # TODO revisit the "not getting a port" issue after we upgrade to Docker 1.1.0
 ANNOUNCE_TEMPLATE = """
@@ -263,7 +265,7 @@ def attach(self, name):
 
 [X-Fleet]
 X-ConditionMachineOf={name}.service
-"""
+"""  # noqa
 
 LOG_TEMPLATE = """
 [Unit]
@@ -277,4 +279,4 @@ def attach(self, name):
 
 [X-Fleet]
 X-ConditionMachineOf={name}.service
-"""
+"""  # noqa


Test patch:
diff --git a/logger/syslog/message_test.go b/logger/syslog/message_test.go
--- a/logger/syslog/message_test.go
+++ b/logger/syslog/message_test.go
@@ -10,45 +10,45 @@ func TestMessageNetSrc(t *testing.T) {
 	tcpAddress, err := net.ResolveTCPAddr("tcp", "localhost:1234")
 
 	if err != nil {
-		t.Errorf("could not resolve TCP address")
+		t.Error("could not resolve TCP address")
 	}
 
 	m := &Message{time.Now(), tcpAddress, 0, 0, time.Now(), "", "", "", "", ""}
 	if m.NetSrc() != "127.0.0.1" {
-		t.Errorf("expected 127.0.0.1, got ", m.NetSrc())
+		t.Errorf("expected 127.0.0.1, got %s", m.NetSrc())
 	}
 
 	udpAddress, err := net.ResolveUDPAddr("udp", "localhost:1234")
 
 	if err != nil {
-		t.Errorf("could not resolve UDP address")
+		t.Error("could not resolve UDP address")
 	}
 
 	m.Source = udpAddress
 	if m.NetSrc() != "127.0.0.1" {
-		t.Errorf("expected 127.0.0.1, got ", m.NetSrc())
+		t.Errorf("expected 127.0.0.1, got %s", m.NetSrc())
 	}
 
 	unixAddress, err := net.ResolveUnixAddr("unix", "/tmp/str")
 
 	if err != nil {
-		t.Errorf("could not resolve unix address")
+		t.Error("could not resolve unix address")
 	}
 
 	m.Source = unixAddress
 	if m.NetSrc() != "/tmp/str" {
-		t.Errorf("expected /tmp/str, got ", m.NetSrc())
+		t.Errorf("expected /tmp/str, got %s", m.NetSrc())
 	}
 
 	unknownAddress, err := net.ResolveIPAddr("ip4", "localhost")
 
 	if err != nil {
-		t.Errorf("could not resolve unknown address")
+		t.Error("could not resolve unknown address")
 	}
 
 	m.Source = unknownAddress
 	if m.NetSrc() != "127.0.0.1" {
-		t.Errorf("expected 127.0.0.1, got ", m.NetSrc())
+		t.Errorf("expected 127.0.0.1, got %s", m.NetSrc())
 	}
 }
 
diff --git a/tests/Makefile b/tests/Makefile
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,10 +1,10 @@
 test: test-smoke
 
-test-smoke:
+test-smoke: test-style
 	GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
 		go test -tags integration -short -v -run TestSmoke
 
-test-full:
+test-full: test-style
 	GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
 		go test -tags integration -v -run TestGlobal
 	GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
@@ -26,6 +26,18 @@ test-full:
 	GOPATH=$(CURDIR)/_vendor:$(GOPATH) \
 		go test -tags integration -v -run TestReleases
 
+setup-root-gotools:
+	sudo GOPATH=/tmp/tmpGOPATH go get -u -v code.google.com/p/go.tools/cmd/cover
+	sudo GOPATH=/tmp/tmpGOPATH go get -u -v code.google.com/p/go.tools/cmd/vet
+	sudo rm -rf /tmp/tmpGOPATH
+
+setup-gotools:
+	go get -v github.com/golang/lint/golint
+
+test-style:
+	go vet -x ./...
+	-golint *.go dockercli etcdutils mock utils
+
 nuke_from_orbit:
 	-docker kill `docker ps -q`
 	-docker rm `docker ps -a -q`
diff --git a/tests/etcdutils/etcdutils.go b/tests/etcdutils/etcdutils.go
--- a/tests/etcdutils/etcdutils.go
+++ b/tests/etcdutils/etcdutils.go
@@ -11,6 +11,7 @@ import (
 	"github.com/deis/deis/tests/utils"
 )
 
+// EtcdHandle is used to set keys and values in a test etcd instance.
 type EtcdHandle struct {
 	Dirs []string
 	Keys []string
@@ -24,6 +25,7 @@ func getetcdClient(port string) *etcd.Client {
 	return c
 }
 
+// InitetcdValues configures a test etcd instance.
 func InitetcdValues(setdir, setkeys []string, port string) *EtcdHandle {
 	cli := getetcdClient(port)
 	controllerHandle := new(EtcdHandle)
@@ -34,6 +36,7 @@ func InitetcdValues(setdir, setkeys []string, port string) *EtcdHandle {
 	return controllerHandle
 }
 
+// SetEtcdValues sets an array of values into a test etcd instance.
 func SetEtcdValues(t *testing.T, keys []string, values []string, c *etcd.Client) {
 	for i, key := range keys {
 		_, err := c.Set(key, values[i], 0)
@@ -43,6 +46,7 @@ func SetEtcdValues(t *testing.T, keys []string, values []string, c *etcd.Client)
 	}
 }
 
+// Publishvalues sets canonical etcd values into a test etcd instance.
 func Publishvalues(t *testing.T, ecli *EtcdHandle) {
 	fmt.Println("--- Publish etcd keys and values")
 	for _, dir := range ecli.Dirs {
diff --git a/tests/utils/itutils.go b/tests/utils/itutils.go
--- a/tests/utils/itutils.go
+++ b/tests/utils/itutils.go
@@ -152,9 +152,9 @@ func CheckList(
 	if strings.Contains(stdout.String(), contain) == notflag {
 		if notflag {
 			t.Fatalf(
-				"Didn't expect '%s' in command output:\n%s", contain, stdout)
+				"Didn't expect '%s' in command output:\n%v", contain, stdout)
 		}
-		t.Fatalf("Expected '%s' in command output:\n%s", contain, stdout)
+		t.Fatalf("Expected '%s' in command output:\n%v", contain, stdout)
 	}
 }