cmd: Add a config file fallback to the user's home directory

The system-global path of

    /etc/jenkins_jobs/jenkins_jobs.ini

is not applicable on Windows. To solve that, and as Linux users would
benefit from a per-user configuration file, too, introduce a fallback at

    ~/.config/jenkins_jobs/jenkins_jobs.ini

following the XDG Base Directory Specification. Try to use that per-user
file if no configuration file is given on the command line and none is
present in the script directory for development purposes.

Change-Id: I1a22454999ee8ac60d6f22545850c33aa03bb29b
This commit is contained in:
Sebastian Schuberth 2015-10-20 17:12:31 +02:00
parent 1778d1037a
commit dbe63dd9d2
3 changed files with 43 additions and 8 deletions

View File

@ -2,10 +2,10 @@ Configuration File
------------------
After installation, you will need to create a configuration file. By
default, ``jenkins-jobs`` looks in
``/etc/jenkins_jobs/jenkins_jobs.ini`` but you may specify an
alternative location when running ``jenkins-jobs``. The file should have
the following format:
default, ``jenkins-jobs`` looks for ``~/.config/jenkins_jobs/jenkins_jobs.ini``,
``<script directory>/jenkins_jobs.ini`` or ``/etc/jenkins_jobs/jenkins_jobs.ini``
(in that order), but you may specify an alternative location when running
``jenkins-jobs``. The file should have the following format:
.. literalinclude:: ../../etc/jenkins_jobs.ini-sample
:language: ini

View File

@ -179,17 +179,28 @@ def main(argv=None):
execute(options, config)
def setup_config_settings(options):
def get_config_file(options):
# Initialize with the global fallback location for the config.
conf = '/etc/jenkins_jobs/jenkins_jobs.ini'
if options.conf:
conf = options.conf
else:
# Fallback to script directory
# Allow a script directory config to override.
localconf = os.path.join(os.path.dirname(__file__),
'jenkins_jobs.ini')
if os.path.isfile(localconf):
conf = localconf
# Allow a user directory config to override.
userconf = os.path.join(os.path.expanduser('~'), '.config',
'jenkins_jobs', 'jenkins_jobs.ini')
if os.path.isfile(userconf):
conf = userconf
return conf
def setup_config_settings(options):
conf = get_config_file(options)
config = configparser.ConfigParser()
# Load default config always
config.readfp(StringIO(DEFAULT_CONF))

View File

@ -6,11 +6,11 @@ import jenkins
from jenkins_jobs import cmd
from jenkins_jobs.errors import JenkinsJobsException
from mock import patch
from tests.base import mock
from tests.cmd.test_cmd import CmdTestsBase
from tests.cmd.test_recurse_path import fake_os_walk
os_walk_return_values = {
'/jjb_projects': [
('/jjb_projects', (['dir1', 'dir2', 'dir3'], ())),
@ -43,6 +43,30 @@ def os_walk_side_effects(path_name, topdown):
return fake_os_walk(os_walk_return_values[path_name])(path_name, topdown)
@mock.patch('jenkins_jobs.builder.Jenkins.get_plugins_info', mock.MagicMock)
class TestConfigs(CmdTestsBase):
def test_use_global_config(self):
"""
Verify that JJB uses the global config file by default
"""
args = self.parser.parse_args(['test', 'foo'])
self.assertEqual(cmd.get_config_file(args),
'/etc/jenkins_jobs/jenkins_jobs.ini')
def test_use_config_in_user_home(self):
"""
Verify that JJB uses config file in user home folder
"""
args = self.parser.parse_args(['test', 'foo'])
# args.output_dir = mock.MagicMock()
# mock_isfile.side_effect = True
expected_loc = os.path.join(os.path.expanduser('~'), '.config',
'jenkins_jobs', 'jenkins_jobs.ini')
with patch('os.path.isfile', return_value=True):
self.assertEqual(cmd.get_config_file(args), expected_loc)
@mock.patch('jenkins_jobs.builder.Jenkins.get_plugins_info', mock.MagicMock)
class TestTests(CmdTestsBase):