diff --git a/CMakeLists.txt b/CMakeLists.txt
index f00141c75..795084c01 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -64,7 +64,11 @@ add_custom_target(QtCreatorSource
COMMAND ${CMAKE_SOURCE_DIR}/get_bzr_source.py -d "${EXT_SOURCE_DIR}/qtcreator/src/plugins/ubuntu" lp:qtcreator-plugin-ubuntu
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
-add_custom_target(sources DEPENDS QtSource LibDusSource MaliitSource fcitx-qtSource AppmenuSource QtCreatorSource)
+add_custom_target(YamlCppSource
+ ${CMAKE_SOURCE_DIR}/get_package_source.py yaml-cpp
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
+
+add_custom_target(sources DEPENDS QtSource LibDusSource MaliitSource fcitx-qtSource AppmenuSource QtCreatorSource YamlCppSource)
add_custom_command(TARGET sources
PRE_BUILD
@@ -123,6 +127,29 @@ ExternalProject_Add(libdbusmenu-qt
INSTALL_COMMAND sh -c "LD_LIBRARY_PATH=${QT_INSTALL_DIR}/lib make install"
)
+ConcatStrings (LIBYAML_BUILD_SCRIPT
+ "${CMAKE_COMMAND} "
+ "-DCMAKE_INSTALL_PREFIX=${QT_INSTALL_DIR} "
+ "-DCMAKE_PREFIX_PATH=${QT_INSTALL_DIR} "
+ "-DCMAKE_BUILD_TYPE=DEBUG" #${CMAKE_BUILD_TYPE_STRING} "
+ "-DCMAKE_INSTALL_LIBDIR=lib ${EXT_SOURCE_DIR}/yaml-cpp "
+ "-DCMAKE_C_FLAGS=-fPIC "
+ "-DCMAKE_CXX_FLAGS=-fPIC "
+)
+
+SET (LIBYAML_PREFIX "${CMAKE_BINARY_DIR}/yaml-cpp")
+ExternalProject_Add(libyaml-cpp
+ DEPENDS ${QT_VERSION}
+ PREFIX "${LIBYAML_PREFIX}"
+ SOURCE_DIR "${EXT_SOURCE_DIR}/yaml-cpp"
+ BINARY_DIR "${LIBYAML_PREFIX}/build"
+ INSTALL_DIR "${QT_INSTALL_DIR}"
+ DOWNLOAD_COMMAND sh -c "exit 0"
+ CONFIGURE_COMMAND sh -c "${LIBYAML_BUILD_SCRIPT}"
+ BUILD_COMMAND sh -c "LD_LIBRARY_PATH=${QT_INSTALL_DIR}/lib make ${GENERATED_MAKE_FLAGS}"
+ INSTALL_COMMAND sh -c "LD_LIBRARY_PATH=${QT_INSTALL_DIR}/lib make install"
+)
+
SET (MALIITPLUGIN_PREFIX "${CMAKE_BINARY_DIR}/maliit-plugin-qt-build")
ExternalProject_Add(maliit-plugin
DEPENDS ${QT_VERSION}
@@ -172,7 +199,7 @@ ExternalProject_Add(appmenu-qt5
SET (QTCREATOR_PREFIX "${CMAKE_BINARY_DIR}/qtcreator-build")
ExternalProject_Add(qtcreator_3.5.0
- DEPENDS appmenu-qt5 fcitx-qt5 maliit-plugin
+ DEPENDS appmenu-qt5 fcitx-qt5 maliit-plugin libyaml-cpp
PREFIX "${QTCREATOR_PREFIX}"
SOURCE_DIR "${EXT_SOURCE_DIR}/qtcreator"
BINARY_DIR "${QTCREATOR_PREFIX}/build"
diff --git a/dist/qtcreator/src/plugins/ubuntu/UbuntuPlugin.pro b/dist/qtcreator/src/plugins/ubuntu/UbuntuPlugin.pro
index ee80ded1f..876e4ef50 100644
--- a/dist/qtcreator/src/plugins/ubuntu/UbuntuPlugin.pro
+++ b/dist/qtcreator/src/plugins/ubuntu/UbuntuPlugin.pro
@@ -220,6 +220,8 @@ HEADERS += \
src/ubuntu/device/remote/ubuntudirectuploadstep.h \
src/ubuntu/device/remote/ubuntudeploystepfactory.h
+include(src/ubuntu/snap/snap.pri)
+
FORMS += \
src/ubuntu/device/remote/ubunturemoterunconfigurationwidget.ui \
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName.pro b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName.pro
deleted file mode 100644
index 741fed29d..000000000
--- a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName.pro
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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
-}
-
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.pro b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.pro
index 02190d872..f80b2a941 100644
--- a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.pro
+++ b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.pro
@@ -16,33 +16,16 @@ QML_FILES += $$files(*.qml,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
+ wrapper.path = /bin
- target.path = /deploy/bin
+ target.path = /bin
INSTALLS+=target wrapper
}
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.desktop b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/setup/gui/appName.desktop
similarity index 100%
rename from dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.desktop
rename to dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/setup/gui/appName.desktop
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.png b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/setup/gui/appName.png
similarity index 100%
rename from dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/appName/appName.png
rename to dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/setup/gui/appName.png
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/snapcraft.yaml b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/snapcraft.yaml
index 567290a5d..eba48c965 100644
--- a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/snapcraft.yaml
+++ b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/snapcraft.yaml
@@ -11,13 +11,19 @@ apps:
parts:
%{ProjectNameL}:
- plugin: dump
- source: deploy/
+ plugin: qmake
+ source: %{ProjectNameL}/
+ qt-version: qt5
+ options: ["CONFIG+=snapcraft"]
+ project-files: [%{ProjectNameL}]
+ build-packages:
+ - build-essential
+ - qtbase5-dev
+ - qt5-qmake
stage-packages:
- ubuntu-sdk-libs
- qtubuntu-desktop
- qtmir-desktop
- mir-graphics-drivers-desktop
-
-
+ after: [qt5conf]
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/wizard.json b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/wizard.json
index b3f10a366..65b3763a0 100644
--- a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/wizard.json
+++ b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/templates/wizards/ubuntu/snap-qtquick-app-qmake/wizard.json
@@ -1,13 +1,13 @@
{
"version": 1,
- "supportedProjectTypes": [ "Qt4ProjectManager.Qt4Project" ],
+ "supportedProjectTypes": [ "SnapcraftProjectManager.SnapcraftProject" ],
"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}",
+ "enabled": "%{JS: [ %{Plugins} ].indexOf('Ubuntu') >= 0}",
"options":
[
@@ -61,14 +61,9 @@
"typeId": "File",
"data":
[
- {
- "source": "appName.pro",
- "target": "%{ProjectFile}",
- "openAsProject": true
- },
{
"source": "snapcraft.yaml",
- "openInEditor": true
+ "openAsProject": true
},
{
"source": "appName/main.cpp",
@@ -81,12 +76,12 @@
"openInEditor": true
},
{
- "source": "appName/appName.desktop",
- "target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.desktop"
+ "source": "setup/gui/appName.desktop",
+ "target": "%{ProjectDirectory}/setup/gui/%{ProjectNameL}.desktop"
},
{
- "source": "appName/appName.png",
- "target": "%{ProjectDirectory}/%{ProjectNameL}/%{ProjectNameL}.png"
+ "source": "setup/gui/appName.png",
+ "target": "%{ProjectDirectory}/setup/gui/%{ProjectNameL}.png"
},
{
"source": "appName/appName.pro",
diff --git a/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/ubuntu/scripts/run_snapcraft.py b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/ubuntu/scripts/run_snapcraft.py
new file mode 100755
index 000000000..985765e47
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/share/qtcreator/ubuntu/scripts/run_snapcraft.py
@@ -0,0 +1,29 @@
+#!/usr/bin/python3
+
+import os
+import sys
+import shutil
+import subprocess
+from optparse import OptionParser
+
+parser = OptionParser(usage="usage: %prog [options] lp:branch")
+parser.add_option(
+ "-s", "--snapcraft", dest="snapcraft")
+options, args = parser.parse_args()
+
+if options.snapcraft is None:
+ options.snapcraft = shutil.which("snapcraft")
+
+if options.snapcraft is None:
+ parser.error("Snapcraft not found.")
+
+if not os.path.isfile(options.snapcraft) or not os.access(options.snapcraft, os.X_OK):
+ parser.error("-s must specify a executable file.")
+
+print("Using snapcraft from :"+options.snapcraft)
+
+ret = subprocess.call([options.snapcraft, "clean"])
+if ret != 0:
+ sys.exit(ret)
+
+sys.exit(subprocess.call([options.snapcraft]+args))
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/UbuntuProject.mimetypes.xml b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/UbuntuProject.mimetypes.xml
index bf1f1d948..3d24983e5 100644
--- a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/UbuntuProject.mimetypes.xml
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/UbuntuProject.mimetypes.xml
@@ -17,4 +17,9 @@
+
+ Snapcraft project file
+
+
+
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfiguration.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfiguration.cpp
new file mode 100644
index 000000000..a7b3d8c99
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfiguration.cpp
@@ -0,0 +1,41 @@
+#include "snapcraftbuildconfiguration.h"
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+SnapcraftBuildConfiguration::SnapcraftBuildConfiguration(ProjectExplorer::Target *target)
+ : ProjectExplorer::BuildConfiguration(target, Constants::SNAPCRAFT_BUILDCONFIGURATION_ID)
+{
+
+}
+
+SnapcraftBuildConfiguration::SnapcraftBuildConfiguration(ProjectExplorer::Target *target, ProjectExplorer::BuildConfiguration *source)
+ : ProjectExplorer::BuildConfiguration(target, source)
+{
+
+}
+
+bool SnapcraftBuildConfiguration::fromMap(const QVariantMap &map)
+{
+ return ProjectExplorer::BuildConfiguration::fromMap(map);
+}
+
+QVariantMap SnapcraftBuildConfiguration::toMap() const
+{
+ return ProjectExplorer::BuildConfiguration::toMap();
+}
+
+ProjectExplorer::NamedWidget *SnapcraftBuildConfiguration::createConfigWidget()
+{
+ return nullptr;
+}
+
+ProjectExplorer::BuildConfiguration::BuildType SnapcraftBuildConfiguration::buildType() const
+{
+ return ProjectExplorer::BuildConfiguration::Unknown;
+}
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfiguration.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfiguration.h
new file mode 100644
index 000000000..e298f2cb2
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfiguration.h
@@ -0,0 +1,33 @@
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTBUILDCONFIGURATION_H
+#define UBUNTU_INTERNAL_SNAPCRAFTBUILDCONFIGURATION_H
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftBuildConfigurationFactory;
+
+class SnapcraftBuildConfiguration : public ProjectExplorer::BuildConfiguration
+{
+ Q_OBJECT
+
+public:
+ friend class SnapcraftBuildConfigurationFactory;
+ // ProjectConfiguration interface
+ virtual bool fromMap(const QVariantMap &map) override;
+ virtual QVariantMap toMap() const override;
+
+ // BuildConfiguration interface
+ virtual ProjectExplorer::NamedWidget *createConfigWidget() override;
+ virtual BuildType buildType() const override;
+
+protected:
+ SnapcraftBuildConfiguration(ProjectExplorer::Target *target);
+ SnapcraftBuildConfiguration(ProjectExplorer::Target *target, BuildConfiguration *source);
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTBUILDCONFIGURATION_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfigurationfactory.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfigurationfactory.cpp
new file mode 100644
index 000000000..a6f4f9634
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfigurationfactory.cpp
@@ -0,0 +1,145 @@
+#include "snapcraftbuildconfigurationfactory.h"
+
+#include "snapcraftproject.h"
+#include "snapcraftbuildconfiguration.h"
+#include "snapcraftrsyncstep.h"
+#include "snapcraftstep.h"
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+SnapcraftBuildInfo::SnapcraftBuildInfo(const SnapcraftBuildConfigurationFactory *factory)
+ :ProjectExplorer::BuildInfo(factory)
+{
+
+}
+
+SnapcraftBuildConfigurationFactory::SnapcraftBuildConfigurationFactory()
+{
+
+}
+
+QList SnapcraftBuildConfigurationFactory::availableBuilds(const ProjectExplorer::Target *parent) const
+{
+ if (qobject_cast(parent->project()))
+ return {};
+
+ QList infoList;
+ ProjectExplorer::BuildInfo *info = createBuildInfo(parent->kit(), parent->project()->projectFilePath().toString());
+ if (info)
+ infoList << info;
+
+ return infoList;
+}
+
+int SnapcraftBuildConfigurationFactory::priority(const ProjectExplorer::Target *) const
+{
+ return 0;
+}
+
+int SnapcraftBuildConfigurationFactory::priority(const ProjectExplorer::Kit *, const QString &) const
+{
+ return 0;
+}
+
+QList SnapcraftBuildConfigurationFactory::availableSetups(const ProjectExplorer::Kit *k, const QString &projectPath) const
+{
+ Utils::MimeDatabase db;
+
+ auto mimeType = db.mimeTypeForFile(projectPath);
+ if (!mimeType.matchesName(Constants::SNAPCRAFT_PROJECT_MIMETYPE))
+ return {};
+
+ QList infoList;
+ ProjectExplorer::BuildInfo *info = createBuildInfo(k, projectPath);
+ if (info)
+ infoList << info;
+
+ return infoList;
+}
+
+ProjectExplorer::BuildConfiguration *SnapcraftBuildConfigurationFactory::create(ProjectExplorer::Target *parent, const ProjectExplorer::BuildInfo *info) const
+{
+ SnapcraftBuildConfiguration *conf = new SnapcraftBuildConfiguration(parent);
+
+ conf->setDisplayName(info->displayName);
+ conf->setBuildDirectory(info->buildDirectory);
+
+ ProjectExplorer::BuildStepList *bs = conf->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
+ bs->insertStep(0, new SnapcraftRsyncStep(bs));
+ bs->insertStep(1, new SnapcraftStep(bs));
+
+ return conf;
+}
+
+bool SnapcraftBuildConfigurationFactory::canRestore(const ProjectExplorer::Target *, const QVariantMap &map) const
+{
+ return (ProjectExplorer::idFromMap(map) == Constants::SNAPCRAFT_BUILDCONFIGURATION_ID);
+}
+
+ProjectExplorer::BuildConfiguration *SnapcraftBuildConfigurationFactory::restore(ProjectExplorer::Target *parent, const QVariantMap &map)
+{
+ QTC_ASSERT(parent, return nullptr);
+ SnapcraftBuildConfiguration *conf = new SnapcraftBuildConfiguration(parent);
+ if (conf->fromMap(map))
+ return conf;
+
+ delete conf;
+ return nullptr;
+}
+
+bool SnapcraftBuildConfigurationFactory::canClone(const ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *product) const
+{
+ QTC_ASSERT(parent, return false);
+ QTC_ASSERT(product, return false);
+ return (product->id() == Constants::SNAPCRAFT_BUILDCONFIGURATION_ID);
+}
+
+ProjectExplorer::BuildConfiguration *SnapcraftBuildConfigurationFactory::clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *product)
+{
+ QTC_ASSERT(parent, return nullptr);
+ QTC_ASSERT(product, return nullptr);
+
+ SnapcraftBuildConfiguration *conf = new SnapcraftBuildConfiguration(parent, product);
+ return conf;
+}
+
+ProjectExplorer::BuildInfo *SnapcraftBuildConfigurationFactory::createBuildInfo(const ProjectExplorer::Kit *k, const QString &projectPath) const
+{
+ SnapcraftBuildInfo *build = new SnapcraftBuildInfo(this);
+ build->buildType = ProjectExplorer::BuildConfiguration::Release;
+ build->typeName = tr("Build");
+ build->kitId = k->id();
+ build->displayName = ProjectExplorer::BuildConfiguration::buildTypeName(build->buildType);
+ build->buildDirectory = shadowBuildDirectory(k, projectPath);
+ return {build};
+}
+
+Utils::FileName SnapcraftBuildConfigurationFactory::shadowBuildDirectory(const ProjectExplorer::Kit *k, const QString &projectPath) const
+{
+
+ Utils::FileName projectDir = ProjectExplorer::Project::projectDirectory(Utils::FileName::fromString(projectPath));
+ const QString projectName = projectDir.fileName();
+
+ ProjectExplorer::ProjectMacroExpander expander(projectPath, projectName,
+ k, tr("build"),
+ ProjectExplorer::BuildConfiguration::Release);
+
+ QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
+ return Utils::FileName::fromString(QDir::cleanPath(QDir(projectDir.toString()).absoluteFilePath(buildPath)));
+}
+
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfigurationfactory.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfigurationfactory.h
new file mode 100644
index 000000000..8143313f5
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildconfigurationfactory.h
@@ -0,0 +1,44 @@
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTBUILDCONFIGURATIONFACTORY_H
+#define UBUNTU_INTERNAL_SNAPCRAFTBUILDCONFIGURATIONFACTORY_H
+
+#include
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftBuildConfigurationFactory;
+
+class SnapcraftBuildInfo : public ProjectExplorer::BuildInfo
+{
+public:
+ SnapcraftBuildInfo(const SnapcraftBuildConfigurationFactory *factory);
+};
+
+class SnapcraftBuildConfigurationFactory : public ProjectExplorer::IBuildConfigurationFactory
+{
+public:
+ SnapcraftBuildConfigurationFactory();
+
+ // IBuildConfigurationFactory interface
+ virtual QList availableBuilds(const ProjectExplorer::Target *parent) const override;
+
+ virtual int priority(const ProjectExplorer::Target *parent) const override;
+ virtual int priority(const ProjectExplorer::Kit *k, const QString &projectPath) const override;
+
+ virtual QList availableSetups(const ProjectExplorer::Kit *k, const QString &projectPath) const override;
+ virtual ProjectExplorer::BuildConfiguration *create(ProjectExplorer::Target *parent, const ProjectExplorer::BuildInfo *info) const override;
+ virtual bool canRestore(const ProjectExplorer::Target *parent, const QVariantMap &map) const override;
+ virtual ProjectExplorer::BuildConfiguration *restore(ProjectExplorer::Target *parent, const QVariantMap &map) override;
+ virtual bool canClone(const ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *product) const override;
+ virtual ProjectExplorer::BuildConfiguration *clone(ProjectExplorer::Target *parent, ProjectExplorer::BuildConfiguration *product) override;
+
+private:
+ ProjectExplorer::BuildInfo *createBuildInfo (const ProjectExplorer::Kit *k, const QString &projectPath) const;
+ Utils::FileName shadowBuildDirectory(const ProjectExplorer::Kit *k, const QString &projectPath) const;
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTBUILDCONFIGURATIONFACTORY_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildstepfactory.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildstepfactory.cpp
new file mode 100644
index 000000000..106036085
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildstepfactory.cpp
@@ -0,0 +1,65 @@
+#include "snapcraftbuildstepfactory.h"
+#include "snapcraftrsyncstep.h"
+#include "snapcraftstep.h"
+#include "snapcraftproject.h"
+
+#include
+
+#include
+#include
+#include
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+SnapcraftBuildStepFactory::SnapcraftBuildStepFactory(QObject *parent) : ProjectExplorer::IBuildStepFactory (parent)
+{
+
+}
+
+QList SnapcraftBuildStepFactory::availableSteps(ProjectExplorer::BuildStepList *parent) const
+{
+ if (parent->id() != ProjectExplorer::Constants::BUILDSTEPS_BUILD)
+ return {};
+
+ if (!parent->target() || !qobject_cast(parent->target()->project()))
+ return {};
+
+ return {
+ ProjectExplorer::BuildStepInfo(Constants::SNAPCRAFT_RSYNCBUILSSTEP_ID, tr("Prepare build")),
+ ProjectExplorer::BuildStepInfo(Constants::SNAPCRAFT_BUILDSTEP_ID, tr("Snapcraft"))
+ };
+}
+
+ProjectExplorer::BuildStep *SnapcraftBuildStepFactory::create(ProjectExplorer::BuildStepList *parent, Core::Id id)
+{
+ if (!Utils::contains(availableSteps(parent), [&id](const ProjectExplorer::BuildStepInfo &step){return id == step.id;}))
+ return nullptr;
+
+ if (id == Constants::SNAPCRAFT_RSYNCBUILSSTEP_ID) {
+ return new SnapcraftRsyncStep(parent);
+ } else if (id == Constants::SNAPCRAFT_BUILDSTEP_ID) {
+ return new SnapcraftStep(parent);
+ }
+
+ return nullptr;
+}
+
+ProjectExplorer::BuildStep *SnapcraftBuildStepFactory::clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product)
+{
+ Core::Id id = product->id();
+ if (!Utils::contains(availableSteps(parent), [&id](const ProjectExplorer::BuildStepInfo &step){return id == step.id;}))
+ return nullptr;
+
+ if (id == Constants::SNAPCRAFT_RSYNCBUILSSTEP_ID) {
+ return new SnapcraftRsyncStep(parent, static_cast(product));
+ } else if (id == Constants::SNAPCRAFT_BUILDSTEP_ID) {
+ return new SnapcraftStep(parent, static_cast(product));
+ }
+
+ return nullptr;
+}
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildstepfactory.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildstepfactory.h
new file mode 100644
index 000000000..d0b7d5eda
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftbuildstepfactory.h
@@ -0,0 +1,25 @@
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTBUILDSTEPFACTORY_H
+#define UBUNTU_INTERNAL_SNAPCRAFTBUILDSTEPFACTORY_H
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftBuildStepFactory : public ProjectExplorer::IBuildStepFactory
+{
+ Q_OBJECT
+public:
+ SnapcraftBuildStepFactory(QObject *parent = nullptr);
+
+ // IBuildStepFactory interface
+public:
+ virtual QList availableSteps(ProjectExplorer::BuildStepList *parent) const override;
+ virtual ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, Core::Id id) override;
+ virtual ProjectExplorer::BuildStep *clone(ProjectExplorer::BuildStepList *parent, ProjectExplorer::BuildStep *product) override;
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTBUILDSTEPFACTORY_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftproject.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftproject.cpp
new file mode 100644
index 000000000..6c89254c6
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftproject.cpp
@@ -0,0 +1,156 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#include "snapcraftproject.h"
+#include "snapcraftprojectnode.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#include
+#pragma GCC diagnostic pop
+
+
+using namespace Ubuntu;
+using namespace Ubuntu::Internal;
+
+SnapcraftProject::SnapcraftProject(SnapcraftProjectManager *manager, const Utils::FileName &fileName)
+ : m_manager(manager),
+ m_fileName(fileName),
+ m_watcher(new QFileSystemWatcher)
+{
+
+ setId(Constants::SNAPCRAFT_PROJECT_ID);
+
+ setProjectContext(Core::Context(Constants::SNAPCRAFT_PROJECT_PROJECTCONTEXT));
+
+
+ m_file = QPointer(new SnapcraftProjectFile());
+ Core::DocumentManager::addDocument(m_file.data(), true);
+ setDocument(m_file.data());
+
+ m_file->setFilePath(fileName);
+
+ m_rootNode = QSharedPointer(new SnapcraftProjectNode(this, fileName, &m_watcher));
+
+ ProjectExplorer::FileNode *projectFileNode = new ProjectExplorer::FileNode(fileName, ProjectExplorer::ProjectFileType, false);
+ m_rootNode->addFileNodes({projectFileNode});
+
+ connect(m_file, &SnapcraftProjectFile::changed, this, &SnapcraftProject::asyncUpdate);
+
+ //we show magic directories that are not listed in the snapcraft.yaml file, therefore we need to watch the directory
+ //if one of those is changed or removed
+ m_watcher.addPath(projectDirectory().toFileInfo().absoluteFilePath());
+ connect(&m_watcher, &QFileSystemWatcher::directoryChanged, this, &SnapcraftProject::maybeUpdate);
+
+ QMetaObject::invokeMethod(this, "asyncUpdate", Qt::QueuedConnection);
+}
+
+QString SnapcraftProject::displayName() const {
+ return m_rootNode->displayName();
+}
+
+ProjectExplorer::IProjectManager *SnapcraftProject::projectManager() const {
+ return m_manager;
+}
+
+ProjectExplorer::ProjectNode *SnapcraftProject::rootProjectNode() const {
+ return m_rootNode.data();
+}
+
+QStringList SnapcraftProject::files(FilesMode) const {
+ QStringList files;
+ //enumChild(projectDir(), files);
+ return files;
+}
+
+bool SnapcraftProject::supportsKit(ProjectExplorer::Kit *, QString *) const
+{
+#if 0
+ UbuntuKitMatcher matcher;
+ if (!matcher.matches(k)) {
+ if(errorMessage)
+ *errorMessage = tr("Only Desktop and Ubuntu Kits are supported");
+ return false;
+ }
+#endif
+ return true;
+}
+
+bool SnapcraftProject::needsConfiguration() const
+{
+ return targets().size() == 0;
+}
+
+bool SnapcraftProject::requiresTargetPanel() const
+{
+ return true;
+}
+
+QString SnapcraftProject::shadowBuildDirectory(const QString &proFilePath
+ , const ProjectExplorer::Kit *k
+ , const QString &suffix
+ , const ProjectExplorer::BuildConfiguration::BuildType buildType)
+{
+ if (proFilePath.isEmpty())
+ return QString();
+
+ QFileInfo info(proFilePath);
+
+ QtSupport::BaseQtVersion *version = QtSupport::QtKitInformation::qtVersion(k);
+ if (version)
+ return info.absolutePath();
+
+ const QString projectName = QFileInfo(proFilePath).completeBaseName();
+ ProjectExplorer::ProjectMacroExpander expander(proFilePath, projectName, k, suffix, buildType);
+ QDir projectDir = QDir(projectDirectory(Utils::FileName::fromString(proFilePath)).toString());
+ QString buildPath = expander.expand(Core::DocumentManager::buildDirectory());
+ return QDir::cleanPath(projectDir.absoluteFilePath(buildPath));
+}
+
+void SnapcraftProject::asyncUpdate()
+{
+ qDebug()<<"Syncing from yaml";
+ try {
+ YAML::Node yaml = YAML::LoadFile(m_fileName.toString().toStdString());
+ if (!m_rootNode->syncFromYAMLNode(yaml)) {
+ qDebug()<<"Invalid YAML file";
+ }
+ } catch (const YAML::Exception &e) {
+ qDebug() << e.what();
+ }
+
+ emit displayNameChanged();
+}
+
+void SnapcraftProject::maybeUpdate(const QString &pathChanged)
+{
+ if (QFileInfo(pathChanged) == projectDirectory().toFileInfo()) {
+ asyncUpdate();
+ }
+}
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftproject.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftproject.h
new file mode 100644
index 000000000..5af257bee
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftproject.h
@@ -0,0 +1,88 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#ifndef SNAPCRAFTPROJECT_H
+#define SNAPCRAFTPROJECT_H
+
+#include "snapcraftprojectmanager.h"
+#include "snapcraftprojectfile.h"
+
+#include
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class UbuntuProjectManager;
+class SnapcraftProjectNode;
+
+class SnapcraftProject : public ProjectExplorer::Project
+{
+ Q_OBJECT
+
+public:
+ SnapcraftProject(SnapcraftProjectManager *manager, const Utils::FileName &fileName);
+
+ QString displayName() const override;
+ ProjectExplorer::IProjectManager *projectManager() const override;
+
+ ProjectExplorer::ProjectNode *rootProjectNode() const override;
+ QStringList files(FilesMode fileMode) const override;
+
+ QDir projectDir() const {
+ return projectDirectory().toString();
+ }
+
+ QString filesFileName() const {
+ return m_fileName.toString();
+ }
+
+ // Project interface
+ bool supportsKit(ProjectExplorer::Kit *k, QString *errorMessage) const override;
+ bool needsConfiguration() const override;
+ bool requiresTargetPanel() const override;
+
+ static QString shadowBuildDirectory(const QString &proFilePath, const ProjectExplorer::Kit *k,
+ const QString &suffix = QString(),
+ const ProjectExplorer::BuildConfiguration::BuildType buildType = ProjectExplorer::BuildConfiguration::Unknown);
+
+protected slots:
+ void asyncUpdate ();
+ void maybeUpdate (const QString &pathChanged);
+
+private:
+ SnapcraftProjectManager *m_manager;
+ QString m_projectName;
+ QPointer m_file;
+
+ Utils::FileName m_fileName;
+ QSharedPointer m_rootNode;
+ QFileSystemWatcher m_watcher;
+};
+}
+}
+
+#endif // SNAPCRAFTPROJECT_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectfile.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectfile.cpp
new file mode 100644
index 000000000..5d10522e9
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectfile.cpp
@@ -0,0 +1,42 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#include "snapcraftprojectfile.h"
+
+using namespace Ubuntu::Internal;
+
+SnapcraftProjectFile::SnapcraftProjectFile(Core::Id id)
+ : TextEditor::TextDocument(id)
+{
+}
+
+Core::IDocument::ReloadBehavior SnapcraftProjectFile::reloadBehavior(Core::IDocument::ChangeTrigger state, Core::IDocument::ChangeType type) const
+{
+ Q_UNUSED(state)
+ Q_UNUSED(type)
+ return BehaviorSilent;
+}
+
+bool SnapcraftProjectFile::reload(QString *errorString, Core::IDocument::ReloadFlag flag, Core::IDocument::ChangeType type)
+{
+ if (type != TypePermissions) {
+ emit changed();
+ }
+
+ return TextDocument::reload(errorString, flag, type);
+}
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectfile.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectfile.h
new file mode 100644
index 000000000..e046fb1b7
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectfile.h
@@ -0,0 +1,48 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#ifndef SNAPCRAFTPROJECTFILE_H
+#define SNAPCRAFTPROJECTFILE_H
+
+#include
+#include
+
+#include
+#include
+
+namespace Ubuntu {
+namespace Internal {
+class SnapcraftProject;
+class SnapcraftProjectFile : public TextEditor::TextDocument
+{
+ Q_OBJECT
+public:
+ SnapcraftProjectFile(Core::Id id = Core::Id());
+
+ // IDocument interface
+ virtual ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override;
+ virtual bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override;
+
+signals:
+ void changed ();
+
+};
+}
+}
+
+#endif // SNAPCRAFTPROJECTFILE_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectmanager.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectmanager.cpp
new file mode 100644
index 000000000..454642ab7
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectmanager.cpp
@@ -0,0 +1,64 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#include "snapcraftprojectmanager.h"
+#include "snapcraftproject.h"
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+
+namespace Ubuntu {
+namespace Internal {
+
+SnapcraftProjectManager::SnapcraftProjectManager()
+{
+
+}
+
+QString SnapcraftProjectManager::mimeType() const
+{
+ return QLatin1String(Constants::SNAPCRAFT_PROJECT_MIMETYPE);
+}
+
+ProjectExplorer::Project *SnapcraftProjectManager::openProject(const QString &fileName, QString *errorString)
+{
+ QFileInfo fileInfo(fileName);
+
+ foreach (ProjectExplorer::Project *pi, ProjectExplorer::SessionManager::projects()) {
+ if (fileName == pi->document()->filePath().toString()) {
+ if (errorString)
+ *errorString = tr("Failed opening project '%1': Project already open") .arg(QDir::toNativeSeparators(fileName));
+ return 0;
+ }
+ }
+
+ if (fileInfo.isFile())
+ return new SnapcraftProject(this, Utils::FileName(fileInfo));
+
+ *errorString = tr("Failed opening project '%1': Project file is not a file").arg(QDir::toNativeSeparators(fileName));
+ return 0;
+}
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectmanager.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectmanager.h
new file mode 100644
index 000000000..8e84d5253
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectmanager.h
@@ -0,0 +1,40 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTPROJECTMANAGER_H
+#define UBUNTU_INTERNAL_SNAPCRAFTPROJECTMANAGER_H
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftProjectManager : public ProjectExplorer::IProjectManager
+{
+public:
+ SnapcraftProjectManager();
+
+ // IProjectManager interface
+ virtual QString mimeType() const override;
+ virtual ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString) override;
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTPROJECTMANAGER_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectnode.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectnode.cpp
new file mode 100644
index 000000000..aac1d6a79
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectnode.cpp
@@ -0,0 +1,496 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#include "snapcraftprojectnode.h"
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#include
+#pragma GCC diagnostic pop
+
+namespace Ubuntu {
+namespace Internal {
+
+static QIcon generateIcon(const QString &overlay) {
+ const QSize desiredSize = QSize(16, 16);
+
+ const QPixmap overlayPixmap(overlay);
+ const QIcon overlayIcon(overlayPixmap.scaled(12, 12));
+ const QPixmap pixmap
+ = Core::FileIconProvider::overlayIcon(QStyle::SP_DirIcon, overlayIcon, desiredSize);
+
+ QIcon result;
+ result.addPixmap(pixmap);
+
+ return result;
+}
+
+static QIcon generateProjectIcon () {
+ static QIcon projectIcon;
+ if (projectIcon.isNull())
+ projectIcon = generateIcon(QString::fromLatin1(Constants::UBUNTU_ICON));
+
+ return projectIcon;
+}
+
+SnapcraftProjectNode::SnapcraftProjectNode(SnapcraftProject *rootProject, const Utils::FileName &projectFilePath, QFileSystemWatcher *watcher)
+ : ProjectExplorer::ProjectNode (projectFilePath),
+ m_rootProject(rootProject),
+ m_watcher(watcher)
+{
+ setDisplayName(projectFilePath.parentDir().toString());
+ setIcon(generateProjectIcon());
+}
+
+SnapcraftProjectNode::~SnapcraftProjectNode()
+{
+ if (m_watcher) {
+
+ }
+}
+
+bool SnapcraftProjectNode::syncFromYAMLNode(YAML::Node rootNode)
+{
+ qDebug()<<"Sync from YAML node";
+ try {
+ QString displayName = QString::fromStdString(rootNode["name"].as());
+ setDisplayName(displayName);
+
+ YAML::Node parts = rootNode["parts"];
+ if (!parts.IsMap()) {
+ qDebug()<<"Parts is not a map";
+ return false;
+ }
+
+ QList existingNodes = subFolderNodes();
+ QList nodesToRemove;
+ QList nodesToAdd;
+
+ QStringList partsFromYaml;
+ QStringList existingParts;
+
+ for (const auto &part : existingNodes) {
+ existingParts << part->displayName();
+ }
+
+ //iterate over the parts
+ for (auto it = parts.begin(); it != parts.end(); ++it) {
+
+ YAML::Node subProject = it->second;
+ QString partName = QString::fromStdString(it->first.as());
+ //QString subType = QString::fromStdString(subProject["plugin"].as());
+ QString source = QDir::cleanPath(QString::fromStdString(subProject["source"].as()));
+
+ partsFromYaml << partName;
+
+ // We only show a part if it locally exists and is a directory
+ QString sourcePathName = QDir::cleanPath(filePath().parentDir().appendPath(source).toString());
+ Utils::FileName sourcePath = Utils::FileName::fromString(sourcePathName);
+ if (sourcePath.exists() && sourcePath.toFileInfo().isDir()) {
+
+ int idx = existingParts.indexOf(partName);
+ if (idx >= 0) {
+ //check if source is still the same
+ SnapcraftGenericPartNode *n = static_cast(existingNodes.at(idx));
+ if (n->filePath() == sourcePath)
+ continue;
+
+ nodesToRemove << n;
+ }
+
+ SnapcraftGenericPartNode *partNode = new SnapcraftGenericPartNode(partName, sourcePath, m_watcher);
+ nodesToAdd << partNode;
+ }
+ }
+
+
+ //snapcraft has magic directories, like setup, we want to show in the project tree
+ QStringList magicSnapcraftDirs{
+ QStringLiteral("setup")
+ };
+
+ for (const QString &magicDir: magicSnapcraftDirs) {
+ Utils::FileName dirPath = filePath().parentDir().appendPath(magicDir);
+ if (dirPath.exists()) {
+ partsFromYaml << magicDir;
+ if(!existingParts.contains(magicDir)) {
+ SnapcraftGenericPartNode *partNode = new SnapcraftGenericPartNode(magicDir, dirPath, m_watcher);
+ nodesToAdd << partNode;
+ }
+ }
+ }
+
+ QSet obsoleteParts = existingParts.toSet() - partsFromYaml.toSet();
+ qDebug()<<"Parts in yaml"<= 0)
+ nodesToRemove << existingNodes.at(idx);
+ }
+
+ //remove old nodes
+ removeFolderNodes(nodesToRemove);
+ addFolderNodes(nodesToAdd);
+ } catch (const YAML::Exception &e) {
+ qDebug()<<"ERRROR ERROR ERROR "< &dirs, QSet &res) {
+ foreach (const QFileInfo &info, dir.entryInfoList(QDir::NoDotAndDotDot|QDir::Dirs|QDir::Files|QDir::Hidden)) {
+ if (info.isDir()) {
+ dirs << Utils::FileName(info);
+ enumChild(QDir(info.absoluteFilePath()), dirs, res);
+ } else {
+ res.insert(Utils::FileName(info));
+ }
+ }
+}
+
+SnapcraftGenericPartNode::SnapcraftGenericPartNode(const QString &partName, const Utils::FileName &folderPath, QFileSystemWatcher *watcher)
+ : ProjectExplorer::FolderNode (folderPath, ProjectExplorer::FolderNodeType, partName)
+ , m_watcher(watcher)
+{
+ scheduleProjectScan();
+
+ setIcon(generateProjectIcon());
+
+ if (watcher->addPath(folderPath.toString())) {
+ qDebug()<<"Added"<directories();
+ QStringList toRemove;
+ for(const QString &path: watched) {
+ if(path.startsWith(myPath))
+ toRemove << path;
+ }
+ m_watcher->removePaths(toRemove);
+ QObject::disconnect(m_watcherConnection);
+ }
+}
+
+void SnapcraftGenericPartNode::maybeScheduleProjectScan(const QString &changedPath)
+{
+ Utils::FileName changed = Utils::FileName::fromString(changedPath);
+ if (filePath().toFileInfo() == changed.toFileInfo())
+ scheduleProjectScan();
+}
+
+void SnapcraftGenericPartNode::scheduleProjectScan()
+{
+ if (m_scanning)
+ return;
+
+ qDebug()<<"Scheduling Project scan";
+
+ m_scanning = true;
+
+ QTimer *rescanTimer = new QTimer();
+ rescanTimer->setSingleShot(true);
+ rescanTimer->start(0);
+ QObject::connect(rescanTimer, &QTimer::timeout, [this, rescanTimer](){
+ qDebug()<<"Starting Project scan";
+ delete rescanTimer;
+ this->scanProjectDirectory();
+
+ m_scanning = false;
+ });
+}
+
+void SnapcraftGenericPartNode::removeFileNodes(const QList &files)
+{
+ foreach(const Utils::FileName &f, files) {
+ if(f.toFileInfo().isDir())
+ continue;
+
+ FindFileNodesForFileVisitor vis(f);
+ this->accept(&vis);
+
+ for (ProjectExplorer::FileNode *node : vis.nodes()) {
+ node->parentFolderNode()->removeFileNodes({node});
+ }
+ }
+}
+
+void SnapcraftGenericPartNode::removeFolderNodes(QList &dirs)
+{
+
+ qSort(dirs.begin(), dirs.end(),[](const Utils::FileName &a, const Utils::FileName &b){
+ return a.toFileInfo().absoluteFilePath() > b.toFileInfo().absoluteFilePath();
+ });
+
+ foreach(const Utils::FileName &f, dirs) {
+ FindNodesForFolderVisitor vis(f);
+ this->accept(&vis);
+
+ FindNodesForFolderVisitor visParent(f.parentDir());
+ this->accept(&visParent);
+
+ if(visParent.nodes().size()) {
+ m_watcher->removePath(f.toFileInfo().absoluteFilePath());
+ visParent.nodes()[0]->removeFolderNodes(vis.nodes());
+ }
+ }
+}
+
+QList SnapcraftGenericPartNode::supportedActions(ProjectExplorer::Node *node) const
+{
+ static const QList fileActions {
+ ProjectExplorer::ProjectAction::Rename,
+ ProjectExplorer::ProjectAction::RemoveFile
+ };
+ static const QList folderActions {
+ ProjectExplorer::ProjectAction::AddNewFile,
+ ProjectExplorer::ProjectAction::RemoveFile
+ };
+ switch (node->nodeType()) {
+ case ProjectExplorer::FileNodeType:
+ return fileActions;
+ case ProjectExplorer::FolderNodeType:
+ case ProjectExplorer::ProjectNodeType:
+ return folderActions;
+ default:
+ return ProjectExplorer::FolderNode::supportedActions(node);
+ }
+}
+
+bool SnapcraftGenericPartNode::addFiles(const QStringList &, QStringList *)
+{
+ return true;
+}
+
+bool SnapcraftGenericPartNode::removeFiles(const QStringList &, QStringList *)
+{
+ return true;
+}
+
+bool SnapcraftGenericPartNode::deleteFiles(const QStringList &)
+{
+ return true;
+}
+
+void SnapcraftGenericPartNode::scanProjectDirectory()
+{
+ QSet dirs;
+ QSet files;
+ enumChild(QDir(filePath().toString()), dirs, files);
+
+ FindFilesAndDirsVisitor vis;
+ this->accept(&vis);
+
+ QSet oldFiles = QSet::fromList(vis.filePaths());
+ QSet oldDirs = QSet::fromList(vis.dirPaths());
+ QSet newFiles(files);
+ QSet newDirs(dirs);
+
+ QSet filesToRemove = oldFiles - newFiles;
+ QSet filesToAdd = newFiles - oldFiles;
+ QList dirsToRemove = (oldDirs - newDirs).toList();
+ QSet dirsToAdd = newDirs - oldDirs;
+
+ qDebug()<<"Removing dirs " <filePath())
+ continue;
+
+ ProjectExplorer::FolderNode *parentNode = nullptr;
+ if (folderPath == filePath()) {
+ parentNode = this;
+ } else {
+ Utils::FileName relativeName = folderPath.relativeChildPath(filePath());
+ QStringList relativeNameList = relativeName.toUserOutput().split(QDir::separator());
+ parentNode = createOrFindFolder(relativeNameList);
+ }
+
+ ProjectExplorer::FileNode *fNode = new ProjectExplorer::FileNode(file, ProjectExplorer::UnknownFileType, false);
+ parentNode->addFileNodes({fNode});
+ }
+}
+
+ProjectExplorer::FolderNode *SnapcraftGenericPartNode::createOrFindFolder(const QStringList &folder)
+{
+ QStringList watches;
+ ProjectExplorer::FolderNode *currFolder = this;
+
+ Utils::FileName currentPath = filePath();
+
+ for (const QString &folderName: folder) {
+
+ QList subnodes = currFolder->subFolderNodes();
+ currentPath = currentPath.appendPath(folderName);
+
+ auto check = [&folderName](ProjectExplorer::FolderNode *f) {
+ return f->filePath().fileName() == folderName;
+ };
+
+ auto it = std::find_if(subnodes.begin(), subnodes.end(), check);
+
+ if (it != subnodes.end()) {
+ //node exists already
+ currFolder = *it;
+ continue;
+ }
+
+ //does not exist lets create a new one
+ ProjectExplorer::FolderNode *fNode = new SnapcraftGenericPartFolderNode(currentPath, ProjectExplorer::FolderNodeType, folderName);
+ currFolder->addFolderNodes({fNode});
+ currFolder = fNode;
+
+ watches << currentPath.toFileInfo().absoluteFilePath();
+ }
+ qDebug()<<"Failed to add watches: "<addPaths(watches);
+ return currFolder;
+}
+
+Utils::FileNameList FindFilesAndDirsVisitor::filePaths() const
+{
+ return m_filePaths;
+}
+
+Utils::FileNameList FindFilesAndDirsVisitor::dirPaths() const
+{
+ return m_dirPaths;
+}
+
+void FindFilesAndDirsVisitor::visitProjectNode(ProjectExplorer::ProjectNode *projectNode)
+{
+ visitFolderNode(projectNode);
+}
+
+void FindFilesAndDirsVisitor::visitFolderNode(ProjectExplorer::FolderNode *folderNode)
+{
+ if (folderNode->nodeType() != ProjectExplorer::ProjectNodeType)
+ m_dirPaths.append(folderNode->filePath());
+
+ for (const ProjectExplorer::FileNode *fileNode : folderNode->fileNodes())
+ m_filePaths.append(fileNode->filePath());
+}
+
+FindFileNodesForFileVisitor::FindFileNodesForFileVisitor(const Utils::FileName &f)
+ : m_file(f)
+{
+
+}
+
+QList FindFileNodesForFileVisitor::nodes() const
+{
+ return m_nodes;
+}
+
+void FindFileNodesForFileVisitor::visitProjectNode(ProjectExplorer::ProjectNode *projectNode)
+{
+ visitFolderNode(projectNode);
+}
+
+void FindFileNodesForFileVisitor::visitFolderNode(ProjectExplorer::FolderNode *folderNode)
+{
+ for(auto fileNode: folderNode->fileNodes()) {
+ if (fileNode->filePath() == m_file)
+ m_nodes.append(fileNode);
+ }
+}
+
+FindNodesForFolderVisitor::FindNodesForFolderVisitor(const Utils::FileName &f)
+ : m_folder(f)
+{
+
+}
+
+QList FindNodesForFolderVisitor::nodes() const
+{
+ return m_nodes;
+}
+
+void FindNodesForFolderVisitor::visitProjectNode(ProjectExplorer::ProjectNode *)
+{
+ return;
+}
+
+void FindNodesForFolderVisitor::visitFolderNode(ProjectExplorer::FolderNode *folderNode)
+{
+ if (m_folder == folderNode->filePath())
+ m_nodes.append(folderNode);
+}
+
+bool SnapcraftGenericPartFolderNode::addFiles(const QStringList &, QStringList *)
+{
+ return true;
+}
+
+bool SnapcraftGenericPartFolderNode::removeFiles(const QStringList &, QStringList *)
+{
+ return true;
+}
+
+bool SnapcraftGenericPartFolderNode::deleteFiles(const QStringList &)
+{
+ return true;
+}
+
+
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectnode.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectnode.h
new file mode 100644
index 000000000..7b7a13ac6
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftprojectnode.h
@@ -0,0 +1,136 @@
+/*
+ * 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 .
+ *
+ * Author: Benjamin Zeller
+ */
+
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTPROJECTNODE_H
+#define UBUNTU_INTERNAL_SNAPCRAFTPROJECTNODE_H
+
+#include
+#include
+#include
+
+#include
+
+class QFileSystemWatcher;
+
+namespace Ubuntu {
+namespace Internal {
+
+class FindFilesAndDirsVisitor : public ProjectExplorer::NodesVisitor {
+public:
+ Utils::FileNameList filePaths() const;
+ Utils::FileNameList dirPaths() const;
+
+ void visitProjectNode(ProjectExplorer::ProjectNode *projectNode) override;
+ void visitFolderNode(ProjectExplorer::FolderNode *folderNode) override;
+
+private:
+ Utils::FileNameList m_filePaths;
+ Utils::FileNameList m_dirPaths;
+};
+
+class FindFileNodesForFileVisitor : public ProjectExplorer::NodesVisitor {
+
+public:
+ FindFileNodesForFileVisitor (const Utils::FileName &f);
+ QList nodes () const;
+
+ void visitProjectNode(ProjectExplorer::ProjectNode *projectNode) override;
+ void visitFolderNode(ProjectExplorer::FolderNode *folderNode) override;
+
+private:
+ Utils::FileName m_file;
+ QList m_nodes;
+};
+
+class FindNodesForFolderVisitor : public ProjectExplorer::NodesVisitor {
+
+public:
+ FindNodesForFolderVisitor (const Utils::FileName &f);
+ QList nodes () const;
+
+ void visitProjectNode(ProjectExplorer::ProjectNode *projectNode) override;
+ void visitFolderNode(ProjectExplorer::FolderNode *folderNode) override;
+
+private:
+ Utils::FileName m_folder;
+ QList m_nodes;
+};
+
+class SnapcraftProject;
+class SnapcraftGenericPartNode;
+
+class SnapcraftProjectNode : public ProjectExplorer::ProjectNode
+{
+public:
+ SnapcraftProjectNode(SnapcraftProject *rootProject, const Utils::FileName &projectFilePath, QFileSystemWatcher *watcher);
+ ~SnapcraftProjectNode();
+
+ bool syncFromYAMLNode(YAML::Node rootNode);
+
+private:
+ SnapcraftProject *m_rootProject = nullptr;
+ QPointer m_watcher;
+};
+
+class SnapcraftGenericPartFolderNode : public ProjectExplorer::FolderNode
+{
+public:
+
+ using ProjectExplorer::FolderNode::FolderNode;
+
+ // FolderNode interface
+ virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
+ virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) override;
+ virtual bool deleteFiles(const QStringList &filePaths) override;
+};
+
+class SnapcraftGenericPartNode : public ProjectExplorer::FolderNode
+{
+public:
+ SnapcraftGenericPartNode(const QString &partName, const Utils::FileName &folderPath, QFileSystemWatcher *watcher);
+ ~SnapcraftGenericPartNode();
+
+ void maybeScheduleProjectScan(const QString &changedPath);
+ void scheduleProjectScan();
+
+ using ProjectExplorer::FolderNode::removeFileNodes;
+ void removeFileNodes (const QList &files);
+
+ using ProjectExplorer::FolderNode::removeFolderNodes;
+ void removeFolderNodes (QList &dirs);
+
+ // Node interface
+ virtual QList supportedActions(ProjectExplorer::Node *node) const override;
+ virtual bool addFiles(const QStringList &filePaths, QStringList *notAdded) override;
+ virtual bool removeFiles(const QStringList &filePaths, QStringList *notRemoved) override;
+ virtual bool deleteFiles(const QStringList &filePaths) override;
+
+protected:
+ ProjectExplorer::FolderNode *createOrFindFolder (const QStringList &folder);
+ void scanProjectDirectory ();
+
+private:
+ bool m_scanning = false;
+ QMetaObject::Connection m_watcherConnection;
+ QPointer m_watcher;
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTPROJECTNODE_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftrsyncstep.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftrsyncstep.cpp
new file mode 100644
index 000000000..5f031d286
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftrsyncstep.cpp
@@ -0,0 +1,51 @@
+#include "snapcraftrsyncstep.h"
+#include "snapcraftproject.h"
+#include "snapcraftbuildconfiguration.h"
+
+#include
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+SnapcraftRsyncStep::SnapcraftRsyncStep(ProjectExplorer::BuildStepList *bsl)
+ : ProjectExplorer::AbstractProcessStep(bsl, Constants::SNAPCRAFT_RSYNCBUILSSTEP_ID)
+{
+ setDefaultDisplayName(tr("Prepare build"));
+}
+
+SnapcraftRsyncStep::SnapcraftRsyncStep(ProjectExplorer::BuildStepList *bsl, SnapcraftRsyncStep *bs)
+ : ProjectExplorer::AbstractProcessStep(bsl, bs)
+{
+
+}
+
+bool SnapcraftRsyncStep::init(QList &)
+{
+ QString projectDir = target()->project()->projectDirectory().toString();
+
+ ProjectExplorer::BuildConfiguration *bc = target()->activeBuildConfiguration();
+ if(!bc)
+ return false;
+
+ ProjectExplorer::ProcessParameters *param = processParameters();
+ param->setWorkingDirectory(bc->buildDirectory().toUserOutput());
+ param->setCommand(QStringLiteral("rsync"));
+ param->setArguments(QString::fromLatin1("-a --delete \"%1/\" \"./\"")
+ .arg(QDir::cleanPath(projectDir)));
+ param->setMacroExpander(bc->macroExpander());
+ param->setEnvironment(bc->environment());
+
+ return true;
+}
+
+ProjectExplorer::BuildStepConfigWidget *SnapcraftRsyncStep::createConfigWidget()
+{
+ return new ProjectExplorer::SimpleBuildStepConfigWidget(this);
+}
+
+
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftrsyncstep.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftrsyncstep.h
new file mode 100644
index 000000000..31a2d9afb
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftrsyncstep.h
@@ -0,0 +1,31 @@
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTRSYNCSTEP_H
+#define UBUNTU_INTERNAL_SNAPCRAFTRSYNCSTEP_H
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftBuildStepFactory;
+class SnapcraftBuildConfigurationFactory;
+
+class SnapcraftRsyncStep : public ProjectExplorer::AbstractProcessStep
+{
+ Q_OBJECT
+public:
+ friend class SnapcraftBuildStepFactory;
+ friend class SnapcraftBuildConfigurationFactory;
+
+ // BuildStep interface
+ virtual bool init(QList &earlierSteps) override;
+ virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
+
+protected:
+ SnapcraftRsyncStep(ProjectExplorer::BuildStepList *bsl);
+ SnapcraftRsyncStep(ProjectExplorer::BuildStepList *bsl, SnapcraftRsyncStep *bs);
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTRSYNCSTEP_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftstep.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftstep.cpp
new file mode 100644
index 000000000..c52b9dd50
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftstep.cpp
@@ -0,0 +1,67 @@
+#include "snapcraftstep.h"
+#include "snapcraftproject.h"
+#include "snapcraftbuildconfiguration.h"
+
+#include
+
+#include
+
+#include
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+SnapcraftStep::SnapcraftStep(ProjectExplorer::BuildStepList *bsl)
+ : ProjectExplorer::AbstractProcessStep(bsl, Constants::SNAPCRAFT_BUILDSTEP_ID)
+{
+ setDefaultDisplayName(tr("Snapcraft"));
+}
+
+SnapcraftStep::SnapcraftStep(ProjectExplorer::BuildStepList *bsl, SnapcraftStep *bs)
+ : ProjectExplorer::AbstractProcessStep(bsl, bs)
+{
+
+}
+
+bool SnapcraftStep::init(QList &)
+{
+ //QString projectDir = target()->project()->projectDirectory().toString();
+ ProjectExplorer::BuildConfiguration *bc = target()->activeBuildConfiguration();
+ if(!bc)
+ return false;
+
+ Utils::FileName snapcraftBin = Utils::FileName::fromString(Constants::UBUNTU_SCRIPTPATH);
+ snapcraftBin = snapcraftBin.appendPath(QString::fromLatin1("run_snapcraft.py"));
+
+ ProjectExplorer::ProcessParameters *param = processParameters();
+ param->setWorkingDirectory(bc->buildDirectory().toUserOutput());
+ param->setCommand(snapcraftBin.toUserOutput());
+ param->setArguments(QString::fromLatin1("-s '%1'").arg(snapcraftBin.toFileInfo().absoluteFilePath()));
+ param->setMacroExpander(bc->macroExpander());
+ param->setEnvironment(bc->environment());
+
+ return true;
+}
+
+ProjectExplorer::BuildStepConfigWidget *SnapcraftStep::createConfigWidget()
+{
+ return new ProjectExplorer::SimpleBuildStepConfigWidget(this);
+}
+
+Utils::FileName SnapcraftStep::snapcraftCommand() const
+{
+ Utils::Environment env = Utils::Environment::systemEnvironment();
+ Utils::FileName fallback = env.searchInPath(QStringLiteral("snapcraft"));
+ if (!target())
+ return fallback;
+
+ Utils::FileName bin = SnapcraftKitInformation::snapcraftPath(target()->kit());
+ if (!bin.exists())
+ return fallback;
+
+ return bin;
+}
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftstep.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftstep.h
new file mode 100644
index 000000000..d777efdab
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/project/snapcraftstep.h
@@ -0,0 +1,33 @@
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTSTEP_H
+#define UBUNTU_INTERNAL_SNAPCRAFTSTEP_H
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftBuildStepFactory;
+class SnapcraftBuildConfigurationFactory;
+
+class SnapcraftStep : public ProjectExplorer::AbstractProcessStep
+{
+ Q_OBJECT
+public:
+ friend class SnapcraftBuildStepFactory;
+ friend class SnapcraftBuildConfigurationFactory;
+
+ // BuildStep interface
+ virtual bool init(QList &earlierSteps) override;
+ virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget() override;
+
+ Utils::FileName snapcraftCommand () const;
+
+protected:
+ SnapcraftStep(ProjectExplorer::BuildStepList *bsl);
+ SnapcraftStep(ProjectExplorer::BuildStepList *bsl, SnapcraftStep *bs);
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTSTEP_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/settings/snapcraftkitinformation.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/settings/snapcraftkitinformation.cpp
new file mode 100644
index 000000000..63dad60a2
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/settings/snapcraftkitinformation.cpp
@@ -0,0 +1,114 @@
+#include "snapcraftkitinformation.h"
+
+#include
+
+#include
+#include
+#include
+
+#include
+
+namespace Ubuntu {
+namespace Internal {
+
+static const char TOOL_ID[] = "SnapcraftProjectManager.SnapcraftKitInformation";
+
+SnapcraftKitInformation::SnapcraftKitInformation()
+{
+ setObjectName(QStringLiteral("SnapcraftKitInformation"));
+ setId(TOOL_ID);
+ setPriority(29000);
+}
+
+Utils::FileName SnapcraftKitInformation::snapcraftPath(const ProjectExplorer::Kit *k)
+{
+ return k->value(TOOL_ID, QVariant::fromValue(Utils::FileName())).value();
+}
+
+void SnapcraftKitInformation::setSnapcraftPath(ProjectExplorer::Kit *k, const Utils::FileName &snapcraft)
+{
+ if (snapcraft.toFileInfo().isExecutable()) {
+ k->setValue(TOOL_ID, QVariant::fromValue(snapcraft));
+ }
+}
+
+QVariant SnapcraftKitInformation::defaultValue(const ProjectExplorer::Kit *) const
+{
+ Utils::Environment env = Utils::Environment::systemEnvironment();
+ return QVariant::fromValue(env.searchInPath(QStringLiteral("snapcraft")));
+}
+
+QList SnapcraftKitInformation::validate(const ProjectExplorer::Kit *) const
+{
+ return QList();
+}
+
+ProjectExplorer::KitInformation::ItemList SnapcraftKitInformation::toUserOutput(const ProjectExplorer::Kit *k) const
+{
+ Utils::FileName snap = snapcraftPath(k);
+ return ItemList {
+ qMakePair(tr("Snapcraft"), snap.exists() ? snap.toUserOutput() : tr("Unconfigured"))
+ };
+}
+
+ProjectExplorer::KitConfigWidget *SnapcraftKitInformation::createConfigWidget(ProjectExplorer::Kit *kit) const
+{
+ return new SnapcraftKitInformationWidget(kit, this);
+}
+
+SnapcraftKitInformationWidget::SnapcraftKitInformationWidget(ProjectExplorer::Kit *kit, const ProjectExplorer::KitInformation *ki)
+ : ProjectExplorer::KitConfigWidget(kit, ki)
+ , m_chooser(new Utils::PathChooser)
+ , m_ignoreChange(false)
+{
+ m_chooser->setExpectedKind(Utils::PathChooser::ExistingCommand);
+ m_chooser->setFileName(SnapcraftKitInformation::snapcraftPath(kit));
+ connect(m_chooser, &Utils::PathChooser::pathChanged,
+ this, &SnapcraftKitInformationWidget::pathWasChanged);
+}
+
+SnapcraftKitInformationWidget::~SnapcraftKitInformationWidget()
+{
+ delete m_chooser;
+}
+
+QString SnapcraftKitInformationWidget::displayName() const
+{
+ return tr("Snapcraft");
+}
+
+void SnapcraftKitInformationWidget::makeReadOnly()
+{
+ m_chooser->setReadOnly(true);
+}
+
+void SnapcraftKitInformationWidget::refresh()
+{
+ if (!m_ignoreChange)
+ m_chooser->setPath(SnapcraftKitInformation::snapcraftPath(kit()).toUserOutput());
+}
+
+QWidget *SnapcraftKitInformationWidget::mainWidget() const
+{
+ return m_chooser->lineEdit();
+}
+
+QString SnapcraftKitInformationWidget::toolTip() const
+{
+ return tr("The snapcraft binary to use for this kit.");
+}
+
+QWidget *SnapcraftKitInformationWidget::buttonWidget() const
+{
+ return m_chooser->buttonAtIndex(0);
+}
+
+void SnapcraftKitInformationWidget::pathWasChanged()
+{
+ m_ignoreChange = true;
+ SnapcraftKitInformation::setSnapcraftPath(kit(), m_chooser->fileName());
+ m_ignoreChange = false;
+}
+
+} // namespace Internal
+} // namespace Ubuntu
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/settings/snapcraftkitinformation.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/settings/snapcraftkitinformation.h
new file mode 100644
index 000000000..81a65ee89
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/settings/snapcraftkitinformation.h
@@ -0,0 +1,59 @@
+#ifndef UBUNTU_INTERNAL_SNAPCRAFTKITINFORMATION_H
+#define UBUNTU_INTERNAL_SNAPCRAFTKITINFORMATION_H
+
+#include
+#include
+
+namespace Utils {
+class PathChooser;
+}
+
+namespace Ubuntu {
+namespace Internal {
+
+class SnapcraftKitInformation : public ProjectExplorer::KitInformation
+{
+ Q_OBJECT
+public:
+ SnapcraftKitInformation();
+
+ static Utils::FileName snapcraftPath (const ProjectExplorer::Kit *k);
+ static void setSnapcraftPath (ProjectExplorer::Kit *k, const Utils::FileName &snapcraft);
+
+ // KitInformation interface
+ virtual QVariant defaultValue(const ProjectExplorer::Kit *) const override;
+ virtual QList validate(const ProjectExplorer::Kit *) const override;
+ virtual ItemList toUserOutput(const ProjectExplorer::Kit *) const override;
+ virtual ProjectExplorer::KitConfigWidget *createConfigWidget(ProjectExplorer::Kit *) const override;
+
+private:
+ Utils::FileName m_snapcraftPath;
+};
+
+class SnapcraftKitInformationWidget : public ProjectExplorer::KitConfigWidget
+{
+public:
+ SnapcraftKitInformationWidget(ProjectExplorer::Kit *kit, const ProjectExplorer::KitInformation *ki);
+ virtual ~SnapcraftKitInformationWidget();
+
+ // KitConfigWidget interface
+ virtual QString displayName() const override;
+ virtual void makeReadOnly() override;
+ virtual void refresh() override;
+ virtual QWidget *mainWidget() const override;
+ virtual QString toolTip() const override;
+ virtual QWidget *buttonWidget() const override;
+
+private:
+ void pathWasChanged();
+private:
+ Utils::PathChooser *m_chooser;
+ bool m_ignoreChange;
+
+
+};
+
+} // namespace Internal
+} // namespace Ubuntu
+
+#endif // UBUNTU_INTERNAL_SNAPCRAFTKITINFORMATION_H
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/snap.pri b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/snap.pri
new file mode 100644
index 000000000..75aa19573
--- /dev/null
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/snap/snap.pri
@@ -0,0 +1,27 @@
+
+LIBS+=-lyaml-cpp
+
+SOURCES += \
+ $$PWD/project/snapcraftproject.cpp \
+ $$PWD/project/snapcraftprojectfile.cpp \
+ $$PWD/project/snapcraftprojectnode.cpp \
+ $$PWD/project/snapcraftprojectmanager.cpp \
+ $$PWD/project/snapcraftbuildconfigurationfactory.cpp \
+ $$PWD/project/snapcraftbuildconfiguration.cpp \
+ $$PWD/project/snapcraftrsyncstep.cpp \
+ $$PWD/project/snapcraftstep.cpp \
+ $$PWD/project/snapcraftbuildstepfactory.cpp \
+ $$PWD/settings/snapcraftkitinformation.cpp
+
+HEADERS += \
+ $$PWD/project/snapcraftproject.h \
+ $$PWD/project/snapcraftprojectfile.h \
+ $$PWD/project/snapcraftprojectnode.h \
+ $$PWD/project/snapcraftprojectmanager.h \
+ $$PWD/project/snapcraftbuildconfigurationfactory.h \
+ $$PWD/project/snapcraftbuildconfiguration.h \
+ $$PWD/project/snapcraftrsyncstep.h \
+ $$PWD/project/snapcraftstep.h \
+ $$PWD/project/snapcraftbuildstepfactory.h \
+ $$PWD/settings/snapcraftkitinformation.h
+
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.cpp
index 0a6e1474b..27ffcffd3 100644
--- a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.cpp
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.cpp
@@ -471,6 +471,11 @@ QString UbuntuClickTool::findOrCreateMakeWrapper (const UbuntuClickTool::Target
return UbuntuClickTool::findOrCreateToolWrapper(QStringLiteral("make"),target);
}
+Utils::FileName UbuntuClickTool::findOrCreateSnapcraftWrapper(const UbuntuClickTool::Target &target)
+{
+ return Utils::FileName::fromString(UbuntuClickTool::findOrCreateToolWrapper(QStringLiteral("snapcraft"),target));
+}
+
QString UbuntuClickTool::mapIncludePathsForCMake(const ProjectExplorer::Kit *k, const QString &in)
{
if (in.isEmpty())
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.h
index 58af03ac5..af69cd338 100644
--- a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.h
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuclicktool.h
@@ -86,6 +86,7 @@ public:
static QString findOrCreateToolWrapper(const QString &tool, const UbuntuClickTool::Target &target);
static QString findOrCreateQMakeWrapper(const UbuntuClickTool::Target &target);
static QString findOrCreateMakeWrapper(const UbuntuClickTool::Target &target);
+ static Utils::FileName findOrCreateSnapcraftWrapper(const UbuntuClickTool::Target &target);
static QString mapIncludePathsForCMake(const ProjectExplorer::Kit *k, const QString &in);
static QString hostArchitecture ();
static bool compatibleWithHostArchitecture (const QString &targetArch);
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuconstants.h b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuconstants.h
index 70235085c..dd34db94f 100644
--- a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuconstants.h
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuconstants.h
@@ -393,6 +393,16 @@ const char UBUNTU_MIGRATE_QMAKE_PROJECT[] = "UbuntuProjectManager.MigrateQMakePr
const char CHROOT_UPDATE_LIST_SCRIPT[] = "%1/ubuntu/scripts/qtc_chroot_get_upgrades.py %2 %3";
+//Snapcraft
+const char SNAPCRAFT_PROJECT_MIMETYPE[] = "application/x-snapcraft";
+const char SNAPCRAFT_PROJECT_ID[ ] = "SnapcraftProjectManager.SnapcraftProject";
+const char SNAPCRAFT_PROJECT_PROJECTCONTEXT[] = "SnapcraftProject.ProjectContext";
+const char SNAPCRAFT_BUILDCONFIGURATION_ID[] = "SnapcraftProjectManager.SnapcraftBuildconfiguration.Id";
+const char SNAPCRAFT_RSYNCBUILSSTEP_ID[] = "SnapcraftProjectManager.SnapcraftRsyncStep.Id";
+const char SNAPCRAFT_BUILDSTEP_ID[] = "SnapcraftProjectManager.SnapcraftStep.Id";
+
+
+
} // namespace Ubuntu
} // namespace Constants
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntukitmanager.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntukitmanager.cpp
index c07153149..aeb7b670c 100644
--- a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntukitmanager.cpp
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntukitmanager.cpp
@@ -5,7 +5,8 @@
#include "ubuntuclickdialog.h"
#include "ubuntuqtversion.h"
#include "settings.h"
-#include "device/container/containerdevice.h"
+#include
+#include
#include
#include
@@ -509,6 +510,8 @@ void UbuntuKitManager::fixKit(ProjectExplorer::Kit *k)
ProjectExplorer::SysRootKitInformation::setSysRoot(k,Utils::FileName::fromString(UbuntuClickTool::targetBasePath(tc->clickTarget())));
}
+ SnapcraftKitInformation::setSnapcraftPath(k, UbuntuClickTool::findOrCreateSnapcraftWrapper(tc->clickTarget()));
+
//make sure we point to a ubuntu device
Core::Id devId = ProjectExplorer::DeviceTypeKitInformation::deviceTypeId(k);
bool devValid = devId.isValid(); //invalid type
diff --git a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuplugin.cpp b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuplugin.cpp
index 0726f2b5f..568f4e783 100644
--- a/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuplugin.cpp
+++ b/dist/qtcreator/src/plugins/ubuntu/src/ubuntu/ubuntuplugin.cpp
@@ -53,6 +53,11 @@
#include
#include
+#include
+#include
+#include
+#include
+
#include "ubuntujsextension.h"
#include
@@ -175,6 +180,13 @@ bool UbuntuPlugin::initialize(const QStringList &arguments, QString *errorString
addAutoReleasedObject(new UbuntuRemoteRunControlFactory);
addAutoReleasedObject(new UbuntuLocalRunControlFactory);
+
+ addAutoReleasedObject(new SnapcraftProjectManager);
+ addAutoReleasedObject(new SnapcraftBuildConfigurationFactory);
+ addAutoReleasedObject(new SnapcraftBuildStepFactory);
+
+ ProjectExplorer::KitManager::registerKitInformation(new SnapcraftKitInformation);
+
// Build support
addAutoReleasedObject(new ClickToolChainFactory);
addAutoReleasedObject(new UbuntuHtmlBuildConfigurationFactory);
@@ -379,6 +391,7 @@ bool UbuntuPlugin::checkContainerSetup()
while (!ok) {
QProcess proc;
+ qDebug()<<"Running "<applicationName(),text, QMessageBox::Yes | QMessageBox::No | QMessageBox::Abort, Core::ICore::mainWindow());