/* -*- 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).
*****************************************************************************
A simple tool for checking the change status of a checkout.
*/
#include "libfossil.h"
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \
printf pfexp; \
} while(0)
static char const * fsl_ckout_change_label(fsl_ckout_change_e change){
switch(change){
case FSL_CKOUT_CHANGE_NONE: return NULL;
case FSL_CKOUT_CHANGE_MOD: return "MODIFIED";
case FSL_CKOUT_CHANGE_MERGE_MOD: return "MERGE-MOD";
case FSL_CKOUT_CHANGE_MERGE_ADD: return "MERGE-ADD";
case FSL_CKOUT_CHANGE_INTEGRATE_MOD: return "INTEGRATE-MOD";
case FSL_CKOUT_CHANGE_INTEGRATE_ADD: return "INTEGRATE-ADD";
case FSL_CKOUT_CHANGE_ADDED: return "ADDED";
case FSL_CKOUT_CHANGE_REMOVED: return "REMOVED";
case FSL_CKOUT_CHANGE_MISSING: return "MISSING";
case FSL_CKOUT_CHANGE_RENAMED: return "RENAMED";
case FSL_CKOUT_CHANGE_IS_EXEC: return "+EXEC";
case FSL_CKOUT_CHANGE_NOT_EXEC: return "-EXEC";
case FSL_CKOUT_CHANGE_BECAME_SYMLINK: return "+SYMLINK";
case FSL_CKOUT_CHANGE_NOT_SYMLINK: return "-SYMLINK";
default:
return "?!NO WAY!?";
}
}
/**
A fsl_ckout_changes_f() impl which outputs change status to f_out().
*/
static int fsl_ckout_changes_fapp(void * state, fsl_ckout_change_e change,
char const * filename, char const * origName){
if(1==++*((int*)state)){
f_out("\nLocal changes compared to this version:\n\n");
}
f_out("%-15s", fsl_ckout_change_label(change));
if(FSL_CKOUT_CHANGE_RENAMED==change){
assert(origName && *origName);
f_out("%s\n%14s %s\n", origName, "->", filename);
}else{
f_out("%s\n", filename);
}
return 0;
}
static int fapp_show_local_changes(fsl_cx * f, fsl_id_t vid, bool doScan){
int rc = 0;
if(doScan) rc = fsl_ckout_changes_scan(f);
if(!rc){
int counter = 0;
rc = fsl_ckout_changes_visit(f, vid, 0,
fsl_ckout_changes_fapp, &counter);
if(!rc){
f_out("%s\n", counter ? "" : "\nNo local changes.");
}
}
return rc;
}
int main(int argc, char const * const * argv ){
int rc = 0;
fsl_cx * f = 0;
fsl_db * db = 0;
fsl_id_t rid = 0;
bool skipFiles = false;
bool useUtc = false;
const char * zVersion = NULL;
fsl_id_t ckoutRid = 0;
bool skipVfileReset = false;
fcli_cliflag FCliFlags[] = {
FCLI_FLAG_BOOL("f","no-files",&skipFiles,
"Disables the status check for local files."),
FCLI_FLAG_BOOL(0,"utc",&useUtc,
"Enables UTC timestamps (default is local time)."),
FCLI_FLAG("v","version","version", &zVersion,
"Shows info for the given version instead of the checkout."),
FCLI_FLAG_BOOL(0,"no-reset", &skipVfileReset,
"Is an internal debugging flag which tells this app "
"not to re-set the vfile contents to be those of the current checkout. "
"For compatibility with fossil(1), do not use it. It is only for testing."),
fcli_cliflag_empty_m
};
fcli_help_info FCliHelp = {
"Outputs status info for the current checkout.",
"",
NULL
};
rc = fcli_setup_v2(argc, argv, FCliFlags, &FCliHelp);
if(rc) goto end;
f = fcli_cx();
db = fsl_needs_ckout(f);
if(!db){
rc = FSL_RC_NOT_A_CKOUT;
goto end;
}
if(fcli_has_unused_args(false)) goto end;
rc = fcli_fingerprint_check(true);
if(rc) goto end;
if(zVersion){
rc = fsl_sym_to_rid(f, zVersion, FSL_SATYPE_CHECKIN, &rid);
if(rc) goto end;
}
if(!rid){
fsl_ckout_version_info(f, &ckoutRid, NULL);
rid = ckoutRid;
}
if( !fsl_rid_is_a_checkin(f, rid) ) {
rc = fcli_err_set(FSL_RC_RANGE,
"%s does not refer to a checkin version.",
zVersion ? zVersion : "RID");
goto end;
}
rc = fcli_ckout_show_info(useUtc);
if(!rc && !skipFiles){
rc = fapp_show_local_changes(f, rid, !skipVfileReset);
}
end:
return fcli_end_of_main(rc);
}