diff --git a/.gitignore b/.gitignore
index 6f97ca1afcc063e5102e7192528d2c2521213aaa..7e5228b8368ab4b1b37a208b46bf08c1d8d8f6b7 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 0000000000000000000000000000000000000000..b0e4bc26f0c8d420970b1e5589f9f4c1082a0e36
--- /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 7d4d0010dcad982ba055bd09c3975e995869f728..5e9031ea57d17185df377cc3163680763b578bd5 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 da5331c4757f15bcb44e1958b15a0e5037131b10..a1bc11d102e4f64e9430ed027b20d6d69831a29f 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 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/tests/runall.py b/tests/runall.py
deleted file mode 100755
index 65fca039fb51c4e558d922f3d61ea6ec2b69ad28..0000000000000000000000000000000000000000
--- 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)