cli: Permet de publier un paquet sur un dépôt

oki publish transmet les données de version, extraites du manifeste et le contenu de la version au format .zip.

Fix #23
This commit is contained in:
2022-11-26 11:46:49 +01:00
parent 46955c7312
commit f9889fb1b5
10 changed files with 74 additions and 9 deletions

View File

@@ -0,0 +1,17 @@
#include "PublishAction.h"
#include "../io/Archive.h"
#include "../io/TmpFile.h"
#include "../io/oki.h"
namespace fs = std::filesystem;
namespace cli {
void PublishAction::run(repository::Repository &repository) {
config::Manifest manifest = config::Manifest::fromFile(OKI_MANIFEST_FILE);
io::TmpFile tmp;
io::Compressor compressor{tmp.getFilename()};
compressor.compress(fs::current_path() / "src");
repository.publish(manifest, tmp.getFilename());
}
}

View File

@@ -0,0 +1,9 @@
#pragma once
#include "CliAction.h"
namespace cli {
class PublishAction : public CliAction {
void run(repository::Repository &repository) override;
};
}

View File

@@ -5,6 +5,7 @@
#include "InstallAction.h"
#include "ListAction.h"
#include "PublishAction.h"
#include "ReInstallAction.h"
#include "ShowAction.h"
@@ -19,9 +20,10 @@ namespace cli {
os << "show: Show the informations of the package\n";
os << "install: Install a new package\n";
os << "reinstall: Install all the package of the manifest\n";
os << "publish: Publish a new version of the current package\n";
}
CliAction *parseArguments(int argc, char *argv[]) {
std::unique_ptr<CliAction> parseArguments(int argc, char *argv[]) {
if (argc < 2) {
std::cerr << "See " << argv[0] << " help for all available actions.\n";
exit(0);
@@ -30,23 +32,25 @@ namespace cli {
help(std::cout);
exit(0);
} else if (strcmp("list", argv[1]) == 0) {
return static_cast<CliAction *>(new ListAction{});
return std::make_unique<ListAction>();
} else if (strcmp("install", argv[1]) == 0) {
if (argc < 3) {
invalidUsage(std::cerr);
std::cerr << "Add a package name after install.\n";
exit(1);
}
return static_cast<CliAction *>(new InstallAction{argv[2]});
return std::make_unique<InstallAction>(argv[2]);
} else if (strcmp("show", argv[1]) == 0) {
if (argc < 3) {
invalidUsage(std::cerr);
std::cerr << "Add a package name after show.\n";
exit(1);
}
return static_cast<CliAction *>(new ShowAction{argv[2]});
return std::make_unique<ShowAction>(argv[2]);
} else if (strcmp("reinstall", argv[1]) == 0) {
return static_cast<CliAction *>(new ReInstallAction{});
return std::make_unique<ReInstallAction>();
} else if (strcmp("publish", argv[1]) == 0) {
return std::make_unique<PublishAction>();
} else {
exit(1);
}

View File

@@ -9,5 +9,5 @@ namespace cli {
/**
* Toutes les actions possibles.
*/
CliAction *parseArguments(int argc, char *argv[]);
std::unique_ptr<CliAction> parseArguments(int argc, char *argv[]);
}

View File

@@ -4,6 +4,7 @@
namespace fs = std::filesystem;
constexpr static std::string_view PACKAGE_SECTION_NAME = "package";
constexpr static std::string_view DEPENDENCY_SECTION_NAME = "dependencies";
namespace config {
@@ -48,6 +49,25 @@ namespace config {
os << *this;
}
std::string Manifest::asFilteredJson() const {
std::stringstream stream;
toml::table filtered;
const toml::node *package = table.get(PACKAGE_SECTION_NAME);
if (package != nullptr) {
package->visit([&](const toml::table &t) {
filtered.insert(t.cbegin(), t.cend());
});
}
const toml::node *dependencies = table.get(DEPENDENCY_SECTION_NAME);
if (dependencies != nullptr) {
dependencies->visit([&](const toml::table &t) {
filtered.insert(DEPENDENCY_SECTION_NAME, t);
});
}
stream << toml::json_formatter{filtered};
return stream.str();
}
std::ostream &operator<<(std::ostream &os, const Manifest &manifest) {
os << manifest.table;
return os;

View File

@@ -50,6 +50,13 @@ namespace config {
*/
void saveFile(std::filesystem::path fileName);
/**
* Sérialise les données du manifeste au format JSON.
*
* @return Les données publiques de version au format JSON.
*/
std::string asFilteredJson() const;
friend std::ostream &operator<<(std::ostream &, const Manifest &);
};
std::ostream &operator<<(std::ostream &os, const Manifest &manifest);

View File

@@ -1,5 +1,4 @@
#include <iostream>
#include <string>
#include "cli/options.h"
#include "io/HttpRequest.h"
@@ -8,13 +7,12 @@
namespace fs = std::filesystem;
int main(int argc, char *argv[]) {
cli::CliAction *action = cli::parseArguments(argc, argv);
std::unique_ptr<cli::CliAction> action = cli::parseArguments(argc, argv);
repository::RemoteRepository repository{"http://localhost:8000"};
try {
action->run(repository);
} catch (const io::APIException &e) {
std::cerr << e.what() << "\n";
}
delete action;
return 0;
}

View File

@@ -70,4 +70,11 @@ namespace repository {
return data.get<std::string>();
}
void RemoteRepository::publish(config::Manifest &manifest, const std::filesystem::path &source) {
io::HttpRequest request = createRequest(apiUrl + "/api/publish");
io::MimePart mime = request.addMime();
mime.addDataPart("manifest", manifest.asFilteredJson());
mime.addFilePart("package", source);
json data = tryReadRequest(request);
}
}

View File

@@ -13,5 +13,6 @@ namespace repository {
package::Package getPackageInfo(std::string_view packageName) override;
std::string getPackageURL(std::string_view packageName, std::string packageVersion) override;
void download(const package::PackageVersion &packageVersion, const std::filesystem::path &destination) override;
void publish(config::Manifest &manifest, const std::filesystem::path &source) override;
};
}

View File

@@ -5,6 +5,7 @@
#include <string_view>
#include <vector>
#include "../config/Manifest.h"
#include "../package/Package.h"
namespace repository {
@@ -29,6 +30,7 @@ namespace repository {
virtual package::Package getPackageInfo(std::string_view packageName) = 0;
virtual std::string getPackageURL(std::string_view packageName, std::string packageVersion) = 0;
virtual void download(const package::PackageVersion &packageVersion, const std::filesystem::path &destination) = 0;
virtual void publish(config::Manifest &manifest, const std::filesystem::path &source) = 0;
virtual ~Repository() = default;
};
}