From 6ba78ce0ad5f398a2b9435ea8514ac111c5df360 Mon Sep 17 00:00:00 2001
From: Kevin Lyda <kevin@ie.suberic.net>
Date: Wed, 2 May 2012 18:39:12 +0100
Subject: [PATCH] Packaging cleanups.

setup.py changes:
  Add test and dist_clean commands.
  Add MANIFEST.in file to make sdist command work.
Test changes:
  Remove unneeded runall.py script.  Also, __init__.py.
  Mentioned tests and how to run them in README.
---
 .gitignore        |   3 ++
 MANIFEST.in       |   5 +++
 README            |   9 ++++-
 setup.py          | 100 ++++++++++++++++++++++++++++++++++++++++++++++
 tests/__init__.py |   0
 tests/runall.py   |  36 -----------------
 6 files changed, 116 insertions(+), 37 deletions(-)
 create mode 100644 MANIFEST.in
 delete mode 100644 tests/__init__.py
 delete mode 100755 tests/runall.py

diff --git a/.gitignore b/.gitignore
index 6f97ca1..7e5228b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,5 @@
+MANIFEST
+dist
 build
 *.pyc
+*.swp
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..b0e4bc2
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1,5 @@
+include LICENSE OWNERS README
+include chkcrontab.py
+include chkcrontab_lib.py
+include setup.py
+recursive-include tests test*
diff --git a/README b/README
index 7d4d001..5e9031e 100644
--- a/README
+++ b/README
@@ -1,3 +1,5 @@
+DESCRIPTION
+
 chkcrontab.py is a script to check crontab files like those in /etc/cron.d
 and /etc/crontab.  It tries to catch glaring errors and warn on suspect
 lines in a crontab file.  Some valid lines will generate warnings.
@@ -9,7 +11,12 @@ Errors will cause a non-zero exit code.  Warnings alone will not.
 
 To see sample output for a bad crontab, run the following:
 
-  ./scripts/chkcrontab.py ./tests/test_crontab
+  ./chkcrontab.py ./tests/test_crontab
 
 See the ./tests/test_crontab.disable crontab for how to disable warnings
 and errors.
+
+CONTRIBUTIONS
+
+Please add unit tests for new features or bug fixes.  To run all
+the unitests run ./setup test.
diff --git a/setup.py b/setup.py
index da5331c..a1bc11d 100755
--- a/setup.py
+++ b/setup.py
@@ -18,9 +18,109 @@
 This installs the chkcrontab command and the crontab.check module.
 """
 
+import os
+import sys
+from distutils import log
 from distutils.core import setup
+from distutils.core import Command
+if sys.version_info < (2, 7):
+  import unittest2 as unittest
+else:
+  import unittest
+
+BASE_DIR = os.path.dirname(globals().get('__file__', os.getcwd()))
+
+
+class TestCommand(Command):
+  description = 'Runs all available tests.'
+  user_options = [ ]
+
+  def initialize_options(self):
+    pass
+
+  def finalize_options(self):
+    pass
+
+  def run(self):
+    test_dir = os.path.join(BASE_DIR, 'tests')
+
+    tests = unittest.TestLoader().discover(test_dir)
+    runner = unittest.TextTestRunner(verbosity=2)
+    result = runner.run(tests)
+    if not result.wasSuccessful():
+      sys.exit(1)
+
+class CleanCommand(Command):
+  description = 'Remove all generated files.'
+  user_options = [ ]
+
+  def initialize_options(self):
+    pass
+
+  def finalize_options(self):
+    pass
+
+  def run(self):
+    # Configure for this project.
+    suffixes2del = [ 'MANIFEST', '.pyc' ]
+    dirs2del = [ './build', './dist' ]
+    dirs2ign = [ './.git' ]
+    # End config.
+    doomed = [ ]
+    # Change to base dir.
+    os.chdir(BASE_DIR)
+    for root, dirs, files in os.walk('.'):
+      # Handle root dirs.
+      if root in dirs2ign:
+        continue
+      if root in dirs2del:
+        doomed.append(root)
+      # Handle files.
+      for f in files:
+        accused = os.path.join(root, f)
+        for suffix in suffixes2del:
+          if f.endswith(suffix):
+            doomed.append(accused)
+            break
+        if accused not in doomed:
+          for d2del in dirs2del:
+            if accused.startswith(d2del):
+              doomed.append(accused)
+              break
+      # Handle dirs.
+      for d in dirs:
+        accused = os.path.join(root, d)
+        for d2ign in dirs2ign:
+          if accused.startswith(d2ign):
+            dirs.remove(d)
+            break
+        if d in dirs:
+          for d2del in dirs2del:
+            if accused.startswith(d2del):
+              doomed.append(accused)
+              break
+    # Probably not required, but just to be safe.
+    for accused in doomed:
+      for d2ign in dirs2ign:
+        if accused.startswith(d2ign):
+          doomed.remove(accused)
+          break
+    doomed.sort(reverse=True)
+    for accused in doomed:
+      log.info('removing "%s"', os.path.normpath(accused))
+      if not self.dry_run:
+        try:
+          os.unlink(accused)
+        except:
+          try:
+            os.rmdir(accused)
+          except:
+            log.warn('unable to remove "%s"', os.path.normpath(accused))
 
 setup(
+    cmdclass={'test': TestCommand,
+              'dist_clean': CleanCommand
+             },
     name='chkcrontab',
     version='1.0',
     url='http://code.google.com/p/chkcrontab',
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/runall.py b/tests/runall.py
deleted file mode 100755
index 65fca03..0000000
--- a/tests/runall.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2011 Google Inc. All Rights Reserved.
-#
-# 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.
-
-"""Run ***ALL*** the testorz!!!"""
-
-import os
-import sys
-if sys.version_info < (2, 7):
-  import unittest2 as unittest
-else:
-  import unittest
-
-BASE_PATH = os.path.dirname(__file__)
-sys.path.insert(0, os.path.join(BASE_PATH, '..'))
-
-if __name__ == '__main__':
-  test_dir = os.path.dirname(globals().get('__file__', os.getcwd()))
-
-  tests = unittest.TestLoader().discover(test_dir)
-  runner = unittest.TextTestRunner(verbosity=2)
-  result = runner.run(tests)
-  if not result.wasSuccessful():
-    sys.exit(1)
-- 
GitLab