aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2022-09-22 17:14:55 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2022-10-04 07:43:01 +0000
commita29bbf5568bf651b076f051720a98e9d0297faa9 (patch)
tree5d99c12c7d9735e7f113c3a04ccf95746ef8dedc
parent512001849af89e4b2c5bfb18b039387d6fe7aaa6 (diff)
Make handling of deprecated items and properties configurable
As of now, a newly deprecated property leads to users getting bombarded with warnings, even though they did not yet have a chance to adapt their project. Now the warnings appear by default one minor version before removal, which together with our convention of keeping deprecated properties for at least two minor versions gives users enough time to adapt without getting spammed. There is also a mode for switching to the previous behavior (for early detection), as well as the possibility to trigger errors instead of warnings, which should be helpful in CI configurations. To support the case where the user cannot do anything about them, the warnings can also be suppressed altogether. Change-Id: I295f816758f0f111fcb0351581a4328be3af5668 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Ivan Komissarov <ABBAPOH@gmail.com>
-rw-r--r--doc/appendix/json-api.qdoc1
-rw-r--r--doc/reference/cli/builtin/cli-resolve.qdoc1
-rw-r--r--doc/reference/cli/cli-options.qdocinc21
-rw-r--r--src/app/qbs/commandlinefrontend.cpp1
-rw-r--r--src/app/qbs/parser/commandlineoption.cpp35
-rw-r--r--src/app/qbs/parser/commandlineoption.h16
-rw-r--r--src/app/qbs/parser/commandlineoptionpool.cpp9
-rw-r--r--src/app/qbs/parser/commandlineoptionpool.h1
-rw-r--r--src/app/qbs/parser/commandlineparser.cpp5
-rw-r--r--src/app/qbs/parser/commandlineparser.h3
-rw-r--r--src/app/qbs/parser/parsercommand.cpp1
-rw-r--r--src/lib/corelib/CMakeLists.txt2
-rw-r--r--src/lib/corelib/corelib.qbs2
-rw-r--r--src/lib/corelib/language/deprecationinfo.h46
-rw-r--r--src/lib/corelib/language/item.cpp22
-rw-r--r--src/lib/corelib/language/item.h3
-rw-r--r--src/lib/corelib/language/itemdeclaration.cpp6
-rw-r--r--src/lib/corelib/language/itemdeclaration.h3
-rw-r--r--src/lib/corelib/language/itemreader.cpp5
-rw-r--r--src/lib/corelib/language/itemreader.h4
-rw-r--r--src/lib/corelib/language/itemreaderastvisitor.cpp22
-rw-r--r--src/lib/corelib/language/itemreadervisitorstate.h5
-rw-r--r--src/lib/corelib/language/moduleloader.cpp37
-rw-r--r--src/lib/corelib/language/projectresolver.cpp2
-rw-r--r--src/lib/corelib/language/propertydeclaration.cpp6
-rw-r--r--src/lib/corelib/language/propertydeclaration.h7
-rw-r--r--src/lib/corelib/tools/deprecationwarningmode.cpp98
-rw-r--r--src/lib/corelib/tools/deprecationwarningmode.h59
-rw-r--r--src/lib/corelib/tools/setupprojectparameters.cpp23
-rw-r--r--src/lib/corelib/tools/setupprojectparameters.h4
-rw-r--r--src/lib/corelib/tools/tools.pri3
-rw-r--r--tests/auto/blackbox/CMakeLists.txt1
-rw-r--r--tests/auto/blackbox/blackbox.qbs1
-rw-r--r--tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs2
-rw-r--r--tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs8
-rw-r--r--tests/auto/blackbox/tst_blackbox.cpp61
-rw-r--r--tests/auto/blackbox/tst_blackbox.h1
37 files changed, 448 insertions, 79 deletions
diff --git a/doc/appendix/json-api.qdoc b/doc/appendix/json-api.qdoc
index 68bb644cf..b555825f9 100644
--- a/doc/appendix/json-api.qdoc
+++ b/doc/appendix/json-api.qdoc
@@ -117,6 +117,7 @@
\row \li build-root \li \l FilePath \li yes
\row \li configuration-name \li string \li no
\row \li data-mode \li \l DataMode \li no
+ \row \li deprecation-warning-mode \li string \li no
\row \li dry-run \li bool \li no
\row \li environment \li \l Environment \li no
\row \li error-handling-mode \li string \li no
diff --git a/doc/reference/cli/builtin/cli-resolve.qdoc b/doc/reference/cli/builtin/cli-resolve.qdoc
index 273ce8403..4569980bd 100644
--- a/doc/reference/cli/builtin/cli-resolve.qdoc
+++ b/doc/reference/cli/builtin/cli-resolve.qdoc
@@ -56,6 +56,7 @@
\include cli-options.qdocinc settings-dir
\include cli-options.qdocinc show-progress
\include cli-options.qdocinc no-fallback-module-provider
+ \include cli-options.qdocinc deprecation-warnings
\section1 Parameters
diff --git a/doc/reference/cli/cli-options.qdocinc b/doc/reference/cli/cli-options.qdocinc
index db8eeae48..ecb8f5c3e 100644
--- a/doc/reference/cli/cli-options.qdocinc
+++ b/doc/reference/cli/cli-options.qdocinc
@@ -331,6 +331,27 @@
//! [config-ui-system]
+//! [deprecation-warnings]
+
+ \section2 \c {--deprecation-warnings <mode>}
+
+ Uses the specified deprecation warning mode, which controls what to do when deprecated
+ items or properties are encountered in the project. By default, a warning is emitted
+ if the item or property is scheduled for removal in the next minor version of \QBS.
+ Warnings can also be switched on or off unconditionally, and it can be specified that
+ project resolving should abort if deprecated constructs are present.
+
+ Possible values of \c <mode> are:
+
+ \list
+ \li \c error
+ \li \c on
+ \li \c before-removal (default value)
+ \li \c off
+ \endlist
+
+//! [deprecation-warnings]
+
//! [log-level]
\section2 \c {--log-level <level>}
diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp
index 489be4ed5..c3269ebcf 100644
--- a/src/app/qbs/commandlinefrontend.cpp
+++ b/src/app/qbs/commandlinefrontend.cpp
@@ -157,6 +157,7 @@ void CommandLineFrontend::start()
params.setSettingsDirectory(m_settings->baseDirectory());
params.setOverrideBuildGraphData(m_parser.command() == ResolveCommandType);
params.setPropertyCheckingMode(ErrorHandlingMode::Strict);
+ params.setDeprecationWarningMode(m_parser.deprecationWarningMode());
if (!m_parser.buildBeforeInstalling() || !m_parser.commandCanResolve())
params.setRestoreBehavior(SetupProjectParameters::RestoreOnly);
const auto buildConfigs = m_parser.buildConfigurations();
diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp
index a09f36c2c..ddbcd4da1 100644
--- a/src/app/qbs/parser/commandlineoption.cpp
+++ b/src/app/qbs/parser/commandlineoption.cpp
@@ -663,6 +663,41 @@ void CommandEchoModeOption::doParse(const QString &representation, QStringList &
m_echoMode = commandEchoModeFromName(mode);
}
+QString DeprecationWarningsOption::description(CommandType command) const
+{
+ Q_UNUSED(command);
+ return Tr::tr("%1 <mode>\n"
+ "\tWhat to do when encountering deprecated items or properties.\n"
+ "\tPossible values are '%2'.\n"
+ "\tThe default is '%3'.\n")
+ .arg(longRepresentation(),
+ allDeprecationWarningModeStrings().join(QLatin1String("', '")),
+ deprecationWarningModeName(defaultDeprecationWarningMode()));
+}
+
+QString DeprecationWarningsOption::longRepresentation() const
+{
+ return QStringLiteral("--deprecation-warnings");
+}
+
+void DeprecationWarningsOption::doParse(const QString &representation, QStringList &input)
+{
+ const QString mode = getArgument(representation, input);
+ if (mode.isEmpty()) {
+ throw ErrorInfo(Tr::tr("Invalid use of option '%1': No deprecation warning mode given.\n"
+ "Usage: %2")
+ .arg(representation, description(command())));
+ }
+
+ if (!allDeprecationWarningModeStrings().contains(mode)) {
+ throw ErrorInfo(Tr::tr("Invalid use of option '%1': "
+ "Invalid deprecation warning mode '%2' given.\nUsage: %3")
+ .arg(representation, mode, description(command())));
+ }
+
+ m_mode = deprecationWarningModeFromName(mode);
+}
+
QString WaitLockOption::description(CommandType command) const
{
Q_UNUSED(command);
diff --git a/src/app/qbs/parser/commandlineoption.h b/src/app/qbs/parser/commandlineoption.h
index f8ec1c735..d51d5f765 100644
--- a/src/app/qbs/parser/commandlineoption.h
+++ b/src/app/qbs/parser/commandlineoption.h
@@ -42,6 +42,7 @@
#include "commandtype.h"
#include <tools/commandechomode.h>
+#include <tools/deprecationwarningmode.h>
#include <tools/joblimits.h>
#include <QtCore/qstringlist.h>
@@ -76,6 +77,7 @@ public:
WaitLockOptionType,
RunEnvConfigOptionType,
DisableFallbackProviderType,
+ DeprecationWarningsOptionType,
};
virtual ~CommandLineOption();
@@ -367,6 +369,20 @@ private:
CommandEchoMode m_echoMode = CommandEchoModeInvalid;
};
+class DeprecationWarningsOption : public CommandLineOption
+{
+public:
+ QString description(CommandType command) const override;
+ QString shortRepresentation() const override { return {}; }
+ QString longRepresentation() const override;
+ DeprecationWarningMode mode() const { return m_mode; }
+
+private:
+ void doParse(const QString &representation, QStringList &input) override;
+
+ DeprecationWarningMode m_mode = defaultDeprecationWarningMode();
+};
+
class SettingsDirOption : public CommandLineOption
{
public:
diff --git a/src/app/qbs/parser/commandlineoptionpool.cpp b/src/app/qbs/parser/commandlineoptionpool.cpp
index 63711f623..3908f262c 100644
--- a/src/app/qbs/parser/commandlineoptionpool.cpp
+++ b/src/app/qbs/parser/commandlineoptionpool.cpp
@@ -134,6 +134,9 @@ CommandLineOption *CommandLineOptionPool::getOption(CommandLineOption::Type type
case CommandLineOption::RunEnvConfigOptionType:
option = new RunEnvConfigOption;
break;
+ case CommandLineOption::DeprecationWarningsOptionType:
+ option = new DeprecationWarningsOption;
+ break;
default:
qFatal("Unknown option type %d", type);
}
@@ -287,4 +290,10 @@ RunEnvConfigOption *CommandLineOptionPool::runEnvConfigOption() const
return static_cast<RunEnvConfigOption *>(getOption(CommandLineOption::RunEnvConfigOptionType));
}
+DeprecationWarningsOption *CommandLineOptionPool::deprecationWarningsOption() const
+{
+ return static_cast<DeprecationWarningsOption *>
+ (getOption(CommandLineOption::DeprecationWarningsOptionType));
+}
+
} // namespace qbs
diff --git a/src/app/qbs/parser/commandlineoptionpool.h b/src/app/qbs/parser/commandlineoptionpool.h
index c7ac263e1..5f3c1d87c 100644
--- a/src/app/qbs/parser/commandlineoptionpool.h
+++ b/src/app/qbs/parser/commandlineoptionpool.h
@@ -79,6 +79,7 @@ public:
WaitLockOption *waitLockOption() const;
DisableFallbackProviderOption *disableFallbackProviderOption() const;
RunEnvConfigOption *runEnvConfigOption() const;
+ DeprecationWarningsOption *deprecationWarningsOption() const;
private:
mutable QHash<CommandLineOption::Type, CommandLineOption *> m_options;
diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp
index 0f70b3fe9..c6134ec80 100644
--- a/src/app/qbs/parser/commandlineparser.cpp
+++ b/src/app/qbs/parser/commandlineparser.cpp
@@ -278,6 +278,11 @@ QString CommandLineParser::settingsDir() const
return d->settingsDir();
}
+DeprecationWarningMode CommandLineParser::deprecationWarningMode() const
+{
+ return d->optionPool.deprecationWarningsOption()->mode();
+}
+
QString CommandLineParser::commandName() const
{
return d->command->representation();
diff --git a/src/app/qbs/parser/commandlineparser.h b/src/app/qbs/parser/commandlineparser.h
index 70586b2d4..999027006 100644
--- a/src/app/qbs/parser/commandlineparser.h
+++ b/src/app/qbs/parser/commandlineparser.h
@@ -41,6 +41,8 @@
#include "commandtype.h"
+#include <tools/deprecationwarningmode.h>
+
#include <QtCore/qstringlist.h>
#include <QtCore/qvariant.h>
@@ -89,6 +91,7 @@ public:
bool showProgress() const;
bool showVersion() const;
QString settingsDir() const;
+ DeprecationWarningMode deprecationWarningMode() const;
private:
class CommandLineParserPrivate;
diff --git a/src/app/qbs/parser/parsercommand.cpp b/src/app/qbs/parser/parsercommand.cpp
index 799bf5dcf..8fa67e241 100644
--- a/src/app/qbs/parser/parsercommand.cpp
+++ b/src/app/qbs/parser/parsercommand.cpp
@@ -208,6 +208,7 @@ static QList<CommandLineOption::Type> resolveOptions()
CommandLineOption::DryRunOptionType,
CommandLineOption::ForceProbesOptionType,
CommandLineOption::LogTimeOptionType,
+ CommandLineOption::DeprecationWarningsOptionType,
CommandLineOption::DisableFallbackProviderType};
}
diff --git a/src/lib/corelib/CMakeLists.txt b/src/lib/corelib/CMakeLists.txt
index a6efd0ff3..7c358722d 100644
--- a/src/lib/corelib/CMakeLists.txt
+++ b/src/lib/corelib/CMakeLists.txt
@@ -306,6 +306,7 @@ set(TOOLS_SOURCES
cleanoptions.cpp
codelocation.cpp
commandechomode.cpp
+ deprecationwarningmode.cpp
dynamictypecheck.h
error.cpp
executablefinder.cpp
@@ -389,6 +390,7 @@ set(TOOLS_HEADERS
cleanoptions.h
codelocation.h
commandechomode.h
+ deprecationwarningmode.h
error.h
generateoptions.h
installoptions.h
diff --git a/src/lib/corelib/corelib.qbs b/src/lib/corelib/corelib.qbs
index cf3c45cda..91532c14e 100644
--- a/src/lib/corelib/corelib.qbs
+++ b/src/lib/corelib/corelib.qbs
@@ -410,6 +410,7 @@ QbsLibrary {
"cleanoptions.cpp",
"codelocation.cpp",
"commandechomode.cpp",
+ "deprecationwarningmode.cpp",
"dynamictypecheck.h",
"error.cpp",
"executablefinder.cpp",
@@ -495,6 +496,7 @@ QbsLibrary {
"cleanoptions.h",
"codelocation.h",
"commandechomode.h",
+ "deprecationwarningmode.h",
"error.h",
"generateoptions.h",
"installoptions.h",
diff --git a/src/lib/corelib/language/deprecationinfo.h b/src/lib/corelib/language/deprecationinfo.h
index 89cd07f4a..2f9bfc103 100644
--- a/src/lib/corelib/language/deprecationinfo.h
+++ b/src/lib/corelib/language/deprecationinfo.h
@@ -39,6 +39,11 @@
#ifndef QBS_DEPRECATIONINFO_H
#define QBS_DEPRECATIONINFO_H
+#include <api/languageinfo.h>
+#include <logging/logger.h>
+#include <logging/translator.h>
+#include <tools/deprecationwarningmode.h>
+#include <tools/error.h>
#include <tools/version.h>
#include <QtCore/qstring.h>
@@ -58,7 +63,46 @@ public:
bool isValid() const { return m_removalVersion.isValid(); }
Version removalVersion() const { return m_removalVersion; }
- QString additionalUserInfo() const { return m_additionalUserInfo; }
+
+ ErrorInfo checkForDeprecation(DeprecationWarningMode mode, const QString &name,
+ const CodeLocation &loc, bool isItem, Logger &logger) const
+ {
+ if (!isValid())
+ return {};
+ const Version qbsVersion = LanguageInfo::qbsVersion();
+ if (removalVersion() <= qbsVersion) {
+ const QString msgTemplate = isItem
+ ? Tr::tr("The item '%1' can no longer be used. It was removed in Qbs %2.")
+ : Tr::tr("The property '%1' can no longer be used. It was removed in Qbs %2.");
+ ErrorInfo error(msgTemplate.arg(name, removalVersion().toString()), loc);
+ if (!m_additionalUserInfo.isEmpty())
+ error.append(m_additionalUserInfo);
+ return error;
+ }
+ const QString msgTemplate = isItem
+ ? Tr::tr("The item '%1' is deprecated and will be removed in Qbs %2.")
+ : Tr::tr("The property '%1' is deprecated and will be removed in Qbs %2.");
+ ErrorInfo error(msgTemplate.arg(name, removalVersion().toString()), loc);
+ if (!m_additionalUserInfo.isEmpty())
+ error.append(m_additionalUserInfo);
+ switch (mode) {
+ case DeprecationWarningMode::Error:
+ return error;
+ case DeprecationWarningMode::On:
+ logger.printWarning(error);
+ break;
+ case DeprecationWarningMode::BeforeRemoval: {
+ const Version next(qbsVersion.majorVersion(), qbsVersion.minorVersion() + 1);
+ if (removalVersion() == next || removalVersion().minorVersion() == 0)
+ logger.printWarning(error);
+ break;
+ }
+ case DeprecationWarningMode::Off:
+ break;
+ }
+
+ return {};
+ }
private:
Version m_removalVersion;
diff --git a/src/lib/corelib/language/item.cpp b/src/lib/corelib/language/item.cpp
index 178a34b00..c58d2058d 100644
--- a/src/lib/corelib/language/item.cpp
+++ b/src/lib/corelib/language/item.cpp
@@ -246,7 +246,7 @@ bool Item::isPresentModule() const
return v && v->type() == Value::JSSourceValueType;
}
-void Item::setupForBuiltinType(Logger &logger)
+void Item::setupForBuiltinType(DeprecationWarningMode deprecationMode, Logger &logger)
{
const BuiltinDeclarations &builtins = BuiltinDeclarations::instance();
const auto properties = builtins.declarationsForType(type()).properties();
@@ -263,23 +263,9 @@ void Item::setupForBuiltinType(Logger &logger)
? StringConstants::undefinedValue()
: pd.initialValueSource());
m_properties.insert(pd.name(), sourceValue);
- } else if (pd.isDeprecated()) {
- const DeprecationInfo &di = pd.deprecationInfo();
- if (di.removalVersion() <= LanguageInfo::qbsVersion()) {
- QString message = Tr::tr("The property '%1' is no longer valid for %2 items. "
- "It was removed in qbs %3.")
- .arg(pd.name(), typeName(), di.removalVersion().toString());
- ErrorInfo error(message, value->location());
- if (!di.additionalUserInfo().isEmpty())
- error.append(di.additionalUserInfo());
- throw error;
- }
- QString warning = Tr::tr("The property '%1' is deprecated and will be removed in "
- "qbs %2.").arg(pd.name(), di.removalVersion().toString());
- ErrorInfo error(warning, value->location());
- if (!di.additionalUserInfo().isEmpty())
- error.append(di.additionalUserInfo());
- logger.printWarning(error);
+ } else if (ErrorInfo error = pd.checkForDeprecation(deprecationMode, value->location(),
+ logger); error.hasError()) {
+ throw error;
}
}
}
diff --git a/src/lib/corelib/language/item.h b/src/lib/corelib/language/item.h
index 22cf6b810..60d74a3f4 100644
--- a/src/lib/corelib/language/item.h
+++ b/src/lib/corelib/language/item.h
@@ -46,6 +46,7 @@
#include "qualifiedid.h"
#include <parser/qmljsmemorypool_p.h>
#include <tools/codelocation.h>
+#include <tools/deprecationwarningmode.h>
#include <tools/error.h>
#include <tools/version.h>
@@ -144,7 +145,7 @@ public:
static void removeChild(Item *parent, Item *child);
void dump() const;
bool isPresentModule() const;
- void setupForBuiltinType(Logger &logger);
+ void setupForBuiltinType(DeprecationWarningMode deprecationMode, Logger &logger);
void copyProperty(const QString &propertyName, Item *target) const;
void overrideProperties(
const QVariantMap &config,
diff --git a/src/lib/corelib/language/itemdeclaration.cpp b/src/lib/corelib/language/itemdeclaration.cpp
index d7230e9d6..eb9fd84a6 100644
--- a/src/lib/corelib/language/itemdeclaration.cpp
+++ b/src/lib/corelib/language/itemdeclaration.cpp
@@ -60,5 +60,11 @@ bool ItemDeclaration::isChildTypeAllowed(ItemType type) const
return m_allowedChildTypes.contains(type);
}
+ErrorInfo ItemDeclaration::checkForDeprecation(DeprecationWarningMode mode, const QString &name,
+ const CodeLocation &loc, Logger &logger) const
+{
+ return deprecationInfo().checkForDeprecation(mode, name, loc, true, logger);
+}
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/language/itemdeclaration.h b/src/lib/corelib/language/itemdeclaration.h
index 6da699d28..1fbd7e456 100644
--- a/src/lib/corelib/language/itemdeclaration.h
+++ b/src/lib/corelib/language/itemdeclaration.h
@@ -71,6 +71,9 @@ public:
const TypeNames &allowedChildTypes() const { return m_allowedChildTypes; }
bool isChildTypeAllowed(ItemType type) const;
+ ErrorInfo checkForDeprecation(DeprecationWarningMode mode, const QString &name,
+ const CodeLocation &loc, Logger &logger) const;
+
private:
ItemType m_type;
Properties m_properties;
diff --git a/src/lib/corelib/language/itemreader.cpp b/src/lib/corelib/language/itemreader.cpp
index 1abc5caf9..a29b36320 100644
--- a/src/lib/corelib/language/itemreader.cpp
+++ b/src/lib/corelib/language/itemreader.cpp
@@ -143,5 +143,10 @@ void ItemReader::setEnableTiming(bool on)
m_elapsedTime = on ? 0 : -1;
}
+void ItemReader::setDeprecationWarningMode(DeprecationWarningMode mode)
+{
+ m_visitorState->setDeprecationWarningMode(mode);
+}
+
} // namespace Internal
} // namespace qbs
diff --git a/src/lib/corelib/language/itemreader.h b/src/lib/corelib/language/itemreader.h
index 3dc5329d2..6b2531cf2 100644
--- a/src/lib/corelib/language/itemreader.h
+++ b/src/lib/corelib/language/itemreader.h
@@ -40,8 +40,8 @@
#ifndef QBS_ITEMREADER_H
#define QBS_ITEMREADER_H
-#include "forward_decls.h"
#include <logging/logger.h>
+#include <tools/deprecationwarningmode.h>
#include <tools/set.h>
#include <QtCore/qstringlist.h>
@@ -87,6 +87,8 @@ public:
void setEnableTiming(bool on);
qint64 elapsedTime() const { return m_elapsedTime; }
+ void setDeprecationWarningMode(DeprecationWarningMode mode);
+
private:
ItemPool *m_pool = nullptr;
QStringList m_searchPaths;
diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp
index f22a1c4e8..721f24079 100644
--- a/src/lib/corelib/language/itemreaderastvisitor.cpp
+++ b/src/lib/corelib/language/itemreaderastvisitor.cpp
@@ -173,7 +173,7 @@ bool ItemReaderASTVisitor::visit(AST::UiObjectDefinition *ast)
// Only the item at the top of the inheritance chain is a built-in item.
// We cannot do this in "part 1", because then the visitor would complain about duplicate
// bindings.
- item->setupForBuiltinType(m_logger);
+ item->setupForBuiltinType(m_visitorState.deprecationWarningMode(), m_logger);
}
return false;
@@ -369,24 +369,10 @@ void ItemReaderASTVisitor::checkDeprecationStatus(ItemType itemType, const QStri
const CodeLocation &itemLocation)
{
const ItemDeclaration itemDecl = BuiltinDeclarations::instance().declarationsForType(itemType);
- const DeprecationInfo &di = itemDecl.deprecationInfo();
- if (!di.isValid())
- return;
- if (di.removalVersion() <= LanguageInfo::qbsVersion()) {
- QString message = Tr::tr("The item '%1' cannot be used anymore. "
- "It was removed in qbs %2.")
- .arg(itemName, di.removalVersion().toString());
- ErrorInfo error(message, itemLocation);
- if (!di.additionalUserInfo().isEmpty())
- error.append(di.additionalUserInfo());
+ const ErrorInfo error = itemDecl.checkForDeprecation(m_visitorState.deprecationWarningMode(),
+ itemName, itemLocation, m_logger);
+ if (error.hasError())
throw error;
- }
- QString warning = Tr::tr("The item '%1' is deprecated and will be removed in "
- "qbs %2.").arg(itemName, di.removalVersion().toString());
- ErrorInfo error(warning, itemLocation);
- if (!di.additionalUserInfo().isEmpty())
- error.append(di.additionalUserInfo());
- m_logger.printWarning(error);
}
void ItemReaderASTVisitor::doCheckItemTypes(const Item *item)
diff --git a/src/lib/corelib/language/itemreadervisitorstate.h b/src/lib/corelib/language/itemreadervisitorstate.h
index 3901be16e..90f88cd5e 100644
--- a/src/lib/corelib/language/itemreadervisitorstate.h
+++ b/src/lib/corelib/language/itemreadervisitorstate.h
@@ -40,6 +40,7 @@
#define QBS_ITEMREADERVISITORSTATE_H
#include <logging/logger.h>
+#include <tools/deprecationwarningmode.h>
#include <tools/set.h>
#include <QtCore/qstringlist.h>
@@ -67,7 +68,11 @@ public:
Item *mostDerivingItem() const;
void setMostDerivingItem(Item *item);
+ void setDeprecationWarningMode(DeprecationWarningMode mode) { m_deprecationWarningMode = mode; }
+ DeprecationWarningMode deprecationWarningMode() const { return m_deprecationWarningMode; }
+
private:
+ DeprecationWarningMode m_deprecationWarningMode = defaultDeprecationWarningMode();
Logger &m_logger;
Set<QString> m_filesRead;
QHash<QString, QStringList> m_directoryEntries;
diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp
index f17a4e200..86553916b 100644
--- a/src/lib/corelib/language/moduleloader.cpp
+++ b/src/lib/corelib/language/moduleloader.cpp
@@ -290,6 +290,7 @@ ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters &parameters)
m_modulePrototypeEnabledInfo.clear();
m_parameterDeclarations.clear();
m_disabledItems.clear();
+ m_reader->setDeprecationWarningMode(parameters.deprecationWarningMode());
m_reader->clearExtraSearchPathsStack();
m_reader->setEnableTiming(parameters.logElapsedTime());
m_moduleProviderLoader->setProjectParameters(m_parameters);
@@ -500,28 +501,10 @@ private:
continue;
const PropertyDeclaration decl = item->propertyDeclaration(it.key());
if (decl.isValid()) {
- if (!decl.isDeprecated())
- continue;
- const DeprecationInfo &di = decl.deprecationInfo();
- QString message;
- bool warningOnly;
- if (decl.isExpired()) {
- message = Tr::tr("The property '%1' can no longer be used. "
- "It was removed in Qbs %2.")
- .arg(decl.name(), di.removalVersion().toString());
- warningOnly = false;
- } else {
- message = Tr::tr("The property '%1' is deprecated and will be removed "
- "in Qbs %2.").arg(decl.name(), di.removalVersion().toString());
- warningOnly = true;
- }
- ErrorInfo error(message, it.value()->location());
- if (!di.additionalUserInfo().isEmpty())
- error.append(di.additionalUserInfo());
- if (warningOnly)
- m_logger.printWarning(error);
- else
- handlePropertyError(error, m_params, m_logger);
+ const ErrorInfo deprecationError = decl.checkForDeprecation(
+ m_params.deprecationWarningMode(), it.value()->location(), m_logger);
+ if (deprecationError.hasError())
+ handlePropertyError(deprecationError, m_params, m_logger);
continue;
}
m_currentName = it.key();
@@ -979,7 +962,7 @@ QList<Item *> ModuleLoader::multiplexProductItem(ProductContext *dummyContext, I
dependsItem->setProperty(StringConstants::profilesProperty(),
VariantValue::create(QStringList()));
dependsItem->setFile(aggregator->file());
- dependsItem->setupForBuiltinType(m_logger);
+ dependsItem->setupForBuiltinType(m_parameters.deprecationWarningMode(), m_logger);
Item::addChild(aggregator, dependsItem);
}
}
@@ -1289,13 +1272,13 @@ void ModuleLoader::prepareProduct(ProjectContext *projectContext, Item *productI
importer->setFile(productItem->file());
importer->setLocation(productItem->location());
importer->setScope(projectContext->scope);
- importer->setupForBuiltinType(m_logger);
+ importer->setupForBuiltinType(m_parameters.deprecationWarningMode(), m_logger);
Item * const dependsItem = Item::create(productItem->pool(), ItemType::Depends);
dependsItem->setProperty(QStringLiteral("name"), VariantValue::create(productContext.name));
dependsItem->setProperty(QStringLiteral("required"), VariantValue::create(false));
dependsItem->setFile(importer->file());
dependsItem->setLocation(importer->location());
- dependsItem->setupForBuiltinType(m_logger);
+ dependsItem->setupForBuiltinType(m_parameters.deprecationWarningMode(), m_logger);
Item::addChild(importer, dependsItem);
Item::addChild(productItem, importer);
prepareProduct(projectContext, importer);
@@ -1973,7 +1956,7 @@ bool ModuleLoader::mergeExportItems(const ProductContext &productContext)
merged->setLocation(exportItems.empty()
? productContext.item->location() : exportItems.back()->location());
Item::addChild(productContext.item, merged);
- merged->setupForBuiltinType(m_logger);
+ merged->setupForBuiltinType(m_parameters.deprecationWarningMode(), m_logger);
pmi.exportItem = merged;
pmi.multiplexId = productContext.multiplexConfigurationId;
productContext.project->topLevelProject->productModules.insert(productContext.name, pmi);
@@ -3501,7 +3484,7 @@ Item *ModuleLoader::wrapInProjectIfNecessary(Item *item)
Item::addChild(prj, item);
prj->setFile(item->file());
prj->setLocation(item->location());
- prj->setupForBuiltinType(m_logger);
+ prj->setupForBuiltinType(m_parameters.deprecationWarningMode(), m_logger);
return prj;
}
diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp
index 4d2d38fc3..208f2c5a6 100644
--- a/src/lib/corelib/language/projectresolver.cpp
+++ b/src/lib/corelib/language/projectresolver.cpp
@@ -490,7 +490,7 @@ void ProjectResolver::resolveProductFully(Item *item, ProjectContext *projectCon
item->property(StringConstants::excludeFilesProperty()));
fakeGroup->setProperty(StringConstants::overrideTagsProperty(),
VariantValue::falseValue());
- fakeGroup->setupForBuiltinType(m_logger);
+ fakeGroup->setupForBuiltinType(m_setupParams.deprecationWarningMode(), m_logger);
subItems.prepend(fakeGroup);
}
diff --git a/src/lib/corelib/language/propertydeclaration.cpp b/src/lib/corelib/language/propertydeclaration.cpp
index 2dbe41afd..05b2a7f55 100644
--- a/src/lib/corelib/language/propertydeclaration.cpp
+++ b/src/lib/corelib/language/propertydeclaration.cpp
@@ -275,6 +275,12 @@ void PropertyDeclaration::setDeprecationInfo(const DeprecationInfo &deprecationI
d->deprecationInfo = deprecationInfo;
}
+ErrorInfo PropertyDeclaration::checkForDeprecation(DeprecationWarningMode mode,
+ const CodeLocation &loc, Logger &logger) const
+{
+ return deprecationInfo().checkForDeprecation(mode, name(), loc, false, logger);
+}
+
// see also: EvaluatorScriptClass::convertToPropertyType()
QVariant PropertyDeclaration::convertToPropertyType(const QVariant &v, Type t,
const QStringList &namePrefix, const QString &key)
diff --git a/src/lib/corelib/language/propertydeclaration.h b/src/lib/corelib/language/propertydeclaration.h
index 137315d14..d1e114296 100644
--- a/src/lib/corelib/language/propertydeclaration.h
+++ b/src/lib/corelib/language/propertydeclaration.h
@@ -40,6 +40,8 @@
#ifndef QBS_PROPERTYDECLARATION_H
#define QBS_PROPERTYDECLARATION_H
+#include <tools/deprecationwarningmode.h>
+
#include <QtCore/qshareddata.h>
#include <QtCore/qstring.h>
@@ -48,9 +50,12 @@ class QVariant;
QT_END_NAMESPACE
namespace qbs {
+class CodeLocation;
+class ErrorInfo;
namespace Internal {
class DeprecationInfo;
class PropertyDeclarationData;
+class Logger;
class PropertyDeclaration
{
@@ -116,6 +121,8 @@ public:
bool isExpired() const;
const DeprecationInfo &deprecationInfo() const;
void setDeprecationInfo(const DeprecationInfo &deprecationInfo);
+ ErrorInfo checkForDeprecation(DeprecationWarningMode mode, const CodeLocation &loc,
+ Logger &logger) const;
static QVariant convertToPropertyType(
const QVariant &v, Type t, const QStringList &namePrefix, const QString &key);
diff --git a/src/lib/corelib/tools/deprecationwarningmode.cpp b/src/lib/corelib/tools/deprecationwarningmode.cpp
new file mode 100644
index 000000000..e140e3e49
--- /dev/null
+++ b/src/lib/corelib/tools/deprecationwarningmode.cpp
@@ -0,0 +1,98 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "deprecationwarningmode.h"
+
+/*!
+ * \enum DeprecationWarningMode
+ * This enum type specifies how \QBS should behave on encountering deprecated items or properties.
+ * \value DeprecationWarningMode::Error Project resolving will stop with an error message.
+ * \value DeprecationWarningMode::On A warning will be printed.
+ * \value DeprecationWarningMode::BeforeRemoval A warning will be printed if and only if this is
+ * the last \QBS version before the removal version. This is the default behavior.
+ * \note If the removal version's minor version number is zero, the behavior is
+ * the same as for ErrorHandlingMode::On.
+ * \value DeprecationWarningMode::Off No warnings will be emitted for deprecated constructs.
+ */
+
+namespace qbs {
+
+DeprecationWarningMode defaultDeprecationWarningMode()
+{
+ return DeprecationWarningMode::BeforeRemoval;
+}
+
+QString deprecationWarningModeName(DeprecationWarningMode mode)
+{
+ switch (mode) {
+ case DeprecationWarningMode::Error:
+ return QStringLiteral("error");
+ case DeprecationWarningMode::On:
+ return QStringLiteral("on");
+ case DeprecationWarningMode::BeforeRemoval:
+ return QStringLiteral("before-removal");
+ case DeprecationWarningMode::Off:
+ return QStringLiteral("off");
+ default:
+ break;
+ }
+ return {};
+}
+
+DeprecationWarningMode deprecationWarningModeFromName(const QString &name)
+{
+ DeprecationWarningMode mode = defaultDeprecationWarningMode();
+ for (int i = 0; i <= int(DeprecationWarningMode::Sentinel); ++i) {
+ if (deprecationWarningModeName(static_cast<DeprecationWarningMode>(i)) == name) {
+ mode = static_cast<DeprecationWarningMode>(i);
+ break;
+ }
+ }
+ return mode;
+}
+
+QStringList allDeprecationWarningModeStrings()
+{
+ QStringList result;
+ for (int i = 0; i <= int(DeprecationWarningMode::Sentinel); ++i)
+ result << deprecationWarningModeName(static_cast<DeprecationWarningMode>(i));
+ return result;
+}
+
+} // namespace qbs
diff --git a/src/lib/corelib/tools/deprecationwarningmode.h b/src/lib/corelib/tools/deprecationwarningmode.h
new file mode 100644
index 000000000..bb2a14155
--- /dev/null
+++ b/src/lib/corelib/tools/deprecationwarningmode.h
@@ -0,0 +1,59 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of Qbs.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QBS_DEPRECATIONWARNINGMODE_H
+#define QBS_DEPRECATIONWARNINGMODE_H
+
+#include "qbs_export.h"
+
+#include <QtCore/qstringlist.h>
+
+namespace qbs {
+
+enum class DeprecationWarningMode { Error, On, BeforeRemoval, Off, Sentinel = Off };
+
+QBS_EXPORT DeprecationWarningMode defaultDeprecationWarningMode();
+QBS_EXPORT QString deprecationWarningModeName(DeprecationWarningMode mode);
+QBS_EXPORT DeprecationWarningMode deprecationWarningModeFromName(const QString &name);
+QBS_EXPORT QStringList allDeprecationWarningModeStrings();
+
+} // namespace qbs
+
+#endif // QBS_DEPRECATIONWARNINGMODE_H
+
diff --git a/src/lib/corelib/tools/setupprojectparameters.cpp b/src/lib/corelib/tools/setupprojectparameters.cpp
index a06ffc4bd..564ebe873 100644
--- a/src/lib/corelib/tools/setupprojectparameters.cpp
+++ b/src/lib/corelib/tools/setupprojectparameters.cpp
@@ -98,6 +98,7 @@ public:
SetupProjectParameters::RestoreBehavior restoreBehavior;
ErrorHandlingMode propertyCheckingMode;
ErrorHandlingMode productErrorMode;
+ DeprecationWarningMode deprecationWarningMode = defaultDeprecationWarningMode();
QProcessEnvironment environment;
};
@@ -125,6 +126,11 @@ template<> ErrorHandlingMode fromJson(const QJsonValue &v)
return ErrorHandlingMode::Strict;
}
+template<> DeprecationWarningMode fromJson(const QJsonValue &v)
+{
+ return deprecationWarningModeFromName(v.toString());
+}
+
template<> SetupProjectParameters::RestoreBehavior fromJson(const QJsonValue &v)
{
const QString value = v.toString();
@@ -154,6 +160,7 @@ SetupProjectParameters SetupProjectParameters::fromJson(const QJsonObject &data)
setValueFromJson(params.d->environment, data, "environment");
setValueFromJson(params.d->restoreBehavior, data, "restore-behavior");
setValueFromJson(params.d->propertyCheckingMode, data, "error-handling-mode");
+ setValueFromJson(params.d->deprecationWarningMode, data, "deprecation-warning-mode");
params.d->productErrorMode = params.d->propertyCheckingMode;
return params;
}
@@ -688,4 +695,20 @@ void SetupProjectParameters::setProductErrorMode(ErrorHandlingMode mode)
d->productErrorMode = mode;
}
+/*!
+ * \brief Indicates how deprecated constructs are handled.
+ */
+DeprecationWarningMode SetupProjectParameters::deprecationWarningMode() const
+{
+ return d->deprecationWarningMode;
+}
+
+/*!
+ * \brief Specifies the behavior on encountering deprecated constructs.
+ */
+void SetupProjectParameters::setDeprecationWarningMode(DeprecationWarningMode mode)
+{
+ d->deprecationWarningMode = mode;
+}
+
} // namespace qbs
diff --git a/src/lib/corelib/tools/setupprojectparameters.h b/src/lib/corelib/tools/setupprojectparameters.h
index 2617a34cd..5c7bf3715 100644
--- a/src/lib/corelib/tools/setupprojectparameters.h
+++ b/src/lib/corelib/tools/setupprojectparameters.h
@@ -41,6 +41,7 @@
#include "qbs_export.h"
+#include <tools/deprecationwarningmode.h>
#include <tools/error.h>
#include <QtCore/qshareddata.h>
@@ -144,6 +145,9 @@ public:
ErrorHandlingMode productErrorMode() const;
void setProductErrorMode(ErrorHandlingMode mode);
+ DeprecationWarningMode deprecationWarningMode() const;
+ void setDeprecationWarningMode(DeprecationWarningMode mode);
+
private:
QSharedDataPointer<Internal::SetupProjectParametersPrivate> d;
};
diff --git a/src/lib/corelib/tools/tools.pri b/src/lib/corelib/tools/tools.pri
index 1fdacc016..835fbbfda 100644
--- a/src/lib/corelib/tools/tools.pri
+++ b/src/lib/corelib/tools/tools.pri
@@ -13,6 +13,7 @@ HEADERS += \
$$PWD/clangclinfo.h \
$$PWD/codelocation.h \
$$PWD/commandechomode.h \
+ $$PWD/deprecationwarningmode.h \
$$PWD/dynamictypecheck.h \
$$PWD/error.h \
$$PWD/executablefinder.h \
@@ -73,6 +74,7 @@ SOURCES += \
$$PWD/clangclinfo.cpp \
$$PWD/codelocation.cpp \
$$PWD/commandechomode.cpp \
+ $$PWD/deprecationwarningmode.cpp \
$$PWD/error.cpp \
$$PWD/executablefinder.cpp \
$$PWD/fileinfo.cpp \
@@ -127,6 +129,7 @@ osx {
$$PWD/cleanoptions.h \
$$PWD/codelocation.h \
$$PWD/commandechomode.h \
+ $$PWD/deprecationwarningmode.h \
$$PWD/error.h \
$$PWD/generateoptions.h \
$$PWD/installoptions.h \
diff --git a/tests/auto/blackbox/CMakeLists.txt b/tests/auto/blackbox/CMakeLists.txt
index 0bf79a433..5b5376064 100644
--- a/tests/auto/blackbox/CMakeLists.txt
+++ b/tests/auto/blackbox/CMakeLists.txt
@@ -1,6 +1,7 @@
add_qbs_test(blackbox
DEFINES
${QBS_UNIT_TESTS_DEFINES}
+ "QBS_VERSION=\"${QBS_VERSION}\""
SOURCES
../shared.h
tst_blackboxbase.cpp
diff --git a/tests/auto/blackbox/blackbox.qbs b/tests/auto/blackbox/blackbox.qbs
index 3f0ff959a..ac6bf750e 100644
--- a/tests/auto/blackbox/blackbox.qbs
+++ b/tests/auto/blackbox/blackbox.qbs
@@ -25,4 +25,5 @@ QbsAutotest {
]
cpp.defines: base.concat(["SRCDIR=" + Utilities.cStringQuote(path)])
.concat(qbsbuildconfig.enableUnitTests ? ["QBS_ENABLE_UNIT_TESTS"] : [])
+ .concat("QBS_VERSION=" + Utilities.cStringQuote(qbsversion.version))
}
diff --git a/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs b/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs
index e3dacffea..e699672a8 100644
--- a/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs
+++ b/tests/auto/blackbox/testdata/deprecated-property/deprecated-property.qbs
@@ -3,6 +3,6 @@ import qbs // FIXME: Don't remove this import because then the test fails!
Product {
Depends { name: "themodule" }
themodule.newProp: true
- themodule.oldProp: false
+ themodule.expiringProp: false
themodule.veryOldProp: false
}
diff --git a/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs b/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs
index cd6b0b70c..58164e918 100644
--- a/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs
+++ b/tests/auto/blackbox/testdata/deprecated-property/modules/themodule/m.qbs
@@ -1,8 +1,8 @@
-import qbs // FIXME: Don't remove this import because then the test fails!
+import qbs.Environment
Module {
property bool newProp
- property bool oldProp
+ property bool expiringProp
property bool forgottenProp
PropertyOptions {
@@ -10,9 +10,9 @@ Module {
description: "Use this, it's good!"
}
PropertyOptions {
- name: "oldProp"
+ name: "expiringProp"
description: "Use newProp instead."
- removalVersion: "99.9"
+ removalVersion: Environment.getEnv("REMOVAL_VERSION")
}
PropertyOptions {
name: "veryOldProp"
diff --git a/tests/auto/blackbox/tst_blackbox.cpp b/tests/auto/blackbox/tst_blackbox.cpp
index 679972d37..8bc905929 100644
--- a/tests/auto/blackbox/tst_blackbox.cpp
+++ b/tests/auto/blackbox/tst_blackbox.cpp
@@ -53,6 +53,7 @@
#include <QtCore/qsettings.h>
#include <QtCore/qtemporarydir.h>
#include <QtCore/qtemporaryfile.h>
+#include <QtCore/qversionnumber.h>
#include <algorithm>
#include <functional>
@@ -1055,22 +1056,68 @@ void TestBlackbox::dependencyScanningLoop()
void TestBlackbox::deprecatedProperty()
{
+ QFETCH(QString, version);
+ QFETCH(QString, mode);
+ QFETCH(bool, expiringWarning);
+ QFETCH(bool, expiringError);
+
QDir::setCurrent(testDataDir + "/deprecated-property");
QbsRunParameters params(QStringList("-q"));
params.expectFailure = true;
+ params.environment.insert("REMOVAL_VERSION", version);
+ if (!mode.isEmpty())
+ params.arguments << "--deprecation-warnings" << mode;
QVERIFY(runQbs(params) != 0);
m_qbsStderr = QDir::fromNativeSeparators(QString::fromLocal8Bit(m_qbsStderr)).toLocal8Bit();
- QVERIFY2(m_qbsStderr.contains("deprecated-property.qbs:6:24 The property 'oldProp' is "
- "deprecated and will be removed in Qbs 99.9.0."), m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.contains("deprecated-property.qbs:7:28 The property 'veryOldProp' can no "
- "longer be used. It was removed in Qbs 1.3.0."), m_qbsStderr.constData());
+ const bool hasExpiringWarning = m_qbsStderr.contains(QByteArray(
+ "deprecated-property.qbs:6:29 The property 'expiringProp' is "
+ "deprecated and will be removed in Qbs ") + version.toLocal8Bit());
+ QVERIFY2(expiringWarning == hasExpiringWarning, m_qbsStderr.constData());
+ const bool hasRemovedOutput = m_qbsStderr.contains(
+ "deprecated-property.qbs:7:28 The property 'veryOldProp' can no "
+ "longer be used. It was removed in Qbs 1.3.0.");
+ QVERIFY2(hasRemovedOutput == !expiringError, m_qbsStderr.constData());
QVERIFY2(m_qbsStderr.contains("Property 'forgottenProp' was scheduled for removal in version "
"1.8.0, but is still present."), m_qbsStderr.constData());
QVERIFY2(m_qbsStderr.contains("themodule/m.qbs:22:5 Removal version for 'forgottenProp' "
"specified here."), m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.count("Use newProp instead.") == 2, m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.count("is deprecated") == 1, m_qbsStderr.constData());
- QVERIFY2(m_qbsStderr.count("was removed") == 1, m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("Use newProp instead.") == 1
+ + int(expiringWarning && !expiringError), m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("is deprecated") == int(expiringWarning), m_qbsStderr.constData());
+ QVERIFY2(m_qbsStderr.count("was removed") == int(!expiringError), m_qbsStderr.constData());
+}
+
+void TestBlackbox::deprecatedProperty_data()
+{
+ QTest::addColumn<QString>("version");
+ QTest::addColumn<QString>("mode");
+ QTest::addColumn<bool>("expiringWarning");
+ QTest::addColumn<bool>("expiringError");
+
+ const auto current = QVersionNumber::fromString(QBS_VERSION);
+ const QString next = QVersionNumber(current.majorVersion(), current.minorVersion() + 1)
+ .toString();
+ const QString nextNext = QVersionNumber(current.majorVersion(), current.minorVersion() + 2)
+ .toString();
+ const QString nextMajor = QVersionNumber(current.majorVersion() + 1).toString();
+
+ QTest::newRow("default/next") << next << QString() << true << false;
+ QTest::newRow("default/nextnext") << nextNext << QString() << false << false;
+ QTest::newRow("default/nextmajor") << nextMajor << QString() << true << false;
+ QTest::newRow("error/next") << next << QString("error") << true << true;
+ QTest::newRow("error/nextnext") << nextNext << QString("error") << true << true;
+ QTest::newRow("error/nextmajor") << nextMajor << QString("error") << true << true;
+ QTest::newRow("on/next") << next << QString("on") << true << false;
+ QTest::newRow("on/nextnext") << nextNext << QString("on") << true << false;
+ QTest::newRow("on/nextmajor") << nextMajor << QString("on") << true << false;
+ QTest::newRow("before-removal/next") << next << QString("before-removal") << true << false;
+ QTest::newRow("before-removal/nextnext") << nextNext << QString("before-removal")
+ << false << false;
+ QTest::newRow("before-removal/nextmajor") << nextMajor << QString("before-removal")
+ << true << false;
+ QTest::newRow("off/next") << next << QString("off") << false << false;
+ QTest::newRow("off/nextnext") << nextNext << QString("off") << false << false;
+ QTest::newRow("off/nextmajor") << nextMajor << QString("off") << false << false;
}
void TestBlackbox::disappearedProfile()
diff --git a/tests/auto/blackbox/tst_blackbox.h b/tests/auto/blackbox/tst_blackbox.h
index dc184989c..285d465fd 100644
--- a/tests/auto/blackbox/tst_blackbox.h
+++ b/tests/auto/blackbox/tst_blackbox.h
@@ -95,6 +95,7 @@ private slots:
void dependenciesProperty();
void dependencyScanningLoop();
void deprecatedProperty();
+ void deprecatedProperty_data();
void disappearedProfile();
void discardUnusedData();
void discardUnusedData_data();