Пример #1
0
    def test_recursive_import_error(self):
        '''Errors that happen inside recursively-fetched targets should have
        context information about the targets that caused them. This test is
        especially important for checking that context isn't lost in
        GatheredExceptions.'''
        # Project NOTABLE_NAME has a BAD_MODULE in it.
        dir_notable = shared.create_dir()
        # Create the peru.yaml file for NOTABLE_NAME.
        self.write_yaml('''\
            imports:
                BAD_MODULE: ./
            git module BAD_MODULE:
                bad_field: stuff
                # The error we get here will actually be that `url` is missing.
            ''',
                        dir=dir_notable)
        # Now make our test project import it.
        self.write_yaml(
            '''\
            imports:
                NOTABLE_NAME: ./notable

            cp module NOTABLE_NAME:
                recursive: true
                path: {}
            ''', dir_notable)
        with self.assertRaises(peru.error.PrintableError) as cm:
            run_peru_command(['sync'], self.test_dir)
        self.assertIn("NOTABLE_NAME", cm.exception.message)
        self.assertIn("BAD_MODULE", cm.exception.message)
Пример #2
0
    def test_identical_plugin_cache_fields(self):
        # Plugins that use caching also need to avoid running in parallel, if
        # their cache directories are the same. The noop_cache plugin (created
        # for this test) uses the path field (but not the nonce field) in its
        # plugin cache key. Check that these two modules are not fetched in
        # parallel, even though their module fields aren't exactly the same.
        foo = shared.create_dir()
        peru_yaml = dedent('''\
            imports:
                foo1: ./
                foo2: ./

            noop_cache module foo1:
                path: {}
                # nonce is ignored, but it makes foo1 different from foo2 as
                # far as the module cache is concerned
                nonce: '1'

            noop_cache module foo2:
                path: {}
                nonce: '2'
            '''.format(foo, foo))
        test_dir = shared.create_dir({'peru.yaml': peru_yaml})
        shared.run_peru_command(['sync'], test_dir)
        assert_parallel(1)
Пример #3
0
 def test_flags_override_vars(self):
     flag_cache_dir = shared.create_dir()
     env_cache_dir = shared.create_dir()
     shared.run_peru_command(['--cache-dir', flag_cache_dir, 'sync'],
                             self.cwd,
                             env={'PERU_CACHE_DIR': env_cache_dir})
     self.assert_success(self.project_dir, self.state_dir, flag_cache_dir)
Пример #4
0
    def test_relative_override_from_subdir(self):
        self.write_peru_yaml('''\
            empty module foo:

            imports:
                foo: ./
            ''')
        # Create some subdirs inside the project.
        subdir = os.path.join(self.test_dir, 'a', 'b')
        peru.compat.makedirs(subdir)
        # Create an override dir outside the project.
        override_dir = shared.create_dir({'foo': 'override'})
        # Set the override from inside subdir, using the relative path that's
        # valid from that location. Peru is going to store this path in
        # .peru/overrides/ at the root, so this tests that we resolve the
        # stored path properly.
        relative_path = os.path.relpath(override_dir, start=subdir)
        run_peru_command(['override', 'add', 'foo', relative_path],
                         subdir)
        # Confirm that the right path is stored on disk.
        expected_stored_path = os.path.relpath(
            override_dir, start=self.test_dir)
        with open(os.path.join(self.peru_dir, "overrides", "foo")) as f:
            actual_stored_path = f.read()
        self.assertEqual(expected_stored_path, actual_stored_path)
        # Confirm that `peru override` prints output that respects the cwd.
        output = run_peru_command(['override'], subdir)
        self.assertEqual("foo: {}\n".format(relative_path), output)
        # Confirm that syncing works.
        self.do_integration_test(['sync'], {'foo': 'override'}, cwd=subdir)
Пример #5
0
    def test_rules_in_override(self):
        def _write_peru_yaml(target):
            self.write_peru_yaml('''\
                imports:
                    TARGET: ./

                cp module foo:
                    path: {}

                rule test_build:
                    build: |
                        printf fee >> fi
                        mkdir -p subdir
                        printf fo >> subdir/fum

                rule test_export:
                    export: subdir
                '''.replace('TARGET', target))

        _write_peru_yaml('foo|test_build')
        override_dir = shared.create_dir()
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)

        # Syncing against a build rule should build in the override.
        self.do_integration_test(['sync'], {'fi': 'fee', 'subdir/fum': 'fo'})

        # Another sync should run the build again.
        self.do_integration_test(
            ['sync'], {'fi': 'feefee', 'subdir/fum': 'fofo'})

        # Make sure export dirs are respected in rules that come after.
        _write_peru_yaml('foo|test_build|test_export|test_build')
        self.do_integration_test(
            ['sync'], {'fum': 'fofofo', 'fi': 'fee', 'subdir/fum': 'fo'})
Пример #6
0
    def test_recursive_import_error(self):
        '''Errors that happen inside recursively-fetched targets should have
        context information about the targets that caused them. This test is
        especially important for checking that context isn't lost in
        GatheredExceptions.'''
        # Project NOTABLE_NAME has a BAD_MODULE in it.
        dir_notable = shared.create_dir()
        # Create the peru.yaml file for NOTABLE_NAME.
        self.write_yaml('''\
            imports:
                BAD_MODULE: ./
            git module BAD_MODULE:
                bad_field: stuff
                # The error we get here will actually be that `url` is missing.
            ''', dir=dir_notable)
        # Now make our test project import it.
        self.write_yaml('''\
            imports:
                NOTABLE_NAME: ./notable

            cp module NOTABLE_NAME:
                recursive: true
                path: {}
            ''', dir_notable)
        with self.assertRaises(peru.error.PrintableError) as cm:
            run_peru_command(['sync'], self.test_dir)
        self.assertIn("NOTABLE_NAME", cm.exception.message)
        self.assertIn("BAD_MODULE", cm.exception.message)
Пример #7
0
    def test_reup_all(self):
        yaml_with_imports = dedent('''\
            imports:
                foo: ./
                bar: ./

            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        test_dir = shared.create_dir({'peru.yaml': yaml_with_imports})
        expected = dedent('''\
            imports:
                foo: ./
                bar: ./

            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
                rev: {}
            ''').format(self.foo_dir, self.foo_master, self.bar_dir,
                        self.bar_otherbranch)
        run_peru_command(['reup'], test_dir)
        # This time we finally pull in barfile.
        assert_contents(test_dir,
                        {'peru.yaml': expected, 'a': 'b', 'barfile': 'new'},
                        excludes=['.peru'])
Пример #8
0
 def test_flags_override_vars(self):
     flag_cache_dir = shared.create_dir()
     env_cache_dir = shared.create_dir()
     shared.run_peru_command(['--cache-dir', flag_cache_dir, 'sync'],
                             self.cwd,
                             env={'PERU_CACHE_DIR': env_cache_dir})
     self.assert_success(self.project_dir, self.state_dir, flag_cache_dir)
Пример #9
0
    def test_relative_override_from_subdir(self):
        self.write_yaml('''\
            empty module foo:

            imports:
                foo: ./
            ''')
        # Create some subdirs inside the project.
        subdir = os.path.join(self.test_dir, 'a', 'b')
        peru.compat.makedirs(subdir)
        # Create an override dir outside the project.
        override_dir = shared.create_dir({'foo': 'override'})
        # Set the override from inside subdir, using the relative path that's
        # valid from that location. Peru is going to store this path in
        # .peru/overrides/ at the root, so this tests that we resolve the
        # stored path properly.
        relative_path = os.path.relpath(override_dir, start=subdir)
        run_peru_command(['override', 'add', 'foo', relative_path], subdir)
        # Confirm that the right path is stored on disk.
        expected_stored_path = os.path.relpath(override_dir,
                                               start=self.test_dir)
        with open(os.path.join(self.peru_dir, 'overrides', 'foo')) as f:
            actual_stored_path = f.read()
        self.assertEqual(expected_stored_path, actual_stored_path)
        # Confirm that `peru override` prints output that respects the cwd.
        output = run_peru_command(['override'], subdir)
        self.assertEqual('foo: {}\n'.format(relative_path), output)
        # Confirm that syncing works.
        self.do_integration_test(['sync'], {'foo': 'override'}, cwd=subdir)
Пример #10
0
 def do_integration_test(self, args, expected, *, cwd=None,
                         **peru_cmd_kwargs):
     if not cwd:
         cwd = self.test_dir
     run_peru_command(args, cwd, **peru_cmd_kwargs)
     assert_contents(self.test_dir, expected,
                     excludes=[DEFAULT_PERU_FILE_NAME, '.peru'])
Пример #11
0
 def test_default_file_name(self):
     shutil.move(self.peru_file, os.path.join(self.project_dir, 'xxx'))
     shared.run_peru_command(['--file-basename', 'xxx', 'sync'],
                             cwd=self.cwd)
     self.assert_success(self.project_dir,
                         self.state_dir,
                         self.cache_dir,
                         more_excludes=['xxx'])
Пример #12
0
 def test_setting_all_env_vars(self):
     cache_dir = shared.create_dir()
     shared.run_peru_command(['sync'],
                             self.cwd,
                             env={
                                 'PERU_CACHE_DIR': cache_dir,
                             })
     self.assert_success(self.project_dir, self.state_dir, cache_dir)
Пример #13
0
 def test_relative_paths(self):
     '''We ran into a bug where calling os.path.dirname(peru_file) was
     returning "", which got passed as the cwd of a plugin job and blew up.
     This test repros that case. We've switched to pathlib.Path.parent to
     fix the issue.'''
     shared.run_peru_command(
         ['--file', 'peru.yaml', '--sync-dir', '.', 'sync'],
         cwd=self.project_dir)
     self.assert_success(self.project_dir, self.state_dir, self.cache_dir)
Пример #14
0
 def test_override_after_regular_sync(self):
     self.write_peru_yaml(self.override_test_yaml)
     # First, do a regular sync.
     self.do_integration_test(['sync'], {'builtfoo': 'bar!'})
     # Now, add an override, and confirm that the new sync works.
     override_dir = shared.create_dir({'foo': 'override'})
     run_peru_command(['override', 'add', 'foo', override_dir],
                      self.test_dir)
     self.do_integration_test(['sync'], {'builtfoo': 'override!'})
Пример #15
0
 def test_relative_paths(self):
     '''We ran into a bug where calling os.path.dirname(peru_file) was
     returning "", which got passed as the cwd of a plugin job and blew up.
     This test repros that case. We've switched to pathlib.Path.parent to
     fix the issue.'''
     shared.run_peru_command(
         ['--file', 'peru.yaml', '--sync-dir', '.', 'sync'],
         cwd=self.project_dir)
     self.assert_success(self.project_dir, self.state_dir, self.cache_dir)
Пример #16
0
 def test_setting_all_flags(self):
     cwd = shared.create_dir()
     sync_dir = shared.create_dir()
     state_dir = shared.create_dir()
     cache_dir = shared.create_dir()
     shared.run_peru_command([
         '--file', self.peru_file, '--sync-dir', sync_dir, '--state-dir',
         state_dir, '--cache-dir', cache_dir, 'sync'
     ], cwd)
     self.assert_success(sync_dir, state_dir, cache_dir)
Пример #17
0
 def test_setting_all_flags(self):
     cwd = shared.create_dir()
     sync_dir = shared.create_dir()
     state_dir = shared.create_dir()
     cache_dir = shared.create_dir()
     shared.run_peru_command(
         ['--file', self.peru_file, '--sync-dir', sync_dir,
          '--state-dir', state_dir, '--cache-dir', cache_dir, 'sync'],
         cwd)
     self.assert_success(sync_dir, state_dir, cache_dir)
Пример #18
0
    def test_override_excludes_dotperu(self):
        self.write_peru_yaml('''\
            empty module foo:

            imports:
                foo: ./
            ''')
        override_dir = shared.create_dir(
            {'foo': 'override', '.peru/bar': 'baz'})
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        self.do_integration_test(['sync'], {'foo': 'override'})
Пример #19
0
 def do_integration_test(self,
                         args,
                         expected,
                         *,
                         cwd=None,
                         **peru_cmd_kwargs):
     if not cwd:
         cwd = self.test_dir
     run_peru_command(args, cwd, **peru_cmd_kwargs)
     assert_contents(self.test_dir,
                     expected,
                     excludes=[DEFAULT_PERU_FILE_NAME, '.peru'])
Пример #20
0
    def test_number_of_git_commands(self):
        '''A no-op sync should be a single git command. Also check that index
        files are deleted after any sync error.'''
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            cp module foo:
                path: {}

            imports:
                foo: subdir
            ''', module_dir)
        index_path = os.path.join(self.test_dir, '.peru/lastimports.index')

        # The first sync should take multiple operations and create a
        # lastimports.index file.
        peru.cache.DEBUG_GIT_COMMAND_COUNT = 0
        self.do_integration_test(['sync'], {'subdir/foo': 'bar'})
        assert peru.cache.DEBUG_GIT_COMMAND_COUNT > 1, \
            'The first sync should take multiple operations.'
        assert os.path.exists(index_path), \
            'The first sync should create an index file.'

        # The second sync should reuse the index file and only take one
        # operation.
        peru.cache.DEBUG_GIT_COMMAND_COUNT = 0
        self.do_integration_test(['sync'], {'subdir/foo': 'bar'})
        assert peru.cache.DEBUG_GIT_COMMAND_COUNT == 1, \
            'The second sync should take only one operation.'
        assert os.path.exists(index_path), \
            'The second sync should preserve the index file.'

        # Now force an error. This should delete the index file.
        with open(os.path.join(self.test_dir, 'subdir/foo'), 'w') as f:
            f.write('dirty')
        with self.assertRaises(peru.cache.DirtyWorkingCopyError):
            run_peru_command(['sync'], self.test_dir)
        assert not os.path.exists(index_path), \
            'The error should delete the index file.'

        # Fix the error and resync with new module contents. This should
        # recreate the index file with the current tree and then succeed,
        # rather than using an empty index and treating the current files as
        # conflicting.
        with open(os.path.join(self.test_dir, 'subdir/foo'), 'w') as f:
            f.write('bar')
        with open(os.path.join(module_dir, 'foo'), 'w') as f:
            f.write('new bar')
        self.do_integration_test(['sync', '--no-cache'],
                                 {'subdir/foo': 'new bar'})
        assert os.path.exists(index_path), \
            'The index should have been recreated.'
Пример #21
0
    def test_number_of_git_commands(self):
        '''A no-op sync should be a single git command. Also check that index
        files are deleted after any sync error.'''
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            cp module foo:
                path: {}

            imports:
                foo: subdir
            ''', module_dir)
        index_path = os.path.join(self.test_dir, '.peru/lastimports.index')

        # The first sync should take multiple operations and create a
        # lastimports.index file.
        peru.cache.DEBUG_GIT_COMMAND_COUNT = 0
        self.do_integration_test(['sync'], {'subdir/foo': 'bar'})
        assert peru.cache.DEBUG_GIT_COMMAND_COUNT > 1, \
            'The first sync should take multiple operations.'
        assert os.path.exists(index_path), \
            'The first sync should create an index file.'

        # The second sync should reuse the index file and only take one
        # operation.
        peru.cache.DEBUG_GIT_COMMAND_COUNT = 0
        self.do_integration_test(['sync'], {'subdir/foo': 'bar'})
        assert peru.cache.DEBUG_GIT_COMMAND_COUNT == 1, \
            'The second sync should take only one operation.'
        assert os.path.exists(index_path), \
            'The second sync should preserve the index file.'

        # Now force an error. This should delete the index file.
        with open(os.path.join(self.test_dir, 'subdir/foo'), 'w') as f:
            f.write('dirty')
        with self.assertRaises(peru.cache.DirtyWorkingCopyError):
            run_peru_command(['sync'], self.test_dir)
        assert not os.path.exists(index_path), \
            'The error should delete the index file.'

        # Fix the error and resync with new module contents. This should
        # recreate the index file with the current tree and then succeed,
        # rather than using an empty index and treating the current files as
        # conflicting.
        with open(os.path.join(self.test_dir, 'subdir/foo'), 'w') as f:
            f.write('bar')
        with open(os.path.join(module_dir, 'foo'), 'w') as f:
            f.write('new bar')
        self.do_integration_test(['sync', '--no-cache'],
                                 {'subdir/foo': 'new bar'})
        assert os.path.exists(index_path), \
            'The index should have been recreated.'
Пример #22
0
    def test_single_reup(self):
        expected = dedent('''\
            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        run_peru_command(['reup', 'foo'], self.test_dir)
        assert_contents(self.test_dir, {'peru.yaml': expected},
                        excludes=['.peru'])
Пример #23
0
    def test_single_reup(self):
        expected = dedent('''\
            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        run_peru_command(['reup', 'foo'], self.test_dir)
        assert_contents(self.test_dir, {'peru.yaml': expected},
                        excludes=['.peru'])
Пример #24
0
    def test_override_excludes_dotperu(self):
        self.write_yaml('''\
            empty module foo:

            imports:
                foo: ./
            ''')
        override_dir = shared.create_dir({
            'foo': 'override',
            '.peru/bar': 'baz'
        })
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        self.do_integration_test(['sync'], {'foo': 'override'})
Пример #25
0
    def test_override(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            cp module foo:
                path: {}

            imports:
                foo: ./
            ''', module_dir)
        override_dir = shared.create_dir({'foo': 'override'})
        # Set the override.
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        # Confirm that the override is configured.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Make sure 'override list' gives the same output as 'override'.
        output = run_peru_command(['override', 'list'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Same as above, but as JSON (with --json flag).
        output = run_peru_command(['override', '--json'], self.test_dir)
        override_dict = json.loads(output)
        self.assertEqual(override_dict, {'foo': override_dir})
        # Run the sync with --no-overrides and confirm nothing changes. Also
        # check that there's no overrides-related output.
        output = self.do_integration_test(['sync', '--no-overrides'],
                                          {'foo': 'bar'})
        self.assertNotIn('overrides', output)
        # Now run the sync normally and confirm that the override worked. Also
        # confirm that we mentioned the override in output, and that the unused
        # overrides warning is not printed.
        output = self.do_integration_test(['sync'], {'foo': 'override'})
        self.assertIn('overrides', output)
        self.assertNotIn('WARNING unused overrides', output)
        # Delete the override.
        run_peru_command(['override', 'delete', 'foo'], self.test_dir)
        # Confirm that the override was deleted.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, '')
        # Rerun the sync and confirm the original content is back.
        self.do_integration_test(['sync'], {'foo': 'bar'})
        # Add a bogus override and confirm the unused overrides warning is
        # printed.
        run_peru_command(['override', 'add', 'bogus', override_dir],
                         self.test_dir)
        output = self.do_integration_test(['sync'], {'foo': 'bar'})
        self.assertIn('WARNING unused overrides', output)
Пример #26
0
    def test_override(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            cp module foo:
                path: {}

            imports:
                foo: ./
            ''', module_dir)
        override_dir = shared.create_dir({'foo': 'override'})
        # Set the override.
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        # Confirm that the override is configured.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Make sure 'override list' gives the same output as 'override'.
        output = run_peru_command(['override', 'list'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Same as above, but as JSON (with --json flag).
        output = run_peru_command(['override', '--json'], self.test_dir)
        override_dict = json.loads(output)
        self.assertEqual(override_dict, {'foo': override_dir})
        # Run the sync with --no-overrides and confirm nothing changes. Also
        # check that there's no overrides-related output.
        output = self.do_integration_test(['sync', '--no-overrides'],
                                          {'foo': 'bar'})
        self.assertNotIn('overrides', output)
        # Now run the sync normally and confirm that the override worked. Also
        # confirm that we mentioned the override in output, and that the unused
        # overrides warning is not printed.
        output = self.do_integration_test(['sync'], {'foo': 'override'})
        self.assertIn('overrides', output)
        self.assertNotIn('WARNING unused overrides', output)
        # Delete the override.
        run_peru_command(['override', 'delete', 'foo'], self.test_dir)
        # Confirm that the override was deleted.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, '')
        # Rerun the sync and confirm the original content is back.
        self.do_integration_test(['sync'], {'foo': 'bar'})
        # Add a bogus override and confirm the unused overrides warning is
        # printed.
        run_peru_command(['override', 'add', 'bogus', override_dir],
                         self.test_dir)
        output = self.do_integration_test(['sync'], {'foo': 'bar'})
        self.assertIn('WARNING unused overrides', output)
Пример #27
0
    def test_build_output(self):
        # Make sure build commands are sending their output to the display like
        # they're supposed do. This also has the effect of testing that modules
        # and rules are cached like they're supposed to be -- if not, they'll
        # show up in the output more than once.
        self.write_peru_yaml('''\
            imports:
                basic: dir1/
                basic|complicated: dir2/

            cp module basic:
                path: {}
                build: echo foo

            rule complicated:
                build: echo bar
            ''')
        expected_output = dedent('''\
            === started basic ===
            === finished basic ===
            foo
            bar
            ''')
        output = run_peru_command(['sync', '-v'], self.test_dir)
        self.assertEqual(expected_output, output)
Пример #28
0
    def test_module_list(self):
        self.write_yaml('''\
            git module foo:
                url: blah
            git module bar:
                url: blah
            ''')

        output = run_peru_command(['module'], self.test_dir)
        self.assertEqual(output, "bar\nfoo\n")

        output = run_peru_command(['module', 'list'], self.test_dir)
        self.assertEqual(output, "bar\nfoo\n")

        output = run_peru_command(['module', 'list', '--json'], self.test_dir)
        self.assertEqual(output, '["bar", "foo"]\n')
Пример #29
0
    def test_module_list(self):
        self.write_yaml('''\
            git module foo:
                url: blah
            git module bar:
                url: blah
            ''')

        output = run_peru_command(['module'], self.test_dir)
        self.assertEqual(output, "bar\nfoo\n")

        output = run_peru_command(['module', 'list'], self.test_dir)
        self.assertEqual(output, "bar\nfoo\n")

        output = run_peru_command(['module', 'list', '--json'], self.test_dir)
        self.assertEqual(output, '["bar", "foo"]\n')
Пример #30
0
    def test_override_after_regular_sync(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml('''\
            cp module foo:
                path: {}

            imports:
                foo: ./
            ''', module_dir)
        # First, do a regular sync.
        self.do_integration_test(['sync'], {'foo': 'bar'})
        # Now, add an override, and confirm that the new sync works.
        override_dir = shared.create_dir({'foo': 'override'})
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        self.do_integration_test(['sync'], {'foo': 'override'})
Пример #31
0
    def test_override_recursive(self):
        # Module A just includes the file 'foo'.
        module_a_dir = shared.create_dir({'foo': 'bar'})
        # Module B imports module A.
        module_b_dir = shared.create_dir()
        self.write_yaml(
            '''\
            cp module A:
                path: {}

            imports:
                A: A/
            ''',
            module_a_dir,
            dir=module_b_dir)
        # Module C (in self.test_dir) imports module B, and also directly
        # imports module A. When we set an override for module A below, we'll
        # want to check that *both* of these imports get overridden.
        self.write_yaml(
            '''\
            cp module B:
                path: {}
                recursive: true
                # Note that module business happens before rule business, so
                # 'drop: peru.yaml' will not affect the recursion, just the
                # final output.
                drop: peru.yaml

            imports:
                B.A: A/
                B: B/
            ''', module_b_dir)
        # First, do a regular sync.
        self.do_integration_test(['sync'], {
            'A/foo': 'bar',
            'B/A/foo': 'bar',
        })
        # Now set an override for B.A.
        override_dir = shared.create_dir({'foo': 'override'})
        run_peru_command(['override', 'add', 'B.A', override_dir],
                         self.test_dir)
        # Now do another sync. *Both* the directly imported copy of A *and* the
        # copy synced inside of B should be overridden.
        self.do_integration_test(['sync'], {
            'A/foo': 'override',
            'B/A/foo': 'override',
        })
Пример #32
0
    def test_rules_in_override(self):
        module_dir = shared.create_dir({'a/b': 'c'})
        yaml = '''
            imports:
                foo|get_a: ./

            cp module foo:
                path: {}

            rule get_a:
                export: a
            '''
        self.write_yaml(yaml, module_dir)
        override_dir = shared.create_dir({'a/b': 'override'})
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        self.do_integration_test(['sync'], {'b': 'override'})
Пример #33
0
    def test_override_after_regular_sync(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            cp module foo:
                path: {}

            imports:
                foo: ./
            ''', module_dir)
        # First, do a regular sync.
        self.do_integration_test(['sync'], {'foo': 'bar'})
        # Now, add an override, and confirm that the new sync works.
        override_dir = shared.create_dir({'foo': 'override'})
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        self.do_integration_test(['sync'], {'foo': 'override'})
Пример #34
0
 def test_duplicate_keys_warning(self):
     self.write_yaml('''\
         git module foo:
         git module foo:
         ''')
     buffer = io.StringIO()
     with redirect_stderr(buffer):
         run_peru_command(['sync'], self.test_dir)
     assert('WARNING' in buffer.getvalue())
     assert('git module foo' in buffer.getvalue())
     # Make sure --quiet suppresses the warning.
     buffer = io.StringIO()
     with redirect_stderr(buffer):
         run_peru_command(['sync', '--quiet'], self.test_dir)
     # Don't literally check that stderr is empty, because that could get
     # tripped up on other Python warnings (like asyncio taking too long).
     assert 'git module foo' not in buffer.getvalue()
Пример #35
0
 def test_duplicate_keys_warning(self):
     self.write_yaml('''\
         git module foo:
         git module foo:
         ''')
     buffer = io.StringIO()
     with redirect_stderr(buffer):
         run_peru_command(['sync'], self.test_dir)
     assert ('WARNING' in buffer.getvalue())
     assert ('git module foo' in buffer.getvalue())
     # Make sure --quiet suppresses the warning.
     buffer = io.StringIO()
     with redirect_stderr(buffer):
         run_peru_command(['sync', '--quiet'], self.test_dir)
     # Don't literally check that stderr is empty, because that could get
     # tripped up on other Python warnings (like asyncio taking too long).
     assert 'git module foo' not in buffer.getvalue()
Пример #36
0
    def test_rules_in_override(self):
        module_dir = shared.create_dir({'a/b': 'c'})
        yaml = '''
            imports:
                foo|get_a: ./

            cp module foo:
                path: {}

            rule get_a:
                export: a
            '''
        self.write_yaml(yaml, module_dir)
        override_dir = shared.create_dir({'a/b': 'override'})
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        self.do_integration_test(['sync'], {'b': 'override'})
Пример #37
0
    def test_override_recursive(self):
        # Module A just includes the file 'foo'.
        module_a_dir = shared.create_dir({'foo': 'bar'})
        # Module B imports module A.
        module_b_dir = shared.create_dir()
        self.write_yaml('''\
            cp module A:
                path: {}

            imports:
                A: A/
            ''',
                        module_a_dir,
                        dir=module_b_dir)
        # Module C (in self.test_dir) imports module B, and also directly
        # imports module A. When we set an override for module A below, we'll
        # want to check that *both* of these imports get overridden.
        self.write_yaml(
            '''\
            cp module B:
                path: {}
                recursive: true
                # Note that module business happens before rule business, so
                # 'drop: peru.yaml' will not affect the recursion, just the
                # final output.
                drop: peru.yaml

            imports:
                B.A: A/
                B: B/
            ''', module_b_dir)
        # First, do a regular sync.
        self.do_integration_test(['sync'], {
            'A/foo': 'bar',
            'B/A/foo': 'bar',
        })
        # Now set an override for B.A.
        override_dir = shared.create_dir({'foo': 'override'})
        run_peru_command(['override', 'add', 'B.A', override_dir],
                         self.test_dir)
        # Now do another sync. *Both* the directly imported copy of A *and* the
        # copy synced inside of B should be overridden.
        self.do_integration_test(['sync'], {
            'A/foo': 'override',
            'B/A/foo': 'override',
        })
Пример #38
0
    def test_override(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml('''\
            cp module foo:
                path: {}

            imports:
                foo: ./
            ''', module_dir)
        override_dir = shared.create_dir({'foo': 'override'})
        # Set the override.
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        # Confirm that the override is configured.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Make sure 'override list' gives the same output as 'override'.
        output = run_peru_command(['override', 'list'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Run the sync and confirm that the override worked.
        self.do_integration_test(['sync'], {'foo': 'override'})
        # Delete the override.
        run_peru_command(['override', 'delete', 'foo'], self.test_dir)
        # Confirm that the override was deleted.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, '')
        # Rerun the sync and confirm the original content is back.
        self.do_integration_test(['sync'], {'foo': 'bar'})
Пример #39
0
    def test_override(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            cp module foo:
                path: {}

            imports:
                foo: ./
            ''', module_dir)
        override_dir = shared.create_dir({'foo': 'override'})
        # Set the override.
        run_peru_command(['override', 'add', 'foo', override_dir],
                         self.test_dir)
        # Confirm that the override is configured.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Make sure 'override list' gives the same output as 'override'.
        output = run_peru_command(['override', 'list'], self.test_dir)
        self.assertEqual(output, 'foo: {}\n'.format(override_dir))
        # Run the sync and confirm that the override worked.
        self.do_integration_test(['sync'], {'foo': 'override'})
        # Delete the override.
        run_peru_command(['override', 'delete', 'foo'], self.test_dir)
        # Confirm that the override was deleted.
        output = run_peru_command(['override'], self.test_dir)
        self.assertEqual(output, '')
        # Rerun the sync and confirm the original content is back.
        self.do_integration_test(['sync'], {'foo': 'bar'})
Пример #40
0
    def test_sync_from_subdir(self):
        peru_yaml = dedent('''\
            # Use a relative module path, to make sure it gets resolved
            # relative to the project root and not the dir where peru was
            # called.
            cp module relative_foo:
                path: {}

            imports:
                relative_foo: subdir
            '''.format(os.path.relpath(self.module_dir, start=self.test_dir)))
        shared.write_files(self.test_dir, {'peru.yaml': peru_yaml})
        subdir = os.path.join(self.test_dir, 'a', 'b')
        peru.compat.makedirs(subdir)
        run_peru_command(['sync'], subdir)
        self.assertTrue(os.path.isdir(os.path.join(self.test_dir, '.peru')),
                        msg=".peru dir didn't end up in the right place")
        assert_contents(os.path.join(self.test_dir, 'subdir'), {'foo': 'bar'})
Пример #41
0
    def test_identical_fields(self):
        # This checks that modules with identical fields are not fetched in
        # parallel. This is the same logic that protects us from fetching a
        # given module twice, like when two other modules both import it.
        foo = shared.create_dir()
        peru_yaml = dedent('''\
            imports:
                foo1: ./
                foo2: ./

            cp module foo1:
                path: {}

            cp module foo2:
                path: {}
            '''.format(foo, foo))
        test_dir = shared.create_dir({'peru.yaml': peru_yaml})
        shared.run_peru_command(['sync'], test_dir)
        assert_parallel(1)
Пример #42
0
    def test_sync_from_subdir(self):
        module_dir = shared.create_dir({'foo': 'bar'})
        self.write_yaml(
            '''\
            # Use a relative module path, to make sure it gets resolved
            # relative to the project root and not the dir where peru was
            # called.
            cp module relative_foo:
                path: {}

            imports:
                relative_foo: subdir
            ''', os.path.relpath(module_dir, start=self.test_dir))
        subdir = os.path.join(self.test_dir, 'a', 'b')
        peru.compat.makedirs(subdir)
        run_peru_command(['sync'], subdir)
        self.assertTrue(os.path.isdir(os.path.join(self.test_dir, '.peru')),
                        msg=".peru dir didn't end up in the right place")
        assert_contents(os.path.join(self.test_dir, 'subdir'), {'foo': 'bar'})
Пример #43
0
    def test_drop_then_pick_is_an_error(self):
        '''We want drop to run before pick, so that deleting a bunch of stuff
        and then trying to pick it turns into an error. The opposite execution
        order would make this silently succeed. See the discussion at
        https://github.com/buildinspace/peru/issues/150#issuecomment-212580912.
        '''
        content = {'foo': 'stuff'}
        module_dir = shared.create_dir(content)
        self.write_yaml('''\
            cp module foobar:
                path: {}
                drop: foo
                pick: foo

            imports:
                foobar: ./
            ''', module_dir)
        with raises_gathered(peru.rule.NoMatchingFilesError):
            run_peru_command(['sync'], self.test_dir)
Пример #44
0
    def test_jobs_flag(self):
        # This checks that the --jobs flag is respected, even when two modules
        # could have been fetched in parallel.
        foo = shared.create_dir()
        bar = shared.create_dir()
        peru_yaml = dedent('''\
            imports:
                foo: ./
                bar: ./

            cp module foo:
                path: {}

            cp module bar:
                path: {}
            '''.format(foo, bar))
        test_dir = shared.create_dir({'peru.yaml': peru_yaml})
        shared.run_peru_command(['sync', '-j1'], test_dir)
        assert_parallel(1)
Пример #45
0
    def test_two_jobs_in_parallel(self):
        # This just checks that two different modules can actually be fetched
        # in parallel.
        foo = shared.create_dir()
        bar = shared.create_dir()
        peru_yaml = dedent('''\
            imports:
                foo: ./
                bar: ./

            cp module foo:
                path: {}

            cp module bar:
                path: {}
            '''.format(foo, bar))
        test_dir = shared.create_dir({'peru.yaml': peru_yaml})
        shared.run_peru_command(['sync'], test_dir)
        assert_parallel(2)
Пример #46
0
    def test_identical_fields(self):
        # This checks that modules with identical fields are not fetched in
        # parallel. This is the same logic that protects us from fetching a
        # given module twice, like when it's imported with two different named
        # rules.
        foo = shared.create_dir()
        peru_yaml = dedent('''\
            imports:
                foo1: ./
                foo2: ./

            cp module foo1:
                path: {}

            cp module foo2:
                path: {}
            '''.format(foo, foo))
        test_dir = shared.create_dir({'peru.yaml': peru_yaml})
        shared.run_peru_command(['sync'], test_dir)
        assert_parallel(1)
Пример #47
0
    def test_drop_then_pick_is_an_error(self):
        '''We want drop to run before pick, so that deleting a bunch of stuff
        and then trying to pick it turns into an error. The opposite execution
        order would make this silently succeed. See the discussion at
        https://github.com/buildinspace/peru/issues/150#issuecomment-212580912.
        '''
        content = {'foo': 'stuff'}
        module_dir = shared.create_dir(content)
        self.write_yaml(
            '''\
            cp module foobar:
                path: {}
                drop: foo
                pick: foo

            imports:
                foobar: ./
            ''', module_dir)
        with raises_gathered(peru.rule.NoMatchingFilesError):
            run_peru_command(['sync'], self.test_dir)
Пример #48
0
    def test_reup_sync(self):
        yaml_with_imports = dedent('''\
            imports:
                foo: ./
                bar: ./

            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        test_dir = shared.create_dir({'peru.yaml': yaml_with_imports})
        # First reup without the sync.
        run_peru_command(['reup', 'foo', '--nosync'], test_dir)
        assert_contents(test_dir, {}, excludes=['.peru', 'peru.yaml'])
        # Now do it with the sync.
        run_peru_command(['reup', 'foo', '--quiet'], test_dir)
        assert_contents(test_dir, {'a': 'b'}, excludes=['.peru', 'peru.yaml'])
Пример #49
0
    def test_reup_sync(self):
        yaml_with_imports = dedent('''\
            imports:
                foo: ./
                bar: ./

            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        test_dir = shared.create_dir({'peru.yaml': yaml_with_imports})
        # First reup without the sync.
        run_peru_command(['reup', 'foo', '--nosync'], test_dir)
        assert_contents(test_dir, {}, excludes=['.peru', 'peru.yaml'])
        # Now do it with the sync.
        run_peru_command(['reup', 'foo', '--quiet'], test_dir)
        assert_contents(test_dir, {'a': 'b'}, excludes=['.peru', 'peru.yaml'])
Пример #50
0
    def test_single_reup(self):
        yaml_without_imports = dedent('''\
            git module foo:
                url: {}
                rev: master

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.bar_dir)
        test_dir = shared.create_dir({'peru.yaml': yaml_without_imports})
        expected = dedent('''\
            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        run_peru_command(['reup', 'foo'], test_dir)
        assert_contents(test_dir, {'peru.yaml': expected}, excludes=['.peru'])
Пример #51
0
    def test_reup_all(self):
        yaml_with_imports = dedent('''\
            imports:
                foo: ./
                bar: ./

            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        test_dir = shared.create_dir({'peru.yaml': yaml_with_imports})
        expected = dedent('''\
            imports:
                foo: ./
                bar: ./

            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
                rev: {}
            ''').format(self.foo_dir, self.foo_master, self.bar_dir,
                        self.bar_otherbranch)
        run_peru_command(['reup'], test_dir)
        # This time we finally pull in barfile.
        assert_contents(test_dir, {
            'peru.yaml': expected,
            'a': 'b',
            'barfile': 'new'
        },
                        excludes=['.peru'])
Пример #52
0
    def test_single_reup(self):
        yaml_without_imports = dedent('''\
            git module foo:
                url: {}
                rev: master

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.bar_dir)
        test_dir = shared.create_dir({'peru.yaml': yaml_without_imports})
        expected = dedent('''\
            git module foo:
                url: {}
                rev: {}

            git module bar:
                url: {}
                reup: otherbranch
            ''').format(self.foo_dir, self.foo_master, self.bar_dir)
        run_peru_command(['reup', 'foo'], test_dir)
        assert_contents(test_dir, {'peru.yaml': expected},
                        excludes=['.peru'])
Пример #53
0
    def test_recursive_import_error(self):
        '''Errors that happen inside recursively-fetched targets should have
        context information about the targets that caused them.'''
        # Project NOTABLE_NAME has a BAD_MODULE in it.
        dir_notable = shared.create_dir()
        # Create the peru.yaml file for NOTABLE_NAME.
        self.write_yaml('''\
            imports:
                BAD_MODULE: ./
            git module BAD_MODULE:
                bad_field: stuff
            ''', dir=dir_notable)
        # Now make our test project import it.
        self.write_yaml('''\
            imports:
                NOTABLE_NAME: ./

            cp module NOTABLE_NAME:
                path: {}
            ''', dir_notable)
        with self.assertRaises(peru.error.PrintableError) as cm:
            run_peru_command(['sync'], self.test_dir)
        self.assertIn("NOTABLE_NAME", cm.exception.message)
        self.assertIn("BAD_MODULE", cm.exception.message)
Пример #54
0
    def test_help(self):
        flag_output = run_peru_command(['--help'], self.test_dir)
        self.assertEqual(peru.main.__doc__, flag_output)

        command_output = run_peru_command(['help'], self.test_dir)
        self.assertEqual(peru.main.__doc__, command_output)

        clean_help = peru.main.COMMAND_DOCS['clean']

        pre_flag_output = run_peru_command(['-h', 'clean'], self.test_dir)
        self.assertEqual(clean_help, pre_flag_output)

        post_flag_output = run_peru_command(['clean', '-h'], self.test_dir)
        self.assertEqual(clean_help, post_flag_output)

        buffer = io.StringIO()
        with redirect_stderr(buffer):
            run_peru_command(['foobarbaz'], self.test_dir, expected_error=1)
        self.assertEqual(peru.main.__doc__, buffer.getvalue())
Пример #55
0
    def test_help(self):
        flag_output = run_peru_command(['--help'], self.test_dir)
        self.assertEqual(peru.main.__doc__, flag_output)

        command_output = run_peru_command(['help'], self.test_dir)
        self.assertEqual(peru.main.__doc__, command_output)

        clean_help = peru.main.COMMAND_DOCS['clean']

        pre_flag_output = run_peru_command(['-h', 'clean'], self.test_dir)
        self.assertEqual(clean_help, pre_flag_output)

        post_flag_output = run_peru_command(['clean', '-h'], self.test_dir)
        self.assertEqual(clean_help, post_flag_output)

        buffer = io.StringIO()
        with redirect_stderr(buffer):
            run_peru_command(['foobarbaz'], self.test_dir, expected_error=1)
        self.assertEqual(peru.main.__doc__, buffer.getvalue())
Пример #56
0
 def test_file_and_file_basename_incompatible(self):
     with self.assertRaises(CommandLineError):
         shared.run_peru_command([
             '--file=foo', '--sync-dir=bar', '--file-basename=baz', 'sync'
         ],
                                 cwd=self.cwd)
Пример #57
0
 def test_version(self):
     version_output = run_peru_command(["--version"], self.test_dir)
     self.assertEqual(peru.main.get_version(), version_output.strip())