added support for uploading snap packages directly to the Ubuntu Store. #197

Merged
merged 1 commit into from Jan 27, 2016
Jump to file or symbol
Failed to load files and symbols.
+2,673 −8
Split
View
@@ -33,7 +33,7 @@ before_script:
- sudo lxc config device add xenial /dev/sda1 disk source=$(pwd) path=$(pwd)
# Install the snapcraft dependencies.
- sudo lxc exec xenial -- apt-get update
- - sudo lxc exec xenial -- apt-get install -y build-essential bzr dpkg-dev git mercurial pyflakes python3.4 python3-apt python3-docopt python3-coverage python3-fixtures python3-jsonschema python3-mccabe python3-pep8 python3-pip python3-requests python3-testscenarios python3-testtools python3-yaml python3-lxml squashfs-tools
+ - sudo lxc exec xenial -- apt-get install -y build-essential bzr dpkg-dev git mercurial pyflakes python-flake8 python3.4 python3-apt python3-docopt python3-coverage python3-fixtures python3-flake8 python3-jsonschema python3-mccabe python3-mock python3-pep8 python3-pip python3-requests python3-requests-oauthlib python3-responses python3-ssoclient python3-testscenarios python3-testtools python3-xdg python3-yaml python3-lxml squashfs-tools
script:
- sudo -E lxc exec xenial -- su - ubuntu -c "cd $(pwd); ./runtests.sh $TEST_SUITE"
after_success:
View
@@ -14,8 +14,11 @@ Build-Depends: bzr,
python3-lxml,
python3-pkg-resources,
python3-requests,
+ python3-requests-oauthlib,
python3-setuptools,
+ python3-ssoclient,
python3-testscenarios,
+ python3-xdg,
python3-yaml,
wget,
xz-utils
@@ -35,6 +38,9 @@ Depends: bzr,
python3-lxml,
python3-pkg-resources,
python3-requests,
+ python3-requests-oauthlib,
+ python3-ssoclient,
+ python3-xdg,
python3-yaml,
squashfs-tools,
sudo,
View
@@ -4,6 +4,8 @@ Depends: @,
build-essential,
python3-pep8,
pyflakes,
+ python-flake8,
python3-fixtures,
+ python3-flake8,
python3-mccabe,
python3-testscenarios
@@ -0,0 +1,45 @@
+# -*- 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 integration_tests
+
+
+class MainTestCase(integration_tests.TestCase):
+
+ def test_main(self):
+ project_dir = 'assemble'
+ output = self.run_snapcraft('list-plugins', project_dir)
+ expected_plugins = [
+ 'ant',
+ 'autotools',
+ 'catkin',
+ 'cmake',
+ 'copy',
+ 'go',
+ 'jdk',
+ 'make',
+ 'maven',
+ 'nil',
+ 'nodejs',
+ 'python2',
+ 'python3',
+ 'qml',
+ 'roscore',
+ 'scons',
+ 'tar-content',
+ ]
+
+ self.assertIn('\n'.join(expected_plugins), output)
@@ -0,0 +1,49 @@
+# -*- 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
+
+from testtools.matchers import (
+ FileExists,
+)
+
+import integration_tests
+
+
+def _get_deb_arch():
+ return _run_dpkg_architecture('-qDEB_BUILD_ARCH')
+
+
+def _run_dpkg_architecture(arg):
+ return subprocess.check_output(
+ ['dpkg-architecture', arg], universal_newlines=True).strip()
+
+
+class UploadTestCase(integration_tests.TestCase):
+
+ def test_upload(self):
+ project_dir = 'assemble'
+ output = self.run_snapcraft('upload', project_dir)
+ os.chdir(project_dir)
+
+ snap_file_path = 'assemble_1.0_{}.snap'.format(_get_deb_arch())
+ self.assertThat(snap_file_path, FileExists())
+
+ self.assertIn('Snap assemble_1.0_amd64.snap not found. Running snap '
+ 'step to create it.', output)
+ self.assertIn('Uploading {}'.format(snap_file_path), output)
+ self.assertIn('{} upload failed'.format(snap_file_path), output)
View
@@ -45,12 +45,7 @@ parseargs(){
run_static_tests(){
SRC_PATHS="bin snapcraft snapcraft/tests examples_tests"
-
- # These three checks could easily be done with flake8 in one shot if
- # we had python3-flake8 provide flake8
- python3 -m pep8 $SRC_PATHS
-
- python3 -m pyflakes $SRC_PATHS
+ python3 /usr/bin/flake8 $SRC_PATHS
# mccabe in 'warning' mode as we have high complexity
mccabe_list=
View
@@ -39,13 +39,20 @@
url='https://github.com/ubuntu-core/snapcraft',
packages=['snapcraft',
'snapcraft.commands',
- 'snapcraft.plugins'],
+ 'snapcraft.plugins',
+ 'snapcraft.storeapi'],
package_data={'snapcraft': ['manifest.txt']},
scripts=['bin/snapcraft'],
data_files=[
('share/snapcraft/schema',
['schema/' + x for x in os.listdir('schema')]),
],
+ install_requires=[
+ 'pyxdg',
+ 'requests',
+ 'requests-oauthlib',
+ 'ssoclient',
+ ],
test_suite='snapcraft.tests',
license='GPL v3',
classifiers=(
@@ -0,0 +1,60 @@
+# -*- 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/>.
+
+"""
+snapcraft login
+
+Authenticates session against Ubuntu One SSO.
+
+Usage:
+ login [options]
+
+Options:
+ -h --help show this help message and exit.
+
+"""
+
+import getpass
+import logging
+
+from docopt import docopt
+
+from snapcraft.config import save_config
+from snapcraft.storeapi import login
+
+
+logger = logging.getLogger(__name__)
+
+
+def main(argv=None):
+ """Authenticates session against Ubuntu One SSO."""
@sergiusens

sergiusens Jan 27, 2016

Collaborator

For help to work, we need this here:

argv = argv if argv else []
args = docopt(__doc__, argv=argv)
+ argv = argv if argv else []
+ docopt(__doc__, argv=argv)
+
+ print('Enter your Ubuntu One SSO credentials.')
+ email = input('Email: ')
+ password = getpass.getpass('Password: ')
+ otp = input('OTP: ')
+
+ logger.info('Authenticating against Ubuntu One SSO.')
+ response = login(email, password, token_name='snapcraft', otp=otp)
+ success = response.get('success', False)
+
+ if success:
+ save_config(response['body'])
+ logger.info('Login successful.')
+ else:
+ logger.info('Login failed.')
@@ -0,0 +1,47 @@
+# -*- 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/>.
+
+"""
+snapcraft logout
+
+Forget credentials for Ubuntu One SSO.
+
+Usage:
+ logout [options]
+
+Options:
+ -h --help show this help message and exit.
+
+"""
+
+import logging
+
+from docopt import docopt
+
+from snapcraft.config import clear_config
+
+
+logger = logging.getLogger(__name__)
+
+
+def main(argv=None):
+ """Forget credentials for Ubuntu One SSO."""
+ argv = argv if argv else []
+ docopt(__doc__, argv=argv)
+
+ logger.info('Clearing credentials for Ubuntu One SSO.')
+ clear_config()
+ logger.info('Credentials cleared.')
@@ -0,0 +1,71 @@
+# -*- 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/>.
+
+"""
+snapcraft upload
+
+Upload snap package to the Ubuntu Store.
+
+Usage:
+ upload [options]
+
+Options:
+ -h --help show this help message and exit.
+
+"""
+
+import logging
+import os
+
+from docopt import docopt
+
+import snapcraft.yaml
+from snapcraft.commands import snap
+from snapcraft.config import load_config
+from snapcraft.storeapi import upload
+
+
+logger = logging.getLogger(__name__)
+
+
+def _format_snap_name(snap):
+ snap['arch'] = (snap['architectures'][0]
+ if len(snap['architectures']) == 1 else 'multi')
+ return '{name}_{version}_{arch}.snap'.format(**snap)
+
+
+def main(argv=None):
+ """Upload snap package to the Ubuntu Store."""
+ argv = argv if argv else []
+ docopt(__doc__, argv=argv)
+
+ # make sure the full lifecycle is executed
+ yaml_config = snapcraft.yaml.load_config()
+ snap_name = _format_snap_name(yaml_config.data)
+
+ if not os.path.exists(snap_name):
+ logger.info(
+ 'Snap {} not found. Running snap step to create it.'.format(
+ snap_name))
+ snap.main(argv=argv)
+
+ logger.info('Uploading {}'.format(snap_name))
+ config = load_config()
+ success = upload(snap_name, config=config)
+ if success:
+ logger.info('{} upload complete'.format(snap_name))
+ else:
+ logger.info('{} upload failed'.format(snap_name))
Oops, something went wrong.