Repository: zalando-stups/senza

Issue:
Senza version warning should not be printed for non-TTYs (piping result to awk etc)
The Senza version check currently destroys popular shell scripting such as:

```
senza li -o tsv | tail -n +2 | awk '{ print $1 }'
```

We should only print the warning if `sys.stdout` is a TTY.

Discussion:

Patch:
diff --git a/senza/aws.py b/senza/aws.py
index 1284ba3..c7f0468 100644
--- a/senza/aws.py
+++ b/senza/aws.py
@@ -55,13 +55,12 @@ def is_status_complete(status: str):
 def get_security_group(region: str, sg_name: str):
     ec2 = boto3.resource('ec2', region)
     try:
-        sec_groups = list(ec2.security_groups.filter(
-            Filters=[{'Name': 'group-name', 'Values': [sg_name]}]
-        ))
-        if not sec_groups:
-            return None
-        # FIXME: What if we have 2 VPC, with a SG with the same name?!
-        return sec_groups[0]
+        # first try by tag name then by group-name (cannot be changed)
+        for _filter in [{'Name': 'tag:Name', 'Values': [sg_name]}, {'Name': 'group-name', 'Values': [sg_name]}]:
+            sec_groups = list(ec2.security_groups.filter(Filters=[_filter]))
+            if sec_groups:
+                # FIXME: What if we have 2 VPC, with a SG with the same name?!
+                return sec_groups[0]
     except ClientError as e:
         error_code = extract_client_error_code(e)
         if error_code == 'InvalidGroup.NotFound':
diff --git a/senza/subcommands/root.py b/senza/subcommands/root.py
index 9162122..e5dab09 100644
--- a/senza/subcommands/root.py
+++ b/senza/subcommands/root.py
@@ -6,6 +6,7 @@ from typing import Optional
 import click
 import requests
 import senza
+import sys
 from clickclick import AliasedGroup, warning
 
 from ..arguments import GLOBAL_OPTIONS, region_option
@@ -81,6 +82,8 @@ def check_senza_version(current_version: str):
     Checks if senza is updated and prints a warning with instructions to update
     if it's not.
     """
+    if not sys.stdout.isatty():
+        return
     current_version = LooseVersion(current_version)
     try:
         latest_version = get_latest_version()


Test patch:
diff --git a/tests/test_aws.py b/tests/test_aws.py
index 4ca762a..8dd5b44 100644
--- a/tests/test_aws.py
+++ b/tests/test_aws.py
@@ -14,6 +14,21 @@ def test_get_security_group(monkeypatch):
     assert results == get_security_group('myregion', 'group_inexistant')
 
 
+def test_get_security_group_by_tag_name(monkeypatch):
+
+    def mock_filter(Filters):
+        if Filters[0]['Name'] == 'tag:Name' and Filters[0]['Values'] == ['my-sg']:
+            sg = MagicMock()
+            sg.id = 'sg-123'
+            return [sg]
+
+    ec2 = MagicMock()
+    ec2.security_groups.filter = mock_filter
+    monkeypatch.setattr('boto3.resource', MagicMock(return_value=ec2))
+
+    assert get_security_group('myregion', 'my-sg').id == 'sg-123'
+
+
 def test_resolve_security_groups(monkeypatch):
     ec2 = MagicMock()
     ec2.security_groups.filter = MagicMock(side_effect=[
diff --git a/tests/test_subcommands/test_root.py b/tests/test_subcommands/test_root.py
index 796d6c9..86f5a4f 100644
--- a/tests/test_subcommands/test_root.py
+++ b/tests/test_subcommands/test_root.py
@@ -34,8 +34,23 @@ def mock_warning(monkeypatch):
     return mock
 
 
+@fixture()
+def mock_tty(monkeypatch):
+    # check_senza_version only prints if we have a TTY
+    monkeypatch.setattr('sys.stdout.isatty', lambda: True)
+
+
+def test_check_senza_version_notty(monkeypatch, mock_get_app_dir, mock_get, mock_warning):
+    with TemporaryDirectory() as temp_dir:
+        mock_get_app_dir.return_value = temp_dir
+        monkeypatch.setattr("senza.subcommands.root.__file__",
+                            '/home/someuser/pymodules/root.py')
+        check_senza_version("0.40")
+        mock_warning.assert_not_called()
+
+
 def test_check_senza_version(monkeypatch,
-                             mock_get_app_dir, mock_get, mock_warning):
+                             mock_get_app_dir, mock_get, mock_warning, mock_tty):
 
     with TemporaryDirectory() as temp_dir_1:
         mock_get_app_dir.return_value = temp_dir_1
@@ -72,7 +87,7 @@ def test_check_senza_version(monkeypatch,
         )
 
 
-def test_check_senza_version_timeout(mock_get_app_dir, mock_get, mock_warning):
+def test_check_senza_version_timeout(mock_get_app_dir, mock_get, mock_warning, mock_tty):
     with TemporaryDirectory() as temp_dir:
         mock_get_app_dir.return_value = temp_dir
         mock_get.side_effect = Timeout
@@ -83,7 +98,8 @@ def test_check_senza_version_timeout(mock_get_app_dir, mock_get, mock_warning):
 def test_check_senza_version_outdated_cache(monkeypatch,  # noqa: F811
                                             mock_get_app_dir,
                                             mock_get,
-                                            mock_warning):
+                                            mock_warning,
+                                            mock_tty):
     monkeypatch.setattr("senza.subcommands.root.__file__",
                         '/usr/pymodules/root.py')
     with TemporaryDirectory() as temp_dir:
@@ -106,7 +122,8 @@ def test_check_senza_version_outdated_cache(monkeypatch,  # noqa: F811
 def test_check_senza_version_exception(monkeypatch,
                                        mock_get_app_dir,
                                        mock_get,
-                                       mock_warning):
+                                       mock_warning,
+                                       mock_tty):
     mock_sentry = MagicMock()
     monkeypatch.setattr("senza.subcommands.root.sentry", mock_sentry)
     with TemporaryDirectory() as temp_dir: