Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a build_source module #178

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 97 additions & 0 deletions obal/data/modules/build_source.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
"""
Build a source package
"""

import os
import re
from contextlib import contextmanager
from glob import glob
from subprocess import CalledProcessError, check_output

from ansible.module_utils.basic import AnsibleModule


@contextmanager
def chdir(directory):
"""
Change the directory in a context manager. Automatically switches back even if an exception
occurs.
"""
old = os.getcwd()
os.chdir(directory)
try:
yield
finally:
os.chdir(old)


def main():
"""
Build a source package
"""
module = AnsibleModule(
argument_spec=dict(
directory=dict(required=True),
)
)

directory = module.params['directory']
path = None

with chdir(directory):
if os.path.exists(os.path.join(directory, 'Rakefile.dist')):
try:
output = check_output(['rake', '-f', 'Rakefile.dist', 'pkg:generate_source'],
universal_newlines=True).rstrip()
except CalledProcessError as error:
module.fail_json(msg='Failed to build using Rakefile.dist',
stdout=error.stdout, stderr=error.stderr)
if not output:
module.fail_json(msg='Failed to determine the output file')
path = output.splitlines()[-1]
elif glob(os.path.join(directory, '*.gemspec')):
gemspecs = glob(os.path.join(directory, '*.gemspec'))
if len(gemspecs) != 1:
gemspec = os.path.join(directory, os.path.basename(directory) + '.gemspec')
if gemspec not in gemspecs:
module.fail_json(msg='Multiple gemspecs found', gemspecs=gemspecs)
else:
gemspec = gemspecs[0]

try:
# TODO: use --output to set the path?
output = check_output(['gem', 'build', gemspec], universal_newlines=True)
except CalledProcessError as error:
module.fail_json(msg='Failed to build gemspec', gemspec=gemspec,
stdout=error.stdout, stderr=error.stderr)

match = re.search(r'File: (?P<path>.+\.gem)', output)
if not match:
module.fail_json(msg='Failed to determine gem file from output', output=output,
gemspec=gemspec)
path = match.group('path')
elif os.path.exists('Rakefile'):
# TODO: bundle install?
try:
output = check_output(['bundle', 'exec', 'rake', 'pkg:generate_source'],
universal_newlines=True).rstrip()
except CalledProcessError as error:
module.fail_json(msg='Failed to build using Rakefile.dist',
stdout=error.stdout, stderr=error.stderr)
if not output:
module.fail_json(msg='Failed to determine the output file')
path = output.splitlines()[-1]
else:
module.fail_json(msg='Unsupported package directory')

if not os.path.isabs(path):
path = os.path.join(directory, path)

if not os.path.exists(path):
module.fail_json(msg="Determined path doesn't exist", path=path)

module.exit_json(changed=path is not None, path=path)


if __name__ == '__main__':
main()