/* -*- 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 implements a basic libfossil client which queues new files for addition into a fossil repo. */ #include "fossil-scm/fossil-cli.h" /* Fossil App mini-framework */ #include "fossil-scm/fossil-internal.h" #define MARKER(pfexp) \ do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \ printf pfexp; \ } while(0) static struct App_ { fsl_buffer absPath; fsl_buffer coRelPath; fsl_ckout_manage_opt addOpt; bool quiet; } App = { fsl_buffer_empty_m, fsl_buffer_empty_m, fsl_ckout_manage_opt_empty_m, false/*quiet*/ }; static int fsl_ckout_manage_f_my(const char *zFilename, bool *include, void *state){ *include = true; if(!App.quiet){ f_out("Queuing: %s\n", zFilename); } return 0; } int main(int argc, char const * const * argv ){ int rc = 0; fsl_cx * f = 0; char inTrans = 0; fsl_db * db; bool useIgnoreGlobs = true; fsl_ckout_manage_opt addOpt = fsl_ckout_manage_opt_empty; fcli_cliflag FCliFlags[] = { FCLI_FLAG_BOOL("q","quiet", &App.quiet, "Do not output the list of files added."), FCLI_FLAG_BOOL_INVERT(0,"no-ignore", &useIgnoreGlobs, "Do not check the ignore-globs config " "setting to determine whether to include " "files or not."), fcli_cliflag_empty_m }; fcli_help_info FCliHelp = { "Queues up files to be added at the next commit.", "file1-or-dir [...fileN-or-dir]", NULL }; fcli.cliFlags = FCliFlags; fcli.appHelp = &FCliHelp; rc = fcli_setup(argc, argv); if(rc) goto end; f = fcli_cx(); db = fsl_needs_ckout(f); if(!db) goto end; if(fcli_has_unused_flags(0)) goto end; else if(!fcli_next_arg(false)){ rc = fcli_err_set(FSL_RC_MISUSE,"No file names provided."); goto end; } rc = fsl_db_transaction_begin(db); if(rc){ fsl_cx_uplift_db_error(f, db); goto end; } inTrans = 1; addOpt.relativeToCwd = true; addOpt.checkIgnoreGlobs = useIgnoreGlobs; addOpt.callback = fsl_ckout_manage_f_my; while((addOpt.filename = fcli_next_arg(true))){ rc = fsl_ckout_manage(f, &addOpt); if(rc) goto end; } if(fcli.clientFlags.dryRun && fcli_is_verbose()>1){ f_out("vfile changed, removed, or renamed files:\n"); fsl_db_each( fsl_cx_db_ckout(f), fsl_stmt_each_f_dump, NULL, "SELECT * from vfile " "WHERE (chnged OR deleted " " OR (origname IS NOT NULL AND origname<>pathname)" " )" " ORDER BY pathname"); } f_out("File(s) added: %u\n", addOpt.counts.added); f_out("File(s) updated: %u\n", addOpt.counts.updated); f_out("File(s) skipped: %u\n", addOpt.counts.skipped); if(fcli.clientFlags.dryRun){ f_out("Dry-run mode. Rolling back transaction.\n"); fsl_db_transaction_rollback(db); }else{ rc = fsl_db_transaction_end(db, 0); } inTrans = 0; end: fsl_buffer_clear(&App.absPath); fsl_buffer_clear(&App.coRelPath); if(inTrans){ int const rc2 = fsl_db_transaction_rollback(db); if(!rc) rc = rc2; } return fcli_end_of_main(rc); }