summaryrefslogtreecommitdiffstats
path: root/gitautodeploy/cli
diff options
context:
space:
mode:
authorOliver Poignant <oliver@poignant.se>2016-05-04 16:09:22 +0200
committerOliver Poignant <oliver@poignant.se>2016-05-04 16:09:22 +0200
commitcd93746bc96a30e2582092d95fca5bcfe74090e3 (patch)
tree2aa04bae68b92fb29dc15d57a37983682956dfda /gitautodeploy/cli
parent8ffdd1428e8969ab813f1008915a237377ae1e25 (diff)
downloadGit-Auto-Deploy-cd93746bc96a30e2582092d95fca5bcfe74090e3.zip
Git-Auto-Deploy-cd93746bc96a30e2582092d95fca5bcfe74090e3.tar.gz
Git-Auto-Deploy-cd93746bc96a30e2582092d95fca5bcfe74090e3.tar.bz2
Separating config parsing from main application
Diffstat (limited to 'gitautodeploy/cli')
-rw-r--r--gitautodeploy/cli/config.py299
1 files changed, 297 insertions, 2 deletions
diff --git a/gitautodeploy/cli/config.py b/gitautodeploy/cli/config.py
index 332b03e..84c79c9 100644
--- a/gitautodeploy/cli/config.py
+++ b/gitautodeploy/cli/config.py
@@ -1,4 +1,299 @@
+def get_config_defaults():
+ """Get the default configuration values."""
+ config = {}
+ config['quiet'] = False
+ config['daemon-mode'] = False
+ config['config'] = None
+ config['ssh-keygen'] = False
+ config['force'] = False
+ config['ssl'] = False
+ config['ssl-pem-file'] = '~/.gitautodeploy.pem'
+ config['pidfilepath'] = '~/.gitautodeploy.pid'
+ config['logfilepath'] = None
+ config['host'] = '0.0.0.0'
+ config['port'] = 8001
-def generate_config():
- print "Generating config" \ No newline at end of file
+ return config
+
+def get_config_from_environment():
+ """Get configuration values provided as environment variables."""
+ import os
+
+ config = {}
+
+ if 'GAD_QUIET' in os.environ:
+ config['quiet'] = True
+
+ if 'GAD_DAEMON_MODE' in os.environ:
+ config['daemon-mode'] = True
+
+ if 'GAD_CONFIG' in os.environ:
+ config['config'] = os.environ['GAD_CONFIG']
+
+ if 'GAD_SSH_KEYGEN' in os.environ:
+ config['ssh-keygen'] = True
+
+ if 'GAD_FORCE' in os.environ:
+ config['force'] = True
+
+ if 'GAD_SSL' in os.environ:
+ config['ssl'] = True
+
+ if 'GADGAD_SSL_PEM_FILE_SSL' in os.environ:
+ config['ssl-pem-file'] = os.environ['GAD_SSL_PEM_FILE']
+
+ if 'GAD_PID_FILE' in os.environ:
+ config['pidfilepath'] = os.environ['GAD_PID_FILE']
+
+ if 'GAD_LOG_FILE' in os.environ:
+ config['logfilepath'] = os.environ['GAD_LOG_FILE']
+
+ if 'GAD_HOST' in os.environ:
+ config['host'] = os.environ['GAD_HOST']
+
+ if 'GAD_PORT' in os.environ:
+ config['port'] = int(os.environ['GAD_PORT'])
+
+ return config
+
+def get_config_from_argv(argv):
+ import argparse
+
+ parser = argparse.ArgumentParser()
+
+ parser.add_argument("-d", "--daemon-mode",
+ help="run in background (daemon mode)",
+ dest="daemon-mode",
+ action="store_true")
+
+ parser.add_argument("-q", "--quiet",
+ help="supress console output",
+ dest="quiet",
+ action="store_true")
+
+ parser.add_argument("-c", "--config",
+ help="custom configuration file",
+ dest="config",
+ type=str)
+
+ parser.add_argument("--ssh-keygen",
+ help="scan repository hosts for ssh keys",
+ dest="ssh-keygen",
+ action="store_true")
+
+ parser.add_argument("--force",
+ help="kill any process using the configured port",
+ dest="force",
+ action="store_true")
+
+ parser.add_argument("--pid-file",
+ help="specify a custom pid file",
+ dest="pidfilepath",
+ type=str)
+
+ parser.add_argument("--log-file",
+ help="specify a log file",
+ dest="logfilepath",
+ type=str)
+
+ parser.add_argument("--host",
+ help="address to bind to",
+ dest="host",
+ type=str)
+
+ parser.add_argument("--port",
+ help="port to bind to",
+ dest="port",
+ type=int)
+
+ parser.add_argument("--ssl",
+ help="use ssl",
+ dest="ssl",
+ action="store_true")
+
+ parser.add_argument("--ssl-pem",
+ help="path to ssl pem file",
+ dest="ssl-pem",
+ type=str)
+
+ config = vars(parser.parse_args(argv))
+
+ # Delete entries for unprovided arguments
+ del_keys = []
+ for key in config:
+ if config[key] is None:
+ del_keys.append(key)
+
+ for key in del_keys:
+ del config[key]
+
+ return config
+
+def find_config_file(target_directories=None):
+ """Attempt to find a path to a config file. Provided paths are scanned
+ for *.conf(ig)?.json files."""
+ import os
+ import re
+ import logging
+ logger = logging.getLogger()
+
+ if not target_directories:
+ return
+
+ # Remove duplicates
+ target_directories = list(set(target_directories))
+
+ # Look for a *conf.json or *config.json
+ for dir in target_directories:
+
+ if not os.access(dir, os.R_OK):
+ continue
+
+ for item in os.listdir(dir):
+ if re.match(r".*conf(ig)?\.json$", item):
+ path = os.path.realpath(os.path.join(dir, item))
+ logger.info("Using '%s' as config" % path)
+ return path
+
+def get_config_from_file(path):
+ """Get configuration values from config file."""
+ import logging
+ import os
+ logger = logging.getLogger()
+
+ config_file_path = os.path.realpath(path)
+ logger.info('Using custom configuration file \'%s\'' % config_file_path)
+
+ # Read config data from json file
+ if config_file_path:
+ config_data = read_json_file(config_file_path)
+ else:
+ logger.info('No configuration file found or specified. Using default values.')
+ config_data = {}
+
+ return config_data
+
+def read_json_file(file_path):
+ import json
+ import logging
+ import re
+ logger = logging.getLogger()
+
+ try:
+ json_string = open(file_path).read()
+
+ except Exception as e:
+ logger.critical("Could not load %s file\n" % file_path)
+ raise e
+
+ try:
+ # Remove commens from JSON (makes sample config options easier)
+ regex = r'\s*(#|\/{2}).*$'
+ regex_inline = r'(:?(?:\s)*([A-Za-z\d\.{}]*)|((?<=\").*\"),?)(?:\s)*(((#|(\/{2})).*)|)$'
+ lines = json_string.split('\n')
+
+ for index, line in enumerate(lines):
+ if re.search(regex, line):
+ if re.search(r'^' + regex, line, re.IGNORECASE):
+ lines[index] = ""
+ elif re.search(regex_inline, line):
+ lines[index] = re.sub(regex_inline, r'\1', line)
+
+ data = json.loads('\n'.join(lines))
+
+ except Exception as e:
+ logger.critical("%s file is not valid JSON\n" % file_path)
+ raise e
+
+ return data
+
+def init_config(config):
+ """Initialize config by filling out missing values etc."""
+
+ import os
+ import re
+ import logging
+ logger = logging.getLogger()
+
+ # Translate any ~ in the path into /home/<user>
+ if 'pidfilepath' in config:
+ config['pidfilepath'] = os.path.expanduser(config['pidfilepath'])
+
+ if 'logfilepath' in config:
+ config['logfilepath'] = os.path.expanduser(config['logfilepath'])
+
+ if 'repositories' not in config:
+ config['repositories'] = []
+
+ for repo_config in config['repositories']:
+
+ # Setup branch if missing
+ if 'branch' not in repo_config:
+ repo_config['branch'] = "master"
+
+ # Setup remote if missing
+ if 'remote' not in repo_config:
+ repo_config['remote'] = "origin"
+
+ # Setup deploy commands list if not present
+ if 'deploy_commands' not in repo_config:
+ repo_config['deploy_commands'] = []
+
+ # Check if any global pre deploy commands is specified
+ if 'global_deploy' in config and len(config['global_deploy'][0]) is not 0:
+ repo_config['deploy_commands'].insert(0, config['global_deploy'][0])
+
+ # Check if any repo specific deploy command is specified
+ if 'deploy' in repo_config:
+ repo_config['deploy_commands'].append(repo_config['deploy'])
+
+ # Check if any global post deploy command is specified
+ if 'global_deploy' in config and len(config['global_deploy'][1]) is not 0:
+ repo_config['deploy_commands'].append(config['global_deploy'][1])
+
+ # If a Bitbucket repository is configured using the https:// URL, a username is usually
+ # specified in the beginning of the URL. To be able to compare configured Bitbucket
+ # repositories with incoming web hook events, this username needs to be stripped away in a
+ # copy of the URL.
+ if 'url' in repo_config and 'bitbucket_username' not in repo_config:
+ regexp = re.search(r"^(https?://)([^@]+)@(bitbucket\.org/)(.+)$", repo_config['url'])
+ if regexp:
+ repo_config['url_without_usernme'] = regexp.group(1) + regexp.group(3) + regexp.group(4)
+
+ # Translate any ~ in the path into /home/<user>
+ if 'path' in repo_config:
+ repo_config['path'] = os.path.expanduser(repo_config['path'])
+
+ return config
+
+def get_repo_config_from_environment():
+ """Look for repository config in any defined environment variables. If
+ found, import to main config."""
+ import logging
+ import os
+
+ if 'GAD_REPO_URL' not in os.environ:
+ return
+
+ logger = logging.getLogger()
+
+ repo_config = {
+ 'url': os.environ['GAD_REPO_URL']
+ }
+
+ logger.info("Added configuration for '%s' found in environment variables" % os.environ['GAD_REPO_URL'])
+
+ if 'GAD_REPO_BRANCH' in os.environ:
+ repo_config['branch'] = os.environ['GAD_REPO_BRANCH']
+
+ if 'GAD_REPO_REMOTE' in os.environ:
+ repo_config['remote'] = os.environ['GAD_REPO_REMOTE']
+
+ if 'GAD_REPO_PATH' in os.environ:
+ repo_config['path'] = os.environ['GAD_REPO_PATH']
+
+ if 'GAD_REPO_DEPLOY' in os.environ:
+ repo_config['deploy'] = os.environ['GAD_REPO_DEPLOY']
+
+ return repo_config \ No newline at end of file