Support packaging snapcraft projects from the IDE (Step 1)

This commit is contained in:
Benjamin Zeller
2016-09-22 18:11:03 +02:00
parent 8b038eef7f
commit d548b7d239
31 changed files with 1298 additions and 81 deletions

View File

@@ -86,7 +86,7 @@ ELSE(CMAKE_BUILD_TYPE MATCHES DEBUG)
ENDIF(CMAKE_BUILD_TYPE MATCHES DEBUG)
add_custom_target(ApplyPatches
env QUILT_PATCHES=debian/patches quilt push -a
${CMAKE_SOURCE_DIR}/apply-patches.sh
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
ExternalProject_Add(${QT_VERSION}

12
apply-patches.sh Executable file
View File

@@ -0,0 +1,12 @@
#!/bin/bash
env QUILT_PATCHES=debian/patches quilt push -a
RESULT=$?
if [ $RESULT -eq 0 -o $RESULT -eq 2 ]; then
exit 0
fi
exit 1

View File

@@ -1,8 +1,6 @@
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
@@ -165,10 +165,10 @@ void CMakeManager::createXmlFile(Utils::
--- a/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
+++ b/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojectmanager.cpp
@@ -165,10 +165,10 @@
proc->setWorkingDirectory(buildDirectoryPath);
proc->setEnvironment(env);
@@ -16,11 +14,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojec
Utils::QtcProcess::addArgs(&args, arguments);
proc->setCommand(executable, args);
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmlprojectmanager/qmlproject.cpp
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -288,9 +288,10 @@ Internal::Manager *QmlProject::projectMa
--- a/dist/qtcreator/src/plugins/qmlprojectmanager/qmlproject.cpp
+++ b/dist/qtcreator/src/plugins/qmlprojectmanager/qmlproject.cpp
@@ -288,9 +288,10 @@
bool QmlProject::supportsKit(Kit *k, QString *errorMessage) const
{
Id deviceType = DeviceTypeKitInformation::deviceTypeId(k);
@@ -33,11 +29,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmlprojectmanager/qmlproject.cp
return false;
}
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.cpp
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -2024,6 +2024,7 @@ EvalResult *QmakeProFileNode::evaluate(c
--- a/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.cpp
+++ b/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.cpp
@@ -2024,6 +2024,7 @@
result->newVarValues[AndroidExtraLibs] = input.readerExact->values(QLatin1String("ANDROID_EXTRA_LIBS"));
result->newVarValues[IsoIconsVar] = input.readerExact->values(QLatin1String("ISO_ICONS"));
result->newVarValues[QmakeProjectName] = input.readerExact->values(QLatin1String("QMAKE_PROJECT_NAME"));
@@ -45,11 +39,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.
result->isDeployable = false;
if (result->projectType == ApplicationTemplate) {
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.h
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -107,7 +107,8 @@ enum QmakeVariable {
--- a/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.h
+++ b/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.h
@@ -107,7 +107,8 @@
AndroidPackageSourceDir,
AndroidExtraLibs,
IsoIconsVar,
@@ -59,10 +51,8 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qmakeprojectmanager/qmakenodes.
};
namespace Internal {
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
--- a/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
+++ b/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfigitem.h
@@ -25,6 +25,8 @@
#pragma once
@@ -72,7 +62,7 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfig
#include <QByteArray>
#include <QList>
@@ -34,7 +36,7 @@ namespace ProjectExplorer { class Kit; }
@@ -34,7 +36,7 @@
namespace CMakeProjectManager {
@@ -81,11 +71,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeconfig
public:
enum Type { FILEPATH, PATH, BOOL, STRING, INTERNAL, STATIC };
CMakeConfigItem();
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.cpp
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.cpp
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.cpp
@@ -568,6 +568,11 @@ bool QtVersionManager::isValidId(int id)
--- a/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.cpp
+++ b/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.cpp
@@ -568,6 +568,11 @@
return m_versions.contains(id);
}
@@ -97,11 +85,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.cpp
BaseQtVersion *QtVersionManager::version(int id)
{
QTC_ASSERT(isLoaded(), return 0);
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.h
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.h
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.h
@@ -63,6 +63,7 @@ public:
--- a/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.h
+++ b/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.h
@@ -63,6 +63,7 @@
static void removeVersion(BaseQtVersion *version);
static bool isValidId(int id);
@@ -109,11 +95,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/qtsupport/qtversionmanager.h
signals:
// content of BaseQtVersion objects with qmake path might have changed
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/plugins.pro
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/plugins.pro
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/plugins.pro
@@ -56,7 +56,8 @@ SUBDIRS = \
--- a/dist/qtcreator/src/plugins/plugins.pro
+++ b/dist/qtcreator/src/plugins/plugins.pro
@@ -56,7 +56,8 @@
winrt \
qmlprofiler \
updateinfo \
@@ -123,11 +107,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/plugins.pro
DO_NOT_BUILD_QMLDESIGNER = $$(DO_NOT_BUILD_QMLDESIGNER)
isEmpty(DO_NOT_BUILD_QMLDESIGNER) {
Index: ubuntu-sdk-ide/dist/qt5/ubuntu-sdk/ubuntu-sdk.pro
===================================================================
--- ubuntu-sdk-ide.orig/dist/qt5/ubuntu-sdk/ubuntu-sdk.pro
+++ ubuntu-sdk-ide/dist/qt5/ubuntu-sdk/ubuntu-sdk.pro
@@ -11,10 +11,10 @@ load(qt_parts)
--- a/dist/qt5/ubuntu-sdk/ubuntu-sdk.pro
+++ b/dist/qt5/ubuntu-sdk/ubuntu-sdk.pro
@@ -11,10 +11,10 @@
src_uitk_launcher.subdir = ubuntu-ui-toolkit-launcher
src_uitk_launcher.depends = sub-src
@@ -141,11 +123,9 @@ Index: ubuntu-sdk-ide/dist/qt5/ubuntu-sdk/ubuntu-sdk.pro
# additional 'make test' target required by continuous integration system
test.target = test
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.cpp
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -387,6 +387,18 @@ void CMakeProject::runCMake()
--- a/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.cpp
+++ b/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.cpp
@@ -387,6 +387,18 @@
}
}
@@ -164,10 +144,8 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojec
QList<CMakeBuildTarget> CMakeProject::buildTargets() const
{
BuildDirManager *bdm = nullptr;
Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.h
===================================================================
--- ubuntu-sdk-ide.orig/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.h
--- a/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.h
+++ b/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeproject.h
@@ -27,6 +27,7 @@
#include "cmake_global.h"
@@ -176,7 +154,7 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojec
#include <projectexplorer/extracompiler.h>
#include <projectexplorer/project.h>
@@ -111,6 +112,8 @@ public:
@@ -111,6 +112,8 @@
void runCMake();
@@ -185,11 +163,9 @@ Index: ubuntu-sdk-ide/dist/qtcreator/src/plugins/cmakeprojectmanager/cmakeprojec
signals:
/// emitted when cmake is running:
void parsingStarted();
Index: ubuntu-sdk-ide/dist/qt5/ubuntu-sdk/src/UbuntuToolkit/menubar.cpp
===================================================================
--- ubuntu-sdk-ide.orig/dist/qt5/ubuntu-sdk/src/UbuntuToolkit/menubar.cpp
+++ ubuntu-sdk-ide/dist/qt5/ubuntu-sdk/src/UbuntuToolkit/menubar.cpp
@@ -249,11 +249,11 @@ PlatformMenuWrapper::PlatformMenuWrapper
--- a/dist/qt5/ubuntu-sdk/src/UbuntuToolkit/menubar.cpp
+++ b/dist/qt5/ubuntu-sdk/src/UbuntuToolkit/menubar.cpp
@@ -249,11 +249,11 @@
, m_target(target)
, m_inserted(false)
{
@@ -206,3 +182,68 @@ Index: ubuntu-sdk-ide/dist/qt5/ubuntu-sdk/src/UbuntuToolkit/menubar.cpp
syncPlatformMenu();
}
--- a/dist/qtcreator/src/plugins/coreplugin/generatedfile.cpp
+++ b/dist/qtcreator/src/plugins/coreplugin/generatedfile.cpp
@@ -161,6 +161,12 @@
Utils::FileSaver saver(m_d->path, flags);
saver.write(m_d->contents);
+
+ if (attributes() & UserExecutable) {
+ QFile *createdFile = saver.file();
+ createdFile->setPermissions(createdFile->permissions() | QFileDevice::ExeOwner);
+ }
+
return saver.finalize(errorMessage);
}
--- a/dist/qtcreator/src/plugins/coreplugin/generatedfile.h
+++ b/dist/qtcreator/src/plugins/coreplugin/generatedfile.h
@@ -46,7 +46,9 @@
/* File exists and the user indicated that he wants to keep it */
KeepExistingFileAttribute = 0x8,
/* Force overwriting of a file without asking the user to keep it */
- ForceOverwrite = 0x10
+ ForceOverwrite = 0x10,
+ /* Set User executable flag*/
+ UserExecutable = 0x20
};
Q_DECLARE_FLAGS(Attributes, Attribute)
--- a/dist/qtcreator/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp
+++ b/dist/qtcreator/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.cpp
@@ -70,6 +70,7 @@
f.overwrite = tmp.value(QLatin1String("overwrite"), false);
f.openInEditor = tmp.value(QLatin1String("openInEditor"), false);
f.openAsProject = tmp.value(QLatin1String("openAsProject"), false);
+ f.isUserExecutable = tmp.value(QLatin1String("userExecutable"), false);
f.options = JsonWizard::parseOptions(tmp.value(QLatin1String("options")), errorMessage);
if (!errorMessage->isEmpty())
@@ -146,6 +147,8 @@
attributes |= Core::GeneratedFile::OpenProjectAttribute;
if (JsonWizard::boolFromVariant(file.overwrite, expander))
attributes |= Core::GeneratedFile::ForceOverwrite;
+ if (JsonWizard::boolFromVariant(file.isUserExecutable, expander))
+ attributes |= Core::GeneratedFile::UserExecutable;
if (file.keepExisting)
attributes |= Core::GeneratedFile::KeepExistingFileAttribute;
@@ -231,6 +234,7 @@
if (!file->write(errorMessage))
return false;
}
+
return true;
}
--- a/dist/qtcreator/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h
+++ b/dist/qtcreator/src/plugins/projectexplorer/jsonwizard/jsonwizardfilegenerator.h
@@ -55,6 +55,7 @@
QVariant overwrite = false;
QVariant openInEditor = false;
QVariant openAsProject = false;
+ QVariant isUserExecutable = false;
QList<JsonWizard::OptionDefinition> options;
};

View File

@@ -106,7 +106,10 @@ SOURCES += \
src/ubuntu/device/container/ubuntulocaldeployconfiguration.cpp \
src/ubuntu/device/container/ubuntulocalrunconfigurationfactory.cpp \
src/ubuntu/device/container/ubuntulocalrunconfiguration.cpp \
src/ubuntu/processoutputdialog.cpp
src/ubuntu/processoutputdialog.cpp \
$$PWD/src/ubuntu/ubuntujsextension.cpp \
src/ubuntu/snap/snapcraftpackagestep.cpp \
src/ubuntu/snap/snaphelper.cpp
HEADERS += \
src/ubuntu/ubuntuplugin.h \
@@ -175,7 +178,10 @@ HEADERS += \
src/ubuntu/device/container/ubuntulocaldeployconfiguration.h \
src/ubuntu/device/container/ubuntulocalrunconfigurationfactory.h \
src/ubuntu/device/container/ubuntulocalrunconfiguration.h \
src/ubuntu/processoutputdialog.h
src/ubuntu/processoutputdialog.h \
$$PWD/src/ubuntu/ubuntujsextension.h \
src/ubuntu/snap/snapcraftpackagestep.h \
src/ubuntu/snap/snaphelper.h
#remote device support
SOURCES += \
@@ -214,6 +220,7 @@ HEADERS += \
src/ubuntu/device/remote/ubuntudirectuploadstep.h \
src/ubuntu/device/remote/ubuntudeploystepfactory.h
FORMS += \
src/ubuntu/device/remote/ubunturemoterunconfigurationwidget.ui \

View File

@@ -0,0 +1,32 @@
# This is the basic qmake template for the Ubuntu-SDK
# it handles creation and installation of the manifest
# file and takes care of subprojects
TEMPLATE = subdirs
SUBDIRS += %{ProjectNameL}
# enables/disabled the extra targets to build a snapcraft package
# also tells the IDE this is a snapcraft project
CONFIG += snapcraft
snapcraft {
SNAPCRAFT_FILE=snapcraft.yaml
#the Ubuntu SDK IDE uses the snap target to create the package
snappy.target = snap
snappy.commands = cd $$OUT_PWD
snappy.commands += && rm -rf \'$$OUT_PWD/snap-deploy\'
snappy.commands += && make INSTALL_ROOT=$$OUT_PWD/snap-deploy install
snappy.commands += && cd $$OUT_PWD/snap-deploy
snappy.commands += && snapcraft
OTHER_FILES+=$$SNAPCRAFT_FILE
QMAKE_EXTRA_TARGETS += snappy
packaging.files = $$SNAPCRAFT_FILE
packaging.path = /
INSTALLS+=packaging
}

View File

@@ -0,0 +1,54 @@
import QtQuick 2.4
import Ubuntu.Components 1.3
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
applicationName: "%{ProjectNameL}.%{DeveloperId}"
width: units.gu(100)
height: units.gu(75)
Page {
header: PageHeader {
id: pageHeader
title: i18n.tr("%{ProjectNameL}")
StyleHints {
foregroundColor: UbuntuColors.orange
backgroundColor: UbuntuColors.porcelain
dividerColor: UbuntuColors.slate
}
}
Label {
id: label
objectName: "label"
anchors {
horizontalCenter: parent.horizontalCenter
top: pageHeader.bottom
topMargin: units.gu(2)
}
text: i18n.tr("Hello..")
}
Button {
objectName: "button"
anchors {
horizontalCenter: parent.horizontalCenter
top: label.bottom
topMargin: units.gu(2)
}
width: parent.width
text: i18n.tr("Tap me!")
onClicked: {
label.text = i18n.tr("..world!")
}
}
}
}

View File

@@ -0,0 +1,9 @@
[Desktop Entry]
Version=1.0
Name=%{ProjectNameL}
Exec=%{ProjectNameL}
TryExec=%{ProjectNameL}
Icon=${SNAP}/meta/gui/%{ProjectNameL}.png
Terminal=false
Type=Application
X-Ubuntu-Touch=true

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -0,0 +1,48 @@
TEMPLATE = app
TARGET = %{ProjectNameL}
QT += qml quick
# enables/disabled the extra targets to build a snapcraft package
# also tells the IDE this is a snapcraft project
CONFIG += snapcraft
SOURCES += main.cpp
RESOURCES += %{ProjectNameL}.qrc
QML_FILES += $$files(*.qml,true) \
$$files(*.js,true)
CONF_FILES += %{ProjectNameL}.png
AP_TEST_FILES += tests/autopilot/run \
$$files(tests/*.py,true)
#show all the files in QtCreator
OTHER_FILES += $${CONF_FILES} \
$${QML_FILES} \
$${AP_TEST_FILES} \
%{ProjectNameL}.desktop \
%{ProjectNameL}.wrapper
snapcraft {
#specify where the config files are installed to
config_files.path = /setup/gui
config_files.files += $${CONF_FILES}
INSTALLS+=config_files
#install the desktop file
desktop_file.path = /setup/gui
desktop_file.files = $$PWD/%{ProjectNameL}.desktop
desktop_file.CONFIG += no_check_exist
INSTALLS+=desktop_file
# Default rules for deployment.
wrapper.files = %{ProjectNameL}.wrapper
wrapper.path = /deploy/bin
target.path = /deploy/bin
INSTALLS+=target wrapper
}

View File

@@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>Main.qml</file>
</qresource>
</RCC>

View File

@@ -0,0 +1,63 @@
#!/bin/bash
if [ "$SNAP_ARCH" == "amd64" ]; then
ARCH="x86_64-linux-gnu"
elif [ "$SNAP_ARCH" == "armhf" ]; then
ARCH="arm-linux-gnueabihf"
else
ARCH="$SNAP_ARCH-linux-gnu"
fi
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH:$LD_LIBRARY_PATH
# XKB config
export XKB_CONFIG_ROOT=$SNAP/usr/share/X11/xkb
if [ "$DESKTOP_SESSION" == "unity8" ]; then
# Qt Platform to Mir
export QT_QPA_PLATFORM=ubuntumirclient
# Mir runtime
export MIR_SOCKET=$XDG_RUNTIME_DIR/mir_socket
export MIR_CLIENT_PLATFORM_PATH=$SNAP/usr/lib/$ARCH/mir/client-platform
fi
# Qt Libs
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH/qt5/libs:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH/pulseaudio:$LD_LIBRARY_PATH
# Qt Modules
export QT_PLUGIN_PATH=$SNAP/usr/lib/$ARCH/qt5/plugins
export QML2_IMPORT_PATH=$QML2_IMPORT_PATH:$SNAP/usr/lib/$ARCH/qt5/qml
export QML2_IMPORT_PATH=$QML2_IMPORT_PATH:$SNAP/lib/$ARCH
# Mesa Libs
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH/mesa:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$SNAP/usr/lib/$ARCH/mesa-egl:$LD_LIBRARY_PATH
# XDG Config
export XDG_CONFIG_DIRS=$SNAP/etc/xdg:$XDG_CONFIG_DIRS
export XDG_CONFIG_DIRS=$SNAP/usr/xdg:$XDG_CONFIG_DIRS
# Note: this doesn't seem to work, QML's LocalStorage either ignores
# or fails to use $SNAP_USER_DATA if defined here
export XDG_DATA_DIRS=$SNAP_USER_DATA:$XDG_DATA_DIRS
export XDG_DATA_DIRS=$SNAP/usr/share:$XDG_DATA_DIRS
# needed for fontconfig
export XDG_DATA_HOME=$SNAP/usr/share
# Font Config
export FONTCONFIG_PATH=$SNAP/etc/fonts/config.d
export FONTCONFIG_FILE=$SNAP/etc/fonts/fonts.conf
# Tell libGL where to find the drivers
export LIBGL_DRIVERS_PATH=$SNAP/usr/lib/$ARCH/dri
# Necessary for the SDK to find the translations directory
export APP_DIR=$SNAP
# ensure the snappy gl libs win
export LD_LIBRARY_PATH="$SNAP_LIBRARY_PATH:$LD_LIBRARY_PATH"
cd $SNAP
exec $SNAP/bin/%{ProjectNameL}

View File

@@ -0,0 +1,14 @@
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:///Main.qml")));
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
}

View File

@@ -0,0 +1,23 @@
name: %{ProjectNameL}
version: 0.01
summary: Example application
description: Shows a basic UITK based UI
confinement: strict
apps:
%{ProjectNameL}:
command: %{ProjectNameL}.wrapper
plugs: [unity7, opengl]
parts:
%{ProjectNameL}:
plugin: dump
source: deploy/
stage-packages:
- ubuntu-sdk-libs
- qtubuntu-desktop
- qtmir-desktop
- mir-graphics-drivers-desktop

View File

@@ -0,0 +1,108 @@
{
"version": 1,
"supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ],
"id": "A.QtQuick Snappy Application",
"category": "B.Snapcraft",
"trDescription": "Creates a experimental C++ Ubuntu snappy application project with a sample UI containing a Label and a Button.",
"trDisplayName": "QtQuick App with QML Ubuntu UI",
"trDisplayCategory": "Snapcraft",
"icon": "../share/ubuntu.png",
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}",
"options":
[
{ "key": "ProjectFile", "value": "%{JS: Util.fileName('%{ProjectDirectory}/%{ProjectName}', 'pro')}" },
{ "key": "ProjectNameL", "value": "%{JS: \"%{ProjectName}\".toLowerCase()}" },
{ "key": "CppFileName", "value": "%{JS: 'main.' + Util.preferredSuffix('text/x-c++src')}" },
{ "key": "IsTopLevelProject", "value": "%{JS: !'%{Exists:ProjectExplorer.Profile.Ids}'}" }
],
"pages":
[
{
"trDisplayName": "Project Location",
"trShortTitle": "Location",
"typeId": "Project"
},
{
"trDisplayName": "Developer ID",
"trShortTitle": "Developer ID",
"typeId": "Fields",
"data" :
[
{
"name": "DeveloperId",
"trDisplayName": "Developer ID:",
"mandatory": true,
"type": "LineEdit",
"data": {
"validator": "^[A-Za-z0-9-]+$",
"trText": "%{JS: Ubuntu.developerId()}"
}
}
]
},
{
"trDisplayName": "Kit Selection",
"trShortTitle": "Kits",
"typeId": "Kits",
"enabled": "%{IsTopLevelProject}",
"data": { "projectFilePath": "%{ProjectFile}" }
},
{
"trDisplayName": "Project Management",
"trShortTitle": "Summary",
"typeId": "Summary"
}
],
"generators":
[
{
"typeId": "File",
"data":
[
{
"source": "appName.pro",
"target": "%{ProjectFile}",
"openAsProject": true
},
{
"source": "snapcraft.yaml",
"openInEditor": true
},
{
"source": "appName/main.cpp",
"target": "%{ProjectDirectory}/%{ProjectNameL}/%{CppFileName}",
"openInEditor": true
},
{
"source": "appName/Main.qml",
"target": "%{ProjectDirectory}/%{ProjectNameL}/Main.qml",
"openInEditor": true
},
{
"source": "appName/appName.desktop",
"target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.desktop"
},
{
"source": "appName/appName.png",
"target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.png"
},
{
"source": "appName/appName.pro",
"target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.pro"
},
{
"source": "appName/appName.qrc",
"target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.qrc"
},
{
"source": "appName/appName.wrapper",
"target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.wrapper",
"userExecutable": true
}
]
}
]
}

View File

@@ -80,7 +80,7 @@ MainView {
spacing: units.gu(2)
Button {
visible: publishModel.showValidationUi
text: "Validate existing click package"
text: "Validate existing package"
onClicked: {
publishModel.on_pushButtonReviewersTools_clicked();
}
@@ -88,7 +88,7 @@ MainView {
Button {
visible: publishModel.showValidationUi
enabled: publishModel.canBuild
text: "Build and validate click package"
text: "Build and validate package"
onClicked: {
publishModel.on_pushButtonClickPackage_clicked();
}

View File

@@ -147,6 +147,7 @@ extra_packages = {
"qttools5-dev:{TARGET}",
"ubuntu-sdk-qmake-extras:{TARGET}",
"ubuntu-ui-toolkit-doc:{TARGET}",
"snapcraft"
],
"ubuntu-sdk-16.10": [
]

View File

@@ -71,3 +71,4 @@ exists( $$PWD/../../plugins.pro ) {
LIBS += -L$$[QT_INSTALL_LIBS]/qtcreator
LIBS += -L$$[QT_INSTALL_LIBS]/qtcreator/plugins
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 Canonical Ltd.
* Copyright 2016 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014 Canonical Ltd.
* Copyright 2016 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by

View File

@@ -0,0 +1,468 @@
/*
* Copyright 2016 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Benjamin Zeller <benjamin.zeller@canonical.com>
*/
#include "snapcraftpackagestep.h"
#include <ubuntu/ubuntuconstants.h>
#include <ubuntu/ubuntupackageoutputparser.h>
#include <projectexplorer/target.h>
#include <projectexplorer/task.h>
#include <projectexplorer/kitinformation.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/toolchain.h>
#include <utils/qtcassert.h>
#include <utils/fileutils.h>
#include <QTimer>
#include <QRegularExpression>
namespace Ubuntu {
namespace Internal {
const char * PACKAGE_NAME_REGEX = "^Snapped ([\\S]+\\.snap)$";
SnapcraftPackageStep::SnapcraftPackageStep(ProjectExplorer::BuildStepList *bsl)
: ProjectExplorer::BuildStep (bsl, Constants::UBUNTU_SNAP_PACKAGESTEP_ID)
{
}
SnapcraftPackageStep::SnapcraftPackageStep(ProjectExplorer::BuildStepList *bsl, SnapcraftPackageStep *other)
: ProjectExplorer::BuildStep (bsl, other)
{
}
SnapcraftPackageStep::~SnapcraftPackageStep()
{
cleanup();
}
QString SnapcraftPackageStep::packagePath() const
{
if(m_snapPackageName.isEmpty())
return QString();
return snapWorkingDir()
+ QDir::separator()
+ m_snapPackageName;
}
QString SnapcraftPackageStep::snapWorkingDir() const
{
return m_buildDir+QStringLiteral("/snap-deploy");
}
bool SnapcraftPackageStep::init(QList<const ProjectExplorer::BuildStep *> &earlierSteps)
{
Q_UNUSED(earlierSteps)
return true;
}
void SnapcraftPackageStep::run(QFutureInterface<bool> &fi)
{
internalInit();
if (m_tasks.size()) {
foreach (const ProjectExplorer::Task& task, m_tasks) {
addTask(task);
}
emit addOutput(tr("Configuration is invalid. Aborting build")
,ProjectExplorer::BuildStep::MessageOutput);
reportRunResult(fi, false);
cleanup();
return;
}
m_state = Idle;
m_futureInterface = &fi;
m_futureInterface->setProgressRange(0,2);
QTimer::singleShot(0,this,SLOT(doNextStep()));
}
void SnapcraftPackageStep::cleanup()
{
if (m_process) {
m_process->disconnect(this);
m_process->kill();
m_process->deleteLater();
m_process = 0;
}
//not owned by us
m_futureInterface = 0;
if (m_outputParserChain) {
delete m_outputParserChain;
m_outputParserChain = 0;
}
//reset params
m_SnapReviewParam = m_MakeParam = ProjectExplorer::ProcessParameters();
m_currParam = nullptr;
}
/*!
* \brief UbuntuPackageStep::setupAndStartProcess
* Setups the interal QProcess and connects the required SIGNALS
* also makes sure the process has a clean output parser
*/
void SnapcraftPackageStep::setupAndStartProcess(ProjectExplorer::ProcessParameters &params)
{
if (m_process) {
m_process->disconnect(this);
m_process->kill();
m_process->deleteLater();
}
m_currParam = &params;
QDir wd(params.effectiveWorkingDirectory());
if (!wd.exists())
wd.mkpath(wd.absolutePath());
QString effectiveCommand = params.effectiveCommand();
if (!QFileInfo(effectiveCommand).exists()) {
onProcessFailedToStart();
return;
}
m_process = new Utils::QtcProcess();
connect(m_process,SIGNAL(finished(int)),this,SLOT(doNextStep()));
connect(m_process,SIGNAL(readyReadStandardOutput()),this,SLOT(onProcessStdOut()));
connect(m_process,SIGNAL(readyReadStandardError()),this,SLOT(onProcessStdErr()));
m_process->setCommand(params.effectiveCommand(),params.effectiveArguments());
m_process->setEnvironment(params.environment());
m_process->setWorkingDirectory(wd.absolutePath());
emit addOutput(tr("Starting: \"%1 %2\"").arg(params.effectiveCommand(),params.effectiveArguments()),
BuildStep::MessageOutput);
ProjectExplorer::IOutputParser *parser = target()->kit()->createOutputParser();
//add special parser on click review step
if(m_state == SnapReview) {
UbuntuPackageOutputParser *packageStepParser = new UbuntuPackageOutputParser;
//packageStepParser->setTreatAllErrorsAsWarnings(m_treatClickErrorsAsWarnings);
connect(this,SIGNAL(currentSubStepFinished()),packageStepParser,SLOT(setEndOfData()));
if (parser)
parser->appendOutputParser(packageStepParser);
else
parser = packageStepParser;
}
if(m_outputParserChain) {
delete m_outputParserChain;
m_outputParserChain = 0;
}
if(parser) {
m_outputParserChain = parser;
m_outputParserChain->setWorkingDirectory(params.effectiveWorkingDirectory());
connect(m_outputParserChain,SIGNAL(addOutput(QString,ProjectExplorer::BuildStep::OutputFormat)),
this,SLOT(outputAdded(QString,ProjectExplorer::BuildStep::OutputFormat)));
connect(m_outputParserChain,SIGNAL(addTask(ProjectExplorer::Task)),
this,SLOT(taskAdded(ProjectExplorer::Task)));
}
m_process->start();
if(!m_process->waitForStarted()) {
onProcessFailedToStart();
return;
}
}
/*!
* \brief UbuntuPackageStep::checkLastProcessSuccess
* Checks if the last process has run without any errors
*/
bool SnapcraftPackageStep::processFinished(FinishedCheckMode mode)
{
//make sure all data has been read
QString line = QString::fromLocal8Bit(m_process->readAllStandardError());
if (!line.isEmpty())
stdError(line);
line = QString::fromLocal8Bit(m_process->readAllStandardOutput());
if (!line.isEmpty())
stdOutput(line);
emit currentSubStepFinished();
bool success = true;
if (m_outputParserChain) {
m_outputParserChain->flush();
if(m_outputParserChain->hasFatalErrors())
success = false;
}
if(success) {
QString command;
if(m_currParam)
command = QDir::toNativeSeparators(m_currParam->effectiveCommand());
else
command = tr("Unknown command");
if (m_process->exitStatus() == QProcess::NormalExit && m_process->exitCode() == 0) {
emit addOutput(tr("The process \"%1\" exited normally.").arg(command),
BuildStep::MessageOutput);
} else if (m_process->exitStatus() == QProcess::NormalExit) {
emit addOutput(tr("The process \"%1\" exited with code %2.")
.arg(command, QString::number(m_process->exitCode())),
BuildStep::ErrorMessageOutput);
if(mode == CheckReturnCode)
//error
success = false;
else {
emit addOutput(tr("Ignoring return code for this step"),BuildStep::ErrorMessageOutput);
}
} else {
emit addOutput(tr("The process \"%1\" crashed.").arg(command), BuildStep::ErrorMessageOutput);
//error
success = false;
}
}
//the process failed, lets clean up
if (!success) {
if(m_futureInterface)
reportRunResult(*m_futureInterface, false);
cleanup();
}
return success;
}
void SnapcraftPackageStep::stdOutput(const QString &line)
{
m_lastLine = line;
if (m_outputParserChain)
m_outputParserChain->stdOutput(line);
emit addOutput(line, BuildStep::NormalOutput, BuildStep::DontAppendNewline);
}
void SnapcraftPackageStep::stdError(const QString &line)
{
if (m_outputParserChain)
m_outputParserChain->stdError(line);
emit addOutput(line, BuildStep::ErrorOutput, BuildStep::DontAppendNewline);
}
void SnapcraftPackageStep::onProcessStdOut()
{
m_process->setReadChannel(QProcess::StandardOutput);
while (m_process->canReadLine()) {
QString line = QString::fromLocal8Bit(m_process->readLine());
stdOutput(line);
}
}
void SnapcraftPackageStep::onProcessStdErr()
{
m_process->setReadChannel(QProcess::StandardError);
while (m_process->canReadLine()) {
QString line = QString::fromLocal8Bit(m_process->readLine());
stdError(line);
}
}
void SnapcraftPackageStep::outputAdded(const QString &string, ProjectExplorer::BuildStep::OutputFormat format)
{
emit addOutput(string, format, BuildStep::DontAppendNewline);
}
void SnapcraftPackageStep::taskAdded(const ProjectExplorer::Task &task)
{
emit addTask(task);
}
void SnapcraftPackageStep::onProcessFailedToStart()
{
if(m_futureInterface)
reportRunResult(*m_futureInterface, false);
QString command = tr("Unknown command");
QString args;
if (m_currParam) {
command = QDir::toNativeSeparators(m_currParam->effectiveCommand());
args = m_currParam->prettyArguments();
}
emit addOutput(tr("Could not start process \"%1\" %2")
.arg(command, args),
BuildStep::ErrorMessageOutput);
cleanup();
}
QString SnapcraftPackageStep::makeCommand(ProjectExplorer::ToolChain *tc, const Utils::Environment &env) const
{
if (tc)
return tc->makeCommand(env);
return QString();
}
ProjectExplorer::BuildStepConfigWidget *SnapcraftPackageStep::createConfigWidget()
{
return nullptr;
}
void SnapcraftPackageStep::cancel()
{
}
bool SnapcraftPackageStep::immutable() const
{
return true;
}
bool SnapcraftPackageStep::runInGuiThread() const
{
return true;
}
void SnapcraftPackageStep::doNextStep()
{
switch (m_state) {
case Idle: {
m_state = MakeSnap;
m_currParam = nullptr;
setupAndStartProcess(m_MakeParam);
break;
}
case MakeSnap: {
if (!processFinished(CheckReturnCode))
return;
m_currParam = nullptr;
QRegularExpression exp((QLatin1String(PACKAGE_NAME_REGEX)));
QRegularExpressionMatch m = exp.match(m_lastLine);
if(m.hasMatch()) {
m_snapPackageName = m.captured(1);
emit addOutput(tr("The click package has been created in %1").arg(snapWorkingDir()) ,
ProjectExplorer::BuildStep::MessageOutput);
}
m_futureInterface->setProgressValueAndText(1,tr("Reviewing snap package"));
m_state = SnapReview;
m_SnapReviewParam.setArguments(QString::fromLatin1(Constants::CLICK_REVIEWERSTOOLS_ARGS).arg(packagePath()));
m_SnapReviewParam.resolveAll();
setupAndStartProcess(m_SnapReviewParam);
break;
}
case SnapReview: {
//we need to ignore the return code for now,
//until we have proper support for ignoring specific errors
if (!processFinished(IgnoreReturnCode))
return;
if(m_futureInterface)
reportRunResult(*m_futureInterface, true);
cleanup();
break;
}
}
}
void SnapcraftPackageStep::internalInit()
{
m_tasks.clear();
QString projectDir = target()->project()->projectDirectory().toString();
m_buildDir.clear();
Utils::Environment env = Utils::Environment::systemEnvironment();
Utils::MacroExpander *mExp = 0;
ProjectExplorer::BuildConfiguration *bc = target()->activeBuildConfiguration();
if (!bc) {
ProjectExplorer::Task t(ProjectExplorer::Task::Error
,tr("No valid BuildConfiguration set for step: %1").arg(displayName())
,Utils::FileName(),-1
,ProjectExplorer::Constants::TASK_CATEGORY_BUILDSYSTEM);
m_tasks.append(t);
//SnapcraftPackageStep::run will stop if tasks exist
return;
}
m_buildDir = bc->buildDirectory().toString();
env = bc->environment();
mExp = bc->macroExpander();
{
QStringList arguments {
QStringLiteral("snap")
};
ProjectExplorer::ProcessParameters* params = &m_MakeParam;
params->setMacroExpander(mExp);
//setup process parameters
params->setWorkingDirectory(m_buildDir);
params->setCommand(
makeCommand(ProjectExplorer::ToolChainKitInformation::toolChain(target()->kit()),
env));
params->setArguments(Utils::QtcProcess::joinArgs(arguments));
Utils::Environment tmpenv = env;
// Force output to english for the parsers. Do this here and not in the toolchain's
// addToEnvironment() to not screw up the users run environment.
tmpenv.set(QLatin1String("LC_ALL"), QLatin1String("C"));
params->setEnvironment(tmpenv);
params->resolveAll();
}
//builds the snap review arguments
{
ProjectExplorer::ProcessParameters* params = &m_SnapReviewParam;
params->setMacroExpander(mExp);
//setup process parameters
params->setWorkingDirectory(m_buildDir);
params->setCommand(QLatin1String(Constants::CLICK_REVIEWERSTOOLS_BINARY));
Utils::Environment tmpEnv = env;
// Force output to english for the parsers. Do this here and not in the toolchain's
// addToEnvironment() to not screw up the users run environment.
tmpEnv.set(QLatin1String("LC_ALL"), QLatin1String("C"));
params->setEnvironment(tmpEnv);
}
}
} // namespace Internal
} // namespace Ubuntu

View File

@@ -0,0 +1,105 @@
/*
* Copyright 2016 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Benjamin Zeller <benjamin.zeller@canonical.com>
*/
#ifndef UBUNTU_INTERNAL_SNAPCRAFTPACKAGESTEP_H
#define UBUNTU_INTERNAL_SNAPCRAFTPACKAGESTEP_H
#include <projectexplorer/buildstep.h>
#include <projectexplorer/ioutputparser.h>
#include <projectexplorer/processparameters.h>
#include <utils/qtcprocess.h>
namespace ProjectExplorer{
class ToolChain;
}
namespace Ubuntu {
namespace Internal {
class SnapcraftPackageStep : public ProjectExplorer::BuildStep
{
Q_OBJECT
public:
enum State {
Idle,
MakeSnap,
SnapReview
};
enum FinishedCheckMode {
CheckReturnCode,
IgnoreReturnCode
};
SnapcraftPackageStep(ProjectExplorer::BuildStepList *bsl);
SnapcraftPackageStep(ProjectExplorer::BuildStepList *bsl, SnapcraftPackageStep *other);
virtual ~SnapcraftPackageStep();
QString packagePath () const;
QString snapWorkingDir () const;
// BuildStep interface
virtual bool init(QList<const ProjectExplorer::BuildStep *> &earlierSteps) override;
virtual void run(QFutureInterface<bool> &fi) override;
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
virtual void cancel() override;
virtual bool immutable() const override;
virtual bool runInGuiThread() const override;
signals:
void currentSubStepFinished();
protected slots:
void doNextStep ();
void onProcessFailedToStart();
void onProcessStdOut();
void onProcessStdErr();
void outputAdded(const QString &string, ProjectExplorer::BuildStep::OutputFormat format);
void taskAdded (const ProjectExplorer::Task & task);
private:
void internalInit ();
void cleanup();
QString makeCommand(ProjectExplorer::ToolChain *tc, const Utils::Environment &env) const;
void setupAndStartProcess(ProjectExplorer::ProcessParameters &params);
void stdOutput(const QString &line);
void stdError(const QString &line);
bool processFinished(FinishedCheckMode mode);
private:
State m_state = SnapcraftPackageStep::Idle;
QList<ProjectExplorer::Task> m_tasks;
QFutureInterface<bool> *m_futureInterface;
Utils::QtcProcess *m_process = nullptr;
ProjectExplorer::IOutputParser *m_outputParserChain = nullptr;
QString m_buildDir;
QString m_lastLine;
QString m_snapPackageName;
ProjectExplorer::ProcessParameters m_MakeParam;
ProjectExplorer::ProcessParameters m_SnapReviewParam;
ProjectExplorer::ProcessParameters *m_currParam = nullptr;
};
} // namespace Internal
} // namespace Ubuntu
#endif // UBUNTU_INTERNAL_SNAPCRAFTPACKAGESTEP_H

View File

@@ -0,0 +1,30 @@
#include "snaphelper.h"
#include <projectexplorer/project.h>
#include <qmakeprojectmanager/qmakeproject.h>
#include <qmakeprojectmanager/qmakeprojectmanagerconstants.h>
namespace Ubuntu {
namespace Internal {
SnapHelper::SnapHelper()
{
}
bool SnapHelper::isSnappyProject(ProjectExplorer::Project *project)
{
if (!project)
return false;
QString mimeType = project->projectManager()->mimeType();
if(mimeType != QLatin1String(QmakeProjectManager::Constants::PROFILE_MIMETYPE))
return false;
QmakeProjectManager::QmakeProject *qPro = static_cast<QmakeProjectManager::QmakeProject *>(project);
QmakeProjectManager::QmakeProFileNode *node = qPro->rootProjectNode();
return node->variableValue(QmakeProjectManager::ConfigVar).contains(QStringLiteral("snapcraft"), Qt::CaseInsensitive);
}
} // namespace Internal
} // namespace Ubuntu

View File

@@ -0,0 +1,22 @@
#ifndef UBUNTU_INTERNAL_SNAPHELPER_H
#define UBUNTU_INTERNAL_SNAPHELPER_H
namespace ProjectExplorer {
class Project;
}
namespace Ubuntu {
namespace Internal {
class SnapHelper
{
public:
SnapHelper();
static bool isSnappyProject (ProjectExplorer::Project* project);
};
} // namespace Internal
} // namespace Ubuntu
#endif // UBUNTU_INTERNAL_SNAPHELPER_H

View File

@@ -344,6 +344,7 @@ const char UBUNTU_LOCAL_DEPLOYCONFIGURATION_ID[] = "UbuntuProjectManager.LocalDe
const char UBUNTU_DEPLOY_UPLOADSTEP_ID[] = "UbuntuProjectManager.UploadStep";
const char UBUNTU_DEPLOY_MAKESTEP_ID[] = "UbuntuProjectManager.UbuntuCMake.DeployMakeStep";
const char UBUNTU_CLICK_PACKAGESTEP_ID[] = "UbuntuProjectManager.ClickPackageStep";
const char UBUNTU_SNAP_PACKAGESTEP_ID[] = "UbuntuProjectManager.SnapPackageStep";
const char UBUNTU_DEPLOY_DESTDIR[] = ".ubuntu-sdk-deploy";
const char UBUNTU_CLICK_SUCCESS_PACKAGE_REGEX[] = "^.*'(.*)'.$";

View File

@@ -0,0 +1,46 @@
/*
* Copyright 2016 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Benjamin Zeller <benjamin.zeller@canonical.com>
*/
#include "ubuntujsextension.h"
#include <ubuntu/ubuntubzr.h>
namespace Ubuntu {
namespace Internal {
UbuntuJsExtension::UbuntuJsExtension(QObject *parent) : QObject(parent)
{
}
QString UbuntuJsExtension::developerId() const
{
QString maintainer = QStringLiteral("username");
UbuntuBzr *bzr = UbuntuBzr::instance();
if(!bzr->isInitialized()) {
bzr->initialize();
bzr->waitForFinished();
}
if(bzr->isInitialized()) {
maintainer = bzr->launchpadId();
}
return maintainer;
}
}}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2016 Canonical Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; version 2.1.
*
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Benjamin Zeller <benjamin.zeller@canonical.com>
*/
#ifndef UBUNTUJSEXTENSION_H
#define UBUNTUJSEXTENSION_H
#include <QObject>
namespace Ubuntu {
namespace Internal {
class UbuntuJsExtension : public QObject
{
Q_OBJECT
public:
explicit UbuntuJsExtension(QObject *parent = 0);
Q_INVOKABLE QString developerId() const;
};
}}
#endif // UBUNTUJSEXTENSION_H

View File

@@ -30,6 +30,8 @@
#include "ubuntuproject.h"
#include <ubuntu/device/remote/ubuntudevice.h>
#include <ubuntu/snap/snaphelper.h>
#include <ubuntu/snap/snapcraftpackagestep.h>
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/project.h>
@@ -159,7 +161,6 @@ void UbuntuPackagingModel::onFinishedAction(const QProcess *proc, QString cmd)
m_ubuntuProcess.append(QStringList() << QString::fromLatin1(Constants::CLICK_REVIEWERSTOOLS_LOCATION).arg(sClickPackagePath));
m_ubuntuProcess.start(QString(QLatin1String(Constants::UBUNTUPACKAGINGWIDGET_CLICK_REVIEWER_TOOLS_AGAINST_PACKAGE)).arg(sClickPackagePath));
}
}
void UbuntuPackagingModel::onMessage(QString msg)
@@ -294,6 +295,16 @@ void UbuntuPackagingModel::on_pushButtonClickPackage_clicked() {
if(!project)
return;
if (SnapHelper::isSnappyProject(project)) {
if(m_reviewToolsInstalled)
m_postPackageTask = Verify;
else
m_postPackageTask = None;
buildSnapPackage();
return;
}
QString mimeType = project->projectManager()->mimeType();
if(mimeType == QLatin1String(CMakeProjectManager::Constants::CMAKEPROJECTMIMETYPE)
|| mimeType == QLatin1String(Ubuntu::Constants::UBUNTUPROJECT_MIMETYPE)
@@ -303,6 +314,7 @@ void UbuntuPackagingModel::on_pushButtonClickPackage_clicked() {
m_postPackageTask = Verify;
else
m_postPackageTask = None;
buildClickPackage();
} else {
m_UbuntuMenu_connection = QObject::connect(UbuntuMenu::instance(),SIGNAL(finished_action(const QProcess*,QString)),this,SLOT(onFinishedAction(const QProcess*,QString)));
@@ -330,10 +342,11 @@ void UbuntuPackagingModel::buildFinished(const bool success)
if (success) {
//the step that created the click package is always in the last list and always the last step
UbuntuPackageStep *pckStep = qobject_cast<UbuntuPackageStep*>(m_packageBuildSteps.last()->steps().last());
if (pckStep && !pckStep->packagePath().isEmpty()) {
SnapcraftPackageStep *snapPckStep = qobject_cast<SnapcraftPackageStep*>(m_packageBuildSteps.last()->steps().last());
if ((pckStep && !pckStep->packagePath().isEmpty()) || (snapPckStep && !snapPckStep->packagePath().isEmpty())) {
m_ubuntuProcess.stop();
QString sClickPackagePath = pckStep->packagePath();
QString sClickPackagePath = pckStep ? pckStep->packagePath() : snapPckStep->packagePath();
if (sClickPackagePath.isEmpty()) {
clearPackageBuildList();
return;
@@ -381,19 +394,34 @@ void UbuntuPackagingModel::buildFinished(const bool success)
void UbuntuPackagingModel::buildAndInstallPackageRequested()
{
m_postPackageTask = Install;
if (SnapHelper::isSnappyProject(ProjectExplorer::SessionManager::startupProject())) {
QMessageBox::information(Core::ICore::mainWindow(), qApp->applicationName(),
tr("Installing is currently not supported for snappy projects."));
return;
}
buildClickPackage();
}
void UbuntuPackagingModel::buildAndVerifyPackageRequested()
{
m_postPackageTask = Verify;
buildClickPackage();
if (SnapHelper::isSnappyProject(ProjectExplorer::SessionManager::startupProject()))
buildSnapPackage();
else
buildClickPackage();
}
void UbuntuPackagingModel::buildPackageRequested()
{
m_postPackageTask = None;
buildClickPackage();
if (SnapHelper::isSnappyProject(ProjectExplorer::SessionManager::startupProject()))
buildSnapPackage();
else
buildClickPackage();
}
void UbuntuPackagingModel::targetChanged()
@@ -561,6 +589,59 @@ void UbuntuPackagingModel::buildClickPackage()
}
}
void UbuntuPackagingModel::buildSnapPackage()
{
ProjectExplorer::Project* project = ProjectExplorer::SessionManager::startupProject();
if(!project) {
QMessageBox::warning(Core::ICore::mainWindow(),tr("No Project"),tr("No valid project loaded."));
return;
}
if(ProjectExplorer::BuildManager::isBuilding()) {
QMessageBox::information(Core::ICore::mainWindow(),tr("Build running"),tr("There is currently a build running, please wait for it to be finished"));
return;
}
if(!ProjectExplorer::ProjectExplorerPlugin::instance()->saveModifiedFiles())
return;
if(!SnapHelper::isSnappyProject(project))
return;
ProjectExplorer::Target* target = project->activeTarget();
if(!target)
return;
ProjectExplorer::BuildConfiguration* bc = target->activeBuildConfiguration();
if(!bc) {
QMessageBox::information(Core::ICore::mainWindow(),tr("Error"),tr("Please add a valid buildconfiguration to your project"));
return;
}
if(!bc->isEnabled()) {
QString disabledReason = bc->disabledReason();
QMessageBox::information(Core::ICore::mainWindow(),tr("Disabled"),tr("The currently selected Buildconfiguration is disabled. %1").arg(disabledReason));
return;
}
clearPackageBuildList();
m_packageBuildSteps.append(QSharedPointer<ProjectExplorer::BuildStepList> (new ProjectExplorer::BuildStepList(bc,ProjectExplorer::Constants::BUILDSTEPS_BUILD)));
ProjectExplorer::BuildStepList *buildSteps = bc->stepList(Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD));
if (buildSteps && buildSteps->count() > 0) {
//add the normal buildsteps
m_packageBuildSteps.last()->cloneSteps(buildSteps);
}
//append the snap packaging step
SnapcraftPackageStep *package = new SnapcraftPackageStep(m_packageBuildSteps.last().data());
m_packageBuildSteps.last()->appendStep(package);
m_buildManagerConnection = connect(ProjectExplorer::BuildManager::instance(),SIGNAL(buildQueueFinished(bool)),this,SLOT(buildFinished(bool)));
ProjectExplorer::BuildManager::buildList(m_packageBuildSteps.last().data(),tr("Build Project"));
}
/*!
* \brief UbuntuPackagingWidget::clearAdditionalBuildSteps
* Clears the last used additional buildsteps

View File

@@ -95,6 +95,7 @@ signals:
private:
void buildClickPackage ();
void buildSnapPackage ();
void clearPackageBuildList ();
void updateFrameworkList ();
void resetValidationResult ();

View File

@@ -49,9 +49,11 @@
#include <ubuntu/device/remote/ubunturemotedeployconfiguration.h>
#include <ubuntu/device/remote/ubuntudeploystepfactory.h>
#include "wizards/ubuntuprojectapplicationwizard.h"
#include "wizards/ubuntufirstrunwizard.h"
#include "wizards/ubuntuprojectmigrationwizard.h"
#include <ubuntu/wizards/ubuntuprojectapplicationwizard.h>
#include <ubuntu/wizards/ubuntufirstrunwizard.h>
#include <ubuntu/wizards/ubuntuprojectmigrationwizard.h>
#include "ubuntujsextension.h"
#include <coreplugin/modemanager.h>
#include <projectexplorer/kitmanager.h>
@@ -60,6 +62,7 @@
#include <projectexplorer/processparameters.h>
#include <coreplugin/featureprovider.h>
#include <coreplugin/coreplugin.h>
#include <coreplugin/jsexpander.h>
#include <utils/mimetypes/mimedatabase.h>
#include <utils/mimetypes/mimeglobpattern_p.h>
#include <cmakeprojectmanager/cmaketoolmanager.h>
@@ -233,6 +236,9 @@ bool UbuntuPlugin::initialize(const QStringList &arguments, QString *errorString
addAutoReleasedObject(new Internal::UbuntuManifestEditorFactory);
addAutoReleasedObject(new Internal::UbuntuApparmorEditorFactory);
//Ubuntu expander
Core::JsExpander::registerQObjectForJs(QStringLiteral("Ubuntu"), new UbuntuJsExtension);
//trigger kit autodetection and update after projectexplorer loaded the kits
connect(ProjectExplorer::KitManager::instance(),SIGNAL(kitsLoaded())
,this,SLOT(onKitsLoaded()));

View File

@@ -18,11 +18,13 @@
#include "ubuntuprojectapplicationwizard.h"
#include "ubuntufirstrunwizard.h"
#include "../ubuntushared.h"
#include "../ubuntuconstants.h"
#include "../ubuntuproject.h"
#include "../ubuntubzr.h"
#include "../ubuntuclicktool.h"
#include <ubuntu/ubuntushared.h>
#include <ubuntu/ubuntushared.h>
#include <ubuntu/ubuntuconstants.h>
#include <ubuntu/ubuntuproject.h>
#include <ubuntu/ubuntubzr.h>
#include <ubuntu/ubuntuclicktool.h>
#include <utils/qtcassert.h>
#include <utils/pathchooser.h>

View File

@@ -24,7 +24,7 @@ def fix (workDir):
for root, dirs, files in os.walk(workDir):
for file in files:
if file.endswith("ubuntu_save_gitmodules"):
shutil.move(os.path.join(root, file), os.path.join(root, ".gitmodules"))
shutil.copy2(os.path.join(root, file), os.path.join(root, ".gitmodules"))
#all subdirectores need a .git dir
for entry in os.listdir(workDir):