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

Add a Windows CI. #695

Merged
merged 9 commits into from
Aug 31, 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
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,52 @@ on:
- main

jobs:
Windows:
runs-on: windows-2022

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup python 3.10
uses: actions/setup-python@v5
with:
python-version: '3.10'

- name: Install packages
run:
choco install pkgconfiglite ninja

- name: Install python modules
run: pip3 install meson

- name: Setup MSVC compiler
uses: bus1/cabuild/action/msdevshell@v1
with:
architecture: x64

- name: Install dependencies
uses: kiwix/kiwix-build/actions/dl_deps_archive@main
with:
target_platform: win-x86_64-static

- name: Compile
shell: cmd
run: |
set PKG_CONFIG_PATH=%cd%\BUILD_win-amd64\INSTALL\lib\pkgconfig
set CPPFLAGS=-I%cd%\BUILD_win-amd64\INSTALL\include
meson.exe setup . build -Dstatic-linkage=true --buildtype=debug
cd build
ninja.exe

- name: Test
shell: cmd
run: |
cd build
meson.exe test --verbose
env:
WAIT_TIME_FACTOR_TEST: 10

Linux:
strategy:
fail-fast: false
Expand Down
2 changes: 2 additions & 0 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ Maintainer: Kiwix team <[email protected]>
Build-Depends: debhelper-compat (= 13),
libzim-dev (>= 9.0.0), libzim-dev (<< 10.0.0),
libkiwix-dev (>= 13.0.0), libkiwix-dev (<< 14.0.0),
cmake,
libdocopt-dev,
meson,
pkg-config,
Standards-Version: 4.5.0
Expand Down
7 changes: 6 additions & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ compiler = meson.get_compiler('cpp')

add_global_arguments('-DKIWIX_TOOLS_VERSION="@0@"'.format(meson.project_version()), language : 'cpp')

if host_machine.system() == 'windows'
add_project_arguments('-DNOMINMAX', language: 'cpp')
endif

static_linkage = get_option('static-linkage')
if static_linkage
# Static build is not supported on MacOS
Expand All @@ -20,8 +24,9 @@ libzim_dep = dependency('libzim', version:'>=9.0.0', static:static_linkage)
libzim_dep = dependency('libzim', version:'<10.0.0', static:static_linkage)
kiwixlib_dep = dependency('kiwix', version:'>=13.0.0', static:static_linkage)
kiwixlib_dep = dependency('kiwix', version:'<14.0.0', static:static_linkage)
docopt_dep = dependency('docopt', static:static_linkage)
mgautierfr marked this conversation as resolved.
Show resolved Hide resolved

all_deps = [thread_dep, kiwixlib_dep, libzim_dep]
all_deps = [thread_dep, kiwixlib_dep, libzim_dep, docopt_dep]

if static_linkage
librt = compiler.find_library('rt', required:false)
Expand Down
236 changes: 84 additions & 152 deletions src/manager/kiwix-manage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* MA 02110-1301, USA.
*/

#include <getopt.h>
#include <docopt/docopt.h>
#include <kiwix/manager.h>
#include <kiwix/tools.h>
#include <cstdlib>
Expand Down Expand Up @@ -51,57 +51,51 @@ void show(const kiwix::Library& library, const std::string& bookId)
std::cout << std::endl;
}

// Older version of docopt doesn't declare Options. Let's declare it ourself.
using Options = std::map<std::string, docopt::value>;


/* Print correct console usage options */
void usage()
{
std::cout << "Usage:" << std::endl
<< "\tkiwix-manage LIBRARY_PATH add ZIM_PATH [OPTIONS]" << std::endl
<< "\tkiwix-manage LIBRARY_PATH remove ZIM_ID [ZIM_ID]..." << std::endl
<< "\tkiwix-manage LIBRARY_PATH show [ZIM_ID]..." << std::endl
<< std::endl

<< "Purpose:" << std::endl
<< "\tManipulates the Kiwix library XML file"
<< std::endl << std::endl

<< "Arguments:" << std::endl
<< "\tLIBRARY_PATH\tis the XML library file path."
<< std::endl << std::endl
<< "\tACTION\t\tis the pre-defined string to specify the action to run on the XML library file."
<< std::endl << std::endl
<< "\t\t\tMust be one of the following values:" << std::endl
<< "\t\t\t* add: add a ZIM file to the library" << std::endl
<< "\t\t\t* remove: remove a ZIM file from the library" << std::endl
<< "\t\t\t* show: show the content of the library"
<< std::endl << std::endl
<< "\tZIM_ID\t\tZIM file unique ID"
<< std::endl << std::endl
<< "\tOPTIONS\t\tCustom options for \"add\" action:" << std::endl
<< "\t\t\t--zimPathToSave=CUSTOM_ZIM_PATH to replace the current ZIM file path" << std::endl
<< "\t\t\t--url=HTTP_ZIM_URL to create an \"url\" attribute for the online version of the ZIM file" << std::endl
<< std::endl
<< "\t\t\tOther options:" << std::endl
<< "\t\t\t-v, --version to print the software version" << std::endl
<< std::endl

<< "Examples:" << std::endl
<< "\tAdd ZIM files to library: kiwix-manage my_library.xml add first.zim second.zim" << std::endl
<< "\tRemove ZIM files from library: kiwix-manage my_library.xml remove e5c2c003-b49e-2756-5176-5d9c86393dd9" << std::endl
<< "\tShow all library ZIM files: kiwix-manage my_library.xml show" << std::endl
<< std::endl

<< "Documentation:" << std::endl
<< "\tSource code\thttps://github.com/kiwix/kiwix-tools" << std::endl
<< "\tMore info\thttps://wiki.kiwix.org/wiki/Kiwix-manage" << std::endl
<< std::endl;
}
static const char USAGE[] =
R"(Manipulates the Kiwix library XML file

Usage:
kiwix-manage LIBRARYPATH add [--zimPathToSave=<custom_zim_path>] [--url=<http_zim_url>] ZIMPATH
kiwix-manage LIBRARYPATH remove|delete ZIMID ...
kiwix-manage LIBRARYPATH show [ZIMID ...]
kiwix-manage -v | --version
kiwix-manage -h | --help

Arguments:
LIBRARYPATH The XML library file path.
ZIMID ZIM file unique ID.
ZIMPATH A path to a zim to add.

Options:
Custom options for "add" action:
--zimPathToSave=<custom_zim_path> Replace the current ZIM file path
--url=<http_zim_url> Create an "url" attribute for the online version of the ZIM file

Other options:
-h --help Print this help
-v --version Print the software version

Examples:
Add ZIM files to library: kiwix-manage my_library.xml add first.zim second.zim
Remove ZIM files from library: kiwix-manage my_library.xml remove e5c2c003-b49e-2756-5176-5d9c86393dd9
Show all library ZIM files: kiwix-manage my_library.xml show

Documentation:
Source code https://github.com/kiwix/kiwix-tools
More info https://wiki.kiwix.org/wiki/Kiwix-manage
)";

int handle_show(const kiwix::Library& library, const std::string& libraryPath,
int argc, char* argv[])
const Options& options)
{
if (argc > 3 ) {
for(auto i=3; i<argc; i++) {
std::string bookId = argv[i];
if (options.at("ZIMID").isStringList()) {
auto bookIds = options.at("ZIMID").asStringList();
for(auto& bookId: bookIds) {
show(library, bookId);
}
} else {
Expand All @@ -114,95 +108,45 @@ int handle_show(const kiwix::Library& library, const std::string& libraryPath,
}

int handle_add(kiwix::LibraryPtr library, const std::string& libraryPath,
int argc, char* argv[])
const Options& options)
{
string zimPath;
string zimPathToSave = ".";
string zimPathToSave;
string url;
int option_index = 0;
int c = 0;
int resultCode = 0;

if (argc <= 3) {
std::cerr << "Path to zim file to add is missing in the command line" << std::endl;
return (-1);
}

/* Options parsing */
optind = 3;
static struct option long_options[] = {
{"url", required_argument, 0, 'u'},
{"zimPathToSave", required_argument, 0, 'z'},
{0, 0, 0, 0}
};

bool has_option = false;
while (true) {
c = getopt_long(argc, argv, "cz:u:", long_options, &option_index);
if (c == -1)
break;

has_option = true;
switch (c) {
case 'u':
url = optarg;
break;
case 'z':
zimPathToSave = optarg;
break;
}
}
kiwix::Manager manager(library);

if (optind >= argc) {
std::cerr << "Path to zim file to add is missing in the command line" << std::endl;
return (-1);
std::string zimPath = options.at("ZIMPATH").asString();
if (options.at("--zimPathToSave").isString()) {
zimPathToSave = options.at("--zimPathToSave").asString();
} else {
zimPathToSave = zimPath;
}

if (has_option && argc-optind > 1) {
std::cerr << "You cannot give option and several zim files to add" << std::endl;
return (-1);
if (options.at("--url").isString()) {
url = options.at("--url").asString();
}

kiwix::Manager manager(library);

for(auto i=optind; i<argc; i++) {
std::string zimPath = argv[i];
if (!zimPath.empty()) {
auto _zimPathToSave = zimPathToSave == "." ? zimPath : zimPathToSave;
if (manager.addBookFromPathAndGetId(zimPath, _zimPathToSave, url, false).empty()) {
std::cerr << "Cannot add zim " << zimPath << " to the library." << std::endl;
resultCode = 1;
}
} else {
std::cerr << "Invalid zim file path" << std::endl;
resultCode = 1;
}
if (manager.addBookFromPathAndGetId(zimPath, zimPathToSave, url, false).empty()) {
std::cerr << "Cannot add zim " << zimPath << " to the library." << std::endl;
return 1;
}

return(resultCode);
return 0;
}

int handle_remove(kiwix::Library& library, const std::string& libraryPath,
int argc, char* argv[])
const Options& options)
{
std::string bookId;
const unsigned int totalBookCount = library.getBookCount(true, true);
int exitCode = 0;

if (argc <= 3) {
std::cerr << "BookId to remove missing in the command line" << std::endl;
return (-1);
}

if (!totalBookCount) {
std::cerr << "Library is empty, no book to delete."
<< std::endl;
return 1;
}

for (int i = 3; i<argc; i++) {
bookId = argv[i];

auto bookIds = options.at("ZIMID").asStringList();
for (auto& bookId: bookIds) {
if (!library.removeBookById(bookId)) {
std::cerr << "Invalid book id '" << bookId << "'." << std::endl;
exitCode = 1;
Expand All @@ -214,49 +158,37 @@ int handle_remove(kiwix::Library& library, const std::string& libraryPath,

int main(int argc, char** argv)
{
string libraryPath = "";
supportedAction action = NONE;
auto library = kiwix::Library::create();

/* General argument parsing */
static struct option long_options[] = {
{"version", no_argument, 0, 'v'},
{0, 0, 0, 0}
};

int option_index = 0;
int c;
while (true && argc == 2) {
c = getopt_long(argc, argv, "v", long_options, &option_index);
if (c == -1)
break;

switch (c) {
case 'v':
version();
return 0;
}
Options args;
try {
args = docopt::docopt_parse(USAGE, {argv+1, argv+argc}, false, false);
} catch (docopt::DocoptArgumentError const & error ) {
std::cerr << error.what() << std::endl;
std::cerr << USAGE << std::endl;
return -1;
}

/* Action related argument parsing */
if (argc > 2) {
libraryPath = argv[1];
string actionString = argv[2];

if (actionString == "add")
action = ADD;
else if (actionString == "show")
action = SHOW;
else if (actionString == "remove" || actionString == "delete")
action = REMOVE;
if (args["--help"].asBool()) {
std::cout << USAGE << std::endl;
return 0;
}

/* Print usage)) if necessary */
if (libraryPath == "" || action == NONE) {
usage();
return -1;
if (args["--version"].asBool()) {
version();
return 0;
}

std::string libraryPath = args.at("LIBRARYPATH").asString();

if (args.at("add").asBool())
action = ADD;
else if (args.at("show").asBool())
action = SHOW;
else if (args.at("remove").asBool() || args.at("delete").asBool())
action = REMOVE;

/* Try to read the file */
libraryPath = kiwix::isRelativePath(libraryPath)
? kiwix::computeAbsolutePath(kiwix::getCurrentDirectory(), libraryPath)
Expand All @@ -273,13 +205,13 @@ int main(int argc, char** argv)
int exitCode = 0;
switch (action) {
case SHOW:
exitCode = handle_show(*library, libraryPath, argc, argv);
exitCode = handle_show(*library, libraryPath, args);
break;
case ADD:
exitCode = handle_add(library, libraryPath, argc, argv);
exitCode = handle_add(library, libraryPath, args);
break;
case REMOVE:
exitCode = handle_remove(*library, libraryPath, argc, argv);
exitCode = handle_remove(*library, libraryPath, args);
break;
case NONE:
break;
Expand Down
Loading
Loading