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

Convert process_func_test_pr.py to a module #183

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
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
Original file line number Diff line number Diff line change
@@ -1,29 +1,42 @@
#!/usr/bin/env python3

import argparse
import base64
import os
import hashlib
import pathlib
import re
import requests
import sys
from urllib.parse import urlparse

from ansible.module_utils.basic import AnsibleModule

def parse_args(args):
"""Parse command line arguments.
__metaclass__ = type

:param args: Command arguments
:type list: [str1, str2,...] List of command line arguments
:returns: Parsed arguments
:rtype: Namespace
"""
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file', action='append',
help='File to update',
required=True)
parser.add_argument('commit_message', type=str,
help='Commit message to process')
return parser.parse_args(args)
DOCUMENTATION = r'''
---
module: process_commit_msg

short_description: Read commit message and perform any actions
'''

EXAMPLES = r'''
# Update requrements files based on commit message
- name: Process commit message
process_commit_msg:
commit_message: "{{ zm.content }}"
files:
- /home/ubuntu/charm-mycharm/test-requirements.txt
- /home/ubuntu/charm-mycharm/src/test-requirements.txt
'''

RETURN = r'''
# Example of possible return value
message:
description: The output message that the test module generates.
type: str
returned: always
sample: 'Updated Files: /home/ubuntu/charm-mycharm/test-requirements.txt'
'''


def extract_lines(commit_message, match_pattern):
Expand Down Expand Up @@ -117,10 +130,74 @@ def process_commit(encoded_commit_message, files):
func(commit_message, files)


def get_file_hash(file_loc):
"""Calculate a hash for the file contents.

:param files: File path
:type files: pathlib.Path
:returns: File hash
:rtype: str
"""
return hashlib.md5(file_loc.read_bytes()).hexdigest()


def get_files_hashes(files):
"""Calculate a has for the contents of each file.

:param files: List of file names.
:type files: List[str]
:returns: File hashes
:rtype: Dict[str]
"""
hashes = {}
for f in files:
file_loc = pathlib.Path(f)
if file_loc.exists():
hashes[f] = get_file_hash(file_loc)
return hashes


def run_module():
module_args = dict(
files=dict(type='list', required=True),
commit_message=dict(type='str', required=True)
)

result = dict(
changed=False,
message=''
)

module = AnsibleModule(
argument_spec=module_args,
supports_check_mode=True
)

if module.check_mode:
module.exit_json(**result)

old_hashes = get_files_hashes(module.params['files'])

process_commit(
module.params['commit_message'],
module.params['files'])

new_hashes = get_files_hashes(module.params['files'])
changed_files = [f for f, h in old_hashes.items() if h != new_hashes[f]]

if changed_files:
result['changed'] = True
result['message'] = 'Updated Files: {}'.format(','.join(changed_files))
else:
result['changed'] = False
result['message'] = 'No files updated'

module.exit_json(**result)


def main():
args = parse_args(sys.argv[1:])
process_commit(args.commit_message, args.file)
run_module()


if __name__ == '__main__':
sys.exit(main())
main()
34 changes: 8 additions & 26 deletions roles/handle-func-test-pr/tasks/main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,29 +3,11 @@
set_fact:
charm_name: "{{ zuul.project.short_name | replace('charm-', '') }}"

- name: Create temporary directory
when: zuul.message is defined
tempfile:
state: directory
register: tmp_dir

- name: Copy over process_func_test_pr.py
when: zuul.message is defined
copy:
src: "process_func_test_pr.py"
dest: "{{ tmp_dir.path }}/process_func_test_pr.py"
mode: '0500'

- name: Run process_func_test_pr.py
when: zuul.message is defined
args:
executable: /bin/bash
shell: |
set -o pipefail
{{ tmp_dir.path }}/process_func_test_pr.py \
-f "{{ zuul.project.src_dir }}/test-requirements.txt" \
-f "{{ zuul.project.src_dir }}/src/test-requirements.txt" \
-f "{{ zuul.project.src_dir }}/build/builds/{{ charm_name }}/test-requirements.txt" \
{{ zuul.message }}


- name: Process commit message
when: zuul.message is defined
process_commit_msg:
commit_message: "{{ zuul.message }}"
files:
- "{{ zuul.project.src_dir }}/test-requirements.txt"
- "{{ zuul.project.src_dir }}/src/test-requirements.txt"
- "{{ zuul.project.src_dir }}/build/builds/{{ charm_name }}/test-requirements.txt"
1 change: 1 addition & 0 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -71,5 +71,6 @@ deps =
os-testr>0.4.1
mock
requests
ansible
basepython = python3
commands = ostestr {posargs}
2 changes: 1 addition & 1 deletion unit_tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@

import sys

sys.path.append('roles/handle-func-test-pr/files/')
sys.path.append('roles/handle-func-test-pr/library')
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import tempfile
import unittest

import process_func_test_pr
import process_commit_msg

TEST_MESSAGE = """
Update to build using charmcraft
Expand Down Expand Up @@ -66,23 +66,15 @@

class TestProcessFuncTestPR(unittest.TestCase):

def test_parser(self):
args = process_func_test_pr.parse_args([
'-f', 'file1',
'-f', 'file2',
'My Message'])
self.assertEqual(args.file, ['file1', 'file2'])
self.assertEqual(args.commit_message, 'My Message')

def test_extract_lines(self):
self.assertEqual(
process_func_test_pr.extract_lines(TEST_MESSAGE, 'Im not there'),
process_commit_msg.extract_lines(TEST_MESSAGE, 'Im not there'),
[])
self.assertEqual(
process_func_test_pr.extract_lines(TEST_MESSAGE, 'Change-Id'),
process_commit_msg.extract_lines(TEST_MESSAGE, 'Change-Id'),
["Change-Id: Iadd11634d1fe44731ecf0a6104561b4aeebff23f"])
self.assertEqual(
process_func_test_pr.extract_lines(
process_commit_msg.extract_lines(
TEST_MESSAGE,
r'.*(Unit test fi|add a build).*'),
['- add a build-requirements.txt',
Expand All @@ -93,7 +85,7 @@ def test_apply_updates(self):
file1 = '{}/file1.txt'.format(tmpdirname)
with open(file1, 'w') as f:
f.write("Yo, hit me with some biscuits and gravy")
process_func_test_pr.apply_updates(
process_commit_msg.apply_updates(
[
('Im not there', 'foo'),
('Yo,', 'Good morning,'),
Expand All @@ -108,7 +100,7 @@ def test_apply_updates(self):
('Good morning, please may I have a savoury scone with '
'Béchamel sauce'))

@mock.patch.object(process_func_test_pr.requests, 'get')
@mock.patch.object(process_commit_msg.requests, 'get')
def _test_process_func_test_pr(self, locations, mock_get):
with tempfile.TemporaryDirectory() as tmpdirname:
def fake_get(url):
Expand All @@ -120,7 +112,7 @@ def fake_get(url):
file1 = '{}/file1.txt'.format(tmpdirname)
with open(file1, 'w') as f:
f.write(locations)
process_func_test_pr.process_func_test_pr(
process_commit_msg.process_func_test_pr(
TEST_MESSAGE,
[file1])
with open(file1, 'r') as f:
Expand Down