/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* Copyright (c) 2014 D. Richard Hipp This program is free software; you can redistribute it and/or modify it under the terms of the Simplified BSD License (also known as the "2-Clause License" or "FreeBSD License".) This program is distributed in the hope that it will be useful, but without any warranty; without even the implied warranty of merchantability or fitness for a particular purpose. Author contact information: drh@hwaci.com http://www.hwaci.com/drh/ ***************************************************************************** This file creates ZIP files from fossil repository content. */ #include "fossil-scm/fossil-cli.h" /* Fossil App mini-framework */ static void fapp_local_help(){ printf("Usage:\n\t%s [options] CHECKIN_VERSION OUTPUT_FILE\n\n", fcli.appName); puts("Creates ZIP files from Fossil repository checkins. Options:\n"); puts("\t-r|--root=STRING causes all ZIPped files to be packed in " "a directory with that name. By default a root directory name " "is generated from the repo's 'project-name' config option and " "the UUID of version being zipped.\n"); puts("\t-V|--verbose enables informational output. Use twice (or -VV) " "to get even more output (list of files being zipped).\n"); puts("\t-q|--quiet Suppresses all non-error output. Trumped by -V."); } 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 * argv ){ int rc = 0; char * sym = NULL; char * fileName = NULL; char * rootDir = NULL; fsl_cx * f; fsl_db * db; char noRoot; fsl_uuid_str uuid = NULL; int fileCounter = 0; fcli.appHelp = fapp_local_help; rc = fcli_setup(argc, argv); if(FSL_RC_BREAK==rc) /* --help */ return 0; else if(rc) goto end; 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 = fcli_flag2("q", "quiet", NULL) ? 0 : 1; } fcli_flag2("root", "r", &rootDir); noRoot = fcli_flag("no-root",NULL) /* undocumented flag, for testing only.*/; 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_CATYPE_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); /* Translate unusual characters to underscores... */ for( ; *pz; ++pz ){ if('_'!=*pz && '-'!=*pz && !fsl_isalnum(*pz)){ *pz = '_'; } } rootDir = fsl_mprintf("%s-%.12s", pname, uuid); 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(rootDir); fsl_free(sym); fsl_free(fileName); fsl_free(uuid); return fcli_end_of_main(rc); }