Skip to content

Commit

Permalink
Merge 637d648 into 4a0bc30
Browse files Browse the repository at this point in the history
  • Loading branch information
tsimonq2 committed Jun 22, 2016
2 parents 4a0bc30 + 637d648 commit d1e9d83
Show file tree
Hide file tree
Showing 8 changed files with 246 additions and 2 deletions.
1 change: 1 addition & 0 deletions debian/tests/control
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Depends: @,
bzr,
git,
mercurial,
subversion,
lxd,
python3-pep8,
pyflakes,
Expand Down
11 changes: 11 additions & 0 deletions integration_tests/snaps/svn-pull-update/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: test-package
version: 0.1
summary: svn integration test
description: use svn
confinement: strict

parts:
svn:
plugin: make
source: repo/
source-type: svn
11 changes: 11 additions & 0 deletions integration_tests/snaps/svn-pull/snapcraft.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name: test-package
version: 0.1
summary: svn integration test
description: use svn
confinement: strict

parts:
svn:
plugin: make
source: repo/
source-type: svn
105 changes: 105 additions & 0 deletions integration_tests/test_svn_pull.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2016 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

import os
import subprocess
import shutil

from testtools.matchers import FileExists

import integration_tests


class SubversionSourceTestCase(integration_tests.TestCase):

def setUp(self):
super().setUp()
if shutil.which('svn') is None:
self.skipTest('svn is not installed')

def _init_svn(self):
subprocess.check_call(
['svnadmin', 'create', 'repo'], stdout=subprocess.DEVNULL)

def test_pull_svn_checkout(self):
project_dir = self.copy_project_to_tmp('svn-pull')
os.chdir(project_dir)

self._init_svn()

subprocess.check_call(
['svn', 'checkout', 'file:///{}'.format(os.path.join(project_dir, 'repo')), 'local'],
stdout=subprocess.DEVNULL)

open(os.path.join('local', 'file'), 'w').close()
subprocess.check_call(
['svn', 'add', 'file'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(
['svn', 'commit', '-m', 'test'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(['svn', 'update'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(
['rm', '-rf', 'local/'], stdout=subprocess.DEVNULL)

part_src_path = os.path.join('parts', 'svn', 'src')
self.run_snapcraft('pull', project_dir)
revno = subprocess.check_output(['svnversion', part_src_path]).strip()
universal_newlines=True
self.assertEqual('1', revno)
self.assertThat(os.path.join(part_src_path, 'file'), FileExists())

def test_pull_svn_update(self):
project_dir = self.copy_project_to_tmp('svn-pull-update')
os.chdir(project_dir)

self._init_svn()

subprocess.check_call(
['svn', 'checkout', 'file:///{}'.format(os.path.join(project_dir, 'repo')), 'local'],
stdout=subprocess.DEVNULL)

open(os.path.join('local', 'file'), 'w').close()
subprocess.check_call(
['svn', 'add', 'file'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(
['svn', 'commit', '-m', 'test'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(['svn', 'update'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(
['rm', '-rf', 'local/'], stdout=subprocess.DEVNULL)

part_src_path = os.path.join('parts', 'svn', 'src')
subprocess.check_call(
['svn', 'checkout', 'file:///{}'.format(os.path.join(project_dir, 'repo')), part_src_path],
stdout=subprocess.DEVNULL)

subprocess.check_call(
['svn', 'checkout', 'file:///{}'.format(os.path.join(project_dir, 'repo')), 'local'],
stdout=subprocess.DEVNULL)
open(os.path.join('local', 'filetwo'), 'w').close()
subprocess.check_call(
['svn', 'add', 'filetwo'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(
['svn', 'commit', '-m', 'testtwo'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(['svn', 'update'], stdout=subprocess.DEVNULL, cwd='local/')
subprocess.check_call(
['rm', '-rf', 'local/'], stdout=subprocess.DEVNULL)

self.run_snapcraft('pull', project_dir)
revno = subprocess.check_output(['svnversion', part_src_path]).strip()
universal_newlines=True
self.assertEqual('2', revno)
self.assertThat(os.path.join(part_src_path, 'file'), FileExists())
self.assertThat(os.path.join(part_src_path, 'filetwo'), FileExists())

40 changes: 39 additions & 1 deletion snapcraft/internal/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
directory tree or a tarball or a revision control repository
('git:...').
- source-type: git, bzr, hg, tar or zip
- source-type: git, bzr, hg, svn, tar, or zip
In some cases the source string is not enough to identify the version
control system or compression algorithim. The source-type key can tell
Expand Down Expand Up @@ -201,6 +201,38 @@ def pull(self):
subprocess.check_call(cmd)


class Subversion(Base):

def __init__(self, source, source_dir, source_tag=None,
source_branch=None):
super().__init__(source, source_dir, source_tag, source_branch)
if source_tag:
if source_branch:
raise IncompatibleOptionsError(
"Can't specify source-tag OR source-branch for a "
"Subversion source")
else:
raise IncompatibleOptionsError(
"Can't specify source-tag for a Subversion source")
elif source_branch:
raise IncompatibleOptionsError(
"Can't specify source-branch for a Subversion source")

def pull(self):
if os.path.exists(os.path.join(self.source_dir, '.svn')):
subprocess.check_call(
['svn', 'update'], cwd=self.source_dir)
else:
if os.path.isdir(self.source):
subprocess.check_call(
['svn', 'checkout',
'file://{}'.format(os.path.abspath(self.source)),
self.source_dir])
else:
subprocess.check_call(
['svn', 'checkout', self.source, self.source_dir])


class Tar(FileBase):

def __init__(self, source, source_dir, source_tag=None,
Expand Down Expand Up @@ -348,6 +380,8 @@ def get_required_packages(options):
packages.append('tar')
elif source_type == 'hg' or source_type == 'mercurial':
packages.append('mercurial')
elif source_type == 'subversion' or source_type == 'svn':
packages.append('subversion')

return packages

Expand All @@ -357,6 +391,8 @@ def get_required_packages(options):
'git': Git,
'hg': Mercurial,
'mercurial': Mercurial,
'svn': Subversion,
'subversion': Subversion,
'tar': Tar,
'zip': Zip,
}
Expand All @@ -379,6 +415,8 @@ def _get_source_type_from_uri(source, ignore_errors=False):
elif source.startswith('git:') or source.startswith('git@') or \
source.endswith('.git'):
source_type = 'git'
elif source.startswith('svn:'):
source_type = 'subversion'
elif _tar_type_regex.match(source):
source_type = 'tar'
elif source.endswith('.zip'):
Expand Down
3 changes: 2 additions & 1 deletion snapcraft/sources.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- Mode:Python; indent-tabs-mode:nil; tab-width:4 -*-
#
# Copyright (C) 2015 Canonical Ltd
# Copyright (C) 2015, 2016 Canonical Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3 as
Expand All @@ -17,6 +17,7 @@
from snapcraft.internal.sources import Bazaar # noqa
from snapcraft.internal.sources import Git # noqa
from snapcraft.internal.sources import Mercurial # noqa
from snapcraft.internal.sources import Subversion # noqa
from snapcraft.internal.sources import Tar # noqa
from snapcraft.internal.sources import Local # noqa
from snapcraft.internal.sources import Zip # noqa
Expand Down
75 changes: 75 additions & 0 deletions snapcraft/tests/test_sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,64 @@ def test_init_with_source_branch_and_tag_raises_exception(self):
self.assertEqual(raised.exception.message, expected_message)


class TestSubversion(SourceTestCase):

def test_pull_remote(self):
svn = sources.Subversion('svn://my-source', 'source_dir')
svn.pull()
self.mock_run.assert_called_once_with(
['svn', 'checkout', 'svn://my-source', 'source_dir'])

def test_pull_local_absolute_path(self):
svn = sources.Subversion(self.path, 'source_dir')
svn.pull()
self.mock_run.assert_called_once_with(
['svn', 'checkout', 'file://'+self.path, 'source_dir'])

def test_pull_local_relative_path(self):
os.mkdir("my-source")
svn = sources.Subversion('my-source', 'source_dir')
svn.pull()
self.mock_run.assert_called_once_with(
['svn', 'checkout',
'file://{}'.format(os.path.join(self.path, 'my-source')),
'source_dir'])

def test_pull_existing(self):
self.mock_path_exists.return_value = True
svn = sources.Subversion('svn://my-source', 'source_dir')
svn.pull()
self.mock_run.assert_called_once_with(
['svn', 'update'], cwd=svn.source_dir)

def test_init_with_source_tag_raises_exception(self):
with self.assertRaises(sources.IncompatibleOptionsError) as raised:
sources.Subversion(
'svn://mysource', 'source_dir', source_tag='tag')
expected_message = (
"Can't specify source-tag for a Subversion source")
self.assertEqual(raised.exception.message, expected_message)

def test_init_with_source_branch_raises_exception(self):
with self.assertRaises(sources.IncompatibleOptionsError) as raised:
sources.Subversion(
'svn://mysource', 'source_dir', source_branch='branch')
expected_message = (
"Can't specify source-branch for a Subversion source")
self.assertEqual(raised.exception.message, expected_message)

def test_init_with_source_branch_and_tag_raises_exception(self):
with self.assertRaises(sources.IncompatibleOptionsError) as raised:
sources.Subversion(
'svn://mysource', 'source_dir', source_tag='tag',
source_branch='branch')

expected_message = (
"Can't specify source-tag OR source-branch for a Subversion "
"source")
self.assertEqual(raised.exception.message, expected_message)


class TestLocal(tests.TestCase):

def test_pull_with_existing_source_dir_creates_symlink(self):
Expand Down Expand Up @@ -422,3 +480,20 @@ def test_get_bzr_source_from_uri(self, mock_pull):

mock_pull.assert_called_once_with()
mock_pull.reset_mock()

@unittest.mock.patch('snapcraft.sources.Subversion.pull')
def test_get_svn_source_from_uri(self, mock_pull):
test_sources = [
'svn://sylpheed.sraoss.jp/sylpheed/trunk'
]

for source in test_sources:
with self.subTest(key=source):
options = tests.MockOptions(source=source)
sources.get(
sourcedir='dummy',
builddir='dummy',
options=options)

mock_pull.assert_called_once_with()
mock_pull.reset_mock()
2 changes: 2 additions & 0 deletions snapcraft/tests/test_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ def test_config_adds_vcs_packages_to_build_packages_from_types(self):
('mercurial', 'mercurial'),
('bzr', 'bzr'),
('tar', 'tar'),
('svn', 'subversion'),
('subversion', 'subversion'),
]
yaml_t = """name: test
version: "1"
Expand Down

0 comments on commit d1e9d83

Please sign in to comment.