Example #1
0
 def test_trumped_by(self):
     compile_rule.register_compile('TRUMPED_BY',
                                   'genfiles/{{path}}.dot.js', ['??'],
                                   self.copy_compile,
                                   trumped_by=['DOUBLE-BRACE'])
     cr = compile_rule.find_compile_rule('genfiles/path/foo.dot.js')
     self.assertEqual('DOUBLE-BRACE', cr.label)
Example #2
0
 def test_cannot_glob_over_generated_files(self):
     with self.assertRaises(AssertionError):
         compile_rule.register_compile(
             'GENFILES GLOB',
             'genfiles/genfiles_glob',
             ['genfiles/*'],
             CopyCompile())
Example #3
0
 def test_outfile_must_live_in_genfiles(self):
     with self.assertRaises(AssertionError):
         compile_rule.register_compile(
             'NOT GENFILES GLOB',
             'not_genfiles/genfiles_glob',
             ['genfiles/*'],
             CopyCompile())
Example #4
0
    def test_missing_input_file_computed_input(self):
        class ComputedInput(computed_inputs.ComputedInputsBase):
            def input_patterns(self, outfile_name, context, triggers, changed):
                return ['genfiles/i_number_2']

        # By having genfiles/bnumber be a trigger-file to compute the
        # inputs to bnumber.rev, we force bnumber to be immediate-built.
        # This should also cause us to build its non-input dep, i_letter_a.
        compile_rule.register_compile(
            'MISSING FILES: IMMEDIATE',
            'genfiles/i_number_2.rev',
            ComputedInput(['genfiles/bletter']),
            self.rev_compile)

        os.unlink(self._abspath('a1'))
        with mock.patch('kake.log.exception') as logger:
            with self.assertRaises(IOError):
                _build('genfiles/i_number_2.rev')
            self.assertEqual(
                [mock.call('FATAL ERROR building %s (needed via %s)',
                           'genfiles/i_letter_a',
                           ('genfiles/i_number_2.rev (via computed dep)'
                            ' -> genfiles/bletter'
                            ' -> genfiles/fletter'
                            ' -> genfiles/i_letter_a'))],
                logger.call_args_list)
Example #5
0
    def test_input_globs(self):
        # This will match a1, a2, b1, b2
        compile_rule.register_compile('BOTH GLOB', 'genfiles/both_glob',
                                      ['??'], self.copy_compile)

        cr = compile_rule.find_compile_rule('genfiles/both_glob')
        self.assertEqual(['a1', 'a2', 'b1', 'b2'],
                         cr.input_files('genfiles/both_glob'))
Example #6
0
 def test_labels_must_be_unique(self):
     compile_rule.register_compile('NON-UNIQUE LABEL',
                                   'genfiles/{{path}}_copy_2',
                                   ['{{path}}2'], self.copy_compile)
     with self.assertRaises(AssertionError):
         compile_rule.register_compile('NON-UNIQUE LABEL',
                                       'genfiles/subdir/{{path}}_copy_2',
                                       ['genfiles/subdir/{{path}}2'],
                                       self.rev_compile)
Example #7
0
    def test_sneaky_underscore(self):
        compile_rule.register_compile(
            'UNDERSCORE VIA VAR',
            'genfiles/{{path}}',
            ['{{path}}'],
            CopyCompile())

        with self.assertRaises(AssertionError):
            kake.make.build('genfiles/_bad_underscore')
Example #8
0
 def test_we_die_if_buildmany_fails_but_not_during_binary_search(self):
     compile_rule.register_compile(
         'FAIL',
         'genfiles/fail*',
         ['a1'],
         FailToBuild())
     with self.assertRaises(Exception):
         _build_many([('genfiles/fail1', {}),
                      ('genfiles/fail2', {}),
                      ('genfiles/fail3', {}),
                      ('genfiles/fail4', {})])
Example #9
0
    def test_compute_crc(self):
        compile_rule.register_compile('COMPUTE CRC',
                                      'genfiles/has_crc', ['??'],
                                      self.copy_compile,
                                      compute_crc=True)

        cr = compile_rule.find_compile_rule('genfiles/has_crc')
        self.assertTrue(cr.compute_crc)

        cr = compile_rule.find_compile_rule('genfiles/both_a_1')
        self.assertFalse(cr.compute_crc)
Example #10
0
    def test_var_with_underscore(self):
        # Testing {var_with_underscore}
        compile_rule.register_compile('VAR WITH UNDERSCORE',
                                      'genfiles/us/{var_with_underscore}.js',
                                      ['{var_with_underscore}2'],
                                      self.rev_compile)

        cr = compile_rule.find_compile_rule('genfiles/us/foo.js')
        self.assertNotEqual(None, cr)
        self.assertEqual({'{var_with_underscore}': 'foo'},
                         cr.var_values('genfiles/us/foo.js'))
Example #11
0
    def test_circular_dep(self):
        # testing circular deps
        compile_rule.register_compile('CIRCULAR 1', 'genfiles/circular1',
                                      ['genfiles/circular2'],
                                      self.copy_compile)
        compile_rule.register_compile('CIRCULAR 2', 'genfiles/circular2',
                                      ['genfiles/circular1'],
                                      self.copy_compile)

        graph = build.DependencyGraph()
        with self.assertRaises(build.CompileFailure):
            self._add_to_dependency_graph('genfiles/circular1', graph)
Example #12
0
    def test_must_not_start_with_underscore(self):
        compile_rule.register_compile(
            'UNDERSCORE IN GENFILES SUBDIR',
            'genfiles/dir/_underscore_ok_here',
            ['foo/infile'],
            CopyCompile())

        with self.assertRaises(AssertionError):
            compile_rule.register_compile(
                'UNDERSCORE IN GENFILES MAINDIR',
                'genfiles/_underscore_not_ok_here',
                ['foo/infile'],
                CopyCompile())
Example #13
0
    def test_must_be_in_genfiles(self):
        compile_rule.register_compile(
            'OUTFILE IN GENFILES',
            'genfiles/outfile',
            ['foo/infile'],
            CopyCompile())

        with self.assertRaises(AssertionError):
            compile_rule.register_compile(
                'OUTFILE NOT IN GENFILES',
                'foo/outfile',
                ['foo/infile'],
                CopyCompile())
Example #14
0
    def test_force_recomputes_inputs(self):
        input_filenames = ['genfiles/i_number_2']

        class ComputedInput(computed_inputs.ComputedInputsBase):
            def __init__(self, *args):
                super(ComputedInput, self).__init__(*args)

            def version(self):
                return 1

            def input_patterns(self, outfile_name, context, triggers, changed):
                return input_filenames

        computed_input = ComputedInput(['a1'])

        compile_rule.register_compile(
            'IMMEDIATE',
            'genfiles/i_number_2.rev',
            computed_input,
            self.copy_compile)

        # We should be calling build twice, once for i_number_2.rev and once
        # for the input 'genfiles/i_number_2'
        with self.assertCalled(self.copy_compile._build, 2):
            _build('genfiles/i_number_2.rev')

        self.assertFileDoesNotExist('genfiles/i_number_1')
        self.assertFile('genfiles/i_number_2',
                        'a2: line 1\na2: line 2\nb2: line 1\nb2: line 2\n')

        # Now lets change the computed input file names
        input_filenames = ['genfiles/i_number_2', 'genfiles/i_number_1']

        # Rebuilding should not call _build at all because the previous inputs
        # and the trigger have not changed.
        with self.assertCalled(self.copy_compile._build, 0):
            _build('genfiles/i_number_2.rev')

        self.assertFileDoesNotExist('genfiles/i_number_1')
        self.assertFile('genfiles/i_number_2',
                        'a2: line 1\na2: line 2\nb2: line 1\nb2: line 2\n')

        # With the force flag though we should be recalculating the inputs and
        # build them both and i_number_2.rev
        with self.assertCalled(self.copy_compile._build, 3):
            _build('genfiles/i_number_2.rev', force=True)

        self.assertFile('genfiles/i_number_1',
                        'a1: line 1\na1: line 2\nb1: line 1\nb1: line 2\n')
        self.assertFile('genfiles/i_number_2',
                        'a2: line 1\na2: line 2\nb2: line 1\nb2: line 2\n')
Example #15
0
    def test_find_compile_rule_prefers_more_directory_parts(self):
        # Something that uses two vs three directory parts
        compile_rule.register_compile('TWO DIRS', 'genfiles/{{path}}_copy_2',
                                      ['{{path}}2'], self.copy_compile)
        compile_rule.register_compile('THREE DIRS',
                                      'genfiles/subdir/{{path}}_copy_2',
                                      ['genfiles/subdir/{{path}}2'],
                                      self.rev_compile)

        cr = compile_rule.find_compile_rule('genfiles/make_a_copy_2')
        self.assertEqual('genfiles/{{path}}_copy_2', cr.output_pattern)
        cr = compile_rule.find_compile_rule('genfiles/whatever/make_a_copy_2')
        self.assertEqual('genfiles/{{path}}_copy_2', cr.output_pattern)
        cr = compile_rule.find_compile_rule('genfiles/subdir/make_a_copy_2')
        self.assertEqual('genfiles/subdir/{{path}}_copy_2', cr.output_pattern)
Example #16
0
    def test_input_map(self):
        # Something that uses a 'system var' in the context.
        compile_rule.register_compile('INPUT MAP', 'genfiles/input_map', [],
                                      WriteContextInputMap())

        _build_many([('genfiles/input_map', {}), ('genfiles/fletter', {})])
        with open(os.path.join(self.tmpdir, 'genfiles', 'input_map')) as f:
            input_map = json.load(f)
        expected = {
            'genfiles/fletter': ['genfiles/i_letter_a', 'genfiles/i_letter_b'],
            'genfiles/i_letter_a': ['a1', 'a2'],
            'genfiles/i_letter_b': ['b1', 'b2'],
            'genfiles/input_map': []
        }
        self.assertEqual(expected, input_map)
Example #17
0
    def test_maybe_symlink_to(self):
        compile_rule.register_compile('SYMLINK',
                                      'genfiles/bletter_symlink',
                                      ['genfiles/fletter'],
                                      self.rev_compile,
                                      maybe_symlink_to='genfiles/bletter')

        _build('genfiles/bletter_symlink')
        self.assertTrue(
            os.path.islink(self._abspath('genfiles', 'bletter_symlink')))
        self.assertEqual(
            os.path.join('bletter'),
            os.readlink(self._abspath('genfiles', 'bletter_symlink')))

        # Check that when we rebuild, it doesn't try to symlink again.
        with self.assertCalled(os.symlink, 0):
            _build('genfiles/bletter_symlink')
Example #18
0
    def test_immediate_build(self):
        class ComputedInput(computed_inputs.ComputedInputsBase):
            def __init__(self, test_method, *args):
                super(ComputedInput, self).__init__(*args)
                self.test_method = test_method

            def version(self):
                return 1

            def input_patterns(self, outfile_name, context, triggers, changed):
                # Not only should our trigger have been built, so should
                # its non-input deps.
                self.test_method.assertFile('genfiles/i_letter_a',
                                            ('a1: line 1\na1: line 2\n'
                                             'a2: line 1\na2: line 2\n'))
                return ['genfiles/i_number_2']

        # By having genfiles/bnumber be a trigger-file to compute the
        # inputs to bnumber.rev, we force bnumber to be immediate-built.
        # This should also cause us to build its non-input dep, i_letter_a.
        compile_rule.register_compile(
            'IMMEDIATE',
            'genfiles/i_number_2.rev',
            ComputedInput(self, ['genfiles/bnumber']),
            self.rev_compile)
        _build('genfiles/i_number_2.rev')
        # This should also have built i_number_2, which is what the
        # ComputedInput returns.
        self.assertFile('genfiles/i_number_2',
                        'a2: line 1\na2: line 2\nb2: line 1\nb2: line 2\n')

        # Make sure that immediate builds can also raise an exception when
        # these is no matching rule
        compile_rule.register_compile(
            'IMMEDIATE2',
            'genfiles/not_a_real_file.bmp',
            ComputedInput(
                self,
                ['genfiles/not_real_either']),
            self.rev_compile)

        with self.assertRaises(
                compile_rule.NoBuildRuleCompileFailure):
            _build('genfiles/not_a_real_file.bmp')
Example #19
0
    def test_find_compile_rule_prefers_longer_extensions(self):
        # Something that uses one vs two vs three extensions
        compile_rule.register_compile(
            'ONE DOT',
            'genfiles/subdir/{{path}}.2',
            ['{{path}}2'],
            self.copy_compile)
        compile_rule.register_compile(
            'TWO DOTS',
            'genfiles/{{path}}.copy.2',
            ['{{path}}2'],
            self.rev_compile)
        compile_rule.register_compile(
            'TWO DOTS NO VARS',
            'genfiles/most_specific.copy.2',
            ['most_specific2'],
            self.rev_compile)

        cr = compile_rule.find_compile_rule(
            'genfiles/subdir/make_a.copy.2')
        self.assertEqual('genfiles/{{path}}.copy.2', cr.output_pattern)
        cr = compile_rule.find_compile_rule(
            'genfiles/subdir/make_a.dupe.2')
        self.assertEqual('genfiles/subdir/{{path}}.2', cr.output_pattern)
        cr = compile_rule.find_compile_rule(
            'genfiles/most_specific.copy.2')
        self.assertEqual('genfiles/most_specific.copy.2', cr.output_pattern)
Example #20
0
    def setUp(self):
        super(TestBase, self).setUp()  # sets up self.tmpdir as ka-root

        os.makedirs(os.path.join(self.tmpdir, 'genfiles', 'computed_inputs'))

        for filename in ('a1', 'a2', 'b1', 'b2', 'number3'):
            with open(self._abspath(filename), 'w') as f:
                f.write('%s: line 1' % filename + "\n")
                f.write('%s: line 2' % filename + "\n")

        compile_rule.register_compile('STATIC',
                                      'genfiles/computed_inputs/static',
                                      ComputedStaticInputs(['a1', 'a2']),
                                      CopyCompile())

        compile_rule.register_compile('UNNORMALIZED',
                                      'genfiles/computed_inputs/unnormalized',
                                      UnnormalizedComputedInputs(['a1', 'a2']),
                                      CopyCompile())

        compile_rule.register_compile('A',
                                      'genfiles/computed_inputs/a{number}',
                                      ComputedInputsFromVar(['number3']),
                                      CopyCompile())

        compile_rule.register_compile(
            'B', 'genfiles/computed_inputs/b{number}',
            ComputedInputsFromVar(['b{number}'], compute_crc=True),
            CopyCompile())

        compile_rule.register_compile(
            'B TAKE 2', 'genfiles/computed_2/b{number}',
            ComputedInputsFromVar(['genfiles/computed_inputs/b{number}']),
            CopyCompile())

        compile_rule.register_compile(
            'FROM CONTEXT', 'genfiles/computed_fromcontext/index',
            ComputedInputsFromContext(['genfiles/computed_inputs/b1']),
            CopyCompile())

        compile_rule.register_compile(
            'COMPUTED', 'genfiles/computed_inputs/content',
            ComputedInputsFromFileContents(['a1'], compute_crc=True),
            CopyCompile())

        compile_rule.register_compile(
            'CURR', 'genfiles/computed_inputs/curr',
            ComputedStaticInputs([computed_inputs.CURRENT_INPUTS]),
            CopyCompile())

        compile_rule.register_compile(
            'CURR2', 'genfiles/computed_inputs/curr2',
            ComputedInputsFromChangedContents(
                ['a1', computed_inputs.CURRENT_INPUTS]), CopyCompile())

        compile_rule.register_compile(
            'FORCE', 'genfiles/computed_inputs/force',
            ComputedStaticInputs(computed_inputs.FORCE), CopyCompile())
Example #21
0
    def setUp(self):
        super(TestComputedIncludes, self).setUp()

        os.makedirs(self._abspath('includes'))

        with open(self._abspath('a.c'), 'w') as f:
            f.write('#include <stdio.h>' + "\n")
            f.write('#include "a.h"' + "\n")
            f.write('int main() { return 0; }' + "\n")

        with open(self._abspath('commented.c'), 'w') as f:
            f.write('/*' + "\n")
            f.write('#include "a.h"' + "\n")
            f.write('*/' + "\n")
            f.write('#include "includes/d.h"' + "\n")

        with open(self._abspath('a.h'), 'w') as f:
            f.write('#include "includes/b.h"' + "\n")

        with open(self._abspath('stdio.h'), 'w') as f:
            f.write('' + "\n")

        with open(self._abspath(os.path.join('includes', 'b.h')), 'w') as f:
            f.write('#include "c.h"' + "\n")

        with open(self._abspath(os.path.join('includes', 'c.h')), 'w') as f:
            f.write('#define AVOID_CIRCULAR_INCLUDE 1' + "\n")
            f.write('#include "b.h"' + "\n")
            f.write('#include "../a.h"' + "\n")

        with open(self._abspath(os.path.join('includes', 'd.h')), 'w') as f:
            f.write('#define MY_USE "hello, world"' + "\n")

        with open(self._abspath('b.c'), 'w') as f:
            f.write('#include "includes/b.h"' + "\n")

        with open(self._abspath('double_include.c'), 'w') as f:
            f.write('#include "./a.h"' + "\n")
            f.write('#include "./a.h"' + "\n")

        with open(self._abspath('yelling.loudc'), 'w') as f:
            f.write('#INCLUDE "VUVUZELA.C"' + "\n")
            f.write('#INCLUDE "GODZILLA.C"' + "\n")
            f.write('INT MAIN() { RETURN 0; }' + "\n")

        with open(self._abspath('vuvuzela.loudc'), 'w') as f:
            f.write('#INCLUDE "GODZILLA.C"' + "\n")

        with open(self._abspath('godzilla.loudc'), 'w') as f:
            f.write('#INCLUDE "VUVUZELA.C"' + "\n")
            f.write('#DEFINE LOCALE "ja-JP"' + "\n")

        with open(self._abspath('magic.c'), 'w') as f:
            f.write('#include "?.h"' + "\n")

        self.includer = computed_inputs.ComputedIncludeInputs(
            '{{path}}.c', r'^#include\s+"(.*?)"', other_inputs=['a1'])

        compile_rule.register_compile('II', 'genfiles/{{path}}.ii',
                                      self.includer, CopyCompile())

        self.full_includer = (computed_inputs.ComputedIncludeInputs(
            '{{path}}.c', r'^#include\s+"(.*?)"|^#include\s+<(.*?)>'))
        compile_rule.register_compile('FULLII', 'genfiles/{{path}}.fullii',
                                      self.full_includer, CopyCompile())

        self.genfiles_includer = ComputedIncludeInputsSubclass(
            'genfiles/{{path}}.c', r'^#include\s+"(.*?)"')

        compile_rule.register_compile('GENII', 'genfiles/{{path}}.genii',
                                      self.genfiles_includer, CopyCompile())

        self.var_dep_includer = VarDependentComputedIncludeInputs(
            'magic.c', r'^#include\s+"(.*?)"')

        compile_rule.register_compile('VARII', 'genfiles/{{path}}.varii',
                                      self.var_dep_includer, CopyCompile())

        self.no_comment_dep_includer = NoCommentComputedIncludeInputs(
            '{{path}}.c', r'^#include\s+"(.*?)"')

        compile_rule.register_compile('NCII', 'genfiles/{{path}}.ncii',
                                      self.no_comment_dep_includer,
                                      CopyCompile())

        compile_rule.register_compile('C', 'genfiles/{{path}}.c',
                                      ['{{path}}.loudc'], DowncaseCompile())
Example #22
0
    def setUp(self):
        super(TestBase, self).setUp()     # sets up self.tmpdir as ka-root

        for filename in ('a1', 'a2', 'b1', 'b2', 'number3'):
            with open(self._abspath(filename), 'w') as f:
                f.write('%s: line 1' % filename + "\n")
                f.write('%s: line 2' % filename + "\n")

        self.copy_compile = CopyCompile()
        self.rev_compile = RevCompile()
        self.write_context = WriteContext()

        # i_number_1 depends on a1 and b1, likewise i_number_2.
        compile_rule.register_compile(
            'NUMBER',
            'genfiles/i_number_{number}',
            ['a{number}', 'b{number}'],
            self.copy_compile)

        # i_letter_a depends on a1 and a2, likewise i_letter_b.
        compile_rule.register_compile(
            'LETTER',
            'genfiles/i_letter_{letter}',
            ['{letter}1', '{letter}2'],
            self.copy_compile)

        # fnumber depends on i_number_1 and i_number_2
        compile_rule.register_compile(
            'FNUMBER',
            'genfiles/fnumber',
            ['genfiles/i_number_1',
             'genfiles/i_number_2'],
            self.copy_compile)

        # fletter depends on i_letter_a and i_letter_b
        compile_rule.register_compile(
            'FLETTER',
            'genfiles/fletter',
            ['genfiles/i_letter_a',
             'genfiles/i_letter_b'],
            self.copy_compile)

        # It uses a different instance of CopyCompile() in order to test
        # that case in TestDependencyChunking.
        compile_rule.register_compile(
            'FMOST',
            'genfiles/fmost',
            ['genfiles/i_letter_a', 'b1'],
            CopyCompile())

        # bnumber depends on oletter, bletter depends on onumber
        compile_rule.register_compile(
            'BLETTER',
            'genfiles/bletter',
            ['genfiles/fletter'],
            self.rev_compile)
        compile_rule.register_compile(
            'BNUMBER',
            'genfiles/bnumber',
            ['genfiles/fnumber'],
            self.rev_compile,
            non_input_deps=['genfiles/i_letter_a'])

        # For testing the num-variables code, and crazy maybe_symlink_to.
        compile_rule.register_compile(
            'I3',
            'genfiles/i_number_3',
            ['number3'],
            self.rev_compile,
            maybe_symlink_to='genfiles/bletter')

        # Something that uses two variables
        compile_rule.register_compile(
            'BOTH',
            'genfiles/both_{letter}_{number}',
            ['{letter}{number}'],
            CopyWithVarCompile(),
            maybe_symlink_to='{letter}{number}')

        # Something that uses a user's context
        compile_rule.register_compile(
            'CONTEXT',
            'genfiles/context_content_{number}',
            [],
            self.write_context)

        # Testing {var} vs {{var}}
        compile_rule.register_compile(
            'DOUBLE-BRACE',
            'genfiles/path/{{path}}.js',
            ['{{path}}2'],
            self.rev_compile)
        compile_rule.register_compile(
            'SINGLE-BRACE',
            'genfiles/dir/{path}.js',
            ['{path}2'],
            self.rev_compile)

        # Testing building a lot of files at the same level.
        # We want to test build_many() and split_files()
        compile_rule.register_compile(
            'BASED_ON_FILENAME (MANY)',
            'genfiles/filename_content.m.{content}',
            [],
            WriteBasedOnFilenameMany())
        compile_rule.register_compile(
            'BASED_ON_FILENAME (SPLIT_OUTPUTS)',
            'genfiles/filename_content.s.{content}',
            [],
            WriteBasedOnFilenameSplit())
        compile_rule.register_compile(
            '200 FILES (BUILD_MANY)',
            'genfiles/200files.build_many',
            ['genfiles/filename_content.m.%d' % i
             for i in range(200)],
            self.copy_compile)
        compile_rule.register_compile(
            '200 FILES (SPLIT_OUTPUTS)',
            'genfiles/200files.split_outputs',
            ['genfiles/filename_content.s.%d' % i
             for i in range(200)],
            self.copy_compile)