Merge remote-tracking branch 'origin/3.1' into master

Change-Id: I8b203e12283374aed707e0e89c2f73d44ff296cb
This commit is contained in:
Katja Marttila 2019-08-23 11:05:07 +03:00
commit 516492370b
71 changed files with 603 additions and 198 deletions

View File

@ -1,9 +1,22 @@
3.1.2
- Gain admin rights for writing MaintenanceTool config files if needed (QTIFW-1363)
- Update INSTALL file (QTIFW-1185)
- Fix initially deactivated buttons when selecting components to update (QTIFW-1320)
- Fix MaintenanceTool file write permission check on Linux and macOS (QTIFW-1324)
- Fix installer hang on Windows with empty command prompt window appearing (QTIFW-1250)
- Add IFW version information to installerbase binary on Windows (QTIFW-1397)
- Fix Mkdir undo operation fail to remove directory in Settings operation (QTIFW-1365)
- Fix IFW version information not apparent on macOS (QTIFW-1396)
- Update repository categories on server authentication request (QTIFW-1358)
- Fix recalculation of components to install in MaintenanceTool (QTIFW-694)
- Enable support for Qt 5.12. In Windows supported compiler is msvc2017 (QTIFW-1312)
3.1.1
- Add fetch to the same pane with package categories (QTIFW-1284)
- Change text in Select Components view when selection of components is not possible (QTIFW-1241)
- Fix long description texts not properly shown by enabling scrolling (QTIFW-1308)
- Fix install button string having a font name in French translation (QTIFW-1333)
- Fix maintenancetool size (QTIFW-1322)
- Fix maintenance tool size (QTIFW-1322)
- Update Russian translation
- Enable links and text selection in component description fields (QTIFW-1292)

24
INSTALL
View File

@ -15,32 +15,38 @@ http://code.qt.io/cgit/installer-framework/installer-framework.git/
Build a static Qt
---------------------
Building the Qt Installer Framework from sources requires Qt (version 5.5
or newer). Supported compilers are MSVC 2013 or newer, GCC 4.7 or newer,
Building the Qt Installer Framework from sources requires Qt version 5.9.x.
Supported compilers are MSVC 2013 or newer, GCC 4.7 or newer,
and Clang 3.1 or newer.
If you want to ship your installer as a single file you have to build
Qt and the Qt Installer Framework statically.
See the Qt documentation for the prerequisites and steps to build Qt from sources.
Please read SSL Import and Export Restrictions from http://doc.qt.io/qt-5/ssl.html if
you are statically linking against OpenSSL libraries.
### Windows
Recommended configuration options for Microsoft Windows:
configure -prefix %CD%\qtbase -release -static -static-runtime -target xp -accessibility -no-opengl -no-icu -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests -skip qtactiveqt -skip qtenginio -skip qtlocation -skip qtmultimedia -skip qtserialport -skip qtquick1 -skip qtquickcontrols -skip qtscript -skip qtsensors -skip qtwebkit -skip qtwebsockets -skip qtxmlpatterns -skip qt3d
configure -prefix %CD%\qtbase -release -static -static-runtime -accessibility -no-icu -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests
Build Qt:
nmake (or 'mingw32-make') module-qtbase module-qtdeclarative module-qttools module-qttranslations module-qtwinextras
### Linux
Recommended configuration options for Linux:
configure -prefix $PWD/qtbase -release -static -accessibility -qt-zlib -qt-libpng -qt-libjpeg -qt-xcb -qt-pcre -qt-freetype -no-glib -no-cups -no-sql-sqlite -no-qml-debug -no-opengl -no-egl -no-xinput -no-xinput2 -no-sm -no-icu -nomake examples -nomake tests -skip qtactiveqt -skip qtenginio -skip qtlocation -skip qtmultimedia -skip qtserialport -skip qtquick1 -skip qtquickcontrols -skip qtscript -skip qtsensors -skip qtwebkit -skip qtwebsockets -skip qtxmlpatterns -skip qt3d
configure -prefix $PWD/qtbase -release -static -accessibility -qt-zlib -qt-libpng -qt-libjpeg -qt-xcb -qt-pcre -no-glib -no-cups -no-sql-sqlite -no-qml-debug -no-opengl -no-egl -no-xinput2 -no-sm -no-icu -nomake examples -nomake tests -no-libudev
Build Qt:
make module-qtbase module-qtdeclarative module-qttools module-qttranslations
### macOS
### OS X
Recommended configuration options for macOS:
Recommended configuration options for OS X:
configure -prefix $PWD/qtbase -release -static -accessibility -qt-zlib -qt-libpng -qt-libjpeg -no-cups -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests -skip qtactiveqt -skip qtenginio -skip qtlocation -skip qtmultimedia -skip qtserialport -skip qtquick1 -skip qtquickcontrols -skip qtscript -skip qtsensors -skip qtwebkit -skip qtwebsockets -skip qtxmlpatterns -skip qt3d
configure -prefix $PWD/qtbase -release -static -no-securetransport -accessibility -qt-zlib -qt-libpng -qt-libjpeg -no-cups -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests -no-freetype
Build Qt:
make module-qtbase module-qtdeclarative module-qttools module-qttranslations
Build the Framework

2
README
View File

@ -1,6 +1,6 @@
The Qt Installer Framework provides a set of tools and utilities to create
installers for the supported desktop Qt platforms: Linux, Microsoft Windows, and
OS X.
macOS.
Documentation

View File

@ -2,7 +2,7 @@
<Installer>
<Name>Qt Installer Framework</Name>
<Title>Qt Installer Framework 3.2.0</Title>
<Version>3.2.0 </Version>
<Version>3.2.0</Version>
<Publisher>Qt Project</Publisher>
<ProductUrl>http://qt-project.org</ProductUrl>
<Watermark>watermark.png</Watermark>

View File

@ -3,6 +3,6 @@
<DisplayName>Qt Installer Framework Binaries</DisplayName>
<Description>Installs the binaries, examples and help files.</Description>
<Version>3.2.0</Version>
<ReleaseDate>2019-05-27</ReleaseDate>
<ReleaseDate>2019-08-23</ReleaseDate>
<Default>True</Default>
</Package>

View File

@ -3,7 +3,7 @@
<DisplayName>Qt Installer Framework</DisplayName>
<Description>Installs the Qt Installer Framework.</Description>
<Version>3.2.0</Version>
<ReleaseDate>2019-05-25</ReleaseDate>
<ReleaseDate>2019-08-23</ReleaseDate>
<Licenses>
<License name="The Qt Company GPL Exception 1.0" file="LICENSE.GPL3-EXCEPT" />
<License name="Third Party Code Licenses" file="3RDPARTY" />

View File

@ -8,7 +8,7 @@
\code
..\..\bin\binarycreator.exe -c config\config.xml -p packages installer.exe
\endcode
\li On Linux or OS X:
\li On Linux or macOS:
\code
../../bin/binarycreator -c config/config.xml -p packages installer
\endcode

View File

@ -65,9 +65,11 @@
If you use a statically built Qt to build the Qt Installer Framework
you do not have to deliver Qt libraries, which enables you to distribute
installers as one file.
installers as one file. Please read SSL Import and Export Restrictions
from http://doc.qt.io/qt-5/ssl.html if you are statically linking against
OpenSSL libraries.
The minimum required Qt version is 5.5.
The required Qt version is 5.9.x.
\section3 Configuring Qt for Windows
@ -75,24 +77,39 @@
Windows:
\code
configure -prefix %CD%\qtbase -release -static -static-runtime -target xp -accessibility -no-opengl -no-icu -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests -skip qtactiveqt -skip qtenginio -skip qtlocation -skip qtmultimedia -skip qtserialport -skip qtquick1 -skip qtquickcontrols -skip qtscript -skip qtsensors -skip qtwebkit -skip qtwebsockets -skip qtxmlpatterns -skip qt3d
configure -prefix %CD%\qtbase -release -static -static-runtime -accessibility -no-icu -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests
\endcode
Build Qt:
\code
nmake (or 'mingw32-make') module-qtbase module-qtdeclarative module-qttools module-qttranslations module-qtwinextras
\endcode
\section3 Configuring Qt for Linux
We recommend that you use the following configuration options for Linux:
\code
configure -prefix $PWD/qtbase -release -static -accessibility -qt-zlib -qt-libpng -qt-libjpeg -qt-xcb -qt-pcre -qt-freetype -no-glib -no-cups -no-sql-sqlite -no-qml-debug -no-opengl -no-egl -no-xinput -no-xinput2 -no-sm -no-icu -nomake examples -nomake tests -skip qtactiveqt -skip qtenginio -skip qtlocation -skip qtmultimedia -skip qtserialport -skip qtquick1 -skip qtquickcontrols -skip qtscript -skip qtsensors -skip qtwebkit -skip qtwebsockets -skip qtxmlpatterns -skip qt3d
configure -prefix $PWD/qtbase -release -static -accessibility -qt-zlib -qt-libpng -qt-libjpeg -qt-xcb -qt-pcre -no-glib -no-cups -no-sql-sqlite -no-qml-debug -no-opengl -no-egl -no-xinput2 -no-sm -no-icu -nomake examples -nomake tests -no-libudev
\endcode
\section3 Configuring Qt for OS X
Build Qt:
\code
make module-qtbase module-qtdeclarative module-qttools module-qttranslations
\endcode
We recommend that you use the following configuration options for OS X:
\section3 Configuring Qt for macOS
We recommend that you use the following configuration options for macOS:
\code
configure -prefix $PWD/qtbase -release -static -accessibility -qt-zlib -qt-libpng -qt-libjpeg -no-cups -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests -skip qtactiveqt -skip qtenginio -skip qtlocation -skip qtmultimedia -skip qtserialport -skip qtquick1 -skip qtquickcontrols -skip qtscript -skip qtsensors -skip qtwebkit -skip qtwebsockets -skip qtxmlpatterns -skip qt3d
configure -prefix $PWD/qtbase -release -static -no-securetransport -accessibility -qt-zlib -qt-libpng -qt-libjpeg -no-cups -no-sql-sqlite -no-qml-debug -nomake examples -nomake tests -no-freetype
\endcode
Build Qt:
\code
make module-qtbase module-qtdeclarative module-qttools module-qttranslations
\endcode
\section2 Setting up Qt Installer Framework

View File

@ -37,7 +37,7 @@
create installers once, and deploy them across all the supported desktop
Qt platforms without rewriting the source code. The installers will have the
native look and feel on the platform where they are run: Linux, Microsoft
Windows, and OS X.
Windows, and macOS.
The Qt Installer Framework tools generate installers with a set of pages
that guide the users during the installation, update, or uninstallation

View File

@ -71,7 +71,7 @@
\image ifw-user-flow-installing.png "Installation workflow"
This section uses the \e {Your Application Installer} example run on OS X
This section uses the \e {Your Application Installer} example run on macOS
to illustrate the default workflow for end users. The installers have the
native look and feel on each supported desktop platform, and therefore they
look and feel different when run on Linux and Windows.
@ -188,7 +188,7 @@
\image ifw-user-flow-adding.png "Add components workflow"
This section uses the \e {Maintenance Tool} installed by the Qt 5 installer
run on OS X as an example implementation of how end users can add components
run on macOS as an example implementation of how end users can add components
after the initial installation. The Maintenance Tool contains the package
manager, updater, and uninstaller.
@ -244,7 +244,7 @@
\image ifw-user-flow-removing.png "Remove components workflow"
This section uses the Qt 5 Maintenance Tool run on OS X as an example
This section uses the Qt 5 Maintenance Tool run on macOS as an example
implementation of how end users can remove all or selected components.
\section1 Removing All Components
@ -297,7 +297,7 @@
\image ifw-user-flow-updating.png "Updating workflow"
This section uses the Qt 5 Maintenance Tool run on OS X as an example
This section uses the Qt 5 Maintenance Tool run on macOS as an example
implementation of how end users can update installed components.
\section1 Starting Updater

View File

@ -42,7 +42,7 @@
The Qt Installer Framework provides a set of tools and utilities to
create installers for the supported desktop Qt platforms: Linux, Microsoft
Windows, and OS X.
Windows, and macOS.
\note Report bugs and suggestions for the Qt Installer Framework project
in the \l{https://bugreports.qt.io/browse/QTIFW}{Qt Bugtracker}.
@ -191,13 +191,13 @@
\row
\li Icon
\li Filename for a custom installer icon. The actual file is looked up by attaching
a '.icns' (OS X), '.ico' (Windows) or '.png' (Unix) suffix. Deprecated,
a '.icns' (macOS), '.ico' (Windows) or '.png' (Unix) suffix. Deprecated,
use \c <InstallerApplicationIcon> or \c <InstallerWindowIcon>
instead.
\row
\li InstallerApplicationIcon
\li Filename for a custom installer icon. The actual file is looked up by attaching
a '.icns' (OS X), '.ico' (Windows). No functionality on Unix.
a '.icns' (macOS), '.ico' (Windows). No functionality on Unix.
\row
\li InstallerWindowIcon
\li Filename for a custom window icon in PNG format for the Installer application.
@ -430,20 +430,13 @@
component.userInterface( "MyPage" ).checkbox.checked = true;
\endcode
\section2 Using Control Scripts to Add Pages
To register a custom page, use the installer::addWizardPage() method
and the object name set in the UI file (for example, \c "MyPage"). Then
call the \c{Dynamic${ObjectName}Callback()} function (for example,
\c {DynamicMyPageCallback()}):
You can also have a callback for the page that is added. To access it,
use the object name set in the UI file (for example, \c "MyPage"). Then
create the \c{Dynamic${ObjectName}Callback} function (for example,
\c {DynamicMyPageCallback}):
\code
function Controller()
{
installer.addWizardPage(component, "MyPage", QInstaller.TargetDirectory)
}
Controller.prototype.DynamicMyPageCallback()
Component.prototype.DynamicMyPageCallback = function()
{
var page = gui.pageWidgetByObjectName("DynamicMyPage");
page.myButton.click,
@ -801,7 +794,7 @@
<location-of-ifw>\binarycreator.exe -t <location-of-ifw>\installerbase.exe -p <package_directory> -c <config_directory>\<config_file> <installer_name>
\endcode
\li On Linux and OS X
\li On Linux and macOS
\code
<location-of-ifw>/binarycreator -t <location-of-ifw>/installerbase -p <package_directory> -c <config_directory>/<config_file> <installer_name>
@ -819,7 +812,7 @@
<location-of-ifw>\binarycreator.exe -t <location-of-ifw>\installerbase.exe -p <package_directory> -c <config_directory>\<config_file> -e <packages> <installer_name>
\endcode
\li On Linux and OS X
\li On Linux and macOS
\code
<location-of-ifw>/binarycreator -t <location-of-ifw>/installerbase -p <package_directory> -c <config_directory>/<config_file> -e <packages> <installer_name>
@ -890,7 +883,7 @@
\row
\li -s or --sign identity
\li Only available on OS X. Allows specifying a code signing identity to be
\li Only available on macOS. Allows specifying a code signing identity to be
used for signing the generated app bundle.
\endtable
@ -914,7 +907,7 @@
\section2 Using Icons
On OS X, if the target binary is suffixed with .app, a OS X
On macOS, if the target binary is suffixed with .app, a macOS
application bundle is created. The icon that you specify in config.xml is
extended with .icns and used as the icon for the created bundle.

View File

@ -330,8 +330,61 @@
\row
\li \c ResetComponentsButton
\li Resets to already installed components.
\row
\li \c FetchCategoryButton
\li Fetch components from a category.
\endtable
\table
\header
\li Widgets
\li Brief Description
\row
\li \c CategoryGroupBox
\li Contains checkboxes for selecting repository categories.
\endtable
Installer Framework 3.1 introduces repository categories as a new feature. When
you use an installer that contains repository categories, you can select a category
by its display name, fetch its contents, and then select the included components for installation.
You can fetch the components from a category as follows:
\code
Controller.prototype.ComponentSelectionPageCallback = function()
{
var page = gui.pageWidgetByObjectName("ComponentSelectionPage");
// if CategoryGroupBox is visible, check one of the checkboxes
// and click fetch button before selecting any components
var groupBox = gui.findChild(page, "CategoryGroupBox");
if (groupBox) {
console.log("groupBox found");
// findChild second argument is the display name of the checkbox
var checkBox = gui.findChild(page, "Archive");
if (checkBox) {
console.log("checkBox found");
console.log("checkBox name: " + checkBox.text);
if (checkBox.checked == false) {
checkBox.click();
var fetchButton = gui.findChild(page, "FetchCategoryButton");
if (fetchButton) {
console.log("fetchButton found");
fetchButton.click();
} else {
console.log("fetchButton NOT found");
}
}
} else {
console.log("checkBox NOT found");
}
} else {
console.log("groupBox NOT found");
}
// you can now select components from the fetched category
}
\endcode
\section2 Start Menu Directory Page
@ -430,13 +483,13 @@
Example code:
\code
function Controller()
function Component()
{
// add page with widget \c SomePageWidget before the target directory page
installer.addWizardPage(component, "SomePageWidget", QInstaller.TargetDirectory)
}
Controller.prototype.DynamicSomePageWidgetCallback = function()
Component.prototype.DynamicSomePageWidgetCallback = function()
{
var page = gui.pageWidgetByObjectName("DynamicSomePageWidget");
page.myButton.click, //direct child of the UI file's widget

View File

@ -130,9 +130,9 @@
\li Creates a shortcut from the file specified by \c filename to
\c linkname.
On Windows, this creates a .lnk file which can have
\c arguments. Furthermore, on Windows, \c filename can be
\c arguments. Furthermore, \c filename can be
an HTTP or FTP URL in which case a URL shortcut is created.
On Unix, this creates a symbolic link.
The operation is currently not implemented on other platforms.
\row
\li CreateDesktopEntry
\li "CreateDesktopEntry" \c {filename "key=value[ key2=value2[ key3=value3]]]"}
@ -243,10 +243,10 @@
\li Restarts the updater or package manager specified by \c core.
\row
\li Settings
\li "Settings" \c path \c method \c key \c aValue
\li Sets or removes the value \c aValue of \c key in the settings file
or registry located at \c path, depending on the value of
\c method: \c set, \c remove, \c add_array_value, and \c remove_array_value.
\li "Settings" \c path \c method \c key \c value
\li Sets or removes the \c value of \c key in the settings file located at
\c path, depending on the value of \c method: \c set, \c remove,
\c add_array_value, and \c remove_array_value.
\endtable
The Extract, License, and MinimumProgress operations are automatically added for matching

View File

@ -42,13 +42,13 @@
Specifies the buttons on an installer page.
\value buttons.BackButton
The \uicontrol Back button (\uicontrol {Go Back} on OS X.)
The \uicontrol Back button (\uicontrol {Go Back} on macOS.)
\value buttons.NextButton
The \uicontrol Next button (\uicontrol Continue on OS X.)
The \uicontrol Next button (\uicontrol Continue on macOS.)
\value buttons.CommitButton
The \uicontrol Commit button.
\value buttons.FinishButton
The \uicontrol Finish button (\uicontrol Done on OS X.)
The \uicontrol Finish button (\uicontrol Done on macOS.)
\value buttons.CancelButton
The \uicontrol Cancel button.
\value buttons.HelpButton

View File

@ -66,6 +66,6 @@
"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
\endcode
On Windows, and OS X, this static function will use the native file dialog
On Windows, and macOS, this static function will use the native file dialog
and not a QFileDialog.
*/

View File

@ -265,7 +265,7 @@
\li Applications directory.
For example, \c {C:\Program Files} on Windows,
\c {/opt} on Linux and \c {/Applications} on OS X.
\c {/opt} on Linux and \c {/Applications} on macOS.
See also the table that lists examples of \l {Applications-directory-on-Windows}
{applications directories on Windows}.

View File

@ -58,7 +58,7 @@
kernel the installer is running on, unless the host operating system is running a form of
compatibility or virtualization layer.
For Windows, Linux, and OS X this will return
For Windows, Linux, and macOS this will return
\list
\li "winnt"
\li "linux"
@ -82,7 +82,7 @@
\endlist
The release version of the operating system kernel. On Windows, it returns the version of the
NT or CE kernel. On Unix systems, including OS X, it returns the same as the \c {uname -r}
NT or CE kernel. On Unix systems, including macOS, it returns the same as the \c {uname -r}
command would return.
\sa QSysInfo::kernelVersion()

View File

@ -195,7 +195,7 @@
..\..\bin\binarycreator.exe -c config\config.xml -p packages YourInstaller.exe
\endcode
\li On Linux or OS X:
\li On Linux or macOS:
\code
../../bin/binarycreator -c config/config.xml -p packages YourInstaller
\endcode

View File

@ -105,7 +105,7 @@
\code
..\..\bin\binarycreator.exe -c config\config.xml -r resources/additional.qrc -p packages installer.exe
\endcode
\li On Linux or OS X:
\li On Linux or macOS:
\code
../../bin/binarycreator -c config/config.xml -r resources/additional.qrc -p packages installer
\endcode

View File

@ -74,7 +74,7 @@
\code
..\..\bin\repogen.exe -p packages repository
\endcode
\li On Linux or OS X:
\li On Linux or macOS:
\code
../../bin/repogen -p packages repository
\endcode
@ -114,7 +114,7 @@
\code
..\..\bin\binarycreator.exe --online-only -c config\config.xml -p packages installer.exe
\endcode
\li On Linux or OS X:
\li On Linux or macOS:
\code
../../bin/binarycreator --online-only -c config/config.xml -p packages installer
\endcode
@ -139,7 +139,7 @@
\code
..\..\bin\repogen.exe --update-new-components -p packages_update repository
\endcode
\li On Linux or OS X:
\li On Linux or macOS:
\code
../../bin/repogen --update-new-components -p packages_update repository
\endcode

View File

@ -61,7 +61,7 @@
In installscript.qs, we use the \c Component() function to connect to the
\c installationFinishedPageIsShown signal when the installation is complete
and to the \c installationFinished signal when the end users click
\uicontrol Finish (\uicontrol Done on OS X):
\uicontrol Finish (\uicontrol Done on macOS):
\quotefromfile openreadme/packages/or.qtproject.ifw.example.openreadme/meta/installscript.qs
\skipto Component()

View File

@ -84,9 +84,9 @@
\printto /\!validOs/
The script uses \l{systemInfo::productType}{systemInfo.productType} to differentiate
between Windows, OS X, and individual Linux distributions.
between Windows, macOS, and individual Linux distributions.
For OS X and Windows, the script checks the operating system kernel version.
For macOS and Windows, the script checks the operating system kernel version.
For a mapping of kernel to operating system versions, see
\l{http://en.wikipedia.org/wiki/Darwin_%28operating_system%29}{Darwin} and
\l{http://en.wikipedia.org/wiki/Windows_NT}{Windows NT}.
@ -95,7 +95,7 @@
the specific distribution and version the binaries are presumably built for,
the installer shows a warning in a modal dialog, but allows installation.
If the Windows or OS X version is too old, though, the script calls the \c cancelInstaller()
If the Windows or macOS version is too old, though, the script calls the \c cancelInstaller()
helper function to prevent an actual installation:
\printuntil /\}/

View File

@ -55,7 +55,7 @@ function Component()
//
// Check whether OS is supported.
//
// For Windows and OS X we check the kernel version:
// For Windows and macOS we check the kernel version:
// - Require at least Windows Vista (winnt kernel version 6.0.x)
// - Require at least OS X 10.7 (Lion) (darwin kernel version 11.x)
//

View File

@ -12,4 +12,4 @@ Linux:
LANGUAGE=de ./installer
On OS X and Windows you need to adapt the system settings to set German as preferred language, and then start the installer.
On macOS and Windows you need to adapt the system settings to set German as preferred language, and then start the installer.

View File

@ -5,6 +5,9 @@ IFW_PRI_INCLUDED = 1
IFW_VERSION_STR = 3.2.0
IFW_VERSION = 0x030200
IFW_VERSION_WIN32 = 3,2,0,0
IFW_VERSION_STR_WIN32 = $$IFW_VERSION_STR\0
IFW_REPOSITORY_FORMAT_VERSION = 1.0.0
IFW_NEWLINE = $$escape_expand(\\n\\t)
@ -123,7 +126,10 @@ isEmpty(GIT_SHA1) {
DEFINES += NOMINMAX QT_NO_CAST_FROM_ASCII QT_STRICT_ITERATORS QT_USE_QSTRINGBUILDER \
"_GIT_SHA1_=$$GIT_SHA1" \
IFW_VERSION_STR=$$IFW_VERSION_STR IFW_VERSION=$$IFW_VERSION
IFW_VERSION_STR=$$IFW_VERSION_STR \
IFW_VERSION=$$IFW_VERSION \
IFW_VERSION_STR_WIN32=$$IFW_VERSION_STR_WIN32 \
IFW_VERSION_WIN32=$$IFW_VERSION_WIN32
DEFINES += IFW_REPOSITORY_FORMAT_VERSION=$$IFW_REPOSITORY_FORMAT_VERSION
LIBS += -l7z

View File

@ -158,7 +158,7 @@ bool Resource::open()
if (isOpen())
return false;
if (!m_file.open(QIODevice::ReadOnly)) {
if (!m_file.open(QIODevice::ReadOnly | QIODevice::Unbuffered)) {
setErrorString(m_file.errorString());
return false;
}

View File

@ -147,6 +147,10 @@ ComponentSelectionPagePrivate::ComponentSelectionPagePrivate(ComponentSelectionP
m_treeViewVLayout->addWidget(m_treeView, 3);
// force a recalculation of components to install to keep the state correct
connect(q, &ComponentSelectionPage::left,
m_core, &PackageManagerCore::clearComponentsToInstallCalculated);
m_mainHLayout = new QHBoxLayout(q);
m_mainHLayout->addLayout(m_treeViewVLayout, 3);
m_mainHLayout->addLayout(m_descriptionVLayout, 2);

View File

@ -38,6 +38,7 @@
#include "lib7z_facade.h"
#include "packagemanagercore.h"
#include "productkeycheck.h"
#include "constants.h"
#include "updateoperations.h"
@ -183,6 +184,23 @@ bool CreateLocalRepositoryOperation::performOperation()
}
setValue(QLatin1String("createddir"), mkDirOp.value(QLatin1String("createddir")));
#if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
// Internal changes to QTemporaryFile break copying Qt resources through
// QInstaller::RemoteFileEngine. We do not register resources to be handled by
// RemoteFileEngine, instead copying using 5.9 succeeded because QFile::copy()
// creates a QTemporaryFile object internally that is handled by the remote engine.
//
// This will not work with Qt 5.10 and above as QTemporaryFile introduced a new
// rename() implementation that explicitly uses its own QTemporaryFileEngine.
//
// Fail and return early if we are working on an elevated permission directory.
if (core && !core->directoryWritable(repoPath)) {
setError(UserDefinedError);
setErrorString(tr("Creating local repository into elevated permissions "
"directory: %1 is not supported.").arg(repoPath));
return false;
}
#endif
// copy the whole meta data into local repository
CopyDirectoryOperation copyDirOp(core);
copyDirOp.setArguments(QStringList() << QLatin1String(":/metadata/") << repoPath);

View File

@ -286,7 +286,7 @@ void QInstaller::removeSystemGeneratedFiles(const QString &path)
{
if (path.isEmpty())
return;
#if defined Q_OS_OSX
#if defined Q_OS_MACOS
QFile::remove(path + QLatin1String("/.DS_Store"));
#elif defined Q_OS_WIN
QFile::remove(path + QLatin1String("/Thumbs.db"));
@ -572,7 +572,7 @@ quint64 QInstaller::fileSize(const QFileInfo &info)
bool QInstaller::isInBundle(const QString &path, QString *bundlePath)
{
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
QFileInfo fi = QFileInfo(path).absoluteFilePath();
while (!fi.isRoot()) {
if (fi.isBundle()) {

View File

@ -381,7 +381,7 @@ static QMessageBox::StandardButton showNewMessageBox(QWidget *parent, QMessageBo
msgBox.setDefaultButton(button);
}
}
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
msgBox.setWindowModality(Qt::WindowModal);
#endif
if (msgBox.exec() == -1)

View File

@ -326,10 +326,21 @@ void MetadataJob::xmlTaskFinished()
QHash<QString, QPair<Repository, Repository> > update;
update.insert(QLatin1String("replace"), qMakePair(original, replacement));
if (s.updateRepositoryCategories(update) == Settings::UpdatesApplied)
qDebug() << "Repository categories updated.";
if (s.updateDefaultRepositories(update) == Settings::UpdatesApplied
|| s.updateUserRepositories(update) == Settings::UpdatesApplied) {
if (m_core->isMaintainer())
if (m_core->isMaintainer()) {
bool gainedAdminRights = false;
if (!m_core->directoryWritable(m_core->value(scTargetDir))) {
m_core->gainAdminRights();
gainedAdminRights = true;
}
m_core->writeMaintenanceConfigFiles();
if (gainedAdminRights)
m_core->dropAdminRights();
}
}
}
status = XmlDownloadRetry;
@ -716,8 +727,16 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
return XmlDownloadRetry;
}
} else if (s.updateDefaultRepositories(repositoryUpdates) == Settings::UpdatesApplied) {
if (m_core->isMaintainer())
if (m_core->isMaintainer()) {
bool gainedAdminRights = false;
if (!m_core->directoryWritable(m_core->value(scTargetDir))) {
m_core->gainAdminRights();
gainedAdminRights = true;
}
m_core->writeMaintenanceConfigFiles();
if (gainedAdminRights)
m_core->dropAdminRights();
}
m_metaFromDefaultRepositories.clear();
QFile::remove(result.target());
return XmlDownloadRetry;

View File

@ -422,9 +422,7 @@ void PackageManagerCore::writeMaintenanceTool()
d->writeMaintenanceTool(d->m_performedOperationsOld + d->m_performedOperationsCurrentSession);
bool gainedAdminRights = false;
QTemporaryFile tempAdminFile(d->targetDir()
+ QLatin1String("/testjsfdjlkdsjflkdsjfldsjlfds") + QString::number(qrand() % 1000));
if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
if (!directoryWritable(d->targetDir())) {
gainAdminRights();
gainedAdminRights = true;
}
@ -538,6 +536,14 @@ void PackageManagerCore::componentsToInstallNeedsRecalculation()
component->updateUncompressedSize(); // this is a recursive call
}
/*!
\sa {installer::clearComponentsToInstallCalculated}{installer.clearComponentsToInstallCalculated}
*/
void PackageManagerCore::clearComponentsToInstallCalculated()
{
d->m_componentsToInstallCalculated = false;
}
/*!
\sa {installer::autoAcceptMessageBoxes}{installer.autoAcceptMessageBoxes}
\sa autoRejectMessageBoxes(), setMessageBoxAutomaticAnswer()
@ -665,7 +671,7 @@ int PackageManagerCore::downloadNeededArchives(double partProgressSize)
}
/*!
Returns \c true if essential component update is found.
Returns \c true if an essential component update is found.
*/
bool PackageManagerCore::foundEssentialUpdate() const
{
@ -673,7 +679,7 @@ bool PackageManagerCore::foundEssentialUpdate() const
}
/*!
Sets the value of \a foundEssentialUpdate, defaults \c true.
Sets the value of \a foundEssentialUpdate, defaults to \c true.
*/
void PackageManagerCore::setFoundEssentialUpdate(bool foundEssentialUpdate)
{
@ -1111,8 +1117,7 @@ void PackageManagerCore::networkSettingsChanged()
if (isMaintainer() ) {
bool gainedAdminRights = false;
QTemporaryFile tempAdminFile(d->targetDir() + QStringLiteral("/XXXXXX"));
if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
if (!directoryWritable(d->targetDir())) {
gainAdminRights();
gainedAdminRights = true;
}
@ -1580,6 +1585,16 @@ Component *PackageManagerCore::componentByName(const QString &name, const QList<
return nullptr;
}
bool PackageManagerCore::directoryWritable(const QString &path) const
{
return d->directoryWritable(path);
}
bool PackageManagerCore::subdirectoriesWritable(const QString &path) const
{
return d->subdirectoriesWritable(path);
}
/*!
Returns a list of components that are marked for installation. The list can
be empty.
@ -2186,7 +2201,7 @@ QString PackageManagerCore::findLibrary(const QString &name, const QStringList &
#if defined(Q_OS_WIN)
return findPath(QString::fromLatin1("%1.lib").arg(name), findPaths);
#else
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
if (findPaths.isEmpty()) {
findPaths.push_back(QLatin1String("/lib"));
findPaths.push_back(QLatin1String("/usr/lib"));

View File

@ -121,6 +121,9 @@ public:
static Component *componentByName(const QString &name, const QList<Component *> &components);
bool directoryWritable(const QString &path) const;
bool subdirectoriesWritable(const QString &path) const;
bool fetchLocalPackagesTree();
LocalPackagesHash localInstalledPackages();
@ -290,6 +293,7 @@ public Q_SLOTS:
void setCompleteUninstallation(bool complete);
void cancelMetaInfoJob();
void componentsToInstallNeedsRecalculation();
void clearComponentsToInstallCalculated();
Q_SIGNALS:
void aboutCalculateComponentsToInstall() const;

View File

@ -345,6 +345,27 @@ QString PackageManagerCorePrivate::targetDir() const
return m_core->value(scTargetDir);
}
bool PackageManagerCorePrivate::directoryWritable(const QString &path) const
{
QTemporaryFile tempFile(path + QStringLiteral("/tempFile") + QString::number(qrand() % 1000));
if (!tempFile.open() || !tempFile.isWritable())
return false;
else
return true;
}
bool PackageManagerCorePrivate::subdirectoriesWritable(const QString &path) const
{
// Iterate over target directory subdirectories for writing access
QDirIterator iterator(path, QDir::AllDirs | QDir::NoDotAndDotDot, QDirIterator::Subdirectories);
while (iterator.hasNext()) {
QTemporaryFile tempFile(iterator.next() + QLatin1String("/tempFile"));
if (!tempFile.open() || !tempFile.isWritable())
return false;
}
return true;
}
QString PackageManagerCorePrivate::configurationFileName() const
{
return m_core->value(scTargetConfigurationFile, QLatin1String("components.xml"));
@ -569,7 +590,7 @@ void PackageManagerCorePrivate::initialize(const QHash<QString, QString> &params
#endif
if (!m_core->isInstaller()) {
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
readMaintenanceConfigFiles(QCoreApplication::applicationDirPath() + QLatin1String("/../../.."));
#else
readMaintenanceConfigFiles(QCoreApplication::applicationDirPath());
@ -697,7 +718,7 @@ Operation *PackageManagerCorePrivate::takeOwnedOperation(Operation *operation)
QString PackageManagerCorePrivate::maintenanceToolName() const
{
QString filename = m_data.settings().maintenanceToolName();
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
if (QInstaller::isInBundle(QCoreApplication::applicationDirPath()))
filename += QLatin1String(".app/Contents/MacOS/") + filename;
#elif defined(Q_OS_WIN)
@ -1013,7 +1034,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
qDebug() << "Writing maintenance tool:" << maintenanceToolRenamedName;
ProgressCoordinator::instance()->emitLabelAndDetailTextChanged(tr("Writing maintenance tool."));
QTemporaryFile out;
QFile out(generateTemporaryFileName());
QInstaller::openForWrite(&out); // throws an exception in case of error
if (!input->seek(0))
@ -1023,7 +1044,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
if (writeBinaryLayout) {
QDir resourcePath(QFileInfo(maintenanceToolRenamedName).dir());
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
if (!resourcePath.path().endsWith(QLatin1String("Contents/MacOS")))
throw Error(tr("Maintenance tool is not a bundle"));
resourcePath.cdUp();
@ -1031,7 +1052,7 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
#endif
// It's a bit odd to have only the magic in the data file, but this simplifies
// other code a lot (since installers don't have any appended data either)
QTemporaryFile dataOut;
QFile dataOut(generateTemporaryFileName());
QInstaller::openForWrite(&dataOut);
QInstaller::appendInt64(&dataOut, 0); // operations start
QInstaller::appendInt64(&dataOut, 0); // operations end
@ -1049,10 +1070,9 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
}
if (!dataOut.rename(resourcePath.filePath(QLatin1String("installer.dat")))) {
throw Error(tr("Cannot write maintenance tool data to %1: %2").arg(out.fileName(),
out.errorString()));
throw Error(tr("Cannot write maintenance tool data to %1: %2").arg(dataOut.fileName(),
dataOut.errorString()));
}
dataOut.setAutoRemove(false);
dataOut.setPermissions(dataOut.permissions() | QFile::WriteUser | QFile::ReadGroup
| QFile::ReadOther);
}
@ -1077,6 +1097,11 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinary(QFile *const input, q
} else {
qDebug() << "Failed to write permissions for maintenance tool.";
}
if (out.exists() && !out.remove()) {
qWarning() << tr("Cannot remove temporary data file \"%1\": %2")
.arg(out.fileName(), out.errorString());
}
}
void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *output, QFile *const input,
@ -1144,16 +1169,14 @@ void PackageManagerCorePrivate::writeMaintenanceToolBinaryData(QFileDevice *outp
void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOperations)
{
bool gainedAdminRights = false;
QTemporaryFile tempAdminFile(targetDir() + QLatin1String("/testjsfdjlkdsjflkdsjfldsjlfds")
+ QString::number(qrand() % 1000));
if (!tempAdminFile.open() || !tempAdminFile.isWritable()) {
if (!directoryWritable(targetDir())) {
m_core->gainAdminRights();
gainedAdminRights = true;
}
const QString targetAppDirPath = QFileInfo(maintenanceToolName()).path();
if (!QDir().exists(targetAppDirPath)) {
// create the directory containing the maintenance tool (like a bundle structure on OS X...)
// create the directory containing the maintenance tool (like a bundle structure on macOS...)
Operation *op = createOwnedOperation(QLatin1String("Mkdir"));
op->setArguments(QStringList() << targetAppDirPath);
performOperationThreaded(op, Backup);
@ -1161,7 +1184,7 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
performedOperations.append(takeOwnedOperation(op));
}
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
// if it is a bundle, we need some stuff in it...
const QString sourceAppDirPath = QCoreApplication::applicationDirPath();
if (isInstaller() && QInstaller::isInBundle(sourceAppDirPath)) {
@ -1321,7 +1344,7 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
// On Mac data is always in a separate file so that the binary can be signed.
// On other platforms data is in separate file only after install so that the
// maintenancetool sign does not break.
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
QDir dataPath(QFileInfo(binaryName).dir());
dataPath.cdUp();
dataPath.cd(QLatin1String("Resources"));
@ -1336,7 +1359,7 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
newBinaryWritten = true;
QFile tmp(binaryName);
QInstaller::openForRead(&tmp);
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
writeMaintenanceToolBinary(&tmp, tmp.size(), true);
#else
writeMaintenanceToolBinary(&tmp, layout.endOfBinaryContent - layout.binaryContentSize, true);
@ -1348,7 +1371,7 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
m_core->setValue(QLatin1String("installedOperationAreSorted"), QLatin1String("true"));
try {
QTemporaryFile file;
QFile file(generateTemporaryFileName());
QInstaller::openForWrite(&file);
writeMaintenanceToolBinaryData(&file, &input, performedOperations, layout);
QInstaller::appendInt64(&file, BinaryContent::MagicCookieDat);
@ -1363,7 +1386,6 @@ void PackageManagerCorePrivate::writeMaintenanceTool(OperationList performedOper
throw Error(tr("Cannot write maintenance tool binary data to %1: %2")
.arg(file.fileName(), file.errorString()));
}
file.setAutoRemove(false);
file.setPermissions(file.permissions() | QFile::WriteUser | QFile::ReadGroup
| QFile::ReadOther);
} catch (const Error &/*error*/) {
@ -1455,8 +1477,7 @@ bool PackageManagerCorePrivate::runInstaller()
}
}
} else if (QDir(target).exists()) {
QTemporaryFile tempAdminFile(target + QLatin1String("/adminrights"));
if (!tempAdminFile.open() || !tempAdminFile.isWritable())
if (!directoryWritable(targetDir()))
adminRightsGained = m_core->gainAdminRights();
}
@ -1536,8 +1557,8 @@ bool PackageManagerCorePrivate::runInstaller()
Operation *createRepo = createOwnedOperation(QLatin1String("CreateLocalRepository"));
if (createRepo) {
QString binaryFile = QCoreApplication::applicationFilePath();
#ifdef Q_OS_OSX
// The installer binary on OSX does not contain the binary content, it's put into
#ifdef Q_OS_MACOS
// The installer binary on macOS does not contain the binary content, it's put into
// the resources folder as separate file. Adjust the actual binary path. No error
// checking here since we will fail later while reading the binary content.
QDir resourcePath(QFileInfo(binaryFile).dir());
@ -1622,10 +1643,16 @@ bool PackageManagerCorePrivate::runPackageUpdater()
//to have some progress for the cleanup/write component.xml step
ProgressCoordinator::instance()->addReservePercentagePoints(1);
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
// check if we need admin rights and ask before the action happens
if (!QTemporaryFile(targetDir() + QStringLiteral("/XXXXXX")).open())
// on Linux and macOS also check target directory subdirectories
if (!directoryWritable(targetDir()) || !subdirectoriesWritable(targetDir()))
adminRightsGained = m_core->gainAdminRights();
#else
// check if we need admin rights and ask before the action happens
if (!directoryWritable(targetDir()))
adminRightsGained = m_core->gainAdminRights();
#endif
const QList<Component *> componentsToInstall = m_core->orderedComponentsToInstall();
qDebug() << "Install size:" << componentsToInstall.size() << "components";
@ -1792,8 +1819,7 @@ bool PackageManagerCorePrivate::runUninstaller()
setStatus(PackageManagerCore::Running);
// check if we need to run elevated and ask before the action happens
QTemporaryFile tempAdminFile(targetDir() + QLatin1String("/adminrights"));
if (!tempAdminFile.open() || !tempAdminFile.isWritable())
if (!directoryWritable(targetDir()))
adminRightsGained = m_core->gainAdminRights();
OperationList undoOperations = m_performedOperationsOld;
@ -2005,7 +2031,7 @@ void PackageManagerCorePrivate::deleteMaintenanceTool()
// every other platform has no problem if we just delete ourselves now
QFile maintenanceTool(QFileInfo(installerBinaryPath()).absoluteFilePath());
maintenanceTool.remove();
# ifdef Q_OS_OSX
# ifdef Q_OS_MACOS
if (QInstaller::isInBundle(installerBinaryPath())) {
const QLatin1String cdUp("/../../..");
removeDirectoryThreaded(QFileInfo(installerBinaryPath() + cdUp).absoluteFilePath());

View File

@ -92,6 +92,9 @@ public:
QString targetDir() const;
QString registerPath();
bool directoryWritable(const QString &path) const;
bool subdirectoriesWritable(const QString &path) const;
QString maintenanceToolName() const;
QString installerBinaryPath() const;

View File

@ -57,7 +57,7 @@ PackageManagerCoreData::PackageManagerCoreData(const QHash<QString, QString> &va
#ifdef Q_OS_WIN
m_variables.insert(QLatin1String("os"), QLatin1String("win"));
#elif defined(Q_OS_OSX)
#elif defined(Q_OS_MACOS)
m_variables.insert(QLatin1String("os"), QLatin1String("mac"));
#elif defined(Q_OS_LINUX)
m_variables.insert(QLatin1String("os"), QLatin1String("x11"));
@ -110,10 +110,8 @@ void PackageManagerCoreData::setDynamicPredefinedVariables()
TCHAR buffer[MAX_PATH + 1] = { 0 };
SHGetFolderPath(nullptr, CSIDL_PROGRAM_FILES, nullptr, 0, buffer);
dir = QString::fromWCharArray(buffer);
#elif defined (Q_OS_OSX)
dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(1);
if (dir.isEmpty())
dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
#elif defined (Q_OS_MACOS)
dir = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation).value(0);
#endif
m_variables.insert(QLatin1String("ApplicationsDir"), dir);

View File

@ -305,7 +305,7 @@ PackageManagerGui::PackageManagerGui(PackageManagerCore *core, QWidget *parent)
setWindowTitle(tr("Maintain %1").arg(m_core->value(scTitle)));
setWindowFlags(windowFlags() &~ Qt::WindowContextHelpButtonHint);
#ifndef Q_OS_OSX
#ifndef Q_OS_MACOS
setWindowIcon(QIcon(m_core->settings().installerWindowIcon()));
#else
setPixmap(QWizard::BackgroundPixmap, m_core->settings().background());
@ -408,7 +408,7 @@ PackageManagerGui::~PackageManagerGui()
\list
\li \c Classic - Classic UI style for Windows 7 and earlier.
\li \c Modern - Modern UI style for Windows 8.
\li \c Mac - UI style for OS X.
\li \c Mac - UI style for macOS.
\li \c Aero - Aero Peek for Windows 7.
\endlist
*/
@ -1543,7 +1543,7 @@ void IntroductionPage::setErrorMessage(const QString &error)
{
QPalette palette;
const PackageManagerCore::Status s = packageManagerCore()->status();
if (s == PackageManagerCore::Failure || s == PackageManagerCore::Failure) {
if (s == PackageManagerCore::Failure) {
palette.setColor(QPalette::WindowText, Qt::red);
} else {
palette.setColor(QPalette::WindowText, palette.color(QPalette::WindowText));
@ -1911,6 +1911,11 @@ void ComponentSelectionPage::entering()
setColoredSubTitle(tr(strings[index]));
d->updateTreeView();
// check component model state so we can enable needed component selection buttons
if (core->isUpdater())
d->onModelStateChanged(d->m_currentModel->checkedState());
setModified(isComplete());
if (core->settings().repositoryCategories().count() > 0 && !core->isOfflineOnly()
&& !core->isUpdater()) {
@ -2173,7 +2178,7 @@ bool TargetDirectoryPage::validatePage()
const QFileInfo fi(targetDir);
if (fi.isDir()) {
QString fileName = packageManagerCore()->settings().maintenanceToolName();
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
if (QInstaller::isInBundle(QCoreApplication::applicationDirPath()))
fileName += QLatin1String(".app/Contents/MacOS/") + fileName;
#elif defined(Q_OS_WIN)
@ -2844,7 +2849,7 @@ void FinishedPage::entering()
}
if (packageManagerCore()->isMaintainer()) {
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
gui()->setOption(QWizard::NoCancelButton, false);
#endif
if (QAbstractButton *cancel = gui()->button(QWizard::CancelButton)) {
@ -2908,7 +2913,7 @@ void FinishedPage::entering()
*/
void FinishedPage::leaving()
{
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
gui()->setOption(QWizard::NoCancelButton, true);
#endif

View File

@ -29,6 +29,8 @@
#include "remoteclient.h"
#include "remoteclient_p.h"
#include <QDir>
namespace QInstaller {
RemoteClient *RemoteClient::s_instance = nullptr;
@ -61,6 +63,18 @@ QString RemoteClient::authorizationKey() const
return d->m_key;
}
QString RemoteClient::socketPathName(const QString &socketName) const
{
QString socketPathName;
if (socketName.startsWith(QLatin1Char('/'))) {
socketPathName = socketName;
} else {
socketPathName = QDir::tempPath();
socketPathName += QLatin1Char('/') + socketName;
}
return socketPathName;
}
/*!
Initializes the client with \a socketName, with the \a key the client
sends to authenticate with the server, \a mode and \a startAs.
@ -69,7 +83,17 @@ void RemoteClient::init(const QString &socketName, const QString &key, Protocol:
Protocol::StartAs startAs)
{
Q_D(RemoteClient);
// Since Qt 5.12.0, we should determince the full socket path on Unix
// platforms before calling QLocalSocketPrivate::_q_connectToSocket().
// Otherwise the new canonical implementation of QDir::tempPath()
// presents unintended usage of RemoteFileEngine.
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0) && defined(Q_OS_UNIX)
d->init(socketPathName(socketName), key, mode, startAs);
#else
d->init(socketName, key, mode, startAs);
#endif
}
void RemoteClient::setAuthorizationFallbackDisabled(bool disabled)

View File

@ -54,6 +54,7 @@ public:
QString socketName() const;
QString authorizationKey() const;
QString socketPathName(const QString &socketName) const;
bool isActive() const;
void setActive(bool active);

View File

@ -324,9 +324,9 @@ bool RemoteFileEngine::open(QIODevice::OpenMode mode)
{
if (connectToServer()) {
return callRemoteMethod<bool>(QString::fromLatin1(Protocol::QAbstractFileEngineOpen),
static_cast<qint32>(mode));
static_cast<qint32>(mode | QIODevice::Unbuffered));
}
return m_fileEngine.open(mode);
return m_fileEngine.open(mode | QIODevice::Unbuffered);
}
/*!

View File

@ -65,7 +65,7 @@ void RemoteServer::start()
if (d->m_localServer)
return;
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
// avoid writing to stderr:
// the parent process has redirected stderr to a pipe to work with sudo,
// but is not reading anymore -> writing to stderr will block after a while.
@ -93,7 +93,17 @@ void RemoteServer::start()
void RemoteServer::init(const QString &socketName, const QString &key, Protocol::Mode mode)
{
Q_D(RemoteServer);
// Since Qt 5.12.0, we should determince the full socket path on Unix
// platforms before calling QLocalSocketPrivate::_q_connectToSocket().
// Otherwise the new canonical implementation of QDir::tempPath()
// presents unintended usage of RemoteFileEngine.
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0) && defined(Q_OS_UNIX)
d->m_socketName = socketPathName(socketName);
#else
d->m_socketName = socketName;
#endif
d->m_key = key;
d->m_mode = mode;
}
@ -116,6 +126,18 @@ QString RemoteServer::authorizationKey() const
return d->m_key;
}
QString RemoteServer::socketPathName(const QString &socketName) const
{
QString socketPathName;
if (socketName.startsWith(QLatin1Char('/'))) {
socketPathName = socketName;
} else {
socketPathName = QDir::tempPath();
socketPathName += QLatin1Char('/') + socketName;
}
return socketPathName;
}
/*!
Restarts the watchdog that tries to kill the server.
*/

View File

@ -53,6 +53,7 @@ public:
QString socketName() const;
QString authorizationKey() const;
QString socketPathName(const QString &socketName) const;
private slots:
void restartWatchdog();

View File

@ -382,7 +382,14 @@ void RemoteServerConnection::handleQFSFileEngine(QIODevice *socket, const QStrin
} else if (command == QLatin1String(Protocol::QAbstractFileEngineCopy)) {
QString newName;
data >>newName;
#ifdef Q_OS_LINUX
// QFileSystemEngine::copyFile() is currently unimplemented on Linux,
// copy using QFile instead of directly with QFSFileEngine.
QFile file(m_engine->fileName(QAbstractFileEngine::AbsoluteName));
sendData(socket, file.copy(newName));
#else
sendData(socket, m_engine->copy(newName));
#endif
} else if (command == QLatin1String(Protocol::QAbstractFileEngineEntryList)) {
qint32 filters;
QStringList filterNames;

View File

@ -208,7 +208,7 @@ QString Repository::categoryname() const
}
/*!
Sets the category name to \a categoryname if the repository belongs to an category.
Sets the category name to \a categoryname if the repository belongs to a category.
*/
void Repository::setCategoryName(const QString &categoryname)
{

View File

@ -28,6 +28,7 @@
#include "repositorycategory.h"
#include "filedownloaderfactory.h"
#include "constants.h"
#include <QDataStream>
#include <QFileInfo>
@ -102,16 +103,20 @@ void RepositoryCategory::setTooltip(const QString &tooltip)
*/
QSet<Repository> RepositoryCategory::repositories() const
{
return variantListToSet<Repository>(m_data.values(QLatin1String("Repositories")));
return variantListToSet<Repository>(m_data.values(scRepositories));
}
/*!
Inserts a set of \a repositories to the category.
Inserts a set of \a repositories to the category. Removes old \a repositories
if \a replace is set to \c true.
*/
void RepositoryCategory::setRepositories(const QSet<Repository> repositories)
void RepositoryCategory::setRepositories(const QSet<Repository> repositories, const bool replace)
{
if (replace)
m_data.remove(scRepositories);
foreach (const Repository &repository, repositories)
m_data.insertMulti(QLatin1String("Repositories"), QVariant().fromValue(repository));
m_data.insertMulti(scRepositories, QVariant().fromValue(repository));
}
/*!
@ -119,7 +124,7 @@ void RepositoryCategory::setRepositories(const QSet<Repository> repositories)
*/
void RepositoryCategory::addRepository(const Repository repository)
{
m_data.insertMulti(QLatin1String("Repositories"), QVariant().fromValue(repository));
m_data.insertMulti(scRepositories, QVariant().fromValue(repository));
}
/*!

View File

@ -54,7 +54,7 @@ public:
void setTooltip(const QString &tooltip);
QSet<Repository> repositories() const;
void setRepositories(const QSet<Repository> repositories);
void setRepositories(const QSet<Repository> repositories, const bool replace = false);
void addRepository(const Repository repository);
bool isEnabled() const;

View File

@ -472,7 +472,7 @@ QString Settings::installerWindowIcon() const
QString Settings::systemIconSuffix() const
{
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
return QLatin1String(".icns");
#elif defined(Q_OS_WIN)
return QLatin1String(".ico");
@ -616,12 +616,46 @@ void Settings::addDefaultRepositories(const QSet<Repository> &repositories)
d->m_data.insertMulti(scRepositories, QVariant().fromValue(repository));
}
void Settings::setRepositoryCategories(const QSet<RepositoryCategory> &repositories)
{
d->m_data.remove(scRepositoryCategories);
addRepositoryCategories(repositories);
}
void Settings::addRepositoryCategories(const QSet<RepositoryCategory> &repositories)
{
foreach (const RepositoryCategory &repository, repositories)
d->m_data.insertMulti(scRepositoryCategories, QVariant().fromValue(repository));
}
Settings::Update Settings::updateRepositoryCategories(const RepoHash &updates)
{
if (updates.isEmpty())
return Settings::NoUpdatesApplied;
QSet<RepositoryCategory> categories = repositoryCategories();
QList<RepositoryCategory> categoriesList = categories.values();
QPair<Repository, Repository> updateValues = updates.value(QLatin1String("replace"));
bool update = false;
foreach (RepositoryCategory category, categoriesList) {
QSet<Repository> repositories = category.repositories();
if (repositories.contains(updateValues.first)) {
update = true;
repositories.remove(updateValues.first);
repositories.insert(updateValues.second);
category.setRepositories(repositories, true);
categoriesList.replace(categoriesList.indexOf(category), category);
}
}
if (update) {
categories = categoriesList.toSet();
setRepositoryCategories(categories);
}
return update ? Settings::UpdatesApplied : Settings::NoUpdatesApplied;
}
static bool apply(const RepoHash &updates, QHash<QUrl, Repository> *reposToUpdate)
{
bool update = false;

View File

@ -115,13 +115,16 @@ public:
QSet<Repository> repositories() const;
QSet<Repository> defaultRepositories() const;
QSet<RepositoryCategory> repositoryCategories() const;
QMap<QString, RepositoryCategory> organizedRepositoryCategories() const;
void setDefaultRepositories(const QSet<Repository> &repositories);
void addDefaultRepositories(const QSet<Repository> &repositories);
void addRepositoryCategories(const QSet<RepositoryCategory> &repositories);
Settings::Update updateDefaultRepositories(const RepoHash &updates);
QSet<RepositoryCategory> repositoryCategories() const;
QMap<QString, RepositoryCategory> organizedRepositoryCategories() const;
void setRepositoryCategories(const QSet<RepositoryCategory> &repositories);
void addRepositoryCategories(const QSet<RepositoryCategory> &repositories);
Settings::Update updateRepositoryCategories(const RepoHash &updates);
QSet<Repository> temporaryRepositories() const;
void setTemporaryRepositories(const QSet<Repository> &repositories, bool replace);
void addTemporaryRepositories(const QSet<Repository> &repositories, bool replace);

View File

@ -180,7 +180,7 @@ bool SettingsOperation::undoOperation()
if (!settingsFile.remove())
qWarning().noquote() << settingsFile.errorString();
if (!value(QLatin1String("createddir")).toString().isEmpty()) {
KDUpdater::MkdirOperation mkDirOperation;
KDUpdater::MkdirOperation mkDirOperation(packageManager());
mkDirOperation.setArguments(QStringList() << QFileInfo(path).absolutePath());
mkDirOperation.setValue(QLatin1String("createddir"), value(QLatin1String("createddir")));

View File

@ -76,7 +76,7 @@ QString SystemInfo::currentCpuArchitecture() const
kernel the installer is running on, unless the host operating system is running a form of
compatibility or virtualization layer.
For Windows, Linux, and OS X this will return:
For Windows, Linux, and macOS this will return:
\list
\li "winnt"
\li "linux"
@ -96,7 +96,7 @@ QString SystemInfo::kernelType() const
\property SystemInfo::kernelVersion
The release version of the operating system kernel. On Windows, it returns the version of the
NT or CE kernel. On Unix systems, including OS X, it returns the same as the \c {uname -r}
NT or CE kernel. On Unix systems, including macOS, it returns the same as the \c {uname -r}
command would return.
Example values are:

View File

@ -455,7 +455,7 @@ QDomDocument UpdateOperation::toXml() const
bool UpdateOperation::fromXml(const QDomDocument &doc)
{
QString target = QCoreApplication::applicationDirPath();
// Does not change target on non OSX platforms.
// Does not change target on non macOS platforms.
if (QInstaller::isInBundle(target, &target))
target = QDir::cleanPath(target + QLatin1String("/.."));

View File

@ -51,7 +51,7 @@ CommandLineParser::CommandLineParser()
QLatin1String("Verbose mode. Prints out more information.")));
m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::Proxy),
QLatin1String("Use system proxy on Windows and Linux. This option has no effect on OS X.")));
QLatin1String("Use system proxy on Windows and Linux. This option has no effect on macOS.")));
m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::NoProxy),
QLatin1String("Do not use system proxy.")));

View File

@ -1,3 +1,21 @@
#include <windows.h>
/* Version info for Windows binary */
VS_VERSION_INFO VERSIONINFO
FILEVERSION IFW_VERSION_WIN32
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "FileVersion", IFW_VERSION_STR_WIN32
END
END
END
/* End of version info */
IDI_ICON1 ICON DISCARDABLE
"installerbase.ico"

View File

@ -44,7 +44,7 @@
#include <iostream>
#if defined(Q_OS_OSX) or defined(Q_OS_UNIX)
#if defined(Q_OS_MACOS) or defined(Q_OS_UNIX)
# include <unistd.h>
# include <sys/types.h>
#endif
@ -66,7 +66,7 @@ int main(int argc, char *argv[])
}
#endif
// increase maximum numbers of file descriptors
#if defined (Q_OS_OSX)
#if defined (Q_OS_MACOS)
QCoreApplication::setSetuidAllowed(true);
struct rlimit rl;
getrlimit(RLIMIT_NOFILE, &rl);
@ -141,7 +141,7 @@ int main(int argc, char *argv[])
Qt::CaseInsensitive) == 0);
if (production) {
argumentsValid = (!key.isEmpty()) && (!socketName.isEmpty());
#if defined(Q_OS_UNIX) && !defined(Q_OS_OSX)
#if defined(Q_OS_UNIX) && !defined(Q_OS_MACOS)
/* In production mode detach child so that sudo waiting on us will terminate. */
pid_t child = fork();
if (child <= -1) {
@ -166,7 +166,7 @@ int main(int argc, char *argv[])
return EXIT_FAILURE;
}
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
// make sure effective == real user id.
uid_t realUserId = getuid();
uid_t effectiveUserId = geteuid();

View File

@ -73,21 +73,21 @@ public:
as the binary layout cannot be appended to the actual maintenance tool binary
itself because of signing.
On OS X: This function will return always the .dat file
On macOS: This function will return always the .dat file
.dat file is located inside the resource folder in the application
bundle in OS X.
bundle in macOS.
*/
QString binaryFile() const
{
QString binaryFile = QCoreApplication::applicationFilePath();
// The installer binary on OSX and Windows does not contain the binary
// The installer binary on macOS and Windows does not contain the binary
// content, it's put into the resources folder as separate file.
// Adjust the actual binary path. No error checking here since we
// will fail later while reading the binary content.
QDir resourcePath(QFileInfo(binaryFile).dir());
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
resourcePath.cdUp();
resourcePath.cd(QLatin1String("Resources"));
#endif
@ -116,7 +116,7 @@ public:
QString bundlePath;
if (QInstaller::isInBundle(fi.absoluteFilePath(), &bundlePath))
fi.setFile(bundlePath);
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
return fi.absoluteDir().filePath(fi.baseName() + QLatin1String(".dat"));
#else
return fi.absoluteDir().filePath(qApp->applicationName() + QLatin1String(".dat"));

View File

@ -1365,15 +1365,15 @@ Fehler beim Laden von %2</translation>
<translation>Willkommen zum %1-Einrichtungsassistenten.</translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation>Komponenten hinzufügen oder entfernen</translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation>Komponenten aktualisieren</translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation>Alle Komponenten entfernen</translation>
</message>
<message>
@ -1393,7 +1393,7 @@ Fehler beim Laden von %2</translation>
<translation> Nur lokale Paketverwaltung verfügbar.</translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation>Beenden</translation>
</message>
</context>

View File

@ -1327,15 +1327,15 @@ Error al descargar %2</translation>
<translation>Bienvenido al Asistente de instalación de %1.</translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation>Agregar o quitar componentes</translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation>Actualizar componentes</translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation>Quitar todos los componentes</translation>
</message>
<message>
@ -1355,7 +1355,7 @@ Error al descargar %2</translation>
<translation> Solo está disponible la administración de paquetes locales.</translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation>Salir</translation>
</message>
</context>

View File

@ -1327,15 +1327,15 @@ Erreur lors du chargement de %2</translation>
<translation>Bienvenue dans lassistant dinstallation de %1</translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation>Ajouter ou supprimer des composants</translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation>Mettre à jour des composants</translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation>Supprimer tous les composants</translation>
</message>
<message>
@ -1355,7 +1355,7 @@ Erreur lors du chargement de %2</translation>
<translation> Seule la gestion des paquetages locaux est disponible.</translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation>Quitter</translation>
</message>
</context>

View File

@ -1327,15 +1327,15 @@ Errore durante il caricamento di %2</translation>
<translation>Installazione guidata di %1.</translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation>Aggiungi o rimuovi componenti</translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation>Aggiorna componenti</translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation>Rimuovi tutti i componenti</translation>
</message>
<message>
@ -1355,7 +1355,7 @@ Errore durante il caricamento di %2</translation>
<translation> Disponibile solo gestione pacchetto locale.</translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation>Esci</translation>
</message>
</context>

View File

@ -1327,15 +1327,15 @@ Error while loading %2</source>
<translation>%1 </translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation></translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation></translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation></translation>
</message>
<message>
@ -1355,7 +1355,7 @@ Error while loading %2</source>
<translation> </translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation></translation>
</message>
</context>

View File

@ -1327,15 +1327,15 @@ Błąd podczas wczytywania %2</translation>
<translation>Witamy w Kreatorze konfiguracji %1.</translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation>Dodaj lub usuń elementy</translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation>Zaktualizuj elementy</translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation>Usuń wszystkie elementy</translation>
</message>
<message>
@ -1355,7 +1355,7 @@ Błąd podczas wczytywania %2</translation>
<translation> Dostępne jedynie lokalne zarządzanie pakietami.</translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation>Zakończ</translation>
</message>
</context>

View File

@ -1327,15 +1327,15 @@ Error while loading %2</source>
<translation>使 %1 </translation>
</message>
<message>
<source>Add or remove components</source>
<source>&amp;Add or remove components</source>
<translation></translation>
</message>
<message>
<source>Update components</source>
<source>&amp;Update components</source>
<translation></translation>
</message>
<message>
<source>Remove all components</source>
<source>&amp;Remove all components</source>
<translation></translation>
</message>
<message>
@ -1355,7 +1355,7 @@ Error while loading %2</source>
<translation> </translation>
</message>
<message>
<source>Quit</source>
<source>&amp;Quit</source>
<translation>退</translation>
</message>
</context>

View File

@ -128,7 +128,7 @@ private slots:
// throws
QInstaller::BinaryContent::findMagicCookie(&file, QInstaller::BinaryContent::MagicCookie);
} catch (const QInstaller::Error &error) {
QCOMPARE(qPrintable(error.message()), "No marker found, stopped after 71.00 KiB.");
QCOMPARE(qPrintable(error.message()), "No marker found, stopped after 71.00 KB.");
} catch (...) {
QFAIL("Unexpected error.");
}

View File

@ -34,6 +34,7 @@
#include <progresscoordinator.h>
#include <QDir>
#include <QFile>
#include <QTemporaryFile>
#include <QTest>
@ -118,15 +119,18 @@ private slots:
QVERIFY(core.calculateComponentsToInstall());
{
QTemporaryFile dummy(testDirectory + QLatin1String("/dummy"));
dummy.open();
QFile dummy(testDirectory + QLatin1String("/dummy"));
QVERIFY(dummy.open(QIODevice::ReadWrite));
core.runInstaller();
QVERIFY(QDir(testDirectory).exists());
QVERIFY(QFileInfo(dummy.fileName()).exists());
dummy.close();
QVERIFY(dummy.remove());
}
QDir().rmdir(testDirectory);
QVERIFY(QDir().rmdir(testDirectory));
ProgressCoordinator::instance()->reset();
}
@ -257,6 +261,58 @@ private slots:
core.calculateComponentsToInstall();
QCOMPARE(core.requiredDiskSpace(), 250ULL);
}
void testDirectoryWritable()
{
PackageManagerCore core;
const QString testDirectory = QInstaller::generateTemporaryFileName();
QVERIFY(QDir().mkpath(testDirectory));
QVERIFY(QDir(testDirectory).exists());
// should be writable
QVERIFY(core.directoryWritable(testDirectory));
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
QFile dirDevice(testDirectory);
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::ExeOwner);
// should not be writable
QVERIFY(!core.directoryWritable(testDirectory));
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
#endif
QVERIFY(QDir().rmdir(testDirectory));
}
void testSubdirectoriesWritable()
{
PackageManagerCore core;
const QString testDirectory = QInstaller::generateTemporaryFileName();
QVERIFY(QDir().mkpath(testDirectory));
QVERIFY(QDir(testDirectory).exists());
const QString testSubdirectory = testDirectory + "/" + QString::number(qrand() % 1000);
QVERIFY(QDir().mkpath(testSubdirectory));
QVERIFY(QDir(testSubdirectory).exists());
// should be writable
QVERIFY(core.subdirectoriesWritable(testDirectory));
#if defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
QFile dirDevice(testSubdirectory);
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::ExeOwner);
// should not be writable
QVERIFY(!core.subdirectoriesWritable(testDirectory));
dirDevice.setPermissions(QFileDevice::ReadOwner | QFileDevice::WriteOwner | QFileDevice::ExeOwner);
#endif
QVERIFY(QDir().rmdir(testSubdirectory));
QVERIFY(QDir().rmdir(testDirectory));
}
};

View File

@ -1,4 +1,6 @@
#include "repository.h"
#include "repositorycategory.h"
#include "settings.h"
#include <QDataStream>
#include <QString>
@ -114,6 +116,51 @@ private slots:
s1 >> r1; s2 >> r2;
QCOMPARE(r1, r2);
}
void testUpdateRepositoryCategories()
{
Settings settings;
RepositoryCategory category;
category.setEnabled(true);
category.setDisplayName(QLatin1String("category"));
Repository original(QUrl("http://example.com/"), true);
original.setEnabled(true);
category.addRepository(original);
Repository replacement = original;
replacement.setUsername(QLatin1String("user"));
replacement.setPassword(QLatin1String("pass"));
QSet<RepositoryCategory> categories;
categories.insert(category);
settings.setRepositoryCategories(categories);
QHash<QString, QPair<Repository, Repository>> update;
// non-empty update
update.insert(QLatin1String("replace"), qMakePair(original, replacement));
QVERIFY(settings.updateRepositoryCategories(update) == Settings::UpdatesApplied);
// verify that the values really updated
QVERIFY(settings.repositoryCategories().values().at(0)
.repositories().values().at(0).username() == "user");
QVERIFY(settings.repositoryCategories().values().at(0)
.repositories().values().at(0).password() == "pass");
// empty update
update.clear();
QVERIFY(settings.updateRepositoryCategories(update) == Settings::NoUpdatesApplied);
// non-matching repository update
Repository nonMatching(QUrl("https://www.qt.io/"), true);
nonMatching.setEnabled(true);
update.insert(QLatin1String("replace"), qMakePair(nonMatching, replacement));
QVERIFY(settings.updateRepositoryCategories(update) == Settings::NoUpdatesApplied);
}
};
QTEST_MAIN(tst_Repository)

View File

@ -280,7 +280,11 @@ private slots:
// ignore Output from script
setExpectedScriptOutput("function receive()");
#if QT_VERSION >= QT_VERSION_CHECK(5,12,0)
QTest::ignoreMessage(QtWarningMsg, "<Unknown File>:38: ReferenceError: foo is not defined");
#else
QTest::ignoreMessage(QtWarningMsg, ":38: ReferenceError: foo is not defined");
#endif
emiter.produceSignal();
const QJSValue value = m_scriptEngine->evaluate("");

View File

@ -49,7 +49,7 @@ void tst_Settings::loadTutorialConfig()
QCOMPARE(settings.installerApplicationIcon(), QLatin1String(":/installer.ico"));
QCOMPARE(settings.installerWindowIcon(), QLatin1String(":/installer.ico"));
QCOMPARE(settings.systemIconSuffix(), QLatin1String(".ico"));
#elif defined(Q_OS_OSX)
#elif defined(Q_OS_MACOS)
QCOMPARE(settings.installerApplicationIcon(), QLatin1String(":/installer.icns"));
QCOMPARE(settings.installerWindowIcon(), QLatin1String(":/installer.icns"));
QCOMPARE(settings.systemIconSuffix(), QLatin1String(".icns"));

View File

@ -263,7 +263,7 @@ static QVersionNumber readMachOMinimumSystemVersion(QIODevice *device)
static int assemble(Input input, const QInstaller::Settings &settings, const QString &signingIdentity)
{
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
if (QInstaller::isInBundle(input.installerExePath)) {
const QString bundle = input.installerExePath;
// if the input file was a bundle
@ -330,9 +330,12 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
<< endl;
plistStream << QLatin1String("\t<key>CFBundlePackageType</key>") << endl;
plistStream << QLatin1String("\t<string>APPL</string>") << endl;
plistStream << QLatin1String("\t<key>CFBundleGetInfoString</key>") << endl;
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
plistStream << QLatin1String("\t<key>CFBundleShortVersionString</key>") << endl;
plistStream << QLatin1String("\t<string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>")
<< endl;
plistStream << QLatin1String("\t<key>CFBundleVersion</key>") << endl;
plistStream << QLatin1String("\t<string>") << QLatin1String(QUOTE(IFW_VERSION_STR)) << ("</string>")
<< endl;
#undef QUOTE
@ -391,7 +394,7 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
// no error handling as this is not fatal
setApplicationIcon(tempFile, settings.installerApplicationIcon());
}
#elif defined(Q_OS_OSX)
#elif defined(Q_OS_MACOS)
if (isBundle) {
// no error handling as this is not fatal
const QString copyscript = QDir::temp().absoluteFilePath(QLatin1String("copylibsintobundle.sh"));
@ -408,7 +411,7 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
QTemporaryFile out;
QString targetName = input.outputPath;
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
QDir resourcePath(QFileInfo(input.outputPath).dir());
resourcePath.cdUp();
resourcePath.cd(QLatin1String("Resources"));
@ -429,7 +432,7 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
QInstaller::openForWrite(&out);
QFile exe(input.installerExePath);
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
if (!exe.copy(input.outputPath)) {
throw Error(QString::fromLatin1("Cannot copy %1 to %2: %3").arg(exe.fileName(),
input.outputPath, exe.errorString()));
@ -474,7 +477,7 @@ static int assemble(Input input, const QInstaller::Settings &settings, const QSt
#endif
QFile::remove(tempFile);
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
if (isBundle && !signingIdentity.isEmpty()) {
qDebug() << "Signing .app bundle...";
@ -657,7 +660,7 @@ static void printUsage()
std::cout << " -rcc|--compile-resource Compiles the default resource and outputs the result into"
<< std::endl;
std::cout << " 'update.rcc' in the current path." << std::endl;
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
std::cout << " -s|--sign identity Sign generated app bundle using the given code " << std::endl;
std::cout << " signing identity" << std::endl;
#endif
@ -715,7 +718,7 @@ void copyConfigData(const QString &configFile, const QString &targetDir)
QString targetFile;
QFileInfo elementFileInfo;
if (tagName == QLatin1String("Icon") || tagName == QLatin1String("InstallerApplicationIcon")) {
#if defined(Q_OS_OSX)
#if defined(Q_OS_MACOS)
const QString suffix = QLatin1String(".icns");
#elif defined(Q_OS_WIN)
const QString suffix = QLatin1String(".ico");
@ -882,7 +885,7 @@ int main(int argc, char **argv)
continue;
} else if (*it == QLatin1String("-rcc") || *it == QLatin1String("--compile-resource")) {
compileResource = true;
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
} else if (*it == QLatin1String("-s") || *it == QLatin1String("--sign")) {
++it;
if (it == args.end() || it->startsWith(QLatin1String("-")))
@ -983,7 +986,7 @@ int main(int argc, char **argv)
confInternal.setValue(QLatin1String("offlineOnly"), offlineOnly);
}
#ifdef Q_OS_OSX
#ifdef Q_OS_MACOS
// on mac, we enforce building a bundle
if (!target.endsWith(QLatin1String(".app")) && !target.endsWith(QLatin1String(".dmg")))
target += QLatin1String(".app");

View File

@ -71,7 +71,7 @@ function handleFile()
if [ `basename $FILE` != $NAME ]; then
# this part handles libraries which are Mac OS X frameworks
# this part handles libraries which are macOS frameworks
if echo $lib | grep '\.framework' >/dev/null; then
local FRAMEWORKPATH=`echo $lib | sed -ne 's,\(.*\.framework\).*,\1,p'`
local FRAMEWORKNAME=`basename $FRAMEWORKPATH`

View File

@ -99,7 +99,7 @@ int BinaryReplace::replace(const QString &source, const QString &target)
result = EXIT_FAILURE;
try {
QFile installerBaseNew(newInstallerBasePath);
#ifndef Q_OS_OSX
#ifndef Q_OS_MACOS
QFile installerBaseOld(target);
QInstaller::openForAppend(&installerBaseNew);

View File

@ -168,7 +168,7 @@ int main(int argc, char *argv[])
if (QInstaller::isInBundle(path, &bundlePath)) {
path = QDir(bundlePath).filePath(QLatin1String("Contents/Resources/installer.dat"));
}
#ifndef Q_OS_OSX
#ifndef Q_OS_MACOS
QFileInfo fi = QFileInfo(path);
bundlePath = path;
QString tmp = QDir(fi.path()).filePath(QLatin1String("installer.dat"));