Repository: ansible/tower-cli
Pull request #416 (2017-10-23 16:57:15)

Get rid of VERSION file and use entry_point in v1 branch
In short, vendoring this VERSION file was not playing
nice with setuptools
* make CUR_API_VERSION importable in v1 branch as constant
* change setup and __init__.py code to adjust

Yes, this does need to be adapted to the master branch / v2

AlanCoding: I thought it might be best to just go all the way to parity with the branches, so I put in the change to get rid of the bin directory here as well.

Patch:
diff --git a/.gitignore b/.gitignore
index ea31c86..5a33862 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,5 +68,8 @@ results.xml
 
 # tower-cli v1 build
 tower_cli_v1/
-bin/tower-cli-v1
 setup_v1.py
+
+# tower-cli v2 build
+tower_cli_v2/
+setup_v2.py
diff --git a/MANIFEST.in b/MANIFEST.in
index 19033f5..2093ffd 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,7 +4,6 @@
 include LICENSE
 include README.rst
 include HISTORY.rst
-include tower_cli/VERSION
 include requirements.txt
 recursive-include docs *
 recursive-include tests *
diff --git a/Makefile b/Makefile
index bbcd8ce..ae5a808 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-VERSION = $(shell cat tower_cli/VERSION)
+VERSION := $(shell python -c "exec(open('''tower_cli/constants.py''').read(), globals()); print VERSION")
 
 DISTS = el6 el7
 DIST_SUFFIX_el6 = 
@@ -35,7 +35,7 @@ clean:
 	rm -rf ansible_tower_cli.egg-info
 	rm -rf rpm-build
 
-dist/ansible-tower-cli-$(VERSION).tar.gz: bin/tower-cli HISTORY.rst LICENSE MANIFEST.in README.rst VERSION requirements.txt setup.py setup.cfg
+dist/ansible-tower-cli-$(VERSION).tar.gz: HISTORY.rst LICENSE MANIFEST.in README.rst requirements.txt setup.py setup.cfg
 	@python setup.py sdist
 
 rpm-build/.exists:
@@ -44,25 +44,23 @@ rpm-build/.exists:
 
 # For devel convenience
 install:
-	sudo rm -rf dist/ build/ 
-	sudo python setup.py install
+	rm -rf dist/ build/
+	python setup.py install
 	
 clean_v1:
 	rm -rf tower_cli_v1
 	rm -rf ansible_tower_cli_v1.egg-info
 	rm -rf setup_v1.py
-	rm -f bin/tower-cli-v1
 
 setup_v1.py:
 	cp -R tower_cli tower_cli_v1/
-	cp bin/tower-cli bin/tower-cli-v1
 	cp setup.py setup_v1.py
 	python version_swap.py
 
 prep_v1: setup_v1.py
 
 install_v1: setup_v1.py
-	sudo rm -rf dist/ build/
-	sudo python setup_v1.py install
+	rm -rf dist/ build/
+	python setup_v1.py install
 
-v1-refresh: clean_v1 install_v1
+v1-refresh: clean clean_v1 install_v1
diff --git a/packaging/rpm/ansible-tower-cli.spec b/packaging/rpm/ansible-tower-cli.spec
index 8cca643..8bb1a69 100644
--- a/packaging/rpm/ansible-tower-cli.spec
+++ b/packaging/rpm/ansible-tower-cli.spec
@@ -51,7 +51,6 @@ rm -rf $RPM_BUILD_ROOT
 %config(noreplace) %ghost %{_sysconfdir}/tower/tower_cli.cfg
 %{python_sitelib}/ansible*
 %{python_sitelib}/tower_cli*
-%{_bindir}/*
 
 %changelog
 * Sun Mar 26 2017 Satoru SATOH <satoru.satoh@gmail.com> - 3.1.3-2
diff --git a/setup.py b/setup.py
index fdc402c..3837493 100644
--- a/setup.py
+++ b/setup.py
@@ -17,6 +17,7 @@
 # limitations under the License.
 
 import re
+import os
 import sys
 from distutils.core import setup
 from setuptools import find_packages
@@ -24,6 +25,7 @@ from setuptools.command.test import test as TestCommand
 
 
 pkg_name = 'tower_cli'
+dashed_name = pkg_name.replace('_', '-')
 
 
 class Tox(TestCommand):
@@ -113,10 +115,18 @@ def combine_files(*args):
     return "\n\n".join(file_contents)
 
 
+# Read the constants, for versioning information
+constants = {}
+exec(
+    open(os.path.join(pkg_name, 'constants.py')).read(),
+    constants
+)
+
+
 setup(
     # Basic metadata
-    name='ansible-%s' % pkg_name.replace('_', '-'),
-    version=open('%s/VERSION' % pkg_name).read().strip(),
+    name='ansible-%s' % dashed_name,
+    version=constants['VERSION'],
     author='Luke Sneeringer',
     author_email='lsneeringer@ansible.com',
     url='https://github.com/ansible/tower-cli',
@@ -131,19 +141,16 @@ setup(
     provides=[
         pkg_name,
     ],
-    scripts=[
-        'bin/%s' % pkg_name.replace('_', '-'),
-    ],
+    entry_points={
+        'console_scripts': [
+            '%s=%s.cli.run:cli' % (dashed_name, pkg_name),
+        ],
+    },
     packages=find_packages(exclude=['tests']),
     # How to do the tests
     tests_require=['tox'],
     cmdclass={'test': Tox},
 
-    # Data files
-    package_data={
-        pkg_name: ['VERSION'],
-    },
-
     # PyPI metadata.
     classifiers=[
         'Development Status :: 5 - Production/Stable',
diff --git a/tower_cli/VERSION b/tower_cli/VERSION
deleted file mode 100644
index c848fb9..0000000
--- a/tower_cli/VERSION
+++ /dev/null
@@ -1,1 +0,0 @@
-3.1.8
diff --git a/tower_cli/__init__.py b/tower_cli/__init__.py
index 62310c0..cddc15e 100644
--- a/tower_cli/__init__.py
+++ b/tower_cli/__init__.py
@@ -15,11 +15,11 @@
 
 from __future__ import absolute_import, unicode_literals
 import importlib
-import os
 
+from tower_cli import constants
 
-whereami = os.path.realpath(os.path.dirname(__file__))
-__version__ = open('%s/VERSION' % whereami, 'r').read().strip()
+
+__version__ = constants.VERSION
 
 
 def get_resource(name):
diff --git a/tower_cli/cli/base.py b/tower_cli/cli/base.py
index 198f0ae..4ae6d3e 100644
--- a/tower_cli/cli/base.py
+++ b/tower_cli/cli/base.py
@@ -12,8 +12,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import os
 import sys
+import pkgutil
 
 import click
 
@@ -41,12 +41,7 @@ class TowerCLI(click.MultiCommand):
         """Return a list of commands present in the commands and resources
         folders, but not subcommands.
         """
-        answer = set()
-        for filename in os.listdir('%s/%s/' % (tower_cli.whereami, 'resources')):
-            if filename.endswith('.py') and not filename.startswith('_'):
-                res = tower_cli.get_resource(filename[:-3])
-                if not getattr(res, 'internal', False):
-                    answer.add(filename[:-3])
+        answer = set([name for _, name, _ in pkgutil.iter_modules(['tower_cli/resources'])])
         for cmd_name in misc.__all__:
             answer.add(cmd_name)
         return sorted(answer)
diff --git a/tower_cli/cli/misc.py b/tower_cli/cli/misc.py
index d4c7cd5..0e2986f 100644
--- a/tower_cli/cli/misc.py
+++ b/tower_cli/cli/misc.py
@@ -25,6 +25,7 @@ from tower_cli import __version__, exceptions as exc
 from tower_cli.api import client
 from tower_cli.conf import with_global_options, Parser, settings
 from tower_cli.utils import secho
+from tower_cli.constants import CUR_API_VERSION
 
 __all__ = ['version', 'config']
 
@@ -37,6 +38,9 @@ def version(**kwargs):
     # Print out the current version of Tower CLI.
     click.echo('Tower CLI %s' % __version__)
 
+    # Print out the current API version of the current code base.
+    click.echo('API %s' % CUR_API_VERSION)
+
     # Attempt to connect to the Ansible Tower server.
     # If we succeed, print a version; if not, generate a failure.
     try:
diff --git a/bin/tower-cli b/tower_cli/cli/run.py
old mode 100755
new mode 100644
similarity index 66%
rename from bin/tower-cli
rename to tower_cli/cli/run.py
index aca2a56..c78ff68
--- a/bin/tower-cli
+++ b/tower_cli/cli/run.py
@@ -1,6 +1,4 @@
-#!/usr/bin/env python
-# Copyright 2013-2014, Ansible, Inc.
-# Luke Sneeringer <lsneeringer@ansible.com>
+# Copyright 2013-2017, Red Hat Inc.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -19,9 +17,7 @@ import click
 from tower_cli.cli.base import TowerCLI
 
 
-if __name__ == '__main__':
-    cli = TowerCLI(
-        params=[click.Option(param_decls=['--version'], is_flag=True,
-                             help='Display tower-cli version.')],
-    )
-    cli()
+cli = TowerCLI(
+    params=[click.Option(param_decls=['--version'], is_flag=True,
+                         help='Display tower-cli version.')],
+)
diff --git a/tower_cli/constants.py b/tower_cli/constants.py
new file mode 100644
index 0000000..02c7a83
--- /dev/null
+++ b/tower_cli/constants.py
@@ -0,0 +1,17 @@
+# Copyright 2017, Ansible by Red Hat.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+VERSION = '3.1.8'
+CUR_API_VERSION = 'v1'
diff --git a/version_swap.py b/version_swap.py
index 0a4501d..c7266d3 100644
--- a/version_swap.py
+++ b/version_swap.py
@@ -26,4 +26,3 @@ for dname, dirs, files in os.walk(package_name):
 
 
 convert_file('setup_v%s.py' % API_VERSION)
-convert_file('bin/tower-cli-v%s' % API_VERSION)


Test patch:
diff --git a/tests/test_cli_misc.py b/tests/test_cli_misc.py
index 0ee5c45..ffabb98 100644
--- a/tests/test_cli_misc.py
+++ b/tests/test_cli_misc.py
@@ -50,7 +50,7 @@ class VersionTests(unittest.TestCase):
             self.assertEqual(result.exit_code, 0)
             self.assertEqual(
                 result.output.strip(),
-                'Tower CLI %s\nAnsible Tower 4.21' % tower_cli.__version__,
+                'Tower CLI %s\nAPI v1\nAnsible Tower 4.21' % tower_cli.__version__,
             )
 
     def test_cannot_connect(self):