When scanning a given branch, we don't want to stop at the base of the
current branch, we want to stop at the base of the *previous* branch on
master. That pulls in the full history of the current branch from where
the older branch diverged.
Given this history:
  (master)
     |
   1.0.0
     | \  (stable/a)
     |  \
     |   1.0.1
   2.0.0
     |
   2.0.1
     | \ (stable/b)
     |  \
     |   2.0.2
   2.1.0
The notes for stable/b branch should include versions 2.0.2, 2.0.1, and
2.0.0 (which is on master) but not 1.0.0 which is the previous release.
Change-Id: If1feddadc1a8e24b163667cd84f5b9e098951c69
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
		
	
		
			
				
	
	
		
			1869 lines
		
	
	
		
			65 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			1869 lines
		
	
	
		
			65 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
						|
# not use this file except in compliance with the License. You may obtain
 | 
						|
# a copy of the License at
 | 
						|
#
 | 
						|
#      http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing, software
 | 
						|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
						|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 | 
						|
# License for the specific language governing permissions and limitations
 | 
						|
# under the License.
 | 
						|
 | 
						|
from __future__ import unicode_literals
 | 
						|
 | 
						|
import itertools
 | 
						|
import logging
 | 
						|
import os.path
 | 
						|
import re
 | 
						|
import subprocess
 | 
						|
import time
 | 
						|
import unittest
 | 
						|
 | 
						|
from dulwich import diff_tree
 | 
						|
from dulwich import objects
 | 
						|
import fixtures
 | 
						|
import mock
 | 
						|
from testtools.content import text_content
 | 
						|
 | 
						|
from reno import config
 | 
						|
from reno import create
 | 
						|
from reno import scanner
 | 
						|
from reno.tests import base
 | 
						|
from reno import utils
 | 
						|
 | 
						|
 | 
						|
_SETUP_TEMPLATE = """
 | 
						|
import setuptools
 | 
						|
try:
 | 
						|
    import multiprocessing  # noqa
 | 
						|
except ImportError:
 | 
						|
    pass
 | 
						|
 | 
						|
setuptools.setup(
 | 
						|
    setup_requires=['pbr'],
 | 
						|
    pbr=True)
 | 
						|
"""
 | 
						|
 | 
						|
_CFG_TEMPLATE = """
 | 
						|
[metadata]
 | 
						|
name = testpkg
 | 
						|
summary = Test Package
 | 
						|
 | 
						|
[files]
 | 
						|
packages =
 | 
						|
    testpkg
 | 
						|
"""
 | 
						|
 | 
						|
 | 
						|
class GPGKeyFixture(fixtures.Fixture):
 | 
						|
    """Creates a GPG key for testing.
 | 
						|
 | 
						|
    It's recommended that this be used in concert with a unique home
 | 
						|
    directory.
 | 
						|
    """
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(GPGKeyFixture, self).setUp()
 | 
						|
        tempdir = self.useFixture(fixtures.TempDir())
 | 
						|
        gnupg_version_re = re.compile('^gpg\s.*\s([\d+])\.([\d+])\.([\d+])')
 | 
						|
        gnupg_version = utils.check_output(['gpg', '--version'],
 | 
						|
                                           cwd=tempdir.path)
 | 
						|
        for line in gnupg_version.split('\n'):
 | 
						|
            gnupg_version = gnupg_version_re.match(line)
 | 
						|
            if gnupg_version:
 | 
						|
                gnupg_version = (int(gnupg_version.group(1)),
 | 
						|
                                 int(gnupg_version.group(2)),
 | 
						|
                                 int(gnupg_version.group(3)))
 | 
						|
                break
 | 
						|
        else:
 | 
						|
            if gnupg_version is None:
 | 
						|
                gnupg_version = (0, 0, 0)
 | 
						|
        config_file = tempdir.path + '/key-config'
 | 
						|
        f = open(config_file, 'wt')
 | 
						|
        try:
 | 
						|
            if gnupg_version[0] == 2 and gnupg_version[1] >= 1:
 | 
						|
                f.write("""
 | 
						|
                %no-protection
 | 
						|
                %transient-key
 | 
						|
                """)
 | 
						|
            f.write("""
 | 
						|
            %no-ask-passphrase
 | 
						|
            Key-Type: RSA
 | 
						|
            Name-Real: Example Key
 | 
						|
            Name-Comment: N/A
 | 
						|
            Name-Email: example@example.com
 | 
						|
            Expire-Date: 2d
 | 
						|
            Preferences: (setpref)
 | 
						|
            %commit
 | 
						|
            """)
 | 
						|
        finally:
 | 
						|
            f.close()
 | 
						|
        # Note that --quick-random (--debug-quick-random in GnuPG 2.x)
 | 
						|
        # does not have a corresponding preferences file setting and
 | 
						|
        # must be passed explicitly on the command line instead
 | 
						|
        if gnupg_version[0] == 1:
 | 
						|
            gnupg_random = '--quick-random'
 | 
						|
        elif gnupg_version[0] >= 2:
 | 
						|
            gnupg_random = '--debug-quick-random'
 | 
						|
        else:
 | 
						|
            gnupg_random = ''
 | 
						|
        cmd = ['gpg', '--gen-key', '--batch']
 | 
						|
        if gnupg_random:
 | 
						|
            cmd.append(gnupg_random)
 | 
						|
        cmd.append(config_file)
 | 
						|
        subprocess.check_call(
 | 
						|
            cmd,
 | 
						|
            cwd=tempdir.path,
 | 
						|
            # Direct stderr to its own pipe, from which we don't read,
 | 
						|
            # to quiet the commands.
 | 
						|
            stderr=subprocess.PIPE,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class GitRepoFixture(fixtures.Fixture):
 | 
						|
 | 
						|
    logger = logging.getLogger('git')
 | 
						|
 | 
						|
    def __init__(self, reporoot):
 | 
						|
        self.reporoot = reporoot
 | 
						|
        super(GitRepoFixture, self).__init__()
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(GitRepoFixture, self).setUp()
 | 
						|
        self.useFixture(GPGKeyFixture())
 | 
						|
        os.makedirs(self.reporoot)
 | 
						|
        self.git('init', '.')
 | 
						|
        self.git('config', '--local', 'user.email', 'example@example.com')
 | 
						|
        self.git('config', '--local', 'user.name', 'reno developer')
 | 
						|
        self.git('config', '--local', 'user.signingkey',
 | 
						|
                 'example@example.com')
 | 
						|
 | 
						|
    def git(self, *args):
 | 
						|
        self.logger.debug('$ git %s', ' '.join(args))
 | 
						|
        output = utils.check_output(
 | 
						|
            ['git'] + list(args),
 | 
						|
            cwd=self.reporoot,
 | 
						|
        )
 | 
						|
        self.logger.debug(output)
 | 
						|
        return output
 | 
						|
 | 
						|
    def commit(self, message='commit message'):
 | 
						|
        self.git('add', '.')
 | 
						|
        self.git('commit', '-m', message)
 | 
						|
        self.git('show', '--pretty=format:%H')
 | 
						|
        time.sleep(0.1)  # force a delay between commits
 | 
						|
 | 
						|
    def add_file(self, name):
 | 
						|
        with open(os.path.join(self.reporoot, name), 'w') as f:
 | 
						|
            f.write('adding %s\n' % name)
 | 
						|
        self.commit('add %s' % name)
 | 
						|
 | 
						|
 | 
						|
class Base(base.TestCase):
 | 
						|
 | 
						|
    logger = logging.getLogger('test')
 | 
						|
 | 
						|
    def _add_notes_file(self, slug='slug', commit=True, legacy=False,
 | 
						|
                        contents='i-am-also-a-template'):
 | 
						|
        n = self.get_note_num()
 | 
						|
        if legacy:
 | 
						|
            basename = '%016x-%s.yaml' % (n, slug)
 | 
						|
        else:
 | 
						|
            basename = '%s-%016x.yaml' % (slug, n)
 | 
						|
        filename = os.path.join(self.reporoot, 'releasenotes', 'notes',
 | 
						|
                                basename)
 | 
						|
        create._make_note_file(filename, contents)
 | 
						|
        self.repo.commit('add %s' % basename)
 | 
						|
        return os.path.join('releasenotes', 'notes', basename)
 | 
						|
 | 
						|
    def _make_python_package(self):
 | 
						|
        setup_name = os.path.join(self.reporoot, 'setup.py')
 | 
						|
        with open(setup_name, 'w') as f:
 | 
						|
            f.write(_SETUP_TEMPLATE)
 | 
						|
        cfg_name = os.path.join(self.reporoot, 'setup.cfg')
 | 
						|
        with open(cfg_name, 'w') as f:
 | 
						|
            f.write(_CFG_TEMPLATE)
 | 
						|
        pkgdir = os.path.join(self.reporoot, 'testpkg')
 | 
						|
        os.makedirs(pkgdir)
 | 
						|
        init = os.path.join(pkgdir, '__init__.py')
 | 
						|
        with open(init, 'w') as f:
 | 
						|
            f.write("Test package")
 | 
						|
        self.repo.commit('add test package')
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(Base, self).setUp()
 | 
						|
        self.fake_logger = self.useFixture(
 | 
						|
            fixtures.FakeLogger(
 | 
						|
                format='%(levelname)8s %(name)s %(message)s',
 | 
						|
                level=logging.DEBUG,
 | 
						|
                nuke_handlers=True,
 | 
						|
            )
 | 
						|
        )
 | 
						|
        # Older git does not have config --local, so create a temporary home
 | 
						|
        # directory to permit using git config --global without stepping on
 | 
						|
        # developer configuration.
 | 
						|
        self.useFixture(fixtures.TempHomeDir())
 | 
						|
        self.useFixture(fixtures.NestedTempfile())
 | 
						|
        self.temp_dir = self.useFixture(fixtures.TempDir()).path
 | 
						|
        self.reporoot = os.path.join(self.temp_dir, 'reporoot')
 | 
						|
        self.repo = self.useFixture(GitRepoFixture(self.reporoot))
 | 
						|
        self.c = config.Config(self.reporoot)
 | 
						|
        self._counter = itertools.count(1)
 | 
						|
        self.get_note_num = lambda: next(self._counter)
 | 
						|
 | 
						|
 | 
						|
class BasicTest(Base):
 | 
						|
 | 
						|
    def test_non_python_no_tags(self):
 | 
						|
        filename = self._add_notes_file()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'0.0.0': [filename]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_python_no_tags(self):
 | 
						|
        self._make_python_package()
 | 
						|
        filename = self._add_notes_file()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'0.0.0': [filename]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_note_before_tag(self):
 | 
						|
        filename = self._add_notes_file()
 | 
						|
        self.repo.add_file('not-a-release-note.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [filename]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_note_commit_tagged(self):
 | 
						|
        filename = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [filename]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_note_commit_after_tag(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        filename = self._add_notes_file()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0-1': [filename]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_other_commit_after_tag(self):
 | 
						|
        filename = self._add_notes_file()
 | 
						|
        self.repo.add_file('ignore-1.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.repo.add_file('ignore-2.txt')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [filename]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_multiple_notes_after_tag(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file()
 | 
						|
        f2 = self._add_notes_file()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0-2': [f1, f2]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_multiple_notes_within_tag(self):
 | 
						|
        self._make_python_package()
 | 
						|
        f1 = self._add_notes_file(commit=False)
 | 
						|
        f2 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [f1, f2]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_multiple_tags(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        f2 = self._add_notes_file()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f1],
 | 
						|
             '2.0.0-1': [f2],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rename_file(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        f2 = f1.replace('slug1', 'slug2')
 | 
						|
        self.repo.git('mv', f1, f2)
 | 
						|
        self.repo.commit('rename note file')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f2],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rename_file_sort_earlier(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        f2 = f1.replace('slug1', 'slug0')
 | 
						|
        self.repo.git('mv', f1, f2)
 | 
						|
        self.repo.commit('rename note file')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f2],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_edit_file(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        with open(os.path.join(self.reporoot, f1), 'w') as f:
 | 
						|
            f.write('---\npreamble: new contents for file')
 | 
						|
        self.repo.commit('edit note file')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f1],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_legacy_file(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file('slug1', legacy=True)
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        f2 = f1.replace('slug1', 'slug2')
 | 
						|
        self.repo.git('mv', f1, f2)
 | 
						|
        self.repo.commit('rename note file')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f2],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rename_legacy_file_to_new(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file('slug1', legacy=True)
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        # Rename the file with the new convention of placing the UUID
 | 
						|
        # after the slug instead of before.
 | 
						|
        f2 = f1.replace('0000000000000001-slug1',
 | 
						|
                        'slug1-0000000000000001')
 | 
						|
        self.repo.git('mv', f1, f2)
 | 
						|
        self.repo.commit('rename note file')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f2],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_limit_by_earliest_version(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f2 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'middle tag', '2.0.0')
 | 
						|
        f3 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'last tag', '3.0.0')
 | 
						|
        self.c.override(
 | 
						|
            earliest_version='2.0.0',
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f2],
 | 
						|
             '3.0.0': [f3],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_delete_file(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        f2 = self._add_notes_file('slug2')
 | 
						|
        self.repo.git('rm', f1)
 | 
						|
        self.repo.commit('remove note file')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f2],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rename_then_delete_file(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        f2 = f1.replace('slug1', 'slug2')
 | 
						|
        self.repo.git('mv', f1, f2)
 | 
						|
        self.repo.git('status')
 | 
						|
        self.repo.commit('rename note file')
 | 
						|
        self.repo.git('rm', f2)
 | 
						|
        self.repo.commit('remove note file')
 | 
						|
        f3 = self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        log_results = self.repo.git('log', '--topo-order',
 | 
						|
                                    '--pretty=%H %d',
 | 
						|
                                    '--name-only')
 | 
						|
        self.addDetail('git log', text_content(log_results))
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'2.0.0': [f3],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_staged_file(self):
 | 
						|
        # Prove that we can get a file we have staged.
 | 
						|
        # Start with a standard commit and tag
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        # Now stage a release note
 | 
						|
        n = self.get_note_num()
 | 
						|
        basename = 'staged-note-%016x.yaml' % n
 | 
						|
        filename = os.path.join(self.reporoot, 'releasenotes', 'notes',
 | 
						|
                                basename)
 | 
						|
        create._make_note_file(filename, 'staged note')
 | 
						|
        self.repo.git('add', filename)
 | 
						|
        status_results = self.repo.git('status')
 | 
						|
        self.addDetail('git status', text_content(status_results))
 | 
						|
        # Now run the scanner
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        self.assertEqual(
 | 
						|
            {'*working-copy*': [
 | 
						|
                (os.path.join('releasenotes', 'notes', basename),
 | 
						|
                 None)],
 | 
						|
             },
 | 
						|
            raw_results,
 | 
						|
        )
 | 
						|
 | 
						|
    @unittest.skip('dulwich does not know how to identify new files')
 | 
						|
    def test_added_tagged_not_staged(self):
 | 
						|
        # Prove that we can get a file we have created but not staged.
 | 
						|
        # Start with a standard commit and tag
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        # Now create a note without staging it
 | 
						|
        n = self.get_note_num()
 | 
						|
        basename = 'staged-note-%016x.yaml' % n
 | 
						|
        filename = os.path.join(self.reporoot, 'releasenotes', 'notes',
 | 
						|
                                basename)
 | 
						|
        create._make_note_file(filename, 'staged note')
 | 
						|
        status_results = self.repo.git('status')
 | 
						|
        self.addDetail('git status', text_content(status_results))
 | 
						|
        # Now run the scanner
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        # Take the staged version of the file, but associate it with
 | 
						|
        # tagged version 1.0.0 because the file was added before that
 | 
						|
        # version.
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [(os.path.join('releasenotes', 'notes', basename),
 | 
						|
                        None)],
 | 
						|
             },
 | 
						|
            raw_results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_modified_tagged_not_staged(self):
 | 
						|
        # Prove that we can get a file we have changed but not staged.
 | 
						|
        # Start with a standard commit and tag
 | 
						|
        self._make_python_package()
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        # Now modify the note
 | 
						|
        fullpath = os.path.join(self.repo.reporoot, f1)
 | 
						|
        with open(fullpath, 'w') as f:
 | 
						|
            f.write('modified first note')
 | 
						|
        status_results = self.repo.git('status')
 | 
						|
        self.addDetail('git status', text_content(status_results))
 | 
						|
        # Now run the scanner
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        # Take the staged version of the file, but associate it with
 | 
						|
        # tagged version 1.0.0 because the file was added before that
 | 
						|
        # version.
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [(f1, None)],
 | 
						|
             },
 | 
						|
            raw_results,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class FileContentsTest(Base):
 | 
						|
 | 
						|
    def test_basic_file(self):
 | 
						|
        # Prove that we can get a file we have committed.
 | 
						|
        f1 = self._add_notes_file(contents='well-known-contents')
 | 
						|
        r = scanner.RenoRepo(self.reporoot)
 | 
						|
        contents = r.get_file_at_commit(f1, 'HEAD')
 | 
						|
        self.assertEqual(
 | 
						|
            b'well-known-contents',
 | 
						|
            contents,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_no_such_file(self):
 | 
						|
        # Returns None when the file does not exist at all.
 | 
						|
        # (we have to commit something, otherwise there is no HEAD)
 | 
						|
        self._add_notes_file(contents='well-known-contents')
 | 
						|
        r = scanner.RenoRepo(self.reporoot)
 | 
						|
        contents = r.get_file_at_commit('no-such-dir/no-such-file', 'HEAD')
 | 
						|
        self.assertEqual(
 | 
						|
            None,
 | 
						|
            contents,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_edit_file_and_commit(self):
 | 
						|
        # Prove that we can edit a file and see the changes.
 | 
						|
        f1 = self._add_notes_file(contents='initial-contents')
 | 
						|
        with open(os.path.join(self.reporoot, f1), 'w') as f:
 | 
						|
            f.write('new contents for file')
 | 
						|
        self.repo.commit('edit note file')
 | 
						|
        r = scanner.RenoRepo(self.reporoot)
 | 
						|
        contents = r.get_file_at_commit(f1, 'HEAD')
 | 
						|
        self.assertEqual(
 | 
						|
            b'new contents for file',
 | 
						|
            contents,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_earlier_version_of_edited_file(self):
 | 
						|
        # Prove that we are not always just returning the most current
 | 
						|
        # version of a file.
 | 
						|
        f1 = self._add_notes_file(contents='initial-contents')
 | 
						|
        with open(os.path.join(self.reporoot, f1), 'w') as f:
 | 
						|
            f.write('new contents for file')
 | 
						|
        self.repo.commit('edit note file')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        r = scanner.RenoRepo(self.reporoot)
 | 
						|
        head = r.head()
 | 
						|
        parent = r.get_parents(head)[0]
 | 
						|
        parent = parent.decode('ascii')
 | 
						|
        contents = r.get_file_at_commit(f1, parent)
 | 
						|
        self.assertEqual(
 | 
						|
            b'initial-contents',
 | 
						|
            contents,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_edit_file_without_commit(self):
 | 
						|
        # Prove we are not picking up the contents from the local
 | 
						|
        # filesystem outside of the git history.
 | 
						|
        f1 = self._add_notes_file(contents='initial-contents')
 | 
						|
        with open(os.path.join(self.reporoot, f1), 'w') as f:
 | 
						|
            f.write('new contents for file')
 | 
						|
        r = scanner.RenoRepo(self.reporoot)
 | 
						|
        contents = r.get_file_at_commit(f1, 'HEAD')
 | 
						|
        self.assertEqual(
 | 
						|
            b'initial-contents',
 | 
						|
            contents,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_staged_file(self):
 | 
						|
        # Prove we are not picking up the contents from the local
 | 
						|
        # filesystem outside of the git history.
 | 
						|
        f1 = self._add_notes_file(contents='initial-contents')
 | 
						|
        with open(os.path.join(self.reporoot, f1), 'w') as f:
 | 
						|
            f.write('new contents for file')
 | 
						|
        r = scanner.RenoRepo(self.reporoot)
 | 
						|
        contents = r.get_file_at_commit(f1, None)
 | 
						|
        self.assertEqual(
 | 
						|
            'new contents for file',
 | 
						|
            contents,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class PreReleaseTest(Base):
 | 
						|
 | 
						|
    def test_alpha(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0.0a1')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0.0a2')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0.0a2': [f1],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_beta(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0.0b1')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0.0b2')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0.0b2': [f1],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_release_candidate(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0.0rc1')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0.0rc2')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0.0rc2': [f1],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_collapse(self):
 | 
						|
        files = []
 | 
						|
        self._make_python_package()
 | 
						|
        files.append(self._add_notes_file('slug1'))
 | 
						|
        self.repo.git('tag', '-s', '-m', 'alpha tag', '1.0.0.0a1')
 | 
						|
        files.append(self._add_notes_file('slug2'))
 | 
						|
        self.repo.git('tag', '-s', '-m', 'beta tag', '1.0.0.0b1')
 | 
						|
        files.append(self._add_notes_file('slug3'))
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release candidate tag', '1.0.0.0rc1')
 | 
						|
        files.append(self._add_notes_file('slug4'))
 | 
						|
        self.repo.git('tag', '-s', '-m', 'full release tag', '1.0.0')
 | 
						|
        self.c.override(
 | 
						|
            collapse_pre_releases=True,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': files,
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_collapse_without_full_release(self):
 | 
						|
        self._make_python_package()
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'alpha tag', '1.0.0.0a1')
 | 
						|
        f2 = self._add_notes_file('slug2')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'beta tag', '1.0.0.0b1')
 | 
						|
        f3 = self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release candidate tag', '1.0.0.0rc1')
 | 
						|
        self.c.override(
 | 
						|
            collapse_pre_releases=True,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0.0a1': [f1],
 | 
						|
             '1.0.0.0b1': [f2],
 | 
						|
             '1.0.0.0rc1': [f3],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_collapse_without_notes(self):
 | 
						|
        self._make_python_package()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'earlier tag', '0.1.0')
 | 
						|
        f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'alpha tag', '1.0.0.0a1')
 | 
						|
        f2 = self._add_notes_file('slug2')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'beta tag', '1.0.0.0b1')
 | 
						|
        f3 = self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release candidate tag', '1.0.0.0rc1')
 | 
						|
        self.c.override(
 | 
						|
            collapse_pre_releases=True,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0.0a1': [f1],
 | 
						|
             '1.0.0.0b1': [f2],
 | 
						|
             '1.0.0.0rc1': [f3],
 | 
						|
             },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class MergeCommitTest(Base):
 | 
						|
 | 
						|
    def test_1(self):
 | 
						|
        # Create changes on master and in the branch
 | 
						|
        # in order so the history is "normal"
 | 
						|
        n1 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'test_merge_commit')
 | 
						|
        n2 = self._add_notes_file()
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self.repo.add_file('ignore-1.txt')
 | 
						|
        # Merge the branch into master.
 | 
						|
        self.repo.git('merge', '--no-ff', 'test_merge_commit')
 | 
						|
        time.sleep(0.1)  # force a delay between commits
 | 
						|
        self.repo.add_file('ignore-2.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '2.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [n1],
 | 
						|
             '2.0.0': [n2]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
        self.assertEqual(
 | 
						|
            ['2.0.0', '1.0.0'],
 | 
						|
            list(raw_results.keys()),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_2(self):
 | 
						|
        # Create changes on the branch before the tag into which it is
 | 
						|
        # actually merged.
 | 
						|
        self.repo.add_file('ignore-0.txt')
 | 
						|
        self.repo.git('checkout', '-b', 'test_merge_commit')
 | 
						|
        n1 = self._add_notes_file()
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        n2 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.repo.add_file('ignore-1.txt')
 | 
						|
        # Merge the branch into master.
 | 
						|
        self.repo.git('merge', '--no-ff', 'test_merge_commit')
 | 
						|
        time.sleep(0.1)  # force a delay between commits
 | 
						|
        self.repo.git('show')
 | 
						|
        self.repo.add_file('ignore-2.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '2.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [n2],
 | 
						|
             '2.0.0': [n1]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
        self.assertEqual(
 | 
						|
            ['2.0.0', '1.0.0'],
 | 
						|
            list(raw_results.keys()),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_3(self):
 | 
						|
        # Create changes on the branch before the tag into which it is
 | 
						|
        # actually merged, with another tag in between the time of the
 | 
						|
        # commit and the time of the merge. This should reflect the
 | 
						|
        # order of events described in bug #1522153.
 | 
						|
        self.repo.add_file('ignore-0.txt')
 | 
						|
        self.repo.git('checkout', '-b', 'test_merge_commit')
 | 
						|
        n1 = self._add_notes_file()
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        n2 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.repo.add_file('ignore-1.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '1.1.0')
 | 
						|
        self.repo.git('merge', '--no-ff', 'test_merge_commit')
 | 
						|
        time.sleep(0.1)  # force a delay between commits
 | 
						|
        self.repo.add_file('ignore-2.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'third tag', '2.0.0')
 | 
						|
        self.repo.add_file('ignore-3.txt')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        # Since the 1.1.0 tag has no notes files, it does not appear
 | 
						|
        # in the output. It's only there to trigger the bug as it was
 | 
						|
        # originally reported.
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [n2],
 | 
						|
             '2.0.0': [n1]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
        self.assertEqual(
 | 
						|
            ['2.0.0', '1.0.0'],
 | 
						|
            list(raw_results.keys()),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_4(self):
 | 
						|
        # Create changes on the branch before the tag into which it is
 | 
						|
        # actually merged, with another tag in between the time of the
 | 
						|
        # commit and the time of the merge. This should reflect the
 | 
						|
        # order of events described in bug #1522153.
 | 
						|
        self.repo.add_file('ignore-0.txt')
 | 
						|
        self.repo.git('checkout', '-b', 'test_merge_commit')
 | 
						|
        n1 = self._add_notes_file()
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        n2 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.repo.add_file('ignore-1.txt')
 | 
						|
        n3 = self._add_notes_file()
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '1.1.0')
 | 
						|
        self.repo.git('merge', '--no-ff', 'test_merge_commit')
 | 
						|
        time.sleep(0.1)  # force a delay between commits
 | 
						|
        self.repo.add_file('ignore-2.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'third tag', '2.0.0')
 | 
						|
        self.repo.add_file('ignore-3.txt')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {'1.0.0': [n2],
 | 
						|
             '1.1.0': [n3],
 | 
						|
             '2.0.0': [n1]},
 | 
						|
            results,
 | 
						|
        )
 | 
						|
        self.assertEqual(
 | 
						|
            ['2.0.0', '1.1.0', '1.0.0'],
 | 
						|
            list(raw_results.keys()),
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class UniqueIdTest(Base):
 | 
						|
 | 
						|
    def test_legacy(self):
 | 
						|
        uid = scanner._get_unique_id(
 | 
						|
            'releasenotes/notes/0000000000000001-slug1.yaml'
 | 
						|
        )
 | 
						|
        self.assertEqual('0000000000000001', uid)
 | 
						|
 | 
						|
    def test_modern(self):
 | 
						|
        uid = scanner._get_unique_id(
 | 
						|
            'releasenotes/notes/slug1-0000000000000001.yaml'
 | 
						|
        )
 | 
						|
        self.assertEqual('0000000000000001', uid)
 | 
						|
 | 
						|
 | 
						|
class BranchBaseTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(BranchBaseTest, self).setUp()
 | 
						|
        self._make_python_package()
 | 
						|
        self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self._add_notes_file('slug2')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '3.0.0')
 | 
						|
        self.repo.git('checkout', '2.0.0')
 | 
						|
        self.repo.git('branch', 'not-master')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
 | 
						|
    def test_current_branch_no_extra_commits(self):
 | 
						|
        # checkout the branch and then ask for its base
 | 
						|
        self.repo.git('checkout', 'not-master')
 | 
						|
        self.assertEqual(
 | 
						|
            '2.0.0',
 | 
						|
            self.scanner._get_branch_base('not-master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_current_branch_extra_commit(self):
 | 
						|
        # checkout the branch and then ask for its base
 | 
						|
        self.repo.git('checkout', 'not-master')
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self.assertEqual(
 | 
						|
            '2.0.0',
 | 
						|
            self.scanner._get_branch_base('not-master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_alternate_branch_no_extra_commits(self):
 | 
						|
        # checkout master and then ask for the alternate branch base
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self.assertEqual(
 | 
						|
            '2.0.0',
 | 
						|
            self.scanner._get_branch_base('not-master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_alternate_branch_extra_commit(self):
 | 
						|
        # checkout master and then ask for the alternate branch base
 | 
						|
        self.repo.git('checkout', 'not-master')
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self.assertEqual(
 | 
						|
            '2.0.0',
 | 
						|
            self.scanner._get_branch_base('not-master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_no_tag_at_base(self):
 | 
						|
        # remove the tag at the branch point
 | 
						|
        self.repo.git('tag', '-d', '2.0.0')
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self.assertIsNone(
 | 
						|
            self.scanner._get_branch_base('not-master')
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class BranchTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(BranchTest, self).setUp()
 | 
						|
        self._make_python_package()
 | 
						|
        self.f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.f2 = self._add_notes_file('slug2')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '3.0.0')
 | 
						|
 | 
						|
    def test_files_current_branch(self):
 | 
						|
        self.repo.git('checkout', '2.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/2')
 | 
						|
        f21 = self._add_notes_file('slug21')
 | 
						|
        log_text = self.repo.git('log', '--decorate')
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '1.0.0': [self.f1],
 | 
						|
                '2.0.0': [self.f2],
 | 
						|
                '2.0.0-1': [f21],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_files_stable_from_master(self):
 | 
						|
        self.repo.git('checkout', '2.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/2')
 | 
						|
        f21 = self._add_notes_file('slug21')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        log_text = self.repo.git('log', '--pretty=%x00%H %d', '--name-only',
 | 
						|
                                 'stable/2')
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/2',
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '2.0.0': [self.f2],
 | 
						|
                '2.0.0-1': [f21],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_files_stable_from_master_no_stop_base(self):
 | 
						|
        self.repo.git('checkout', '2.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/2')
 | 
						|
        f21 = self._add_notes_file('slug21')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        log_text = self.repo.git('log', '--pretty=%x00%H %d', '--name-only',
 | 
						|
                                 'stable/2')
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/2',
 | 
						|
        )
 | 
						|
        self.c.override(
 | 
						|
            stop_at_branch_base=False,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '1.0.0': [self.f1],
 | 
						|
                '2.0.0': [self.f2],
 | 
						|
                '2.0.0-1': [f21],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_pre_release_branch_no_collapse(self):
 | 
						|
        f4 = self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'pre-release', '4.0.0.0rc1')
 | 
						|
        # Add a commit on master after the tag
 | 
						|
        self._add_notes_file('slug5')
 | 
						|
        # Move back to the tag and create the branch
 | 
						|
        self.repo.git('checkout', '4.0.0.0rc1')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/4')
 | 
						|
        # Create a commit on the branch
 | 
						|
        f41 = self._add_notes_file('slug41')
 | 
						|
        log_text = self.repo.git(
 | 
						|
            'log', '--pretty=%x00%H %d', '--name-only', '--graph',
 | 
						|
            '--all', '--decorate',
 | 
						|
        )
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        rev_list = self.repo.git('rev-list', '--first-parent',
 | 
						|
                                 '^stable/4', 'master')
 | 
						|
        self.addDetail('rev-list', text_content(rev_list))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/4',
 | 
						|
            collapse_pre_releases=False,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '4.0.0.0rc1': [f4],
 | 
						|
                '4.0.0.0rc1-1': [f41],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_pre_release_branch_collapse(self):
 | 
						|
        f4 = self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'pre-release', '4.0.0.0rc1')
 | 
						|
        # Add a commit on master after the tag
 | 
						|
        self._add_notes_file('slug5')
 | 
						|
        # Move back to the tag and create the branch
 | 
						|
        self.repo.git('checkout', '4.0.0.0rc1')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/4')
 | 
						|
        # Create a commit on the branch
 | 
						|
        f41 = self._add_notes_file('slug41')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release', '4.0.0')
 | 
						|
        log_text = self.repo.git(
 | 
						|
            'log', '--pretty=%x00%H %d', '--name-only', '--graph',
 | 
						|
            '--all', '--decorate',
 | 
						|
        )
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        rev_list = self.repo.git('rev-list', '--first-parent',
 | 
						|
                                 '^stable/4', 'master')
 | 
						|
        self.addDetail('rev-list', text_content(rev_list))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/4',
 | 
						|
            collapse_pre_releases=True,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '4.0.0': [f4, f41],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_pre_release_note_before_branch(self):
 | 
						|
        f4 = self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'beta', '4.0.0.0b1')
 | 
						|
        self.repo.add_file('not-a-release-note.txt')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'pre-release', '4.0.0.0rc1')
 | 
						|
        # Add a commit on master after the tag
 | 
						|
        self._add_notes_file('slug5')
 | 
						|
        # Move back to the tag and create the branch
 | 
						|
        self.repo.git('checkout', '4.0.0.0rc1')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/4')
 | 
						|
        # Create a commit on the branch
 | 
						|
        f41 = self._add_notes_file('slug41')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release', '4.0.0')
 | 
						|
        log_text = self.repo.git(
 | 
						|
            'log', '--pretty=%x00%H %d', '--name-only', '--graph',
 | 
						|
            '--all', '--decorate',
 | 
						|
        )
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        rev_list = self.repo.git('rev-list', '--first-parent',
 | 
						|
                                 '^stable/4', 'master')
 | 
						|
        self.addDetail('rev-list', text_content(rev_list))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/4',
 | 
						|
            collapse_pre_releases=True,
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '4.0.0': [f4, f41],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_full_release_branch(self):
 | 
						|
        f4 = self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release', '4.0.0')
 | 
						|
        # Add a commit on master after the tag
 | 
						|
        self._add_notes_file('slug5')
 | 
						|
        # Move back to the tag and create the branch
 | 
						|
        self.repo.git('checkout', '4.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/4')
 | 
						|
        # Create a commit on the branch
 | 
						|
        f41 = self._add_notes_file('slug41')
 | 
						|
        log_text = self.repo.git(
 | 
						|
            'log', '--pretty=%x00%H %d', '--name-only', '--graph',
 | 
						|
            '--all', '--decorate',
 | 
						|
        )
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        rev_list = self.repo.git('rev-list', '--first-parent',
 | 
						|
                                 '^stable/4', 'master')
 | 
						|
        self.addDetail('rev-list', text_content(rev_list))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/4',
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '4.0.0': [f4],
 | 
						|
                '4.0.0-1': [f41],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_branch_tip_of_master(self):
 | 
						|
        # We have branched from master, but not added any commits to
 | 
						|
        # master.
 | 
						|
        f4 = self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release', '4.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/4')
 | 
						|
        # Create a commit on the branch
 | 
						|
        f41 = self._add_notes_file('slug41')
 | 
						|
        f42 = self._add_notes_file('slug42')
 | 
						|
        log_text = self.repo.git(
 | 
						|
            'log', '--pretty=%x00%H %d', '--name-only', '--graph',
 | 
						|
            '--all', '--decorate',
 | 
						|
        )
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        rev_list = self.repo.git('rev-list', '--first-parent',
 | 
						|
                                 '^stable/4', 'master')
 | 
						|
        self.addDetail('rev-list', text_content(rev_list))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/4',
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '4.0.0': [f4],
 | 
						|
                '4.0.0-2': [f41, f42],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_branch_no_more_commits(self):
 | 
						|
        # We have branched from master, but not added any commits to
 | 
						|
        # our branch or to master.
 | 
						|
        f4 = self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'release', '4.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/4')
 | 
						|
        # Create a commit on the branch
 | 
						|
        log_text = self.repo.git(
 | 
						|
            'log', '--pretty=%x00%H %d', '--name-only', '--graph',
 | 
						|
            '--all', '--decorate',
 | 
						|
        )
 | 
						|
        self.addDetail('git log', text_content(log_text))
 | 
						|
        rev_list = self.repo.git('rev-list', '--first-parent',
 | 
						|
                                 '^stable/4', 'master')
 | 
						|
        self.addDetail('rev-list', text_content(rev_list))
 | 
						|
        self.c.override(
 | 
						|
            branch='stable/4',
 | 
						|
        )
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        raw_results = self.scanner.get_notes_by_version()
 | 
						|
        results = {
 | 
						|
            k: [f for (f, n) in v]
 | 
						|
            for (k, v) in raw_results.items()
 | 
						|
        }
 | 
						|
        self.assertEqual(
 | 
						|
            {
 | 
						|
                '4.0.0': [f4],
 | 
						|
            },
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_remote_branches(self):
 | 
						|
        self.repo.git('checkout', '2.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/2')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        scanner1 = scanner.Scanner(self.c)
 | 
						|
        head1 = scanner1._get_ref('stable/2')
 | 
						|
        self.assertIsNotNone(head1)
 | 
						|
        print('head1', head1)
 | 
						|
        # Create a second repository by cloning the first.
 | 
						|
        print(utils.check_output(
 | 
						|
            ['git', 'clone', self.reporoot, 'reporoot2'],
 | 
						|
            cwd=self.temp_dir,
 | 
						|
        ))
 | 
						|
        reporoot2 = os.path.join(self.temp_dir, 'reporoot2')
 | 
						|
        print(utils.check_output(
 | 
						|
            ['git', 'remote', 'update'],
 | 
						|
            cwd=reporoot2,
 | 
						|
        ))
 | 
						|
        print(utils.check_output(
 | 
						|
            ['git', 'remote', '-v'],
 | 
						|
            cwd=reporoot2,
 | 
						|
        ))
 | 
						|
        print(utils.check_output(
 | 
						|
            ['find', '.git/refs'],
 | 
						|
            cwd=reporoot2,
 | 
						|
        ))
 | 
						|
        print(utils.check_output(
 | 
						|
            ['git', 'branch', '-a'],
 | 
						|
            cwd=reporoot2,
 | 
						|
        ))
 | 
						|
        c2 = config.Config(reporoot2)
 | 
						|
        scanner2 = scanner.Scanner(c2)
 | 
						|
        head2 = scanner2._get_ref('origin/stable/2')
 | 
						|
        self.assertIsNotNone(head2)
 | 
						|
        self.assertEqual(head1, head2)
 | 
						|
 | 
						|
 | 
						|
class ScanStopPointPrereleaseVersionsTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(ScanStopPointPrereleaseVersionsTest, self).setUp()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        self._make_python_package()
 | 
						|
        self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first series', '1.0.0.0rc1')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/a')
 | 
						|
        self._add_notes_file('slug2')
 | 
						|
        self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '1.0.0')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self._add_notes_file('slug5')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second series', '2.0.0.0b3')
 | 
						|
        self._add_notes_file('slug6')
 | 
						|
        self._add_notes_file('slug7')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '2.0.0.0rc1')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/b')
 | 
						|
        self._add_notes_file('slug8')
 | 
						|
        self._add_notes_file('slug9')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'third tag', '2.0.0')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
 | 
						|
    def test_beta_collapse(self):
 | 
						|
        self.assertEqual(
 | 
						|
            '1.0.0.0rc1',
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.0.0b3', ['2.0.0.0b3', '1.0.0.0rc1'],
 | 
						|
                True, 'master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rc_collapse_master(self):
 | 
						|
        self.assertEqual(
 | 
						|
            '1.0.0.0rc1',
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.0.0rc1', ['2.0.0.0rc1', '2.0.0.0b3', '1.0.0.0rc1'],
 | 
						|
                True, 'master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rc_collapse_branch(self):
 | 
						|
        self.assertEqual(
 | 
						|
            '1.0.0.0rc1',
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.0.0rc1', ['2.0.0.0rc1', '2.0.0.0b3', '1.0.0.0rc1'],
 | 
						|
                True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_rc_no_collapse(self):
 | 
						|
        self.assertEqual(
 | 
						|
            '2.0.0.0b3',
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.0.0rc1', ['2.0.0.0rc1', '2.0.0.0b3', '1.0.0.0rc1'],
 | 
						|
                False, 'master'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_stable_branch_with_collapse(self):
 | 
						|
        self.assertEqual(
 | 
						|
            '1.0.0.0rc1',
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.0', ['2.0.0', '2.0.0.0rc1', '2.0.0.0b3', '1.0.0.0rc1'],
 | 
						|
                True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
    # def test_nova_newton(self):
 | 
						|
    #     self.assertEqual(
 | 
						|
    #         '13.0.0.0rc3',
 | 
						|
    #         self.scanner._find_scan_stop_point(
 | 
						|
    #             '14.0.0',
 | 
						|
    #             [u'14.0.3', u'14.0.2', u'14.0.1', u'14.0.0.0rc2',
 | 
						|
    #              u'14.0.0', u'14.0.0.0rc1', u'14.0.0.0b3', u'14.0.0.0b2',
 | 
						|
    #              u'14.0.0.0b1', u'13.0.0.0rc3', u'13.0.0', u'13.0.0.0rc2',
 | 
						|
    #              u'13.0.0.0rc1', u'13.0.0.0b3', u'13.0.0.0b2', u'13.0.0.0b1',
 | 
						|
    #              u'12.0.0.0rc3', u'12.0.0', u'12.0.0.0rc2', u'12.0.0.0rc1',
 | 
						|
    #              u'12.0.0.0b3', u'12.0.0.0b2', u'12.0.0.0b1', u'12.0.0a0',
 | 
						|
    #              u'2015.1.0rc3', u'2015.1.0', u'2015.1.0rc2', u'2015.1.0rc1',
 | 
						|
    #              u'2015.1.0b3', u'2015.1.0b2', u'2015.1.0b1', u'2014.2.rc2',
 | 
						|
    #              u'2014.2', u'2014.2.rc1', u'2014.2.b3', u'2014.2.b2',
 | 
						|
    #              u'2014.2.b1', u'2014.1.rc1', u'2014.1.b3', u'2014.1.b2',
 | 
						|
    #              u'2014.1.b1', u'2013.2.rc1', u'2013.2.b3', u'2013.1.rc1',
 | 
						|
    #              u'folsom-2', u'folsom-1', u'essex-1', u'diablo-2',
 | 
						|
    #              u'diablo-1', u'2011.2', u'2011.2rc1', u'2011.2gamma1',
 | 
						|
    #              u'2011.1rc1', u'0.9.0'],
 | 
						|
    #             True),
 | 
						|
    #     )
 | 
						|
 | 
						|
 | 
						|
class ScanStopPointRegularVersionsTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(ScanStopPointRegularVersionsTest, self).setUp()
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        self._make_python_package()
 | 
						|
        self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first series', '1.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/a')
 | 
						|
        self._add_notes_file('slug2')
 | 
						|
        self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '1.0.1')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self._add_notes_file('slug5')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second series', '2.0.0')
 | 
						|
        self._add_notes_file('slug6')
 | 
						|
        self._add_notes_file('slug7')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '2.0.1')
 | 
						|
        self.repo.git('checkout', '-b', 'stable/b')
 | 
						|
        self._add_notes_file('slug8')
 | 
						|
        self._add_notes_file('slug9')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'third tag', '2.0.2')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
 | 
						|
    def test_invalid_earliest_version(self):
 | 
						|
        self.assertIsNone(
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                'not.a.numeric.version', [], True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_none(self):
 | 
						|
        self.assertIsNone(
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                None, [], True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_unknown_version(self):
 | 
						|
        self.assertIsNone(
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.2', [], True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_only_version(self):
 | 
						|
        self.assertIsNone(
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.2', ['1.0.0'], True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
    def test_find_prior_branch(self):
 | 
						|
        self.assertEqual(
 | 
						|
            '1.0.0',
 | 
						|
            self.scanner._find_scan_stop_point(
 | 
						|
                '2.0.2', ['2.0.2', '2.0.1', '2.0.0', '1.0.0'],
 | 
						|
                True, 'stable/b'),
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class GetRefTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(GetRefTest, self).setUp()
 | 
						|
        self._make_python_package()
 | 
						|
        self.f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.repo.git('branch', 'stable/foo')
 | 
						|
        self.repo.git('tag', 'bar-eol')
 | 
						|
 | 
						|
    def test_signed_tag(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        ref = self.scanner._get_ref('1.0.0')
 | 
						|
        expected = self.scanner._repo.head()
 | 
						|
        self.assertEqual(expected, ref)
 | 
						|
 | 
						|
    def test_unsigned_tag(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        ref = self.scanner._get_ref('bar-eol')
 | 
						|
        expected = self.scanner._repo.head()
 | 
						|
        self.assertEqual(expected, ref)
 | 
						|
 | 
						|
    def test_eol_tag_from_branch(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        ref = self.scanner._get_ref('stable/bar')
 | 
						|
        expected = self.scanner._repo.head()
 | 
						|
        self.assertEqual(expected, ref)
 | 
						|
 | 
						|
    def test_head(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        ref = self.scanner._get_ref(None)
 | 
						|
        expected = self.scanner._repo.head()
 | 
						|
        self.assertEqual(expected, ref)
 | 
						|
 | 
						|
 | 
						|
class TagsTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(TagsTest, self).setUp()
 | 
						|
        self._make_python_package()
 | 
						|
        self.f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.f2 = self._add_notes_file('slug2')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '2.0.0')
 | 
						|
        self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '3.0.0')
 | 
						|
 | 
						|
    def test_master(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_tags_on_branch(None)
 | 
						|
        self.assertEqual(
 | 
						|
            ['3.0.0', '2.0.0', '1.0.0'],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_get_ref(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        ref = self.scanner._get_ref('3.0.0')
 | 
						|
        expected = self.scanner._repo.head()
 | 
						|
        self.assertEqual(expected, ref)
 | 
						|
 | 
						|
    def test_not_master(self):
 | 
						|
        self.repo.git('checkout', '2.0.0')
 | 
						|
        self.repo.git('checkout', '-b', 'not-master')
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'not on master', '2.0.1')
 | 
						|
        self.repo.git('checkout', 'master')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_tags_on_branch('not-master')
 | 
						|
        self.assertEqual(
 | 
						|
            ['2.0.1', '2.0.0', '1.0.0'],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_unsigned(self):
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self.repo.git('tag', '-m', 'first tag', '4.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_tags_on_branch(None)
 | 
						|
        self.assertEqual(
 | 
						|
            ['4.0.0', '3.0.0', '2.0.0', '1.0.0'],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_tagged_tag_annotated(self):
 | 
						|
        time.sleep(1)
 | 
						|
        self.repo.git('tag', '-s', '-m', 'fourth tag', '4.0.0', '3.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_tags_on_branch(None)
 | 
						|
        self.assertEqual(
 | 
						|
            ['3.0.0', '4.0.0', '2.0.0', '1.0.0'],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_tagged_tag_lightweight(self):
 | 
						|
        time.sleep(1)
 | 
						|
        self.repo.git('tag', '-m', 'fourth tag', '4.0.0', '3.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_tags_on_branch(None)
 | 
						|
        self.assertEqual(
 | 
						|
            ['3.0.0', '4.0.0', '2.0.0', '1.0.0'],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class VersionTest(Base):
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        super(VersionTest, self).setUp()
 | 
						|
        self._make_python_package()
 | 
						|
        self.f1 = self._add_notes_file('slug1')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'first tag', '1.0.0')
 | 
						|
        self.f2 = self._add_notes_file('slug2')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'second tag', '2.0.0')
 | 
						|
        self._add_notes_file('slug3')
 | 
						|
        self.repo.git('tag', '-s', '-m', 'third tag', '3.0.0')
 | 
						|
 | 
						|
    def test_tagged_head(self):
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_current_version(None)
 | 
						|
        self.assertEqual(
 | 
						|
            '3.0.0',
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_head_after_tag(self):
 | 
						|
        self._add_notes_file('slug4')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_current_version(None)
 | 
						|
        self.assertEqual(
 | 
						|
            '3.0.0-1',
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_multiple_tags(self):
 | 
						|
        # The timestamp resolution appears to be 1 second, so sleep to
 | 
						|
        # ensure distinct timestamps for the 2 tags. In practice it is
 | 
						|
        # unlikely that anything could apply 2 signed tags within a
 | 
						|
        # single second (certainly not a person).
 | 
						|
        time.sleep(1)
 | 
						|
        self.repo.git('tag', '-s', '-m', 'fourth tag', '4.0.0')
 | 
						|
        self.scanner = scanner.Scanner(self.c)
 | 
						|
        results = self.scanner._get_current_version(None)
 | 
						|
        self.assertEqual(
 | 
						|
            '4.0.0',
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
 | 
						|
class AggregateChangesTest(Base):
 | 
						|
 | 
						|
    def test_ignore(self):
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        name = 'prefix/add-%016x' % n  # no .yaml extension
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_ADD,
 | 
						|
                old=objects.TreeEntry(path=None, mode=None, sha=None),
 | 
						|
                new=objects.TreeEntry(
 | 
						|
                    path=name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='not-a-hash',
 | 
						|
                )
 | 
						|
            )
 | 
						|
        ]
 | 
						|
        results = scanner._aggregate_changes(entry, changes, 'prefix')
 | 
						|
        self.assertEqual(
 | 
						|
            [],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_add(self):
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        name = 'prefix/add-%016x.yaml' % n
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_ADD,
 | 
						|
                old=objects.TreeEntry(path=None, mode=None, sha=None),
 | 
						|
                new=objects.TreeEntry(
 | 
						|
                    path=name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='not-a-hash',
 | 
						|
                )
 | 
						|
            )
 | 
						|
        ]
 | 
						|
        results = list(scanner._aggregate_changes(entry, changes, 'prefix'))
 | 
						|
        self.assertEqual(
 | 
						|
            [('%016x' % n, 'add', name, 'commit-id')],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_delete(self):
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        name = 'prefix/delete-%016x.yaml' % n
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_DELETE,
 | 
						|
                old=objects.TreeEntry(
 | 
						|
                    path=name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='not-a-hash',
 | 
						|
                ),
 | 
						|
                new=objects.TreeEntry(path=None, mode=None, sha=None)
 | 
						|
            )
 | 
						|
        ]
 | 
						|
        results = list(scanner._aggregate_changes(entry, changes, 'prefix'))
 | 
						|
        self.assertEqual(
 | 
						|
            [('%016x' % n, 'delete', name)],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_change(self):
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        name = 'prefix/change-%016x.yaml' % n
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_MODIFY,
 | 
						|
                old=objects.TreeEntry(
 | 
						|
                    path=name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='old-sha',
 | 
						|
                ),
 | 
						|
                new=objects.TreeEntry(
 | 
						|
                    path=name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='new-sha',
 | 
						|
                ),
 | 
						|
            )
 | 
						|
        ]
 | 
						|
        results = list(scanner._aggregate_changes(entry, changes, 'prefix'))
 | 
						|
        self.assertEqual(
 | 
						|
            [('%016x' % n, 'modify', name, 'commit-id')],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_add_then_delete(self):
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        new_name = 'prefix/new-%016x.yaml' % n
 | 
						|
        old_name = 'prefix/old-%016x.yaml' % n
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_ADD,
 | 
						|
                old=objects.TreeEntry(path=None, mode=None, sha=None),
 | 
						|
                new=objects.TreeEntry(
 | 
						|
                    path=new_name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='new-hash',
 | 
						|
                )
 | 
						|
            ),
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_DELETE,
 | 
						|
                old=objects.TreeEntry(
 | 
						|
                    path=old_name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='old-hash',
 | 
						|
                ),
 | 
						|
                new=objects.TreeEntry(path=None, mode=None, sha=None)
 | 
						|
            )
 | 
						|
        ]
 | 
						|
        results = list(scanner._aggregate_changes(entry, changes, 'prefix'))
 | 
						|
        self.assertEqual(
 | 
						|
            [('%016x' % n, 'rename', old_name, new_name, 'commit-id')],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_delete_then_add(self):
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        new_name = 'prefix/new-%016x.yaml' % n
 | 
						|
        old_name = 'prefix/old-%016x.yaml' % n
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_DELETE,
 | 
						|
                old=objects.TreeEntry(
 | 
						|
                    path=old_name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='old-hash',
 | 
						|
                ),
 | 
						|
                new=objects.TreeEntry(path=None, mode=None, sha=None)
 | 
						|
            ),
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type=diff_tree.CHANGE_ADD,
 | 
						|
                old=objects.TreeEntry(path=None, mode=None, sha=None),
 | 
						|
                new=objects.TreeEntry(
 | 
						|
                    path=new_name.encode('utf-8'),
 | 
						|
                    mode='0222',
 | 
						|
                    sha='new-hash',
 | 
						|
                )
 | 
						|
            ),
 | 
						|
        ]
 | 
						|
        results = list(scanner._aggregate_changes(entry, changes, 'prefix'))
 | 
						|
        self.assertEqual(
 | 
						|
            [('%016x' % n, 'rename', old_name, new_name, 'commit-id')],
 | 
						|
            results,
 | 
						|
        )
 | 
						|
 | 
						|
    def test_tree_changes(self):
 | 
						|
        # Under some conditions when dulwich sees merge commits,
 | 
						|
        # changes() returns a list with nested lists. See commit
 | 
						|
        # cc11da6dcfb1dbaa015e9804b6a23f7872380c1b in this repo for an
 | 
						|
        # example.
 | 
						|
        entry = mock.Mock()
 | 
						|
        n = self.get_note_num()
 | 
						|
        # The files modified by the commit are actually
 | 
						|
        # reno/scanner.py, but the fake names are used in this test to
 | 
						|
        # comply with the rest of the configuration for the scanner.
 | 
						|
        old_name = 'prefix/old-%016x.yaml' % n
 | 
						|
        entry.commit.id = 'commit-id'
 | 
						|
        changes = [[
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type='modify',
 | 
						|
                old=diff_tree.TreeEntry(
 | 
						|
                    path=old_name.encode('utf-8'),
 | 
						|
                    mode=33188,
 | 
						|
                    sha=b'8247dfdd116fd0e3cc4ba32328e4a3eafd227de6',
 | 
						|
                ),
 | 
						|
                new=diff_tree.TreeEntry(
 | 
						|
                    path=old_name.encode('utf-8'),
 | 
						|
                    mode=33188,
 | 
						|
                    sha=b'611f3663f54afb1f018a6a8680b6488da50ac340',
 | 
						|
                ),
 | 
						|
            ),
 | 
						|
            diff_tree.TreeChange(
 | 
						|
                type='modify',
 | 
						|
                old=diff_tree.TreeEntry(
 | 
						|
                    path=old_name.encode('utf-8'),
 | 
						|
                    mode=33188,
 | 
						|
                    sha=b'ecb7788066eefa9dc8f110b56360efe7b1140b84',
 | 
						|
                ),
 | 
						|
                new=diff_tree.TreeEntry(
 | 
						|
                    path=old_name.encode('utf-8'),
 | 
						|
                    mode=33188,
 | 
						|
                    sha=b'611f3663f54afb1f018a6a8680b6488da50ac340',
 | 
						|
                ),
 | 
						|
            ),
 | 
						|
        ]]
 | 
						|
        results = list(scanner._aggregate_changes(entry, changes, 'prefix'))
 | 
						|
        self.assertEqual(
 | 
						|
            [('%016x' % n, 'modify', old_name, 'commit-id'),
 | 
						|
             ('%016x' % n, 'modify', old_name, 'commit-id')],
 | 
						|
            results,
 | 
						|
        )
 |