/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/*
Copyright 2013-2021 The Libfossil Authors, see LICENSES/BSD-2-Clause.txt
SPDX-License-Identifier: BSD-2-Clause-FreeBSD
SPDX-FileCopyrightText: 2021 The Libfossil Authors
SPDX-ArtifactOfProjectName: Libfossil
SPDX-FileType: Code
Heavily indebted to the Fossil SCM project (https://fossil-scm.org).
*/
/*
This file creates ZIP files from fossil repository content.
*/
#include "fossil-scm/fossil-cli.h" /* Fossil App mini-framework */
static int vbose = 0;
static int fsl_card_F_visitor_progress(fsl_card_F const * fc,
void * state){
++(*((int*)state));
if(vbose>1){
f_out("Adding: %.12s %s\n", fc->uuid, fc->name);
}
return 0;
}
int main(int argc, char const * const * argv ){
int rc = 0;
const char * sym = NULL;
const char * fileName = NULL;
const char * rootDir = NULL;
fsl_cx * f;
fsl_db * db;
bool noRoot = false;
fsl_uuid_str uuid = NULL;
int fileCounter = 0;
bool fQuiet = false;
fcli_cliflag FCliFlags[] = {
FCLI_FLAG_BOOL("q","quiet",&fQuiet,
"Suppress non-error output unless --verbose is used."),
FCLI_FLAG("r","root","dir-name",&rootDir,
"Use the given name for the zip file's top-most "
"directory. The default is based on the project's name "
"and exported version."),
fcli_cliflag_empty_m
};
fcli.cliFlags = FCliFlags;
fcli_help_info FCliHelp = {
"Creates ZIP files from fossil repository checkins.",
"CHECKIN_VERSION OUTPUT_FILE",
NULL
};
fcli.appHelp = &FCliHelp;
rc = fcli_setup(argc, argv);
if(rc) goto end;
noRoot = fcli_flag("no-root",NULL) /* undocumented flag, for testing only.*/;
vbose = fcli_is_verbose();
f = fcli_cx();
db = fsl_needs_repo(f);
if(!db){
rc = FSL_RC_NOT_A_REPO;
goto end;
}
if(!vbose){
vbose = fQuiet ? 0 : 1;
}
if(fcli_has_unused_flags(0)) goto end;
sym = fcli_next_arg(1);
fileName = fcli_next_arg(1);
if(!sym || !*sym || !fileName || !*fileName){
rc = fcli_err_set(FSL_RC_MISUSE,
"Usage: %s [options] CHECKIN_VERSION OUTPUT_FILE"
"\nOr try --help.",
fcli.appName);
goto end;
}
rc = fsl_sym_to_uuid(f, sym, FSL_SATYPE_CHECKIN, &uuid, NULL);
if(rc) goto end;
if(!noRoot && !rootDir){
char * pname;
char * pz;
pz = pname = fsl_config_get_text(f, FSL_CONFDB_REPO,
"project-name", NULL);
if(!pz){
pz = pname = fsl_mprintf("Unnamed Project");
}
/* Translate unusual characters to underscores... */
for( ; *pz; ++pz ){
if('_'!=*pz && '-'!=*pz
&& !fsl_isalnum(*pz)){
*pz = '_';
}
}
pz = fsl_mprintf("%s-%.12s", pname, uuid);
fcli_fax(pz);
rootDir = pz;
fsl_free(pname);
}
if(vbose){
f_out("Extracting repository version %.12s to file %s...\n",
uuid, fileName);
}
rc = fsl_repo_zip_sym_to_filename(f, sym, noRoot ? NULL : rootDir,
fileName,
vbose ? fsl_card_F_visitor_progress : NULL,
&fileCounter);
if(vbose && !rc){
f_out("%d file(s) zipped to %s\n", fileCounter, fileName);
}
end:
fsl_free(uuid);
return fcli_end_of_main(rc);
}