tom added force option to make commands

Allow to overwrite already existing migration, model, seeder.
This commit is contained in:
silverqx
2022-07-10 10:40:48 +02:00
parent a0b743f234
commit 1f843372d3
18 changed files with 251 additions and 225 deletions

View File

@@ -266,6 +266,7 @@ function(tinytom_sources out_headers out_sources)
commands/integratecommand.hpp
commands/listcommand.hpp
commands/make/concerns/prepareoptionvalues.hpp
commands/make/makecommand.hpp
commands/make/migrationcommand.hpp
commands/make/modelcommand.hpp
commands/make/modelcommandconcepts.hpp
@@ -334,6 +335,7 @@ function(tinytom_sources out_headers out_sources)
commands/integratecommand.cpp
commands/listcommand.cpp
commands/make/concerns/prepareoptionvalues.cpp
commands/make/makecommand.cpp
commands/make/migrationcommand.cpp
commands/make/modelcommand.cpp
# commands/make/projectcommand.cpp

View File

@@ -19,6 +19,7 @@ headersList += \
$$PWD/tom/commands/integratecommand.hpp \
$$PWD/tom/commands/listcommand.hpp \
$$PWD/tom/commands/make/concerns/prepareoptionvalues.hpp \
$$PWD/tom/commands/make/makecommand.hpp \
$$PWD/tom/commands/make/migrationcommand.hpp \
$$PWD/tom/commands/make/modelcommand.hpp \
$$PWD/tom/commands/make/modelcommandconcepts.hpp \

View File

@@ -0,0 +1,56 @@
#pragma once
#ifndef TOM_COMMANDS_MAKE_MAKECOMMAND_HPP
#define TOM_COMMANDS_MAKE_MAKECOMMAND_HPP
#include <orm/macros/systemheader.hpp>
TINY_SYSTEM_HEADER
#include <filesystem>
#include "tom/commands/command.hpp"
TINYORM_BEGIN_COMMON_NAMESPACE
namespace Tom::Commands::Make
{
/*! Base class for the make-related commands. */
class MakeCommand : public Command
{
Q_DISABLE_COPY(MakeCommand)
/*! Alias for the filesystem path. */
using fspath = std::filesystem::path;
public:
/*! Constructor. */
MakeCommand(Application &application, QCommandLineParser &parser);
/*! Virtual destructor. */
inline ~MakeCommand() override = default;
protected:
/*! Check whether the created file already exists and create folder if needed. */
void prepareFileSystem(
const QString &type, const fspath &folder, const QString &basename,
const QString &className = {}) const;
/*! Throw if the given classname constains a namespace or path. */
static void throwIfContainsNamespaceOrPath(
const QString &type, const QString &className,
const QString &source);
private:
/*! Ensure that a file in the given folder doesn't already exist. */
void throwIfModelAlreadyExists(
const QString &type, const fspath &folder, const QString &basename,
const QString &className) const;
/*! Ensure a directory exists. */
static void ensureDirectoryExists(const fspath &path);
};
} // namespace Tom::Commands::Make
TINYORM_END_COMMON_NAMESPACE
#endif // TOM_COMMANDS_MAKE_MAKECOMMAND_HPP

View File

@@ -5,7 +5,7 @@
#include <orm/macros/systemheader.hpp>
TINY_SYSTEM_HEADER
#include "tom/commands/command.hpp"
#include "tom/commands/make/makecommand.hpp"
#include "tom/commands/make/support/migrationcreator.hpp"
#include "tom/tomconstants.hpp"
@@ -15,7 +15,7 @@ namespace Tom::Commands::Make
{
/*! Create a new migration file. */
class MigrationCommand : public Command
class MigrationCommand : public MakeCommand
{
Q_DISABLE_COPY(MigrationCommand)

View File

@@ -7,8 +7,8 @@ TINY_SYSTEM_HEADER
#include <unordered_set>
#include "tom/commands/command.hpp"
#include "tom/commands/make/concerns/prepareoptionvalues.hpp"
#include "tom/commands/make/makecommand.hpp"
#include "tom/commands/make/modelcommandconcepts.hpp"
#include "tom/commands/make/support/modelcreator.hpp"
#include "tom/tomconstants.hpp"
@@ -28,7 +28,7 @@ namespace Support
} // namespace Support
/*! Create a new model class. */
class ModelCommand : public Command,
class ModelCommand : public MakeCommand,
protected Concerns::PrepareOptionValues
{
Q_DISABLE_COPY(ModelCommand)
@@ -121,13 +121,12 @@ namespace Support
private:
/*! Throw if the model name constains a namespace or path. */
static void throwIfContainsNamespaceOrPath(
const std::vector<QStringList> &classNames, const QString &source);
const std::vector<QStringList> &classNames, const QString &source,
const QString &commandType = QStringLiteral("model"));
/*! Throw if the model name constains a namespace or path. */
static void throwIfContainsNamespaceOrPath(const QStringList &classNames,
const QString &source);
/*! Throw if the model name constains a namespace or path. */
static void throwIfContainsNamespaceOrPath(const QString &className,
const QString &source);
static void throwIfContainsNamespaceOrPath(
const QStringList &classNames, const QString &source,
const QString &commandType = QStringLiteral("model"));
};
/* public */

View File

@@ -5,7 +5,7 @@
#include <orm/macros/systemheader.hpp>
TINY_SYSTEM_HEADER
#include "tom/commands/command.hpp"
#include "tom/commands/make/makecommand.hpp"
#include "tom/commands/make/support/seedercreator.hpp"
#include "tom/tomconstants.hpp"
@@ -15,7 +15,7 @@ namespace Tom::Commands::Make
{
/*! Create a new seeder class. */
class SeederCommand : public Command
class SeederCommand : public MakeCommand
{
Q_DISABLE_COPY(SeederCommand)
@@ -54,10 +54,6 @@ namespace Tom::Commands::Make
/*! The seeder creator instance. */
Support::SeederCreator m_creator {};
private:
/*! Throw if the seeder name constains a namespace or path. */
static void throwIfContainsNamespaceOrPath(const QString &className);
};
/* public */

View File

@@ -50,13 +50,6 @@ namespace Tom::Commands::Make::Support
populateStub(const QString &name, QString &&stub, const QString &table);
/*! Get the class name of a migration name. */
static QString getClassName(const QString &name);
/*! Ensure a directory exists. */
static void ensureDirectoryExists(const fspath &path);
private:
/*! Ensure that a migration with the given name doesn't already exist. */
static void throwIfMigrationAlreadyExists(const QString &name,
const fspath &migrationsPath);
};
} // namespace Tom::Commands::Make::Support

View File

@@ -41,9 +41,6 @@ namespace Tom::Commands::Make::Support
/*! Get the full path to the model. */
static fspath getPath(const QString &basename, const fspath &path);
/*! Ensure a directory exists. */
static void ensureDirectoryExists(const fspath &path);
/*! Populate the place-holders in the model stub. */
std::string populateStub(const QString &className, const CmdOptions &cmdOptions,
bool isSetPreserveOrder);
@@ -192,12 +189,6 @@ namespace Tom::Commands::Make::Support
/*! Cached relations list size to avoid recomputation. */
std::size_t m_relationsListSize = 0;
private:
/*! Ensure that a model with the given name doesn't already exist. */
static void throwIfModelAlreadyExists(
const QString &className, const QString &basename,
const fspath &modelsPath);
};
} // namespace Tom::Commands::Make::Support

View File

@@ -37,21 +37,12 @@ namespace Tom::Commands::Make::Support
/*! Get the full path to the seeder. */
static fspath getPath(const QString &basename, const fspath &path);
/*! Ensure a directory exists. */
static void ensureDirectoryExists(const fspath &path);
/*! Populate the place-holders in the seeder stub. */
static std::string
populateStub(const QString &className, QString &&table);
/*! Get the table name from the seeder class name. */
static QString getTableName(QString className);
private:
/*! Ensure that a seeder with the given name doesn't already exist. */
void throwIfSeederAlreadyExists(
const QString &className, const QString &basename,
const fspath &seedersPath) const;
};
} // namespace Tom::Commands::Make::Support

View File

@@ -14,6 +14,7 @@ sourcesList += \
$$PWD/tom/commands/integratecommand.cpp \
$$PWD/tom/commands/listcommand.cpp \
$$PWD/tom/commands/make/concerns/prepareoptionvalues.cpp \
$$PWD/tom/commands/make/makecommand.cpp \
$$PWD/tom/commands/make/migrationcommand.cpp \
$$PWD/tom/commands/make/modelcommand.cpp \
# $$PWD/tom/commands/make/projectcommand.cpp \

View File

@@ -0,0 +1,100 @@
#include "tom/commands/make/makecommand.hpp"
#include "tom/exceptions/invalidargumenterror.hpp"
#include "tom/tomconstants.hpp"
namespace fs = std::filesystem;
using fspath = std::filesystem::path;
using Tom::Constants::DateTimePrefix;
using Tom::Constants::force;
TINYORM_BEGIN_COMMON_NAMESPACE
namespace Tom::Commands::Make
{
/* public */
MakeCommand::MakeCommand(Application &application, QCommandLineParser &parser)
: Command(application, parser)
{}
/* protected */
void MakeCommand::prepareFileSystem(
const QString &type, const fspath &folder, const QString &basename,
const QString &className) const
{
throwIfModelAlreadyExists(type, folder, basename, className);
ensureDirectoryExists(folder);
}
void MakeCommand::throwIfContainsNamespaceOrPath(
const QString &type, const QString &className, const QString &source)
{
if (!className.contains(QStringLiteral("::")) && !className.contains(QChar('/')) &&
!className.contains(QChar('\\'))
)
return;
throw Exceptions::InvalidArgumentError(
QStringLiteral("Namespace or path is not allowed in the %1 name (%2).")
.arg(type, source));
}
/* private */
void MakeCommand::throwIfModelAlreadyExists(
const QString &type, const fspath &folder, const QString &basename,
const QString &className) const
{
// Nothing to check
if (!fs::exists(folder))
return;
auto itemName = className.isEmpty() ? basename : className;
using options = fs::directory_options;
for (const auto &entry :
fs::directory_iterator(folder, options::skip_permission_denied)
) {
// Check only files
if (!entry.is_regular_file())
continue;
// Extract base filename without the extension
auto entryName = QString::fromStdString(entry.path().stem().string());
// If checking a migration then also remove the datetime prefix
if (type == QStringLiteral("migration"))
entryName = entryName.mid(DateTimePrefix.size() + 1);
if (entryName == basename) {
// Allow overwriting a file using the --force option
if (!isSet(force))
throw Exceptions::InvalidArgumentError(
QStringLiteral("A '%1' %2 already exists.")
.arg(std::move(itemName), type));
comment(QStringLiteral("Overwriting '%1' already existing %2.")
.arg(std::move(itemName), type));
break;
}
}
}
void MakeCommand::ensureDirectoryExists(const fspath &path)
{
if (fs::exists(path) && fs::is_directory(path))
return;
fs::create_directories(path);
}
} // namespace Tom::Commands::Make
TINYORM_END_COMMON_NAMESPACE

View File

@@ -23,6 +23,7 @@ using StringUtils = Orm::Tiny::Utils::String;
using Tom::Constants::create_;
using Tom::Constants::create_up;
using Tom::Constants::force;
using Tom::Constants::fullpath;
using Tom::Constants::path_;
using Tom::Constants::path_up;
@@ -41,7 +42,7 @@ namespace Tom::Commands::Make
/* public */
MigrationCommand::MigrationCommand(Application &application, QCommandLineParser &parser)
: Command(application, parser)
: MakeCommand(application, parser)
{}
const std::vector<PositionalArgument> &MigrationCommand::positionalArguments() const
@@ -56,13 +57,16 @@ const std::vector<PositionalArgument> &MigrationCommand::positionalArguments() c
QList<QCommandLineOption> MigrationCommand::optionsSignature() const
{
return {
{create_, QStringLiteral("The table name to be created"), create_up}, // Value
{table_, QStringLiteral("The table name to migrate (update)"), table_up}, // Value
{path_, QStringLiteral("The location where the migration file should be "
"created"), path_up}, // Value
{realpath_, QStringLiteral("Indicate that any provided migration file paths are "
"pre-resolved absolute paths")},
{fullpath, QStringLiteral("Output the full path of the created migration")},
{create_, QStringLiteral("The table name to be created"), create_up}, // Value
{table_, QStringLiteral("The table name to migrate (update)"), table_up}, // Value
{path_, QStringLiteral("The location where the migration file should be "
"created"), path_up}, // Value
{realpath_, QStringLiteral("Indicate that any provided migration file paths "
"are pre-resolved absolute paths")},
{fullpath, QStringLiteral("Output the full path of the created migration")},
{{QChar('f'),
force}, QStringLiteral("Overwrite the migration file if already exists")},
};
}
@@ -76,6 +80,9 @@ int MigrationCommand::run()
auto [datetimePrefix, migrationName, extension] =
prepareMigrationNameClassName(argument(NAME).trimmed());
// Check whether a migration file already exists and create parent folder if needed
prepareFileSystem(QStringLiteral("migration"), getMigrationPath(), migrationName);
auto table = value(table_);
auto createArg = value(create_);
@@ -206,6 +213,11 @@ void MigrationCommand::writeMigration(
fspath MigrationCommand::getMigrationPath() const
{
static fspath cached;
if (!cached.empty())
return cached;
// Default location
if (!isSet(path_))
return application().getMigrationsPath();
@@ -225,7 +237,7 @@ fspath MigrationCommand::getMigrationPath() const
QStringLiteral("Migrations path '%1' exists and it's not a directory.")
.arg(migrationsPath.c_str()));
return migrationsPath;
return cached = migrationsPath;
}
} // namespace Tom::Commands::Make

View File

@@ -41,6 +41,7 @@ using Tom::Constants::disable_incrementing;
using Tom::Constants::disable_timestamps;
using Tom::Constants::fillable;
using Tom::Constants::fillable_up;
using Tom::Constants::force;
using Tom::Constants::foreign_key;
using Tom::Constants::foreign_key_up;
using Tom::Constants::fullpath;
@@ -84,7 +85,7 @@ namespace Tom::Commands::Make
/* public */
ModelCommand::ModelCommand(Application &application, QCommandLineParser &parser)
: Command(application, parser)
: MakeCommand(application, parser)
{}
const std::vector<PositionalArgument> &ModelCommand::positionalArguments() const
@@ -186,6 +187,9 @@ QList<QCommandLineOption> ModelCommand::optionsSignature() const
"paths are pre-resolved absolute paths")},
{fullpath, QStringLiteral("Output the full path of the created "
"model")},
{{QChar('f'),
force}, QStringLiteral("Overwrite the model class if already "
"exists")},
};
}
@@ -227,6 +231,7 @@ int ModelCommand::run()
const auto [className, cmdOptions] = prepareModelClassNames(argument(NAME),
createCmdOptions());
// Unused warnings
showUnusedOptionsWarnings(cmdOptions);
if (!m_unusedBtmOptions.empty() || m_shownUnusedForeignKey ||
@@ -234,6 +239,10 @@ int ModelCommand::run()
)
newLine();
// Check whether a model file already exists and create parent folder if needed
prepareFileSystem(QStringLiteral("model"), getModelPath(), className.toLower(),
className);
// Ready to write the model to the disk 🧨✨
writeModel(className, cmdOptions);
@@ -275,7 +284,8 @@ ModelCommand::prepareModelClassNames(QString &&className, CmdOptions &&cmdOption
] = cmdOptions;
// Validate the model class names
throwIfContainsNamespaceOrPath(className, QStringLiteral("argument 'name'"));
MakeCommand::throwIfContainsNamespaceOrPath(QStringLiteral("model"), className,
QStringLiteral("argument 'name'"));
throwIfContainsNamespaceOrPath(oneToOneList,
QStringLiteral("option --one-to-one"));
throwIfContainsNamespaceOrPath(oneToManyList,
@@ -285,9 +295,11 @@ ModelCommand::prepareModelClassNames(QString &&className, CmdOptions &&cmdOption
throwIfContainsNamespaceOrPath(belongsToManyList,
QStringLiteral("option --belongs-to-many"));
throwIfContainsNamespaceOrPath(pivotClasses,
QStringLiteral("option --pivot"));
QStringLiteral("option --pivot"),
QStringLiteral("pivot model"));
throwIfContainsNamespaceOrPath(pivotInverseClasses,
QStringLiteral("option --pivot-inverse"));
QStringLiteral("option --pivot-inverse"),
QStringLiteral("pivot model"));
oneToOneList = StringUtils::studly(std::move(oneToOneList));
oneToManyList = StringUtils::studly(std::move(oneToManyList));
@@ -484,6 +496,11 @@ RelationsOrder ModelCommand::relationsOrder()
fspath ModelCommand::getModelPath() const
{
static fspath cached;
if (!cached.empty())
return cached;
// Default location
if (!isSet(path_))
return application().getModelsPath();
@@ -503,7 +520,7 @@ fspath ModelCommand::getModelPath() const
QStringLiteral("Models path '%1' exists and it's not a directory.")
.arg(modelsPath.c_str()));
return modelsPath;
return cached = modelsPath;
}
const std::unordered_set<QString> &ModelCommand::relationNames()
@@ -525,6 +542,7 @@ void ModelCommand::createMigration(const QString &className) const
table.append(QChar('s'));
call(MakeMigration, {longOption(create_, table),
boolCmd(force),
QStringLiteral("create_%1_table").arg(std::move(table))});
}
@@ -534,37 +552,25 @@ void ModelCommand::createSeeder(const QString &className) const
// FUTURE tom, add hidden options support to the tom's parser, add --table option for the make:seeder command and pass singular table name for pivot models because currently the make:seeder command generates eg. taggeds table name (even if this table name is in the commented code), command to reproduce: tom make:model Tagged --pivot-model --seeder silverqx
call(MakeSeeder, {std::move(seederClassName)});
call(MakeSeeder, {boolCmd(force), std::move(seederClassName)});
}
/* private */
void ModelCommand::throwIfContainsNamespaceOrPath(
const std::vector<QStringList> &classNames, const QString &source)
const std::vector<QStringList> &classNames, const QString &source,
const QString &commandType)
{
for (const auto &classNameList : classNames)
throwIfContainsNamespaceOrPath(classNameList, source);
throwIfContainsNamespaceOrPath(classNameList, source, commandType);
}
void ModelCommand::throwIfContainsNamespaceOrPath(const QStringList &classNames,
const QString &source)
void ModelCommand::throwIfContainsNamespaceOrPath(
const QStringList &classNames, const QString &source,
const QString &commandType)
{
for (const auto &className : classNames)
throwIfContainsNamespaceOrPath(className, source);
}
void ModelCommand::throwIfContainsNamespaceOrPath(const QString &className,
const QString &source)
{
if (!className.contains(QStringLiteral("::")) && !className.contains(QChar('/')) &&
!className.contains(QChar('\\'))
)
return;
throw Exceptions::InvalidArgumentError(
QStringLiteral("Namespace or path is not allowed in the model "
"names (%1).")
.arg(source));
MakeCommand::throwIfContainsNamespaceOrPath(commandType, className, source);
}
} // namespace Tom::Commands::Make

View File

@@ -15,10 +15,12 @@ using Orm::Constants::NAME;
using StringUtils = Orm::Tiny::Utils::String;
using Tom::Constants::force;
using Tom::Constants::fullpath;
using Tom::Constants::path_;
using Tom::Constants::path_up;
using Tom::Constants::realpath_;
using Tom::Constants::seeder;
TINYORM_BEGIN_COMMON_NAMESPACE
@@ -28,7 +30,7 @@ namespace Tom::Commands::Make
/* public */
SeederCommand::SeederCommand(Application &application, QCommandLineParser &parser)
: Command(application, parser)
: MakeCommand(application, parser)
{}
const std::vector<PositionalArgument> &SeederCommand::positionalArguments() const
@@ -43,11 +45,14 @@ const std::vector<PositionalArgument> &SeederCommand::positionalArguments() cons
QList<QCommandLineOption> SeederCommand::optionsSignature() const
{
return {
{path_, QStringLiteral("The location where the seeder file should be "
"created"), path_up}, // Value
{realpath_, QStringLiteral("Indicate that any provided seeder file paths are "
"pre-resolved absolute paths")},
{fullpath, QStringLiteral("Output the full path of the created seeder")},
{path_, QStringLiteral("The location where the seeder file should be "
"created"), path_up}, // Value
{realpath_, QStringLiteral("Indicate that any provided seeder file paths are "
"pre-resolved absolute paths")},
{fullpath, QStringLiteral("Output the full path of the created seeder")},
{{QChar('f'),
force}, QStringLiteral("Overwrite the seeder class if already exists")},
};
}
@@ -57,6 +62,9 @@ int SeederCommand::run()
const auto className = prepareSeederClassName(argument(NAME));
// Check whether a seeder file already exists and create parent folder if needed
prepareFileSystem(seeder, getSeederPath(), className.toLower(), className);
// Ready to write the seeder to the disk 🧨✨
writeSeeder(className);
@@ -68,7 +76,8 @@ int SeederCommand::run()
QString SeederCommand::prepareSeederClassName(QString &&className)
{
// Validate the seeder name
throwIfContainsNamespaceOrPath(className);
throwIfContainsNamespaceOrPath(QStringLiteral("seeder"), className,
QStringLiteral("argument 'name'"));
static const auto Seeder = QStringLiteral("Seeder");
static const auto Seeder_lc = QStringLiteral("seeder");
@@ -106,6 +115,11 @@ void SeederCommand::writeSeeder(const QString &className) const
fspath SeederCommand::getSeederPath() const
{
static fspath cached;
if (!cached.empty())
return cached;
// Default location
if (!isSet(path_))
return application().getSeedersPath();
@@ -125,18 +139,7 @@ fspath SeederCommand::getSeederPath() const
QStringLiteral("Seeders path '%1' exists and it's not a directory.")
.arg(seedersPath.c_str()));
return seedersPath;
}
void SeederCommand::throwIfContainsNamespaceOrPath(const QString &className)
{
if (!className.contains(QStringLiteral("::")) && !className.contains(QChar('/')) &&
!className.contains(QChar('\\'))
)
return;
throw Exceptions::InvalidArgumentError(
"Namespace or path is not allowed in the seeder name.");
return cached = seedersPath;
}
} // namespace Tom::Commands::Make

View File

@@ -7,11 +7,8 @@
#include <orm/tiny/utils/string.hpp>
#include "tom/commands/make/stubs/migrationstubs.hpp"
#include "tom/exceptions/invalidargumenterror.hpp"
#include "tom/tomconstants.hpp"
namespace fs = std::filesystem;
using fspath = std::filesystem::path;
using StringUtils = Orm::Tiny::Utils::String;
@@ -35,15 +32,11 @@ fspath MigrationCreator::create(
auto migrationPath = getPath(std::move(datetimePrefix), name, std::move(extension),
migrationsPath);
throwIfMigrationAlreadyExists(name, migrationsPath);
/* First we will get the stub file for the migration, which serves as a type
of template for the migration. Once we have those we will populate the
various place-holders, and save the file. */
auto stub = getStub(table, create);
ensureDirectoryExists(migrationsPath);
// Output it as binary stream to force line endings to LF
std::ofstream(migrationPath, std::ios::out | std::ios::binary)
<< populateStub(name, std::move(stub), table);
@@ -112,42 +105,6 @@ QString MigrationCreator::getClassName(const QString &name)
return StringUtils::studly(name);
}
void MigrationCreator::ensureDirectoryExists(const fspath &path)
{
if (fs::exists(path) && fs::is_directory(path))
return;
fs::create_directories(path);
}
/* private */
void MigrationCreator::throwIfMigrationAlreadyExists(const QString &name,
const fspath &migrationsPath)
{
// Nothing to check
if (!fs::exists(migrationsPath))
return;
using options = fs::directory_options;
for (const auto &entry :
fs::directory_iterator(migrationsPath, options::skip_permission_denied)
) {
// Check only files
if (!entry.is_regular_file())
continue;
// Extract migration name without datetime prefix and extension
auto entryName = QString::fromStdString(entry.path().stem().string())
.mid(DateTimePrefix.size() + 1);
if (entryName == name)
throw Exceptions::InvalidArgumentError(
QStringLiteral("A '%1' migration already exists.").arg(name));
}
}
} // namespace Tom::Commands::Make::Support
TINYORM_END_COMMON_NAMESPACE

View File

@@ -17,9 +17,6 @@
#include "tom/commands/make/modelcommandconcepts.hpp"
#include "tom/commands/make/stubs/modelstubs.hpp"
#include "tom/exceptions/invalidargumenterror.hpp"
namespace fs = std::filesystem;
using fspath = std::filesystem::path;
@@ -74,10 +71,6 @@ fspath ModelCreator::create(const QString &className, const CmdOptions &cmdOptio
auto modelPath = getPath(basename, modelsPath);
throwIfModelAlreadyExists(className, basename, modelsPath);
ensureDirectoryExists(modelsPath);
// Output it as binary stream to force line endings to LF
std::ofstream(modelPath, std::ios::out | std::ios::binary)
<< populateStub(className, cmdOptions, isSetPreserveOrder);
@@ -92,14 +85,6 @@ fspath ModelCreator::getPath(const QString &basename, const fspath &path)
return path / (basename.toStdString() + ".hpp");
}
void ModelCreator::ensureDirectoryExists(const fspath &path)
{
if (fs::exists(path) && fs::is_directory(path))
return;
fs::create_directories(path);
}
std::string ModelCreator::populateStub(
const QString &className, const CmdOptions &cmdOptions,
const bool isSetPreserveOrder)
@@ -1062,33 +1047,6 @@ QString ModelCreator::joinRelationsList(RelationsWithOrder &&relationsList)
return relationsQList.join(NEWLINE);
}
/* private */
void ModelCreator::throwIfModelAlreadyExists(
const QString &className, const QString &basename, const fspath &modelsPath)
{
// Nothing to check
if (!fs::exists(modelsPath))
return;
using options = fs::directory_options;
for (const auto &entry :
fs::directory_iterator(modelsPath, options::skip_permission_denied)
) {
// Check only files
if (!entry.is_regular_file())
continue;
// Extract base filename without the extension
auto entryName = QString::fromStdString(entry.path().stem().string());
if (entryName == basename)
throw Exceptions::InvalidArgumentError(
QStringLiteral("A '%1' model already exists.").arg(className));
}
}
} // namespace Tom::Commands::Make::Support
TINYORM_END_COMMON_NAMESPACE

View File

@@ -5,9 +5,6 @@
#include <orm/tiny/utils/string.hpp>
#include "tom/commands/make/stubs/seederstubs.hpp"
#include "tom/exceptions/invalidargumenterror.hpp"
namespace fs = std::filesystem;
using fspath = std::filesystem::path;
@@ -28,10 +25,6 @@ fspath SeederCreator::create(const QString &className, fspath &&seedersPath) con
auto seederPath = getPath(basename, seedersPath);
throwIfSeederAlreadyExists(className, basename, seedersPath);
ensureDirectoryExists(seedersPath);
/* Populate the various place-holders, and save the file.
Output it as binary stream to force line endings to LF. */
std::ofstream(seederPath, std::ios::out | std::ios::binary)
@@ -47,14 +40,6 @@ fspath SeederCreator::getPath(const QString &basename, const fspath &path)
return path / (basename.toStdString() + ".hpp");
}
void SeederCreator::ensureDirectoryExists(const fspath &path)
{
if (fs::exists(path) && fs::is_directory(path))
return;
fs::create_directories(path);
}
std::string
SeederCreator::populateStub(const QString &className, QString &&table)
{
@@ -87,34 +72,6 @@ QString SeederCreator::getTableName(QString className)
return StringUtils::snake(className);
}
/* private */
void SeederCreator::throwIfSeederAlreadyExists(
const QString &className, const QString &basename,
const fspath &seedersPath) const
{
// Nothing to check
if (!fs::exists(seedersPath))
return;
using options = fs::directory_options;
for (const auto &entry :
fs::directory_iterator(seedersPath, options::skip_permission_denied)
) {
// Check only files
if (!entry.is_regular_file())
continue;
// Extract base filename without the extension
auto entryName = QString::fromStdString(entry.path().stem().string());
if (entryName == basename)
throw Exceptions::InvalidArgumentError(
QStringLiteral("A '%1' seeder already exists.").arg(className));
}
}
} // namespace Tom::Commands::Make::Support
TINYORM_END_COMMON_NAMESPACE

View File

@@ -187,7 +187,8 @@ _tom() {
'--table=[The table to migrate]:table name' \
'--path=[The location where the migration file should be created]:folder path:_files -/' \
'--realpath[Indicate any provided migration file paths are pre-resolved absolute paths]' \
'--fullpath[Output the full path of the migration]'
'--fullpath[Output the full path of the migration]' \
'(-f --force)'{-f,--force}'[Overwrite the model class if already exists]'
;;
make:model)
@@ -220,7 +221,8 @@ _tom() {
'(-o --preserve-order)'{-o,--preserve-order}'[Preserve relations order defined on the command-line]' \
'--path=[The location where the migration file should be created]:folder path:_files -/' \
'--realpath[Indicate any provided migration file paths are pre-resolved absolute paths]' \
'--fullpath[Output the full path of the migration]'
'--fullpath[Output the full path of the migration]' \
'(-f --force)'{-f,--force}'[Overwrite the migration file if already exists]'
;;
make:seeder)
@@ -229,7 +231,8 @@ _tom() {
'1::class name:()' \
'--path=[The location where the migration file should be created]:folder path:_files -/' \
'--realpath[Indicate any provided migration file paths are pre-resolved absolute paths]' \
'--fullpath[Output the full path of the migration]'
'--fullpath[Output the full path of the migration]' \
'(-f --force)'{-f,--force}'[Overwrite the seeder class if already exists]'
;;
migrate:fresh)