]> git.ipfire.org Git - thirdparty/git.git/blame - fsmonitor-settings.c
fsmonitor-settings: stub in macOS-specific incompatibility checking
[thirdparty/git.git] / fsmonitor-settings.c
CommitLineData
1e0ea5c4
JH
1#include "cache.h"
2#include "config.h"
3#include "repository.h"
4#include "fsmonitor-settings.h"
5
6/*
7 * We keep this structure defintion private and have getters
8 * for all fields so that we can lazy load it as needed.
9 */
10struct fsmonitor_settings {
11 enum fsmonitor_mode mode;
62a62a28 12 enum fsmonitor_reason reason;
1e0ea5c4
JH
13 char *hook_path;
14};
15
62a62a28
JH
16static enum fsmonitor_reason check_for_incompatible(struct repository *r)
17{
18 if (!r->worktree) {
19 /*
20 * Bare repositories don't have a working directory and
21 * therefore have nothing to watch.
22 */
23 return FSMONITOR_REASON_BARE;
24 }
25
d33c804d
JH
26#ifdef HAVE_FSMONITOR_OS_SETTINGS
27 {
28 enum fsmonitor_reason reason;
29
30 reason = fsm_os__incompatible(r);
31 if (reason != FSMONITOR_REASON_OK)
32 return reason;
33 }
34#endif
35
62a62a28
JH
36 return FSMONITOR_REASON_OK;
37}
38
39static struct fsmonitor_settings *alloc_settings(void)
1e0ea5c4
JH
40{
41 struct fsmonitor_settings *s;
62a62a28
JH
42
43 CALLOC_ARRAY(s, 1);
44 s->mode = FSMONITOR_MODE_DISABLED;
45 s->reason = FSMONITOR_REASON_UNTESTED;
46
47 return s;
48}
49
50static void lookup_fsmonitor_settings(struct repository *r)
51{
1e0ea5c4
JH
52 const char *const_str;
53 int bool_value;
54
55 if (r->settings.fsmonitor)
56 return;
57
1e0ea5c4
JH
58 /*
59 * Overload the existing "core.fsmonitor" config setting (which
60 * has historically been either unset or a hook pathname) to
61 * now allow a boolean value to enable the builtin FSMonitor
62 * or to turn everything off. (This does imply that you can't
63 * use a hook script named "true" or "false", but that's OK.)
64 */
65 switch (repo_config_get_maybe_bool(r, "core.fsmonitor", &bool_value)) {
66
67 case 0: /* config value was set to <bool> */
68 if (bool_value)
69 fsm_settings__set_ipc(r);
62a62a28
JH
70 else
71 fsm_settings__set_disabled(r);
1e0ea5c4
JH
72 return;
73
74 case 1: /* config value was unset */
75 const_str = getenv("GIT_TEST_FSMONITOR");
76 break;
77
78 case -1: /* config value set to an arbitrary string */
79 if (repo_config_get_pathname(r, "core.fsmonitor", &const_str))
80 return; /* should not happen */
81 break;
82
83 default: /* should not happen */
84 return;
85 }
86
62a62a28
JH
87 if (const_str && *const_str)
88 fsm_settings__set_hook(r, const_str);
89 else
90 fsm_settings__set_disabled(r);
1e0ea5c4
JH
91}
92
93enum fsmonitor_mode fsm_settings__get_mode(struct repository *r)
94{
95 if (!r)
96 r = the_repository;
62a62a28
JH
97 if (!r->settings.fsmonitor)
98 lookup_fsmonitor_settings(r);
1e0ea5c4
JH
99
100 return r->settings.fsmonitor->mode;
101}
102
103const char *fsm_settings__get_hook_path(struct repository *r)
104{
105 if (!r)
106 r = the_repository;
62a62a28
JH
107 if (!r->settings.fsmonitor)
108 lookup_fsmonitor_settings(r);
1e0ea5c4
JH
109
110 return r->settings.fsmonitor->hook_path;
111}
112
113void fsm_settings__set_ipc(struct repository *r)
114{
62a62a28
JH
115 enum fsmonitor_reason reason = check_for_incompatible(r);
116
117 if (reason != FSMONITOR_REASON_OK) {
118 fsm_settings__set_incompatible(r, reason);
119 return;
120 }
121
122 /*
123 * Caller requested IPC explicitly, so avoid (possibly
124 * recursive) config lookup.
125 */
1e0ea5c4
JH
126 if (!r)
127 r = the_repository;
62a62a28
JH
128 if (!r->settings.fsmonitor)
129 r->settings.fsmonitor = alloc_settings();
1e0ea5c4
JH
130
131 r->settings.fsmonitor->mode = FSMONITOR_MODE_IPC;
62a62a28 132 r->settings.fsmonitor->reason = reason;
1e0ea5c4
JH
133 FREE_AND_NULL(r->settings.fsmonitor->hook_path);
134}
135
136void fsm_settings__set_hook(struct repository *r, const char *path)
137{
62a62a28
JH
138 enum fsmonitor_reason reason = check_for_incompatible(r);
139
140 if (reason != FSMONITOR_REASON_OK) {
141 fsm_settings__set_incompatible(r, reason);
142 return;
143 }
144
145 /*
146 * Caller requested hook explicitly, so avoid (possibly
147 * recursive) config lookup.
148 */
1e0ea5c4
JH
149 if (!r)
150 r = the_repository;
62a62a28
JH
151 if (!r->settings.fsmonitor)
152 r->settings.fsmonitor = alloc_settings();
1e0ea5c4
JH
153
154 r->settings.fsmonitor->mode = FSMONITOR_MODE_HOOK;
62a62a28 155 r->settings.fsmonitor->reason = reason;
1e0ea5c4
JH
156 FREE_AND_NULL(r->settings.fsmonitor->hook_path);
157 r->settings.fsmonitor->hook_path = strdup(path);
158}
159
160void fsm_settings__set_disabled(struct repository *r)
161{
162 if (!r)
163 r = the_repository;
62a62a28
JH
164 if (!r->settings.fsmonitor)
165 r->settings.fsmonitor = alloc_settings();
1e0ea5c4
JH
166
167 r->settings.fsmonitor->mode = FSMONITOR_MODE_DISABLED;
62a62a28
JH
168 r->settings.fsmonitor->reason = FSMONITOR_REASON_OK;
169 FREE_AND_NULL(r->settings.fsmonitor->hook_path);
170}
171
172void fsm_settings__set_incompatible(struct repository *r,
173 enum fsmonitor_reason reason)
174{
175 if (!r)
176 r = the_repository;
177 if (!r->settings.fsmonitor)
178 r->settings.fsmonitor = alloc_settings();
179
180 r->settings.fsmonitor->mode = FSMONITOR_MODE_INCOMPATIBLE;
181 r->settings.fsmonitor->reason = reason;
1e0ea5c4
JH
182 FREE_AND_NULL(r->settings.fsmonitor->hook_path);
183}
62a62a28
JH
184
185enum fsmonitor_reason fsm_settings__get_reason(struct repository *r)
186{
187 if (!r)
188 r = the_repository;
189 if (!r->settings.fsmonitor)
190 lookup_fsmonitor_settings(r);
191
192 return r->settings.fsmonitor->reason;
193}
194
195char *fsm_settings__get_incompatible_msg(const struct repository *r,
196 enum fsmonitor_reason reason)
197{
198 struct strbuf msg = STRBUF_INIT;
199
200 switch (reason) {
201 case FSMONITOR_REASON_UNTESTED:
202 case FSMONITOR_REASON_OK:
203 goto done;
204
205 case FSMONITOR_REASON_BARE:
206 strbuf_addf(&msg,
207 _("bare repository '%s' is incompatible with fsmonitor"),
208 xgetcwd());
209 goto done;
5c58fbd2
JH
210
211 case FSMONITOR_REASON_VFS4GIT:
212 strbuf_addf(&msg,
213 _("virtual repository '%s' is incompatible with fsmonitor"),
214 r->worktree);
215 goto done;
62a62a28
JH
216 }
217
218 BUG("Unhandled case in fsm_settings__get_incompatible_msg: '%d'",
219 reason);
220
221done:
222 return strbuf_detach(&msg, NULL);
223}