diff --git a/changelog.txt b/changelog.txt index 4e5c1dd4..94c0ceba 100644 --- a/changelog.txt +++ b/changelog.txt @@ -4,6 +4,8 @@ jc changelog - Update airport_s parser to fix error on parsing empty data - Update arp parser to fix error on parsing empty data - Update blkid parser to fix error on parsing empty data +- Update crontab parser to fix error on parsing empty data +- Update crontab_u parser to fix error on parsing empty data - Add tests to all parsers for no data condition 20200610 v1.11.4 diff --git a/jc/parsers/crontab.py b/jc/parsers/crontab.py index b64e2281..2b581a25 100644 --- a/jc/parsers/crontab.py +++ b/jc/parsers/crontab.py @@ -132,7 +132,7 @@ import jc.parsers.universal class info(): - version = '1.2' + version = '1.3' description = 'crontab command and file parser' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -225,44 +225,45 @@ def parse(data, raw=False, quiet=False): # Clear any blank lines cleandata = list(filter(None, cleandata)) - # Clear any commented lines - for i, line in reversed(list(enumerate(cleandata))): - if line.strip().startswith('#'): - cleandata.pop(i) + if cleandata: + # Clear any commented lines + for i, line in reversed(list(enumerate(cleandata))): + if line.strip().startswith('#'): + cleandata.pop(i) - # Pop any variable assignment lines - cron_var = [] - for i, line in reversed(list(enumerate(cleandata))): - if '=' in line: - var_line = cleandata.pop(i) - var_name = var_line.split('=', maxsplit=1)[0].strip() - var_value = var_line.split('=', maxsplit=1)[1].strip() - cron_var.append({'name': var_name, - 'value': var_value}) + # Pop any variable assignment lines + cron_var = [] + for i, line in reversed(list(enumerate(cleandata))): + if '=' in line: + var_line = cleandata.pop(i) + var_name = var_line.split('=', maxsplit=1)[0].strip() + var_value = var_line.split('=', maxsplit=1)[1].strip() + cron_var.append({'name': var_name, + 'value': var_value}) - raw_output['variables'] = cron_var + raw_output['variables'] = cron_var - # Pop any shortcut lines - shortcut_list = [] - for i, line in reversed(list(enumerate(cleandata))): - if line.strip().startswith('@'): - shortcut_line = cleandata.pop(i) - occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@') - cmd = shortcut_line.split(maxsplit=1)[1].strip() - shortcut_list.append({'occurrence': occurrence, - 'command': cmd}) + # Pop any shortcut lines + shortcut_list = [] + for i, line in reversed(list(enumerate(cleandata))): + if line.strip().startswith('@'): + shortcut_line = cleandata.pop(i) + occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@') + cmd = shortcut_line.split(maxsplit=1)[1].strip() + shortcut_list.append({'occurrence': occurrence, + 'command': cmd}) - # Add header row for parsing - cleandata[:0] = ['minute hour day_of_month month day_of_week command'] + # Add header row for parsing + cleandata[:0] = ['minute hour day_of_month month day_of_week command'] - if len(cleandata) > 1: - cron_list = jc.parsers.universal.simple_table_parse(cleandata) + if len(cleandata) > 1: + cron_list = jc.parsers.universal.simple_table_parse(cleandata) - raw_output['schedule'] = cron_list + raw_output['schedule'] = cron_list - # Add shortcut entries back in - for item in shortcut_list: - raw_output['schedule'].append(item) + # Add shortcut entries back in + for item in shortcut_list: + raw_output['schedule'].append(item) if raw: return raw_output diff --git a/jc/parsers/crontab_u.py b/jc/parsers/crontab_u.py index 6487cf3e..64ce9e81 100644 --- a/jc/parsers/crontab_u.py +++ b/jc/parsers/crontab_u.py @@ -133,7 +133,7 @@ import jc.parsers.universal class info(): - version = '1.1' + version = '1.2' description = 'crontab file parser with user support' author = 'Kelly Brazil' author_email = 'kellyjonbrazil@gmail.com' @@ -226,46 +226,47 @@ def parse(data, raw=False, quiet=False): # Clear any blank lines cleandata = list(filter(None, cleandata)) - # Clear any commented lines - for i, line in reversed(list(enumerate(cleandata))): - if line.strip().startswith('#'): - cleandata.pop(i) + if cleandata: + # Clear any commented lines + for i, line in reversed(list(enumerate(cleandata))): + if line.strip().startswith('#'): + cleandata.pop(i) - # Pop any variable assignment lines - cron_var = [] - for i, line in reversed(list(enumerate(cleandata))): - if '=' in line: - var_line = cleandata.pop(i) - var_name = var_line.split('=', maxsplit=1)[0].strip() - var_value = var_line.split('=', maxsplit=1)[1].strip() - cron_var.append({'name': var_name, - 'value': var_value}) + # Pop any variable assignment lines + cron_var = [] + for i, line in reversed(list(enumerate(cleandata))): + if '=' in line: + var_line = cleandata.pop(i) + var_name = var_line.split('=', maxsplit=1)[0].strip() + var_value = var_line.split('=', maxsplit=1)[1].strip() + cron_var.append({'name': var_name, + 'value': var_value}) - raw_output['variables'] = cron_var + raw_output['variables'] = cron_var - # Pop any shortcut lines - shortcut_list = [] - for i, line in reversed(list(enumerate(cleandata))): - if line.strip().startswith('@'): - shortcut_line = cleandata.pop(i) - occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@') - usr = shortcut_line.split(maxsplit=2)[1].strip() - cmd = shortcut_line.split(maxsplit=2)[2].strip() - shortcut_list.append({'occurrence': occurrence, - 'user': usr, - 'command': cmd}) + # Pop any shortcut lines + shortcut_list = [] + for i, line in reversed(list(enumerate(cleandata))): + if line.strip().startswith('@'): + shortcut_line = cleandata.pop(i) + occurrence = shortcut_line.split(maxsplit=1)[0].strip().lstrip('@') + usr = shortcut_line.split(maxsplit=2)[1].strip() + cmd = shortcut_line.split(maxsplit=2)[2].strip() + shortcut_list.append({'occurrence': occurrence, + 'user': usr, + 'command': cmd}) - # Add header row for parsing - cleandata[:0] = ['minute hour day_of_month month day_of_week user command'] + # Add header row for parsing + cleandata[:0] = ['minute hour day_of_month month day_of_week user command'] - if len(cleandata) > 1: - cron_list = jc.parsers.universal.simple_table_parse(cleandata) + if len(cleandata) > 1: + cron_list = jc.parsers.universal.simple_table_parse(cleandata) - raw_output['schedule'] = cron_list + raw_output['schedule'] = cron_list - # Add shortcut entries back in - for item in shortcut_list: - raw_output['schedule'].append(item) + # Add shortcut entries back in + for item in shortcut_list: + raw_output['schedule'].append(item) if raw: return raw_output diff --git a/tests/test_crontab.py b/tests/test_crontab.py index 176f1de2..f40650d2 100644 --- a/tests/test_crontab.py +++ b/tests/test_crontab.py @@ -17,6 +17,12 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/crontab.json'), 'r', encoding='utf-8') as f: self.centos_7_7_crontab_json = json.loads(f.read()) + def test_crontab_nodata(self): + """ + Test 'crontab' with no data + """ + self.assertEqual(jc.parsers.crontab.parse('', quiet=True), {}) + def test_crontab_centos_7_7(self): """ Test 'crontab' on Centos 7.7 diff --git a/tests/test_crontab_u.py b/tests/test_crontab_u.py index 5e5f83b7..ca36e7bc 100644 --- a/tests/test_crontab_u.py +++ b/tests/test_crontab_u.py @@ -23,6 +23,12 @@ class MyTests(unittest.TestCase): with open(os.path.join(THIS_DIR, os.pardir, 'tests/fixtures/centos-7.7/crontab-u.json'), 'r', encoding='utf-8') as f: self.centos_7_7_crontab_u_json = json.loads(f.read()) + def test_crontab_u_nodata(self): + """ + Test 'crontab' with no data (has a user field) + """ + self.assertEqual(jc.parsers.crontab_u.parse('', quiet=True), {}) + def test_crontab_u_ubuntu_18_4(self): """ Test 'crontab' on Ubuntu 18.4 (has a user field)