Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate package name when loading poac.toml #876

Merged
merged 1 commit into from
Jan 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Cmd/Init.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "Init.hpp"

#include "../Logger.hpp"
#include "../Manifest.hpp"
#include "Global.hpp"
#include "New.hpp"

Expand Down Expand Up @@ -36,7 +37,8 @@ initMain(const std::span<const StringRef> args) {
}

const String packageName = fs::current_path().stem().string();
if (!verifyPackageName(packageName)) {
if (const auto err = validatePackageName(packageName)) {
Logger::error("package names ", err.value(), ": `", packageName, '`');
return EXIT_FAILURE;
}

Expand Down
50 changes: 3 additions & 47 deletions src/Cmd/New.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "../Exception.hpp"
#include "../Git2.hpp"
#include "../Logger.hpp"
#include "../Manifest.hpp"
#include "../Rustify.hpp"
#include "Global.hpp"

Expand Down Expand Up @@ -110,52 +111,6 @@ createTemplateFiles(const bool isBin, const StringRef projectName) {
}
}

bool
verifyPackageName(const StringRef name) noexcept {
// Empty
if (name.empty()) {
Logger::error("missing package name");
return false;
}

// Only one character
if (name.size() == 1) {
Logger::error("only one character in package name: ", name);
return false;
}

// Only lowercase letters, numbers, dashes, and underscores
for (const char& c : name) {
if (!std::islower(c) && !std::isdigit(c) && c != '-' && c != '_') {
Logger::error("invalid character in package name: ", name);
return false;
}
}

// Start with a letter
if (!std::isalpha(name[0])) {
Logger::error("package names must start with a letter: ", name);
return false;
}

// End with a letter or digit
if (!std::isalnum(name[name.size() - 1])) {
Logger::error("package names must end with a letter or digit: ", name);
return false;
}

// Using C++ keywords
const HashSet<StringRef> keywords = {
#include "../Keywords.def"
};
if (keywords.contains(name)) {
Logger::error("package names cannot be a C++ keyword: ", name);
return false;
}

return true;
}

int
newMain(const std::span<const StringRef> args) {
// Parse args
Expand All @@ -180,7 +135,8 @@ newMain(const std::span<const StringRef> args) {
}
}

if (!verifyPackageName(packageName)) {
if (const auto err = validatePackageName(packageName)) {
Logger::error("package names ", err.value(), ": `", packageName, '`');
return EXIT_FAILURE;
}

Expand Down
1 change: 0 additions & 1 deletion src/Cmd/New.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
static inline constexpr StringRef newDesc = "Create a new poac project";

String createPoacToml(StringRef) noexcept;
bool verifyPackageName(StringRef) noexcept;

int newMain(std::span<const StringRef>);
void newHelp() noexcept;
53 changes: 48 additions & 5 deletions src/Manifest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,48 @@ editionToYear(const StringRef edition) {
throw PoacError("invalid edition: ", edition);
}

// Returns an error message if the package name is invalid.
Option<String>
validatePackageName(const StringRef name) noexcept {
// Empty
if (name.empty()) {
return "must not be empty";
}

// Only one character
if (name.size() == 1) {
return "must be more than one character";
}

// Only lowercase letters, numbers, dashes, and underscores
for (const char c : name) {
if (!std::islower(c) && !std::isdigit(c) && c != '-' && c != '_') {
return "must only contain lowercase letters, numbers, dashes, and "
"underscores";
}
}

// Start with a letter
if (!std::isalpha(name[0])) {
return "must start with a letter";
}

// End with a letter or digit
if (!std::isalnum(name[name.size() - 1])) {
return "must end with a letter or digit";
}

// Using C++ keywords
const HashSet<StringRef> keywords = {
#include "Keywords.def"
};
if (keywords.contains(name)) {
return "must not be a C++ keyword";
}

return None;
}

static Package&
parsePackage() {
Manifest& manifest = Manifest::instance();
Expand All @@ -172,12 +214,13 @@ parsePackage() {

const toml::value& data = manifest.data.value();
const auto package = toml::find<Package>(data, "package");
if (package.name.empty()) {
throw PoacError(toml::format_error(
"invalid name", data.at("package.name"), "must not be empty"
));

if (const auto err = validatePackageName(package.name)) {
throw PoacError(
toml::format_error("invalid name", data.at("package.name"), err.value())
);
}
editionToYear(package.edition); // verification
editionToYear(package.edition); // validation

manifest.package = package;
return manifest.package.value();
Expand Down
1 change: 1 addition & 0 deletions src/Manifest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct Profile {
};

const Path& getManifestPath();
Option<String> validatePackageName(StringRef) noexcept;
const String& getPackageName();
u16 editionToYear(StringRef);
const String& getPackageEdition();
Expand Down