/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* Copyright (c) 2013 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 implements a basic 'ls' for in-repo content (not yet filesystem-level). */ #include "fossil-scm/fossil-cli.h" /* Fossil App mini-framework */ /* #include "fossil-scm/fossil-internal.h" */ static void fcli_local_help(){ printf("Usage:\n\t%s [options]\n\n", fcli.appName); puts("Lists all files in a repository. Currently does no introspection " "vs. the local checkout. " "\nOptions:\n"); puts("\t-g|--glob GLOB_LIST list only filenames matching the given " "list of space-or-comma-separated glob pattern All patterns must " "be provided as a single string argument, so be sure to quote them " "if your shell might resolve them as wildcards.\n"); puts("\t-v|--invert Inverts the effect of --glob to mean list files " "whose names do NOT match the given blob.\n"); puts("\t--own|-o lists only files actually contained in the " "given version's manifest. The result will differ only " "for delta manifests.\n"); puts("\t--version|-v=VERSION (uuid or symbolic name). " "Default is 'current' if there is an opened checkout, " "else 'trunk'.\n"); puts("\t--verbose|-V enables more details.\n"); } static struct LsApp { char * glob; fsl_list globs; char invertGlob; } LsApp = { NULL, fsl_list_empty_m, 0/*invertGlob*/ }; static char ls_matches(char const * name){ if(!LsApp.globs.used) return 1; else{ char const rc = fsl_glob_list_matches(&LsApp.globs, name) ? 1 : 0; return LsApp.invertGlob ? !rc : rc; } } /** A fsl_card_F_visitor_f() implementation which outputs state from fc to the fossil output channel. */ static int ls_F_card_v(fsl_card_F const * fc, void * state){ char show; if(!fc->uuid) return 0 /* was removed in this manifest */; show = ls_matches(fc->name); if(show){ char perm; if(FSL_FILE_PERM_EXE & fc->perm) perm = 'x'; else if(FSL_FILE_PERM_LINK & fc->perm) perm = 'L'; else perm = '-'; if(fcli.verbose){ f_out("%-8"FSL_ID_T_PFMT, fsl_uuid_to_rid(fcli.f, fc->uuid)); } f_out("%.*s %c %s\n", 12, fc->uuid, perm, fc->name); } return 0; } int main(int argc, char * const * argv ){ int rc = 0; char * lsVersion = NULL; fsl_cx * f; fsl_deck deck = fsl_deck_empty; fsl_deck * d = &deck; char onlyFromSelf = 0; fcli.appHelp = fcli_local_help; rc = fcli_setup(argc, argv); if(FSL_RC_BREAK==rc) /* --help */ return 0; else if(rc) goto end; /* Set up/validate args... */ f = fcli.f; if(!fsl_cx_db_repo(f)){ rc = fcli_err_set(FSL_RC_NOT_A_REPO, "Requires a repository db. See --help."); goto end; } onlyFromSelf = fcli_flag2("o", "own", NULL); fcli_flag2("g","glob", &LsApp.glob); if(LsApp.glob){ fsl_glob_list_parse(&LsApp.globs, LsApp.glob); } LsApp.invertGlob = fcli_flag2("v","invert", NULL); if(!fcli_flag_or_arg("v","version", &lsVersion)){ /* this flag check MUST come last! */ lsVersion = fsl_strdup(fsl_cx_db_checkout(f) ? "current" : "trunk"); } if(fcli_has_unused_flags(0)) goto end; /* Find/load the checkin... */ rc = fsl_deck_load_sym(f, d, lsVersion, FSL_CATYPE_CHECKIN); if(rc) goto end; /* Output the list...*/ f_out("File list from manifest version '%s' [%.*s] " "(RID %"FSL_ID_T_PFMT")...\n", lsVersion, 12, d->uuid, (fsl_id_t)d->rid); if(d->B.uuid){ f_out("This is a delta manifest from baseline [%.*s].%s\n", 12, d->B.uuid, onlyFromSelf ? " Only listing differences from the baseline version." : ""); } if(fcli.verbose) f_out("RID "); f_out("%-12s P Name\n", "UUID"); rc = fsl_deck_F_foreach(d, onlyFromSelf ? 0 : 1, ls_F_card_v, NULL); end: fsl_free(LsApp.glob); fsl_glob_list_clear(&LsApp.globs); fsl_free(lsVersion); fsl_deck_finalize(d); rc = fcli_end_of_main(rc); return rc; }