Merge branch 'fix-pckq' into calamares
This commit is contained in:
commit
42bc197f67
@ -95,15 +95,24 @@ Config::introductionPackage() const
|
|||||||
return *defaultIntroduction;
|
return *defaultIntroduction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline QString
|
||||||
|
make_gs_key( const Calamares::ModuleSystem::InstanceKey& key )
|
||||||
|
{
|
||||||
|
return QStringLiteral( "packagechooser_" ) + key.id();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::updateGlobalStorage( const QStringList& selected ) const
|
Config::updateGlobalStorage( const QStringList& selected ) const
|
||||||
{
|
{
|
||||||
|
if ( m_packageChoice.has_value() )
|
||||||
|
{
|
||||||
|
cWarning() << "Inconsistent package choices -- both model and single-selection QML";
|
||||||
|
}
|
||||||
if ( m_method == PackageChooserMethod::Legacy )
|
if ( m_method == PackageChooserMethod::Legacy )
|
||||||
{
|
{
|
||||||
//QString value = selected.join( ',' );
|
QString value = selected.join( ',' );
|
||||||
QString value = ( m_pkgc );
|
Calamares::JobQueue::instance()->globalStorage()->insert( make_gs_key( m_defaultId ), value );
|
||||||
Calamares::JobQueue::instance()->globalStorage()->insert( m_id, value );
|
cDebug() << m_defaultId << "selected" << value;
|
||||||
cDebug() << m_id<< "selected" << value;
|
|
||||||
}
|
}
|
||||||
else if ( m_method == PackageChooserMethod::Packages )
|
else if ( m_method == PackageChooserMethod::Packages )
|
||||||
{
|
{
|
||||||
@ -119,16 +128,53 @@ Config::updateGlobalStorage( const QStringList& selected ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Config::setPkgc( const QString& pkgc )
|
Config::updateGlobalStorage() const
|
||||||
{
|
{
|
||||||
m_pkgc = pkgc;
|
if ( m_model->packageCount() > 0 )
|
||||||
emit pkgcChanged( m_pkgc );
|
{
|
||||||
|
cWarning() << "Inconsistent package choices -- both model and single-selection QML";
|
||||||
|
}
|
||||||
|
if ( m_method == PackageChooserMethod::Legacy )
|
||||||
|
{
|
||||||
|
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
if ( m_packageChoice.has_value() )
|
||||||
|
{
|
||||||
|
gs->insert( make_gs_key( m_defaultId ), m_packageChoice.value() );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gs->remove( make_gs_key( m_defaultId ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ( m_method == PackageChooserMethod::Packages )
|
||||||
|
{
|
||||||
|
cWarning() << "Unsupported single-selection packagechooser method 'Packages'";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Unknown packagechooser method" << smash( m_method );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setPackageChoice( const QString& packageChoice )
|
||||||
|
{
|
||||||
|
if ( packageChoice.isEmpty() )
|
||||||
|
{
|
||||||
|
m_packageChoice.reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_packageChoice = packageChoice;
|
||||||
|
}
|
||||||
|
emit packageChoiceChanged( m_packageChoice.value_or( QString() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
Config::prettyStatus() const
|
Config::prettyStatus() const
|
||||||
{
|
{
|
||||||
return tr( "Install option: <strong>%1</strong>" ).arg( m_pkgc );
|
return tr( "Install option: <strong>%1</strong>" ).arg( m_packageChoice.value_or( tr( "None" ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -197,36 +243,15 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
PackageChooserMode::Required );
|
PackageChooserMode::Required );
|
||||||
m_method = PackageChooserMethodNames().find( CalamaresUtils::getString( configurationMap, "method" ),
|
m_method = PackageChooserMethodNames().find( CalamaresUtils::getString( configurationMap, "method" ),
|
||||||
PackageChooserMethod::Legacy );
|
PackageChooserMethod::Legacy );
|
||||||
m_pkgc = CalamaresUtils::getString( configurationMap, "pkgc" );
|
|
||||||
|
|
||||||
if ( m_method == PackageChooserMethod::Legacy )
|
if ( m_method == PackageChooserMethod::Legacy )
|
||||||
{
|
{
|
||||||
const QString configId = CalamaresUtils::getString( configurationMap, "id" );
|
cDebug() << "Using module ID" << m_defaultId;
|
||||||
const QString base = QStringLiteral( "packagechooser_" );
|
|
||||||
if ( configId.isEmpty() )
|
|
||||||
{
|
|
||||||
if ( m_defaultId.id().isEmpty() )
|
|
||||||
{
|
|
||||||
// We got nothing to work with
|
|
||||||
m_id = base;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_id = base + m_defaultId.id();
|
|
||||||
}
|
|
||||||
cDebug() << "Using default ID" << m_id << "from" << m_defaultId.toString();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_id = base + configId;
|
|
||||||
cDebug() << "Using configured ID" << m_id;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( configurationMap.contains( "items" ) )
|
if ( configurationMap.contains( "items" ) )
|
||||||
{
|
{
|
||||||
fillModel( m_model, configurationMap.value( "items" ).toList() );
|
fillModel( m_model, configurationMap.value( "items" ).toList() );
|
||||||
}
|
|
||||||
|
|
||||||
QString default_item_id = CalamaresUtils::getString( configurationMap, "default" );
|
QString default_item_id = CalamaresUtils::getString( configurationMap, "default" );
|
||||||
if ( !default_item_id.isEmpty() )
|
if ( !default_item_id.isEmpty() )
|
||||||
@ -243,4 +268,13 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setPackageChoice( CalamaresUtils::getString( configurationMap, "packageChoice" ) );
|
||||||
|
if ( m_method != PackageChooserMethod::Legacy )
|
||||||
|
{
|
||||||
|
cWarning() << "Single-selection QML module must use 'Legacy' method.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "modulesystem/InstanceKey.h"
|
#include "modulesystem/InstanceKey.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
enum class PackageChooserMode
|
enum class PackageChooserMode
|
||||||
{
|
{
|
||||||
@ -40,7 +41,16 @@ class Config : public Calamares::ModuleSystem::Config
|
|||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
Q_PROPERTY( QString pkgc READ pkgc WRITE setPkgc NOTIFY pkgcChanged )
|
/** @brief This is the single-select package-choice
|
||||||
|
*
|
||||||
|
* For (QML) modules that support only a single selection and
|
||||||
|
* just want to do things in a straightforward pick-this-one
|
||||||
|
* way, the packageChoice property is a (the) way to go.
|
||||||
|
*
|
||||||
|
* Writing to this property means that any other form of package-
|
||||||
|
* choice or selection is ignored.
|
||||||
|
*/
|
||||||
|
Q_PROPERTY( QString packageChoice READ packageChoice WRITE setPackageChoice NOTIFY packageChoiceChanged )
|
||||||
Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL )
|
Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL )
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -75,16 +85,21 @@ public:
|
|||||||
* (and only) the packages in @p selected as selected.
|
* (and only) the packages in @p selected as selected.
|
||||||
*/
|
*/
|
||||||
void updateGlobalStorage( const QStringList& selected ) const;
|
void updateGlobalStorage( const QStringList& selected ) const;
|
||||||
/// As updateGlobalStorage() with an empty selection list
|
/** @brief Write selection to global storage
|
||||||
void fillGSSecondaryConfiguration() const { updateGlobalStorage( QStringList() ); }
|
*
|
||||||
|
* Updates the GS keys for this packagechooser, marking **only**
|
||||||
|
* the package choice as selected. This assumes that the single-
|
||||||
|
* selection QML code is in use.
|
||||||
|
*/
|
||||||
|
void updateGlobalStorage() const;
|
||||||
|
|
||||||
QString pkgc() const { return m_pkgc; }
|
QString packageChoice() const { return m_packageChoice.value_or( QString() ); }
|
||||||
void setPkgc( const QString& pkgc );
|
void setPackageChoice( const QString& packageChoice );
|
||||||
|
|
||||||
QString prettyStatus() const;
|
QString prettyStatus() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void pkgcChanged( QString pkgc );
|
void packageChoiceChanged( QString packageChoice );
|
||||||
void prettyStatusChanged();
|
void prettyStatusChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -95,12 +110,14 @@ private:
|
|||||||
PackageChooserMode m_mode = PackageChooserMode::Optional;
|
PackageChooserMode m_mode = PackageChooserMode::Optional;
|
||||||
/// How this module stores to GS
|
/// How this module stores to GS
|
||||||
PackageChooserMethod m_method = PackageChooserMethod::Legacy;
|
PackageChooserMethod m_method = PackageChooserMethod::Legacy;
|
||||||
/// Id (used to identify settings from this module in GS)
|
|
||||||
QString m_id;
|
|
||||||
/// Value to use for id if none is set in the config file
|
/// Value to use for id if none is set in the config file
|
||||||
Calamares::ModuleSystem::InstanceKey m_defaultId;
|
Calamares::ModuleSystem::InstanceKey m_defaultId;
|
||||||
/// QML selection
|
/** @brief QML selection (for single-selection approaches)
|
||||||
QString m_pkgc;
|
*
|
||||||
|
* If there is no value, then there has been no selection.
|
||||||
|
* Reading the property will return an empty QString.
|
||||||
|
*/
|
||||||
|
std::optional< QString > m_packageChoice;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,11 +15,10 @@ mode: required
|
|||||||
#
|
#
|
||||||
# - "legacy" or "custom" or "contextualprocess"
|
# - "legacy" or "custom" or "contextualprocess"
|
||||||
# When set to "legacy", writes a GlobalStorage value for the choice that
|
# When set to "legacy", writes a GlobalStorage value for the choice that
|
||||||
# has been made. The key is *packagechooser_<id>*. Normally, the module's
|
# has been made. The key is *packagechooser_<id>*. The module's
|
||||||
# instance name is used; see the *instances* section of `settings.conf`.
|
# instance name is used; see the *instances* section of `settings.conf`.
|
||||||
# If there is just one packagechooser module, and no special instance is set,
|
# If there is just one packagechooser module, and no special instance is set,
|
||||||
# resulting GS key is probably *packagechooser@packagechooser*.
|
# resulting GS key is probably *packagechooser_packagechooser*.
|
||||||
# You can set *id* to change that, but it is not recommended.
|
|
||||||
#
|
#
|
||||||
# The GS value is a comma-separated list of the IDs of the selected
|
# The GS value is a comma-separated list of the IDs of the selected
|
||||||
# packages, or an empty string if none is selected.
|
# packages, or an empty string if none is selected.
|
||||||
@ -33,15 +32,12 @@ mode: required
|
|||||||
# consumption by the *packages* module (which should appear later
|
# consumption by the *packages* module (which should appear later
|
||||||
# in the `exec` section. These package settings will then be handed
|
# in the `exec` section. These package settings will then be handed
|
||||||
# off to whatever package manager is configured there.
|
# off to whatever package manager is configured there.
|
||||||
# The *id* key is not used.
|
|
||||||
#
|
#
|
||||||
# There is no need to put this module in the `exec` section. There
|
# There is no need to put this module in the `exec` section. There
|
||||||
# are no jobs that this module provides. You should put **other**
|
# are no jobs that this module provides. You should put **other**
|
||||||
# modules, either *contextualprocess* or *packages* or some custom
|
# modules, either *contextualprocess* or *packages* or some custom
|
||||||
# module, in the `exec` section to do the actual work.
|
# module, in the `exec` section to do the actual work.
|
||||||
method: legacy
|
method: legacy
|
||||||
# The *id* key is used only in "legacy" mode
|
|
||||||
# id: ""
|
|
||||||
|
|
||||||
|
|
||||||
# Human-visible strings in this module. These are all optional.
|
# Human-visible strings in this module. These are all optional.
|
||||||
@ -51,13 +47,13 @@ method: legacy
|
|||||||
# Each key can have a [locale] added to it, which is used as
|
# Each key can have a [locale] added to it, which is used as
|
||||||
# the translated string for that locale. For the strings
|
# the translated string for that locale. For the strings
|
||||||
# associated with the "no-selection" item, see *items*, below
|
# associated with the "no-selection" item, see *items*, below
|
||||||
# with the explicit id "".
|
# with the explicit item-*id* "".
|
||||||
#
|
#
|
||||||
labels:
|
labels:
|
||||||
step: "Packages"
|
step: "Packages"
|
||||||
step[nl]: "Pakketten"
|
step[nl]: "Pakketten"
|
||||||
|
|
||||||
# (Optional) 'id' of pre-selected list-view item.
|
# (Optional) item-*id* of pre-selected list-view item.
|
||||||
# Pre-selects one of the items below.
|
# Pre-selects one of the items below.
|
||||||
# default: kde
|
# default: kde
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ PackageChooserQmlViewStep::jobs() const
|
|||||||
void
|
void
|
||||||
PackageChooserQmlViewStep::onLeave()
|
PackageChooserQmlViewStep::onLeave()
|
||||||
{
|
{
|
||||||
m_config->fillGSSecondaryConfiguration();
|
m_config->updateGlobalStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1,25 +1,26 @@
|
|||||||
# SPDX-FileCopyrightText: no
|
# SPDX-FileCopyrightText: no
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
#
|
#
|
||||||
# Configuration for the low-density software chooser
|
# Configuration for the low-density software chooser, QML implementation
|
||||||
---
|
#
|
||||||
# Software selection mode, to set whether the software packages
|
# The example QML implementation uses single-selection, rather than
|
||||||
# can be chosen singly, or multiply.
|
# a model for the available packages. That makes it simpler: the
|
||||||
|
# QML itself codes the available options, descriptions and images
|
||||||
|
# -- after all, this is **low density** selection, so a custom UI
|
||||||
|
# can make sense for the few choices that need to be made.
|
||||||
|
#
|
||||||
#
|
#
|
||||||
# Possible modes are "optional", "required" (for zero-or-one or exactly-one)
|
|
||||||
# or "optionalmultiple", "requiredmultiple" (for zero-or-more
|
|
||||||
# or one-or-more).
|
|
||||||
mode: required
|
|
||||||
|
|
||||||
|
---
|
||||||
# Software installation method:
|
# Software installation method:
|
||||||
#
|
#
|
||||||
# - "legacy" or "custom" or "contextualprocess"
|
# - "legacy" or "custom" or "contextualprocess"
|
||||||
# When set to "legacy", writes a GlobalStorage value for the choice that
|
# When set to "legacy", writes a GlobalStorage value for the choice that
|
||||||
# has been made. The key is *packagechooser_<id>*. Normally, the module's
|
# has been made. The key is *packagechooser_<id>*. The module's
|
||||||
# instance name is used; see the *instances* section of `settings.conf`.
|
# instance name is used; see the *instances* section of `settings.conf`.
|
||||||
# If there is just one packagechooser module, and no special instance is set,
|
# If there is just one packagechooserq module, and no special instance is set,
|
||||||
# resulting GS key is probably *packagechooser@packagechooser*.
|
# resulting GS key is probably *packagechooser_packagechooserq*.
|
||||||
# You can set *id* to change that, but it is not recommended.
|
# (Do note that the prefix of the GS key remains "packagechooser_")
|
||||||
#
|
#
|
||||||
# The GS value is a comma-separated list of the IDs of the selected
|
# The GS value is a comma-separated list of the IDs of the selected
|
||||||
# packages, or an empty string if none is selected.
|
# packages, or an empty string if none is selected.
|
||||||
@ -33,16 +34,20 @@ mode: required
|
|||||||
# consumption by the *packages* module (which should appear later
|
# consumption by the *packages* module (which should appear later
|
||||||
# in the `exec` section. These package settings will then be handed
|
# in the `exec` section. These package settings will then be handed
|
||||||
# off to whatever package manager is configured there.
|
# off to whatever package manager is configured there.
|
||||||
# The *id* key is not used.
|
|
||||||
#
|
#
|
||||||
# There is no need to put this module in the `exec` section. There
|
# There is no need to put this module in the `exec` section. There
|
||||||
# are no jobs that this module provides. You should put **other**
|
# are no jobs that this module provides. You should put **other**
|
||||||
# modules, either *contextualprocess* or *packages* or some custom
|
# modules, either *contextualprocess* or *packages* or some custom
|
||||||
# module, in the `exec` section to do the actual work.
|
# module, in the `exec` section to do the actual work.
|
||||||
|
#
|
||||||
method: legacy
|
method: legacy
|
||||||
# The *id* key is used only in "legacy" mode
|
|
||||||
# id: ""
|
|
||||||
|
|
||||||
# The *pkgc* is used for setting the default selection in the QML view
|
# The *packageChoice* value is used for setting the default selection
|
||||||
pkgc: libreoffice
|
# in the QML view; this should match one of the keys used in the QML
|
||||||
|
# module for package names.
|
||||||
|
#
|
||||||
|
# (e.g. the sample QML uses "no_office_suite", "minimal_install" and
|
||||||
|
# "libreoffice" as possible choices).
|
||||||
|
#
|
||||||
|
packageChoice: libreoffice
|
||||||
|
|
||||||
|
@ -80,12 +80,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if ( ! checked ) {
|
if ( checked ) {
|
||||||
print("L not used")
|
config.packageChoice = "libreoffice"
|
||||||
}
|
|
||||||
else {
|
|
||||||
config.pkgc = "libreoffice"
|
|
||||||
print( config.pkgc )
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,13 +142,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if ( ! checked ) {
|
if ( checked ) {
|
||||||
print("not used")
|
config.packageChoice = "no_office_suite"
|
||||||
//console.log("removed")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
print("No Office Suite")
|
|
||||||
config.pkgc = "no_office_suite"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,12 +206,8 @@ Item {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onCheckedChanged: {
|
onCheckedChanged: {
|
||||||
if ( ! checked ) {
|
if ( checked ) {
|
||||||
print("M not used")
|
config.packageChoice = "minimal_install"
|
||||||
}
|
|
||||||
else {
|
|
||||||
print("minimal")
|
|
||||||
config.pkgc = "minimal_install"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
|
# === This file is part of Calamares - <https://calamares.io> ===
|
||||||
|
#
|
||||||
|
# SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
#
|
||||||
if( NOT WITH_QML )
|
if( NOT WITH_QML )
|
||||||
calamares_skip_module( "summaryq (QML is not supported in this build)" )
|
calamares_skip_module( "summaryq (QML is not supported in this build)" )
|
||||||
return()
|
return()
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
internetCheckUrl: http://example.com
|
internetCheckUrl: http://example.com
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
# Nothing at all
|
# Nothing at all
|
||||||
---
|
---
|
||||||
bogus: 1
|
bogus: 1
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
# Set to blank
|
# Set to blank
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
# Set to something broken
|
# Set to something broken
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
# Empty list
|
# Empty list
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
# Multiple, all valid
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
internetCheckUrl:
|
internetCheckUrl:
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
|
# Multiple, all valid, in short-list form
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
internetCheckUrl: [ http://example.com, http://bogus.example.com, http://nonexistent.example.com ]
|
internetCheckUrl: [ http://example.com, http://bogus.example.com, http://nonexistent.example.com ]
|
||||||
|
@ -1,3 +1,6 @@
|
|||||||
|
# SPDX-FileCopyrightText: no
|
||||||
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
|
#
|
||||||
# "0" is a valid URL (?) but "" is not
|
# "0" is a valid URL (?) but "" is not
|
||||||
---
|
---
|
||||||
requirements:
|
requirements:
|
||||||
|
Loading…
Reference in New Issue
Block a user