Exemple #1
0
    def test_clean_all(self):
        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call('partdir1'),
            mock.call().__bool__(),
            mock.call('partdir2'),
            mock.call().__bool__(),
            mock.call('partdir3'),
            mock.call().__bool__(),
            mock.call(common.get_partsdir()),
            mock.call().__bool__(),
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call('partdir1'),
            mock.call('partdir2'),
            mock.call('partdir3'),
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
Exemple #2
0
def main(argv=None):
    argv = argv if argv else []
    args = docopt(__doc__, argv=argv)

    config = snapcraft.yaml.load_config()

    if args['PART']:
        config.validate_parts(args['PART'])

    for part in config.all_parts:
        if not args['PART'] or part.name in args['PART']:
            part.clean()

    # parts dir does not contain only generated code.
    if (os.path.exists(common.get_partsdir()) and
            not os.listdir(common.get_partsdir())):
        os.rmdir(common.get_partsdir())

    parts_match = set(config.part_names) == set(args['PART'])
    # Only clean stage if all the parts were cleaned up.
    clean_stage = not args['PART'] or parts_match
    if clean_stage and os.path.exists(common.get_stagedir()):
        logger.info('Cleaning up staging area')
        shutil.rmtree(common.get_stagedir())

    if os.path.exists(common.get_snapdir()):
        logger.info('Cleaning up snapping area')
        shutil.rmtree(common.get_snapdir())
Exemple #3
0
    def test_clean_all(self):
        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call('partdir1'),
            mock.call().__bool__(),
            mock.call('partdir2'),
            mock.call().__bool__(),
            mock.call('partdir3'),
            mock.call().__bool__(),
            mock.call(common.get_partsdir()),
            mock.call().__bool__(),
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call('partdir1'),
            mock.call('partdir2'),
            mock.call('partdir3'),
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
    def test_partial_clean(self):
        parts = self.make_snapcraft_yaml(n=3)

        main(["clean", "clean0", "clean2"])

        for i in [0, 2]:
            self.assertFalse(
                os.path.exists(parts[i]["part_dir"]), "Expected for {!r} to be wiped".format(parts[i]["part_dir"])
            )

        self.assertTrue(os.path.exists(parts[1]["part_dir"]), "Expected a part directory for the clean1 part")

        self.assertTrue(os.path.exists(common.get_partsdir()))
        self.assertTrue(os.path.exists(common.get_stagedir()))
        self.assertTrue(os.path.exists(common.get_snapdir()))

        # Now clean it the rest of the way
        main(["clean", "clean1"])

        for i in range(0, 3):
            self.assertFalse(
                os.path.exists(parts[i]["part_dir"]), "Expected for {!r} to be wiped".format(parts[i]["part_dir"])
            )

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemple #5
0
def clean(args):
    config = _load_config()

    part_names = {part.name for part in config.all_parts}
    for part_name in args.parts:
        if part_name not in part_names:
            logger.error('The part named {!r} is not defined in '
                         '\'snapcraft.yaml\''.format(part_name))
            sys.exit(1)

    for part in config.all_parts:
        if not args.parts or part.name in args.parts:
            part.clean()

    # parts dir does not contain only generated code.
    if (os.path.exists(common.get_partsdir()) and
            not os.listdir(common.get_partsdir())):
        os.rmdir(common.get_partsdir())

    clean_stage = not args.parts or part_names == set(args.parts)
    if clean_stage and os.path.exists(common.get_stagedir()):
        logger.info('Cleaning up staging area')
        shutil.rmtree(common.get_stagedir())

    if os.path.exists(common.get_snapdir()):
        logger.info('Cleaning up snapping area')
        shutil.rmtree(common.get_snapdir())
    def test_clean_stage_after_fileset_change(self):
        # Create part1 and get it through the "build" step.
        handler = pluginhandler.load_plugin('part1', 'nil')
        handler.makedirs()

        bindir = os.path.join(handler.code.installdir, 'bin')
        os.makedirs(bindir)
        open(os.path.join(bindir, '1'), 'w').close()
        open(os.path.join(bindir, '2'), 'w').close()

        handler.mark_done('build')
        handler.stage()

        # Verify that both files have been staged
        self.assertTrue(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '1')))
        self.assertTrue(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '2')))

        # Now update the `stage` fileset to only snap one of these files
        handler.code.options.stage = ['bin/1']

        # Now clean the strip step for part1
        handler.clean_stage({})

        # Verify that part1's file is no longer staged
        self.assertFalse(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '1')),
            'Expected bin/1 to be cleaned')
        self.assertFalse(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '2')),
            'Expected bin/2 to be cleaned as well, even though the filesets '
            'changed since it was staged.')
    def test_build_environment(self):
        class Options:
            configflags = []

        plugin = cmake.CMakePlugin('test-part', Options())
        os.makedirs(plugin.builddir)
        plugin.build()

        expected = {}

        expected['CMAKE_PREFIX_PATH'] = '$CMAKE_PREFIX_PATH:{}'.format(
            common.get_stagedir())
        expected['CMAKE_INCLUDE_PATH'] = '$CMAKE_INCLUDE_PATH:' + ':'.join(
            ['{0}/include', '{0}/usr/include', '{0}/include/{1}',
             '{0}/usr/include/{1}']).format(common.get_stagedir(),
                                            common.get_arch_triplet())
        expected['CMAKE_LIBRARY_PATH'] = '$CMAKE_LIBRARY_PATH:' + ':'.join(
            ['{0}/lib', '{0}/usr/lib', '{0}/lib/{1}',
             '{0}/usr/lib/{1}']).format(common.get_stagedir(),
                                        common.get_arch_triplet())

        self.assertEqual(3, self.run_mock.call_count)
        for call_args in self.run_mock.call_args_list:
            environment = call_args[1]['env']
            for variable, value in expected.items():
                self.assertTrue(
                    variable in environment,
                    'Expected variable "{}" to be in environment'.format(
                        variable))

                self.assertEqual(environment[variable], value,
                                 'Expected ${}={}, but it was {}'.format(
                                 variable, value, environment[variable]))
    def test_partial_clean(self):
        parts = self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean2'])

        for i in [0, 2]:
            self.assertFalse(
                os.path.exists(parts[i]['part_dir']),
                'Expected for {!r} to be wiped'.format(parts[i]['part_dir']))

        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the clean1 part')

        self.assertTrue(os.path.exists(common.get_partsdir()))
        self.assertTrue(os.path.exists(common.get_stagedir()))
        self.assertTrue(os.path.exists(common.get_snapdir()))

        # Now clean it the rest of the way
        clean.main(['clean1'])

        for i in range(0, 3):
            self.assertFalse(
                os.path.exists(parts[i]['part_dir']),
                'Expected for {!r} to be wiped'.format(parts[i]['part_dir']))

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemple #9
0
def _cleanup_common_directories(config):
    _remove_directory_if_empty(common.get_partsdir())
    _remove_directory_if_empty(common.get_stagedir())
    _remove_directory_if_empty(common.get_snapdir())

    max_index = -1
    for part in config.all_parts:
        step = part.last_step()
        if step:
            index = common.COMMAND_ORDER.index(step)
            if index > max_index:
                max_index = index

    # If no parts have been pulled, remove the parts directory. In most cases
    # this directory should have already been cleaned, but this handles the
    # case of a failed pull.
    should_remove_partsdir = max_index < common.COMMAND_ORDER.index('pull')
    if should_remove_partsdir and os.path.exists(common.get_partsdir()):
        logger.info('Cleaning up parts directory')
        shutil.rmtree(common.get_partsdir())

    # If no parts have been staged, remove staging area.
    should_remove_stagedir = max_index < common.COMMAND_ORDER.index('stage')
    if should_remove_stagedir and os.path.exists(common.get_stagedir()):
        logger.info('Cleaning up staging area')
        shutil.rmtree(common.get_stagedir())

    # If no parts have been stripped, remove snapping area.
    should_remove_snapdir = max_index < common.COMMAND_ORDER.index('strip')
    if should_remove_snapdir and os.path.exists(common.get_snapdir()):
        logger.info('Cleaning up snapping area')
        shutil.rmtree(common.get_snapdir())
    def clear_common_directories(self):
        if os.path.exists(common.get_partsdir()):
            shutil.rmtree(common.get_partsdir())

        if os.path.exists(common.get_stagedir()):
            shutil.rmtree(common.get_stagedir())

        if os.path.exists(common.get_snapdir()):
            shutil.rmtree(common.get_snapdir())
Exemple #11
0
    def _build_environment(self):
        env = os.environ.copy()
        env['CMAKE_PREFIX_PATH'] = '$CMAKE_PREFIX_PATH:{}'.format(
            common.get_stagedir())
        env['CMAKE_INCLUDE_PATH'] = '$CMAKE_INCLUDE_PATH:' + ':'.join([
            '{0}/include', '{0}/usr/include', '{0}/include/{1}',
            '{0}/usr/include/{1}'
        ]).format(common.get_stagedir(), common.get_arch_triplet())
        env['CMAKE_LIBRARY_PATH'] = '$CMAKE_LIBRARY_PATH:' + ':'.join([
            '{0}/lib', '{0}/usr/lib', '{0}/lib/{1}', '{0}/usr/lib/{1}'
        ]).format(common.get_stagedir(), common.get_arch_triplet())

        return env
    def test_clean_nested_dependent_parts(self):
        yaml = """name: clean-test
version: 1.0
summary: test clean
description: test clean

parts:
  main:
    plugin: nil
    source: .

  dependent:
    plugin: nil
    source: .
    after: [main]

  dependent-dependent:
    plugin: nil
    source: .
    after: [dependent]"""

        super().make_snapcraft_yaml(yaml)

        part_dirs = {}
        for part in ['main', 'dependent', 'dependent-dependent']:
            part_dirs[part] = os.path.join(common.get_partsdir(), part)
            os.makedirs(part_dirs[part])

        os.makedirs(common.get_stagedir())
        os.makedirs(common.get_snapdir())

        # Cleaning only `main`. Since `dependent` depends upon main, we expect
        # that it will be cleaned as well. Otherwise it won't be using the new
        # `main` when it is built.
        clean.main(['main'])

        self.assertFalse(os.path.exists(part_dirs['main']),
                         'Expected part directory for main to be cleaned')
        self.assertFalse(
            os.path.exists(part_dirs['dependent']),
            'Expected part directory for dependent to be cleaned as it '
            'depends upon main')

        self.assertFalse(
            os.path.exists(part_dirs['dependent-dependent']),
            'Expected part directory for dependent-dependent to be cleaned as '
            'it depends upon dependent, which depends upon main')

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemple #13
0
    def _build_environment(self):
        env = os.environ.copy()
        env['CMAKE_PREFIX_PATH'] = '$CMAKE_PREFIX_PATH:{}'.format(
            common.get_stagedir())
        env['CMAKE_INCLUDE_PATH'] = '$CMAKE_INCLUDE_PATH:' + ':'.join(
            ['{0}/include', '{0}/usr/include', '{0}/include/{1}',
             '{0}/usr/include/{1}']).format(common.get_stagedir(),
                                            common.get_arch_triplet())
        env['CMAKE_LIBRARY_PATH'] = '$CMAKE_LIBRARY_PATH:' + ':'.join(
            ['{0}/lib', '{0}/usr/lib', '{0}/lib/{1}',
             '{0}/usr/lib/{1}']).format(common.get_stagedir(),
                                        common.get_arch_triplet())

        return env
    def test_cleanbuild(self, mock_installed, mock_call):
        mock_installed.return_value = True

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml()
        # simulate build artifacts

        dirs = [
            os.path.join(common.get_partsdir(), 'part1', 'src'),
            common.get_stagedir(),
            common.get_snapdir(),
            os.path.join(common.get_partsdir(), 'plugins'),
        ]
        files_tar = [
            os.path.join(common.get_partsdir(), 'plugins', 'x-plugin.py'),
            'main.c',
        ]
        files_no_tar = [
            os.path.join(common.get_stagedir(), 'binary'),
            os.path.join(common.get_snapdir(), 'binary'),
            'snap-test.snap',
            'snap-test_1.0_source.tar.bz2',
        ]
        for d in dirs:
            os.makedirs(d)
        for f in files_tar + files_no_tar:
            open(f, 'w').close()

        cleanbuild.main()

        self.assertEqual(
            'Setting up container with project assets\n'
            'Waiting for a network connection...\n'
            'Network connection established\n'
            'Retrieved snap-test_1.0_amd64.snap\n',
            fake_logger.output)

        with tarfile.open('snap-test_1.0_source.tar.bz2') as tar:
            tar_members = tar.getnames()

        for f in files_no_tar:
            f = os.path.relpath(f)
            self.assertFalse('./{}'.format(f) in tar_members,
                             '{} should not be in {}'.format(f, tar_members))
        for f in files_tar:
            f = os.path.relpath(f)
            self.assertTrue('./{}'.format(f) in tar_members,
                            '{} should be in {}'.format(f, tar_members))
    def test_cleanbuild(self, mock_installed, mock_call):
        mock_installed.return_value = True

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        self.make_snapcraft_yaml()
        # simulate build artifacts

        dirs = [
            os.path.join(common.get_partsdir(), 'part1', 'src'),
            common.get_stagedir(),
            common.get_snapdir(),
            os.path.join(common.get_partsdir(), 'plugins'),
        ]
        files_tar = [
            os.path.join(common.get_partsdir(), 'plugins', 'x-plugin.py'),
            'main.c',
        ]
        files_no_tar = [
            os.path.join(common.get_stagedir(), 'binary'),
            os.path.join(common.get_snapdir(), 'binary'),
            'snap-test.snap',
            'snap-test_1.0_source.tar.bz2',
        ]
        for d in dirs:
            os.makedirs(d)
        for f in files_tar + files_no_tar:
            open(f, 'w').close()

        cleanbuild.main()

        self.assertEqual(
            'Setting up container with project assets\n'
            'Waiting for a network connection...\n'
            'Network connection established\n'
            'Retrieved snap-test_1.0_amd64.snap\n', fake_logger.output)

        with tarfile.open('snap-test_1.0_source.tar.bz2') as tar:
            tar_members = tar.getnames()

        for f in files_no_tar:
            f = os.path.relpath(f)
            self.assertFalse('./{}'.format(f) in tar_members,
                             '{} should not be in {}'.format(f, tar_members))
        for f in files_tar:
            f = os.path.relpath(f)
            self.assertTrue('./{}'.format(f) in tar_members,
                            '{} should be in {}'.format(f, tar_members))
    def test_clean_stage(self):
        filesets = {
            'all': {
                'fileset': ['*'],
            },
            'no1': {
                'fileset': ['-1'],
            },
            'onlya': {
                'fileset': ['a'],
            },
            'onlybase': {
                'fileset': ['*', '-*/*'],
            },
            'nostara': {
                'fileset': ['-*/a'],
            },
        }

        for key, value in filesets.items():
            with self.subTest(key=key):
                self.clear_common_directories()

                handler = pluginhandler.load_plugin('test_part', 'nil', {
                    'stage': value['fileset']
                })
                handler.makedirs()

                installdir = handler.code.installdir
                os.makedirs(installdir + '/1/1a/1b')
                os.makedirs(installdir + '/2/2a')
                os.makedirs(installdir + '/3')
                open(installdir + '/a', mode='w').close()
                open(installdir + '/b', mode='w').close()
                open(installdir + '/1/a', mode='w').close()
                open(installdir + '/3/a', mode='w').close()

                handler.mark_done('build')

                # Stage the installed files
                handler.stage()

                self.assertTrue(os.listdir(common.get_stagedir()))

                handler.clean_stage({})

                self.assertFalse(os.listdir(common.get_stagedir()),
                                 'Expected snapdir to be completely cleaned')
    def test_strip_one_part_only_from_3(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml(n=3)

        strip.main(['strip1', ])

        self.assertFalse(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'snap.yaml')),
            'There should not be a snap.yaml')
        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the strip1 part')
        self.assertTrue(os.path.exists(parts[1]['state_file']),
                        'Expected a state file for the strip1 part')

        with open(parts[1]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the strip1 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         " strip1 to be 'strip'")

        for i in [0, 2]:
            self.assertFalse(os.path.exists(parts[i]['part_dir']),
                             'Pulled wrong part')
            self.assertFalse(os.path.exists(parts[i]['state_file']),
                             'Expected for only to be a state file for build1')
    def test_strip_defaults(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml()

        strip.main()

        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'package.yaml')),
            'Expected a package.yaml')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[0]['part_dir']),
                        'Expected a part directory for the build0 part')
        self.assertTrue(os.path.exists(parts[0]['state_file']),
                        'Expected a state file for the build0 part')

        with open(parts[0]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(
            len(state), 1, 'Expected only one line in the state '
            'file for the build0 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "build0 to be 'strip'")
    def test_stage_ran_twice_is_a_noop(self):
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml()

        stage.main()

        self.assertEqual(
            'Pulling stage0 \n'
            'Building stage0 \n'
            'Staging stage0 \n',
            fake_logger.output)

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[0]['part_dir']),
                        'Expected a part directory for the build0 part')

        self.verify_state('build0', parts[0]['state_dir'], 'stage')

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        stage.main()

        self.assertEqual(
            'Skipping pull stage0  (already ran)\n'
            'Skipping build stage0  (already ran)\n'
            'Skipping stage stage0  (already ran)\n',
            fake_logger.output)
    def test_upload(self):
        upload.main()

        self.assertEqual(
            'Snap snap-test_1.0_amd64.snap not found. '
            'Running snap step to create it.\n'
            'Pulling part1 \n'
            'Building part1 \n'
            'Staging part1 \n'
            'Stripping part1 \n'
            'Snapping snap-test_1.0_amd64.snap\n'
            'Snapped snap-test_1.0_amd64.snap\n',
            self.fake_logger.output)

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(self.state_file,
                        'Expected a state file for the part1 part')

        with open(self.state_file) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the part1 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "part1 to be 'strip'")

        self.mock_upload.assert_called_once_with(
            'snap-test_1.0_amd64.snap',
            'snap-test',
            config=self.mock_load_config.return_value)
    def test_strip_defaults(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml()

        strip.main()

        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'snap.yaml')),
            'Expected a snap.yaml')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[0]['part_dir']),
                        'Expected a part directory for the build0 part')
        self.assertTrue(os.path.exists(parts[0]['state_file']),
                        'Expected a state file for the build0 part')

        with open(parts[0]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the build0 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "build0 to be 'strip'")
    def test_string_replacement_with_complex_data(self):
        stagedir = common.get_stagedir()

        subject = {
            'filesets': {
                'files': [
                    'somefile',
                    '$SNAPCRAFT_STAGE/file1',
                    'SNAPCRAFT_STAGE/really',
                ]
            },
            'configFlags': [
                '--with-python',
                '--with-swig $SNAPCRAFT_STAGE/swig',
            ],
        }

        expected = {
            'filesets': {
                'files': [
                    'somefile',
                    '{}/file1'.format(stagedir),
                    'SNAPCRAFT_STAGE/really',
                ]
            },
            'configFlags': [
                '--with-python',
                '--with-swig {}/swig'.format(stagedir),
            ],
        }

        self.assertEqual(pluginhandler._expand_env(subject), expected)
Exemple #23
0
    def test_upload(self):
        upload.main()

        self.assertEqual(
            'Snap snap-test_1.0_amd64.snap not found. '
            'Running snap step to create it.\n'
            'Pulling part1 \n'
            'Building part1 \n'
            'Staging part1 \n'
            'Stripping part1 \n'
            'Snapping snap-test_1.0_amd64.snap\n'
            'Snapped snap-test_1.0_amd64.snap\n', self.fake_logger.output)

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(self.state_file,
                        'Expected a state file for the part1 part')

        with open(self.state_file) as sf:
            state = sf.readlines()
        self.assertEqual(
            len(state), 1, 'Expected only one line in the state '
            'file for the part1 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "part1 to be 'strip'")

        self.mock_upload.assert_called_once_with(
            'snap-test_1.0_amd64.snap',
            'snap-test',
            config=self.mock_load_config.return_value)
    def test_stage_one_part_only_from_3(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml(n=3)

        stage.main([
            'stage1',
        ])

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the stage1 part')
        self.assertTrue(os.path.exists(parts[1]['state_file']),
                        'Expected a state file for the stage1 part')

        with open(parts[1]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(
            len(state), 1, 'Expected only one line in the state '
            'file for the stage1 part')
        self.assertEqual(
            state[0], 'stage', "Expected the state file for "
            " stage1 to be 'stage'")

        for i in [0, 2]:
            self.assertFalse(os.path.exists(parts[i]['part_dir']),
                             'Pulled wrong part')
            self.assertFalse(
                os.path.exists(parts[i]['state_file']),
                'Expected for only to be a state file for build1')
    def test_strip_one_part_only_from_3(self):
        fake_logger = fixtures.FakeLogger(level=logging.ERROR)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml(n=3)

        main(['strip', 'strip1'])

        self.assertFalse(
            os.path.exists(
                os.path.join(common.get_snapdir(), 'meta', 'snap.yaml')),
            'There should not be a snap.yaml')
        self.assertTrue(os.path.exists(common.get_snapdir()),
                        'Expected a snap directory')
        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the strip1 part')

        self.verify_state('strip1', parts[1]['state_dir'], 'strip')

        for i in [0, 2]:
            self.assertFalse(os.path.exists(parts[i]['part_dir']),
                             'Pulled wrong part')
            self.assertFalse(os.path.exists(parts[i]['state_dir']),
                             'Expected for only to be a state file for build1')
Exemple #26
0
    def test_string_replacement_with_complex_data(self):
        stagedir = common.get_stagedir()

        subject = {
            'filesets': {
                'files': [
                    'somefile',
                    '$SNAPCRAFT_STAGE/file1',
                    'SNAPCRAFT_STAGE/really',
                ]
            },
            'configFlags': [
                '--with-python',
                '--with-swig $SNAPCRAFT_STAGE/swig',
            ],
        }

        expected = {
            'filesets': {
                'files': [
                    'somefile',
                    '{}/file1'.format(stagedir),
                    'SNAPCRAFT_STAGE/really',
                ]
            },
            'configFlags': [
                '--with-python',
                '--with-swig {}/swig'.format(stagedir),
            ],
        }

        self.assertEqual(pluginhandler._expand_env(subject), expected)
Exemple #27
0
    def test_snap_defaults(self, mock_call):
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)
        self.make_snapcraft_yaml()

        snap.main()

        self.assertEqual(
            'Pulling part1 \n'
            'Building part1 \n'
            'Staging part1 \n'
            'Stripping part1 \n'
            'Snapping snap-test_1.0_amd64.snap\n'
            'Snapped snap-test_1.0_amd64.snap\n',
            fake_logger.output)

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(self.state_file,
                        'Expected a state file for the part1 part')

        with open(self.state_file) as sf:
            state = sf.readlines()
        self.assertEqual(len(state), 1, 'Expected only one line in the state '
                         'file for the part1 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "part1 to be 'strip'")

        mock_call.assert_called_once_with([
            'mksquashfs', common.get_snapdir(), 'snap-test_1.0_amd64.snap',
            '-noappend', '-comp', 'xz'])
Exemple #28
0
    def test_clean_all(self):
        self.make_snapcraft_yaml(n=3)

        clean.main()

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
    def test_clean_all_when_all_parts_specified(self):
        self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean1', 'clean2'])

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
Exemple #30
0
    def test_clean_all_when_all_parts_specified(self):
        self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean1', 'clean2'])

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
    def test_clean_all(self):
        self.make_snapcraft_yaml(n=3)

        clean.main()

        self.assertFalse(os.path.exists(common.get_partsdir()))
        self.assertFalse(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
    def test_clean_stage_multiple_independent_parts(self):
        # Create part1 and get it through the "build" step.
        handler1 = pluginhandler.load_plugin('part1', 'nil')
        handler1.makedirs()

        bindir = os.path.join(handler1.code.installdir, 'bin')
        os.makedirs(bindir)
        open(os.path.join(bindir, '1'), 'w').close()

        handler1.mark_done('build')

        # Now create part2 and get it through the "build" step.
        handler2 = pluginhandler.load_plugin('part2', 'nil')
        handler2.makedirs()

        bindir = os.path.join(handler2.code.installdir, 'bin')
        os.makedirs(bindir)
        open(os.path.join(bindir, '2'), 'w').close()

        handler2.mark_done('build')

        # Now stage both parts
        handler1.stage()
        handler2.stage()

        # Verify that part1's file has been staged
        self.assertTrue(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '1')))

        # Verify that part2's file has been staged
        self.assertTrue(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '2')))

        # Now clean the stage step for part1
        handler1.clean_stage({})

        # Verify that part1's file is no longer staged
        self.assertFalse(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '1')),
            "Expected part1's staged files to be cleaned")

        # Verify that part2's file is still there
        self.assertTrue(
            os.path.exists(os.path.join(common.get_stagedir(), 'bin', '2')),
            "Expected part2's staged files to be untouched")
Exemple #33
0
def _expand_env(attr):
    if isinstance(attr, str) and _SNAPCRAFT_STAGE in attr:
        return attr.replace(_SNAPCRAFT_STAGE, common.get_stagedir())
    elif isinstance(attr, list) or isinstance(attr, tuple):
        return [_expand_env(i) for i in attr]
    elif isinstance(attr, dict):
        return {k: _expand_env(attr[k]) for k in attr}

    return attr
Exemple #34
0
def _expand_env(attr):
    if isinstance(attr, str) and _SNAPCRAFT_STAGE in attr:
        return attr.replace(_SNAPCRAFT_STAGE, common.get_stagedir())
    elif isinstance(attr, list) or isinstance(attr, tuple):
        return [_expand_env(i) for i in attr]
    elif isinstance(attr, dict):
        return {k: _expand_env(attr[k]) for k in attr}

    return attr
Exemple #35
0
    def stage_env(self):
        stagedir = common.get_stagedir()
        env = []

        env += _runtime_env(stagedir)
        env += _build_env_for_stage(stagedir)
        for part in self.all_parts:
            env += part.env(stagedir)

        return env
Exemple #36
0
    def stage_env(self):
        stagedir = common.get_stagedir()
        env = []

        env += _runtime_env(stagedir)
        env += _build_env_for_stage(stagedir)
        for part in self.all_parts:
            env += part.env(stagedir)

        return env
Exemple #37
0
def clean(args):
    config = _load_config()

    for part in config.all_parts:
        logger.info("Cleaning up for part %r", part.name)
        if os.path.exists(part.partdir):
            shutil.rmtree(part.partdir)

    # parts dir does not contain only generated code.
    if os.path.exists(common.get_partsdir()) and not os.listdir(common.get_partsdir()):
        os.rmdir(common.get_partsdir())

    logger.info("Cleaning up staging area")
    if os.path.exists(common.get_stagedir()):
        shutil.rmtree(common.get_stagedir())

    logger.info("Cleaning up snapping area")
    if os.path.exists(common.get_snapdir()):
        shutil.rmtree(common.get_snapdir())
Exemple #38
0
    def stage_env(self):
        root = common.get_stagedir()
        env = []

        env += self.runtime_env(root)
        env += self.build_env(root)
        for part in self.all_parts:
            env += part.env(root)

        return env
Exemple #39
0
    def stage_env(self):
        root = common.get_stagedir()
        env = []

        env += self.runtime_env(root)
        env += self.build_env(root)
        for part in self.all_parts:
            env += part.env(root)

        return env
Exemple #40
0
    def test_no_parts_defined(self):
        self.fake_config.all_parts = []

        self.mock_load_config.return_value = self.fake_config

        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
Exemple #41
0
    def test_no_parts_defined(self):
        self.fake_config.all_parts = []

        self.mock_load_config.return_value = self.fake_config

        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
Exemple #42
0
def clean(args):
    config = _load_config()

    for part in config.all_parts:
        logger.info('Cleaning up for part %r', part.name)
        if os.path.exists(part.partdir):
            shutil.rmtree(part.partdir)

    # parts dir does not contain only generated code.
    if (os.path.exists(common.get_partsdir()) and
            not os.listdir(common.get_partsdir())):
        os.rmdir(common.get_partsdir())

    logger.info('Cleaning up staging area')
    if os.path.exists(common.get_stagedir()):
        shutil.rmtree(common.get_stagedir())

    logger.info('Cleaning up snapping area')
    if os.path.exists(common.get_snapdir()):
        shutil.rmtree(common.get_snapdir())
Exemple #43
0
    def test_clean_all_when_all_parts_specified(self):
        class args:
            parts = ["part1", "part2", "part3"]

        cmds.clean(args())

        self.mock_exists.assert_has_calls(
            [
                mock.call(common.get_partsdir()),
                mock.call().__bool__(),
                mock.call(common.get_stagedir()),
                mock.call().__bool__(),
                mock.call(common.get_snapdir()),
                mock.call().__bool__(),
            ]
        )

        self.mock_rmtree.assert_has_calls([mock.call(common.get_stagedir()), mock.call(common.get_snapdir())])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
        self.assertEqual(self.clean_calls, ["part1", "part2", "part3"])
Exemple #44
0
    def test_clean_all(self):
        class args:
            parts = []
        cmds.clean(args())

        self.mock_exists.assert_has_calls([
            mock.call(common.get_partsdir()),
            mock.call().__bool__(),
            mock.call(common.get_stagedir()),
            mock.call().__bool__(),
            mock.call(common.get_snapdir()),
            mock.call().__bool__(),
        ])

        self.mock_rmtree.assert_has_calls([
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.mock_rmdir.assert_called_once_with(common.get_partsdir())
        self.assertEqual(self.clean_calls, ['part1', 'part2', 'part3'])
Exemple #45
0
    def test_just_upload_if_snap_file_exists(self):
        self.mock_os.path.exists.return_value = True

        upload.main()

        # stages are not build if snap file already exists
        self.assertFalse(os.path.exists(common.get_stagedir()),
                         'Expected a stage directory')
        self.assertFalse(os.path.exists(self.state_file))

        self.mock_upload.assert_called_once_with(
            'snap-test_1.0_amd64.snap',
            'snap-test',
            config=self.mock_load_config.return_value)
Exemple #46
0
    def test_everything_is_clean(self):
        self.mock_exists.return_value = False
        self.mock_listdir.side_effect = FileNotFoundError()

        cmds.clean({})

        self.mock_exists.assert_has_calls([
            mock.call('partdir1'),
            mock.call('partdir2'),
            mock.call('partdir3'),
            mock.call(common.get_partsdir()),
            mock.call(common.get_stagedir()),
            mock.call(common.get_snapdir()),
        ])

        self.assertFalse(self.mock_rmdir.called)
        self.assertFalse(self.mock_rmtree.called)
Exemple #47
0
    def build_env_for_part(self, part, root_part=True):
        """Return a build env of all the part's dependencies."""

        env = []
        stagedir = common.get_stagedir()
        for dep_part in part.deps:
            env += dep_part.env(stagedir)
            env += self.build_env_for_part(dep_part, root_part=False)

        if root_part:
            env += part.env(part.installdir)
            env += _runtime_env(stagedir)
            env += _runtime_env(part.installdir)
            env += _build_env_for_stage(stagedir)
        else:
            env += part.env(stagedir)
            env += _runtime_env(stagedir)

        return env
Exemple #48
0
    def test_dict_with_string_replacements(self):
        stagedir = common.get_stagedir()

        replacements = (
            (
                'no replacement',
                {
                    '1': 'snapcraft_stage/usr/bin',
                    '2': '/usr/bin',
                },
                {
                    '1': 'snapcraft_stage/usr/bin',
                    '2': '/usr/bin',
                },
            ),
            (
                'replaced start',
                {
                    '1': '$SNAPCRAFT_STAGE/usr/bin',
                    '2': '/usr/bin',
                },
                {
                    '1': '{}/usr/bin'.format(stagedir),
                    '2': '/usr/bin',
                },
            ),
            (
                'replaced between',
                {
                    '1': '--without-python',
                    '2': '--with-swig $SNAPCRAFT_STAGE/usr/swig',
                },
                {
                    '1': '--without-python',
                    '2': '--with-swig {}/usr/swig'.format(stagedir),
                },
            ),
        )

        for test_name, subject, expected in replacements:
            self.subTest(key=test_name)
            self.assertEqual(pluginhandler._expand_env(subject), expected)
Exemple #49
0
    def test_partial_clean(self):
        parts = self.make_snapcraft_yaml(n=3)

        clean.main(['clean0', 'clean2', ])

        for i in [0, 2]:
            self.assertFalse(
                os.path.exists(parts[i]['part_dir']),
                'Expected for {!r} to be wiped'.format(parts[i]['part_dir']))
            self.assertFalse(
                os.path.exists(parts[i]['state_file']),
                'Expected for {!r} to be wiped'.format(parts[i]['state_file']))

        self.assertTrue(os.path.exists(parts[1]['part_dir']),
                        'Expected a part directory for the clean1 part')
        self.assertTrue(os.path.exists(parts[1]['state_file']),
                        'Expected a state file for the clean1 part')

        self.assertTrue(os.path.exists(common.get_partsdir()))
        self.assertTrue(os.path.exists(common.get_stagedir()))
        self.assertFalse(os.path.exists(common.get_snapdir()))
    def test_strip_ran_twice_is_a_noop(self):
        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)
        parts = self.make_snapcraft_yaml()

        strip.main()

        self.assertEqual(
            'Pulling strip0 \n'
            'Building strip0 \n'
            'Staging strip0 \n'
            'Stripping strip0 \n', fake_logger.output)

        self.assertTrue(os.path.exists(common.get_stagedir()),
                        'Expected a stage directory')
        self.assertTrue(os.path.exists(common.get_partsdir()),
                        'Expected a parts directory')
        self.assertTrue(os.path.exists(parts[0]['part_dir']),
                        'Expected a part directory for the build0 part')
        self.assertTrue(os.path.exists(parts[0]['state_file']),
                        'Expected a state file for the build0 part')

        with open(parts[0]['state_file']) as sf:
            state = sf.readlines()
        self.assertEqual(
            len(state), 1, 'Expected only one line in the state '
            'file for the build0 part')
        self.assertEqual(state[0], 'strip', "Expected the state file for "
                         "build0 to be 'strip'")

        fake_logger = fixtures.FakeLogger(level=logging.INFO)
        self.useFixture(fake_logger)

        strip.main()

        self.assertEqual(
            'Skipping pull strip0  (already ran)\n'
            'Skipping build strip0  (already ran)\n'
            'Skipping stage strip0  (already ran)\n'
            'Skipping strip strip0  (already ran)\n', fake_logger.output)
Exemple #51
0
    def make_snapcraft_yaml(self, n=1, create=True):
        parts = '\n'.join([self.yaml_part.format(i) for i in range(n)])
        super().make_snapcraft_yaml(self.yaml_template.format(parts=parts))
        open('icon.png', 'w').close()

        parts = []
        for i in range(n):
            part_dir = os.path.join(common.get_partsdir(), 'clean{}'.format(i))
            state_file = os.path.join(part_dir, 'state')
            parts.append({
                'part_dir': part_dir,
                'state_file': state_file,
            })
            if create:
                os.makedirs(part_dir)
                open(state_file, 'w').close()

        if create:
            os.makedirs(common.get_stagedir())
            os.makedirs(common.get_snapdir())

        return parts
Exemple #52
0
 def test_get_stagedir(self):
     self.assertEqual(os.path.join(self.path, 'stage'),
                      common.get_stagedir())