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)