1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
/* -*- 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
*/
/**
This is a test app demonstrating creating a repository and checking in files
without an associated checkout.
*/
#ifdef NDEBUG
/* Force assert() to always be in effect. */
#undef NDEBUG
#endif
#include "fossil-scm/fossil-cli.h"
#include "fossil-scm/fossil-internal.h"
//#include <string.h>
// Only for testing/debugging..
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \
printf pfexp; \
} while(0)
// Global app state.
struct App_ {
char const * repoDbName;
} App = {
"_ciwoco.f"
};
static int repo_create(void){
int rc;
fsl_cx * const f = fcli_cx();
fsl_repo_create_opt cOpt = fsl_repo_create_opt_empty;
cOpt.commitMessage =
"This is a repo. There are many like it "
"but this one is mine.";
cOpt.filename = App.repoDbName;
fsl_file_unlink(cOpt.filename);
rc = fsl_repo_create(f, &cOpt);
MARKER(("fsl_repo_create() rc=%s\n", fsl_rc_cstr(rc)));
if(rc) goto end;
assert(0==rc);
assert(fsl_cx_db_repo(f));
end:
return rc;
}
static int app_stuff(void){
int rc = 0;
fsl_cx * const f = fcli_cx();
rc = repo_create();
if(rc) goto end;
f_out("(Re)created repo: %s\n", fsl_cx_db_file_repo(f, NULL));
#if 0
fsl_deck d = fsl_deck_empty;
fsl_buffer mParent = fsl_buffer_empty;
fsl_buffer mDerived = fsl_buffer_empty;
fsl_buffer content = fsl_buffer_empty;
fsl_cx * const f = fcli_cx();
char const * fname = 0;
fsl_card_F const * fc;
rc = fsl_deck_load_sym(f, &d, "trunk", FSL_SATYPE_CHECKIN);
assert(0==rc);
assert(d.f == f);
rc = fsl_deck_output(&d, fsl_output_f_buffer, &mParent);
if(rc) goto end;
fname = "auto.def";
fc = fsl_deck_F_seek(&d, fname);
assert(fc);
rc = fsl_deck_F_set(&d, fname, NULL, FSL_FILE_PERM_REGULAR, NULL);
assert(FSL_RC_MISUSE==rc);
rc = fsl_deck_derive(&d);
assert(0==rc);
assert(f == d.f);
rc = fsl_deck_F_set(&d, fname, NULL, FSL_FILE_PERM_REGULAR, NULL);
assert(0==rc);
rc = fsl_deck_F_set(&d, fname, NULL, FSL_FILE_PERM_REGULAR, NULL);
assert(FSL_RC_NOT_FOUND==rc);
fsl_buffer_append(&content, "Hi, world\n", -1)
/**
"Hi, world\n" ==>
SHA1: be43c4b3274c6ccd6c77950a2ddc743aafb70ecf
SHA3: 3efd06d75c7a8895b41edbee5160cc9a2ff11d89f4d4b4810a35b353b754b806
*/;
rc = fsl_deck_F_set_content(&d, fname, &content,
FSL_FILE_PERM_REGULAR, NULL);
assert(0==rc);
rc = fsl_deck_D_set(&d, fsl_julian_now());
assert(0==rc);
rc = fsl_deck_C_set(&d, "Testing.", -1);
assert(0==rc);
rc = fsl_deck_U_set(&d, "scratchpad");
assert(0==rc);
rc = fsl_deck_output(&d, fsl_output_f_buffer, &mDerived);
if(rc) goto end;
assert(0!=strstr(fsl_buffer_cstr(&mDerived),
"F auto.def be43c4b3274c6ccd6c77950a2ddc743aafb70ecf")
||
0!=strstr(fsl_buffer_cstr(&mDerived),
"F auto.def 3efd06d75c7a8895b41edbee5160cc9a2ff11d89f4d4b4810a35b353b754b806")
);
MARKER(("Pay attention to the auto.def hash below and make sure it matches "
"the one listed here in these sources: be43... or 3efd...\n"));
rc = fsl_diff_text( &mParent, &mDerived, fsl_output_f_FILE, stdout,
1, 0, FSL_DIFF_ANSI_COLOR);
assert(0==rc);
end:
fsl_buffer_clear(&content);
fsl_buffer_clear(&mParent);
fsl_buffer_clear(&mDerived);
fsl_deck_finalize(&d);
#endif
end:
return rc;
}
int main(int argc, const char * const * argv ){
fsl_cx * f = 0;
/**
Set up flag handling, which is used for processing
basic CLI flags and generating --help text output.
*/
const fcli_cliflag FCliFlags[] = {
fcli_cliflag_empty_m // list MUST end with this (or equivalent)
};
const fcli_help_info FCliHelp = {
"A demo of creating a new repo and checking in files "
"without a checkout.",
NULL, // very brief usage text, e.g. "file1 [...fileN]"
NULL // optional callback which outputs app-specific help
|
|
|
>
|
>
|
|
|
|
|
>
|
|
>
<
|
|
>
>
|
<
|
|
<
<
<
<
<
<
|
<
<
<
>
|
<
<
|
|
|
|
|
|
|
|
|
<
|
<
<
<
<
<
<
|
<
<
>
|
|
|
|
>
>
>
>
>
>
|
<
<
|
<
>
|
<
<
>
>
|
<
>
>
>
>
|
|
<
>
>
|
<
>
>
<
>
>
>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
/* -*- 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
*/
/**
This is a test app demonstrating creating a repository and checking
in files without an associated checkout.
*/
#ifdef NDEBUG
/* Force assert() to always be in effect. */
#undef NDEBUG
#endif
#include "fossil-scm/fossil-cli.h"
#include "fossil-scm/fossil-internal.h"
//#include <string.h>
// Only for testing/debugging..
#define MARKER(pfexp) \
do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \
printf pfexp; \
} while(0)
// Global app state.
struct App_ {
char const * repoDbName;
bool addEmptyCommit;
} App = {
"_ciwoco.f",
true/*addEmptyCommit*/
};
static int repo_create(bool addEgg){
int rc;
fsl_cx * const f = fcli_cx();
fsl_repo_create_opt cOpt = fsl_repo_create_opt_empty;
if(addEgg){
cOpt.commitMessage =
"This is a repo. There are many like it "
"but this one is mine.";
}else{
cOpt.commitMessage = NULL;
}
cOpt.filename = App.repoDbName;
fsl_file_unlink(cOpt.filename);
rc = fsl_repo_create(f, &cOpt);
//MARKER(("fsl_repo_create() rc=%s\n", fsl_rc_cstr(rc)));
if(rc) goto end;
assert(0==rc);
assert(fsl_cx_db_repo(f));
end:
return rc;
}
static int app_stuff(void){
int rc = 0;
fsl_cx * const f = fcli_cx();
fsl_buffer content = fsl_buffer_empty;
fsl_deck d = fsl_deck_empty;
char const *fname = 0;
rc = repo_create(App.addEmptyCommit);
if(rc) goto end;
f_out("(Re)created repo: %s\n", fsl_cx_db_file_repo(f, NULL));
if(App.addEmptyCommit){
f_out("Empty initial commit was added.\n");
}else{
f_out("No empty initial commit was created.\n");
}
assert(fsl_needs_repo(f));
rc = fsl_cx_transaction_begin(f);
if(rc) goto end;
if(App.addEmptyCommit){
rc = fsl_deck_load_sym(f, &d, "trunk", FSL_SATYPE_CHECKIN);
assert(0==rc);
assert(f==d.f);
rc = fsl_deck_derive(&d);
assert(0==rc);
}else{
fsl_deck_init(f, &d, FSL_SATYPE_CHECKIN);
}
rc = fsl_deck_D_set(&d, fsl_julian_now());
assert(0==rc);
rc = fsl_deck_C_set(&d, "File added w/o checkout.", -1);
assert(0==rc);
rc = fsl_deck_U_set(&d, "ciwoco");
assert(0==rc);
char const * fnames[] = {
"f-test-ciwoco.c",
"Makefile.in",
NULL
};
for( int i = 0; (fname = fnames[i]); ++i ){
rc = fsl_buffer_fill_from_filename(&content, fname);
assert(0==rc);
rc = fsl_deck_F_set_content(&d, fname, &content,
FSL_FILE_PERM_REGULAR, NULL);
assert(0==rc);
f_out("Added file: %s\n", fname);
}
rc = fsl_deck_save(&d, false);
assert(0==rc);
f_out("Saved checkin %s\n", d.uuid);
assert(fsl_cx_transaction_level(f)>0);
rc = fsl_cx_transaction_end(f, false);
end:
if(fsl_cx_transaction_level(f)){
fsl_cx_transaction_end(f, true);
}
fsl_deck_finalize(&d);
fsl_buffer_clear(&content);
if(!rc){
f_out("Results are in repo file %s\n", App.repoDbName);
}
return rc;
}
int main(int argc, const char * const * argv ){
/**
Set up flag handling, which is used for processing
basic CLI flags and generating --help text output.
*/
const fcli_cliflag FCliFlags[] = {
FCLI_FLAG_BOOL_INVERT("e", "empty", &App.addEmptyCommit,
"If set, do not create the initial "
"empty checkin."),
fcli_cliflag_empty_m // list MUST end with this (or equivalent)
};
const fcli_help_info FCliHelp = {
"A demo of creating a new repo and checking in files "
"without a checkout.",
NULL, // very brief usage text, e.g. "file1 [...fileN]"
NULL // optional callback which outputs app-specific help
|
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
swaps out the allocator with a fail-fast one, meaning that if an
allocation fails, the app crashes. This frees up the client app
from much of the tedium of dealing with allocation errors (which,
in practice, "never happen").
*/
int rc = fcli_setup(argc, argv);
if(rc) goto end;
f = fcli_cx();
/**
After all args processing, check for extra/unused flags
with:
*/
// if((rc=fcli_has_unused_flags(false))) goto end;
// Or, more generally:
if((rc=fcli_has_unused_args(false))) goto end;
MARKER(("THIS APP IS INCOMPLETE.\n"));
/** Check for a repository (if needed) with: */
if(fsl_cx_db_repo(f)){
rc = fcli_err_set(FSL_RC_MISUSE,
"This app must be started without a repo/checkout.");
/* Sets the context's error state and will produce an appropriate
error message from fcli_end_of_main(). */
goto end;
}
rc = app_stuff();
end:
return fcli_end_of_main(rc);
}
|
<
<
<
<
<
<
<
<
<
<
|
|
<
<
|
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
|
swaps out the allocator with a fail-fast one, meaning that if an
allocation fails, the app crashes. This frees up the client app
from much of the tedium of dealing with allocation errors (which,
in practice, "never happen").
*/
int rc = fcli_setup(argc, argv);
if(rc) goto end;
if((rc=fcli_has_unused_args(false))) goto end;
else if(fsl_cx_db_repo(fcli_cx())){
rc = fcli_err_set(FSL_RC_MISUSE,
"This app must be started WITHOUT a repo/checkout.");
goto end;
}
rc = app_stuff();
end:
return fcli_end_of_main(rc);
}
|