Skip to content

Commit

Permalink
Added spec command
Browse files Browse the repository at this point in the history
  • Loading branch information
paramite committed Sep 26, 2014
1 parent 7981cb9 commit 85de6a5
Show file tree
Hide file tree
Showing 7 changed files with 218 additions and 2 deletions.
7 changes: 6 additions & 1 deletion README
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@ b) run "bade sync"
a) do your updates in Puppetfile, commit changes in Puppetfile
b) run "bade sync" or "bade init --commit" if you want to generate a commit too

4. To generate SPEC file from Puppetfile and tag repo with "version-release" tag:
a) do step 3.
b) run "spec --version <version> --release <release> --old /path/to/current/file.spec --output /path/to/new/file.spec"


TO-DO:
- spec command for generating SPEC file from template
- spec command for generating SPEC file from template [DONE]
- spec command should parse patches from old file
- add command for adding modules
- rm command for removing modules
- unit tests
49 changes: 49 additions & 0 deletions bade/bade.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,18 @@
#

import click
import os

from . import commands
from . import utils


DEFAULT_OUTPUT = os.path.expanduser(
'~/rpmbuild/SPECS/openstack-puppet-modules.spec'
)
DEFAULT_TEMPLATE = 'openstack-puppet-modules.template'


# Setup option container
class Config(object):
def __init__(self):
Expand Down Expand Up @@ -100,5 +108,46 @@ def sync_wrapper(config, repo, commit):
raise


@bade.command('spec')
@click.option('--version', required=True,
help='Version for a tag.')
@click.option('--release', required=True,
help='Release for a tag.')
@click.option('--old', required=True,
help='Path to old SPEC file.')
@click.option('--output', default=DEFAULT_OUTPUT,
help='Path to output SPEC file.')
@click.option('--template', default=DEFAULT_TEMPLATE,
help='Path to template from which SPEC is generated.')
@click.argument('repo', default='.')
@pass_config
def sync_wrapper(config, repo, version, release, old, output,
template):
"""Generates SPEC file from Puppetfile and tags repo appropriately.
"""
try:
utils.shout(
'Generating SPEC file {0} from template {1}'.format(
output, template
),
verbose=config.verbose,
level='info'
)
commands.spec.command(config, repo, version, release, old,
output, template)
except utils.ExecutionError as ex:
utils.shout(ex, verbose=True, level='error')
utils.shout(
'====== stdout ======\n{stdout}\n'
'====== stderr ======\n{stderr}'.format(**ex.__dict__),
verbose=config.verbose,
level=None,
)
except Exception as ex:
utils.shout(ex, verbose=True, level='error')
if config.verbose:
raise


if __name__ == '__main__':
bade()
2 changes: 1 addition & 1 deletion bade/commands/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@

from . import init, sync
from . import init, sync, spec
108 changes: 108 additions & 0 deletions bade/commands/spec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*-

import codecs
import datetime
import jinja2
import os

from .. import utils
from . import init


# setup jinja environment
jinja_env = jinja2.Environment(
block_start_string='[@',
block_end_string='@]',
variable_start_string='[[',
variable_end_string=']]',
trim_blocks=True,
loader=jinja2.FileSystemLoader([
# bades built-in templates
os.path.join(
os.path.dirname(os.path.dirname(__file__)), 'templates'
),
# user's templates
os.path.join(
os.path.expanduser('~'), '.bade', 'templates'
)
])
)

def format_datetime(value):
return value.strftime('%a %b %d %Y')
jinja_env.filters['datetime'] = format_datetime


def format_global(value):
return value.replace('-', '_')
jinja_env.filters['global'] = format_global


def format_rjust(value, value_from, offset):
space = offset - len(value_from) + len(value)
return value.rjust(space)
jinja_env.filters['rjust'] = format_rjust


def command(config, repo, version, release, old, output, template):
"""Generates SPEC file from template and tags repo accordingly.
"""
puppetfile = utils.PuppetFile(repo)
puppetfile.load()

# fill required metadata to puppetfile
for module, info in puppetfile.items():
info['fullname'] = (
os.path.basename(info['git']).split('.', 1)[0]
)
for key, value in info.items():
info[key] = unicode(value)

# get changelog from old spec
_locals = locals()
rc, stdout, stderr = utils.execute(
'tail -n +$('
'grep -n -e "^%changelog" {old} | cut -d\':\' -f1'
') {old}'.format(**_locals),
can_fail=False
)
old_changelog = u'' if rc else stdout[len('%changelog'):]
old_changelog = old_changelog.decode('utf-8')

# get current date
current_date = datetime.datetime.today()

# get name and email from git repo
rc, stdout, stderr = utils.execute(
'cd {repo} && '
'git config --get user.name && '
'git config --get user.email'.format(**_locals)
)
user_name, user_email = stdout.strip().split('\n', 1)
user_name = user_name.decode('utf-8')
user_email = user_email.decode('utf-8')

# generate message for a tag
msg = '{0}-{1}\\n'.format(version, release)
for module, info in puppetfile.items():
msg += '{0}{1}\\n'.format(
module, format_rjust(info['commit'], module, 10)
)

# generate spec file
_locals = locals()
template_obj = jinja_env.get_template(template)
with codecs.open(os.path.abspath(output), 'wb', 'utf-8') as ofile:
ofile.write(template_obj.render(**_locals))

# tag repo
rc, stdout, stderr = utils.execute(
'cd {repo} && '
'git tag -a -m $\'{msg}\' {version}-{release}'.format(**_locals)
)
utils.shout(
'New tag {version}-{release} has been created in repo. Please run '
'"git push origin {version}-{release}" to upload tag to upstream'.format(**_locals),
verbose=True,
level='info'
)
50 changes: 50 additions & 0 deletions bade/templates/openstack-puppet-modules.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

[@ for item in puppetfile|dictsort @]
%global [[ item.0|global ]]_commit [[ item.1.commit|rjust(item.0, 16) ]]
[@ endfor @]

Name: openstack-puppet-modules
Version: [[ version ]]
Release: [[ release ]]%{?dist}
Summary: Set of Puppet modules used to deploy OpenStack
License: ASL 2.0 and GPLv2 and GPLv3
URL: https://github.com/redhat-openstack/openstack-puppet-modules

Source: https://github.com/redhat-openstack/openstack-puppet-modules/archive/%{version}-%{release}.tar.gz
BuildArch: noarch
Requires: rubygem-json

%description
A collection of Puppet modules used to install and configure OpenStack.


%prep
%setup 0

find %{_builddir}/%{name}-%{version}/ -type f -name ".*" -exec rm {} +
find %{_builddir}/%{name}-%{version}/ -size 0 -exec rm {} +
find %{_builddir}/%{name}-%{version}/ \( -name "*.pl" -o -name "*.sh" \) -exec chmod +x {} +
find %{_builddir}/%{name}-%{version}/ \( -name "*.pp" -o -name "*.py" \) -exec chmod -x {} +
find %{_builddir}/%{name}-%{version}/ \( -name "*.rb" -o -name "*.erb" \) -exec chmod -x {} + -exec sed -i "/^#!/{d;q}" {} +
find %{_builddir}/%{name}-%{version}/ \( -name spec -o -name ext \) | xargs rm -rf


%build


%install
rm -rf %{buildroot}
install -d -m 0755 %{buildroot}/%{_datadir}/openstack-puppet/modules/
[@ for item in puppetfile|dictsort @]
cp -r [[ item.1.fullname ]]-%{[[ item.0|global ]]_commit} %{buildroot}/%{_datadir}/openstack-puppet/modules/[[ item.0 ]]
[@ endfor @]


%files
%{_datadir}/openstack-puppet/modules/*


%changelog
* [[ current_date|datetime ]] [[ user_name ]] <[[ user_email ]]> - [[ version ]]-[[ release ]]
- Updated to release [[ version ]]-[[ release ]]
[[ old_changelog ]]
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
Click
jinja2
3 changes: 3 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,12 @@
setup(
name='Bade',
version='0.1',
author='Martin Magr',
author_email='[email protected]',
py_modules=['bade'],
install_requires=[
'Click',
'jinja2',
],
entry_points={
'console_scripts': [
Expand Down

0 comments on commit 85de6a5

Please sign in to comment.