/* -*- 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;
}