kibi-core 0.9.1 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/status.pl CHANGED
@@ -19,12 +19,16 @@ status_meta_dict(StatusDict) :-
19
19
  snapshot_id(SnapshotId),
20
20
  synced_at(DataFile, SyncedAt),
21
21
  freshness_state(DataFile, Dirty, SyncState),
22
+ stale_reasons(StaleReasons, StaleReasonCount, StaleReasonsTruncated),
22
23
  StatusDict = _{
23
24
  branch: Branch,
24
25
  snapshotId: SnapshotId,
25
26
  syncedAt: SyncedAt,
26
27
  dirty: Dirty,
27
28
  syncState: SyncState,
29
+ staleReasons: StaleReasons,
30
+ staleReasonCount: StaleReasonCount,
31
+ staleReasonsTruncated: StaleReasonsTruncated,
28
32
  kbPath: KbPath,
29
33
  lastSyncSource: persisted
30
34
  }.
@@ -37,15 +41,33 @@ status_meta_dict(StatusDict) :-
37
41
  syncedAt: null,
38
42
  dirty: false,
39
43
  syncState: unknown,
44
+ staleReasons: [],
45
+ staleReasonCount: 0,
46
+ staleReasonsTruncated: false,
40
47
  kbPath: KbPath,
41
48
  lastSyncSource: unknown
42
49
  }.
43
50
 
51
+ attached_kb_info(Branch, KbPath, DataFile) :-
52
+ kb:kb_attached(KbPath),
53
+ branch_workspace_from_kb_path(KbPath, Branch, _WorkspaceRoot),
54
+ kb:kb_storage_mode(journaled),
55
+ !,
56
+ directory_file_path(KbPath, 'CURRENT', DataFile).
44
57
  attached_kb_info(Branch, KbPath, DataFile) :-
45
58
  kb:kb_attached(KbPath),
46
59
  branch_workspace_from_kb_path(KbPath, Branch, _WorkspaceRoot),
47
60
  directory_file_path(KbPath, 'kb.rdf', DataFile).
48
61
 
62
+ snapshot_id(SnapshotId) :-
63
+ kb:kb_attached_snapshot(journal_snapshot(_Generation, Sequence)),
64
+ Sequence =:= 0,
65
+ !,
66
+ SnapshotId = missing.
67
+ snapshot_id(SnapshotId) :-
68
+ kb:kb_attached_snapshot(journal_snapshot(Generation, Sequence)),
69
+ !,
70
+ format(atom(SnapshotId), '~w:~w', [Generation, Sequence]).
49
71
  snapshot_id(SnapshotId) :-
50
72
  kb:kb_attached_snapshot(stamp(MTime, Size)),
51
73
  !,
@@ -56,6 +78,14 @@ snapshot_id(SnapshotId) :-
56
78
  SnapshotId = missing.
57
79
  snapshot_id(unknown).
58
80
 
81
+ journal_before_first_commit :-
82
+ kb:kb_storage_mode(journaled),
83
+ kb:kb_attached_snapshot(journal_snapshot(_, 0)),
84
+ !.
85
+
86
+ synced_at(_, null) :-
87
+ journal_before_first_commit,
88
+ !.
59
89
  synced_at(DataFile, SyncedAt) :-
60
90
  exists_file(DataFile),
61
91
  !,
@@ -64,6 +94,13 @@ synced_at(DataFile, SyncedAt) :-
64
94
  % Before the first successful sync there is no kb.rdf, so the public JSON contract must expose syncedAt: null.
65
95
  synced_at(_, null).
66
96
 
97
+ journal_before_first_commit_state(true, unknown) :-
98
+ journal_before_first_commit,
99
+ !.
100
+
101
+ freshness_state(_, Dirty, State) :-
102
+ journal_before_first_commit_state(Dirty, State),
103
+ !.
67
104
  freshness_state(DataFile, true, stale) :-
68
105
  exists_file(DataFile),
69
106
  time_file(DataFile, SnapshotTime),
@@ -74,31 +111,118 @@ freshness_state(DataFile, false, fresh) :-
74
111
  !.
75
112
  freshness_state(_, true, unknown).
76
113
 
114
+ stale_reasons(Reasons, Count, Truncated) :-
115
+ findall(Reason, stale_indexed_source_reason(Reason), IndexedReasons),
116
+ findall(Reason, stale_knowledge_lane_reason(Reason), KnowledgeReasons),
117
+ findall(Reason, stale_documentation_reason(Reason), DocumentationReasons),
118
+ append(IndexedReasons, KnowledgeReasons, IndexedAndKnowledge),
119
+ append(IndexedAndKnowledge, DocumentationReasons, Reasons0),
120
+ sort(Reasons0, Sorted),
121
+ length(Sorted, Count),
122
+ ( Count > 200
123
+ -> length(Reasons, 200), append(Reasons, _, Sorted), Truncated = true
124
+ ; Reasons = Sorted, Truncated = false
125
+ ).
126
+
127
+ stale_indexed_source_reason(Reason) :-
128
+ attached_workspace_root(WorkspaceRoot),
129
+ kb:kb_indexed_sources(Sources),
130
+ member(SourceAtom, Sources),
131
+ repo_relative_source(SourceAtom, RelativeSource),
132
+ directory_file_path(WorkspaceRoot, RelativeSource, SourcePath),
133
+ ( exists_file(SourcePath)
134
+ -> time_file(SourcePath, FileTime),
135
+ kb_snapshot_time(SnapshotTime),
136
+ FileTime > SnapshotTime,
137
+ Code = indexed_source_newer
138
+ ; exists_directory(SourcePath)
139
+ -> fail
140
+ ; Code = indexed_source_missing
141
+ ),
142
+ entity_ids_for_source(RelativeSource, EntityIds),
143
+ Reason = _{code: Code, path: RelativeSource, entityIds: EntityIds}.
144
+
145
+ stale_knowledge_lane_reason(Reason) :-
146
+ attached_workspace_root(WorkspaceRoot),
147
+ knowledge_lane(Lane),
148
+ directory_file_path(WorkspaceRoot, '.kb', KbRoot),
149
+ directory_file_path(KbRoot, Lane, LaneRoot),
150
+ exists_directory(LaneRoot),
151
+ kb_snapshot_time(SnapshotTime),
152
+ directory_tree_newer_path(LaneRoot, SnapshotTime, Path),
153
+ workspace_relative_path(WorkspaceRoot, Path, RelativePath),
154
+ entity_ids_for_source(RelativePath, EntityIds),
155
+ Reason = _{code: knowledge_source_newer, path: RelativePath, entityIds: EntityIds}.
156
+
157
+ stale_documentation_reason(Reason) :-
158
+ attached_workspace_root(WorkspaceRoot),
159
+ directory_file_path(WorkspaceRoot, 'documentation', DocumentationRoot),
160
+ exists_directory(DocumentationRoot),
161
+ kb_snapshot_time(SnapshotTime),
162
+ directory_tree_newer_path(DocumentationRoot, SnapshotTime, Path),
163
+ workspace_relative_path(WorkspaceRoot, Path, RelativePath),
164
+ entity_ids_for_source(RelativePath, EntityIds),
165
+ Reason = _{code: documentation_source_newer, path: RelativePath, entityIds: EntityIds}.
166
+
167
+ kb_snapshot_time(SnapshotTime) :-
168
+ kb:kb_attached(KbPath),
169
+ ( directory_file_path(KbPath, 'CURRENT', DataFile), exists_file(DataFile)
170
+ -> time_file(DataFile, SnapshotTime)
171
+ ; directory_file_path(KbPath, 'kb.rdf', DataFile), exists_file(DataFile)
172
+ -> time_file(DataFile, SnapshotTime)
173
+ ; SnapshotTime = 0
174
+ ).
175
+
176
+ entity_ids_for_source(RelativeSource, EntityIds) :-
177
+ findall(Id,
178
+ (kb_entity(Id, _Type, Props),
179
+ entity_source_property(Props, RawSource),
180
+ source_value_atom(RawSource, SourceAtom),
181
+ repo_relative_source(SourceAtom, RelativeSource),
182
+ Id \= '') ,
183
+ Ids0),
184
+ sort(Ids0, EntityIds).
185
+
186
+ entity_source_property(Props, RawSource) :-
187
+ memberchk(sourceFile=RawSource, Props),
188
+ !.
189
+ entity_source_property(Props, RawSource) :-
190
+ memberchk(source=RawSource, Props).
191
+
77
192
  workspace_state_changed(SnapshotTime) :-
78
193
  workspace_source_changed(SnapshotTime),
79
194
  !.
195
+ workspace_state_changed(SnapshotTime) :-
196
+ knowledge_lane_tree_changed(SnapshotTime),
197
+ !.
80
198
  workspace_state_changed(SnapshotTime) :-
81
199
  documentation_tree_changed(SnapshotTime),
82
200
  !.
83
201
 
84
202
  workspace_source_changed(SnapshotTime) :-
85
203
  attached_workspace_root(WorkspaceRoot),
86
- kb_entity(_, _, Props),
87
- memberchk(source=SourceValue, Props),
88
- source_value_atom(SourceValue, SourceAtom),
204
+ kb:kb_indexed_sources(Sources),
205
+ member(SourceAtom, Sources),
89
206
  repo_relative_source(SourceAtom, RelativeSource),
90
207
  directory_file_path(WorkspaceRoot, RelativeSource, SourcePath),
91
208
  ( exists_file(SourcePath)
92
209
  -> time_file(SourcePath, FileTime),
93
210
  FileTime > SnapshotTime
211
+ ; exists_directory(SourcePath)
212
+ -> fail
94
213
  ; true
95
214
  ),
96
215
  !.
97
216
 
98
- documentation_tree_changed(_SnapshotTime) :-
217
+ knowledge_lane_tree_changed(SnapshotTime) :-
99
218
  attached_workspace_root(WorkspaceRoot),
100
- documentation_markdown_untracked(WorkspaceRoot),
219
+ knowledge_lane(Lane),
220
+ directory_file_path(WorkspaceRoot, '.kb', KbRoot),
221
+ directory_file_path(KbRoot, Lane, LaneRoot),
222
+ exists_directory(LaneRoot),
223
+ directory_tree_newer(LaneRoot, SnapshotTime),
101
224
  !.
225
+
102
226
  documentation_tree_changed(SnapshotTime) :-
103
227
  attached_workspace_root(WorkspaceRoot),
104
228
  directory_file_path(WorkspaceRoot, 'documentation', DocumentationRoot),
@@ -106,55 +230,38 @@ documentation_tree_changed(SnapshotTime) :-
106
230
  directory_tree_newer(DocumentationRoot, SnapshotTime),
107
231
  !.
108
232
 
109
- documentation_markdown_untracked(WorkspaceRoot) :-
110
- directory_file_path(WorkspaceRoot, 'documentation', DocumentationRoot),
111
- exists_directory(DocumentationRoot),
112
- documentation_markdown_file(DocumentationRoot, FilePath),
113
- path_relative_to_workspace(WorkspaceRoot, FilePath, RelativePath),
114
- \+ known_source_path(RelativePath),
115
- !.
116
-
117
- documentation_markdown_file(Path, Path) :-
233
+ directory_tree_newer(Path, SnapshotTime) :-
118
234
  exists_file(Path),
119
- file_name_extension(_, md, Path),
120
235
  entity_documentation_file(Path),
121
236
  \+ ignored_documentation_file(Path),
237
+ time_file(Path, EntryTime),
238
+ EntryTime > SnapshotTime,
122
239
  !.
123
- documentation_markdown_file(Path, FilePath) :-
240
+
241
+ directory_tree_newer(Path, SnapshotTime) :-
124
242
  exists_directory(Path),
125
243
  directory_files(Path, Entries),
126
244
  member(Entry, Entries),
127
245
  Entry \= '.',
128
246
  Entry \= '..',
129
247
  directory_file_path(Path, Entry, ChildPath),
130
- documentation_markdown_file(ChildPath, FilePath).
131
-
132
- path_relative_to_workspace(WorkspaceRoot, FilePath, RelativePath) :-
133
- atom_concat(WorkspaceRoot, '/', Prefix),
134
- atom_concat(Prefix, RelativePath, FilePath).
135
-
136
- known_source_path(RelativePath) :-
137
- kb_entity(_, _, Props),
138
- memberchk(source=SourceValue, Props),
139
- source_value_atom(SourceValue, SourceAtom),
140
- repo_relative_source(SourceAtom, RelativePath).
248
+ directory_tree_newer(ChildPath, SnapshotTime),
249
+ !.
141
250
 
142
- directory_tree_newer(Path, SnapshotTime) :-
251
+ directory_tree_newer_path(Path, SnapshotTime, Path) :-
143
252
  exists_file(Path),
144
253
  entity_documentation_file(Path),
145
254
  \+ ignored_documentation_file(Path),
146
255
  time_file(Path, EntryTime),
147
- EntryTime > SnapshotTime,
148
- !.
149
- directory_tree_newer(Path, SnapshotTime) :-
256
+ EntryTime > SnapshotTime.
257
+ directory_tree_newer_path(Path, SnapshotTime, ChildPath) :-
150
258
  exists_directory(Path),
151
259
  directory_files(Path, Entries),
152
260
  member(Entry, Entries),
153
261
  Entry \= '.',
154
262
  Entry \= '..',
155
- directory_file_path(Path, Entry, ChildPath),
156
- directory_tree_newer(ChildPath, SnapshotTime),
157
- !.
263
+ directory_file_path(Path, Entry, Candidate),
264
+ directory_tree_newer_path(Candidate, SnapshotTime, ChildPath).
158
265
 
159
266
  attached_workspace_root(WorkspaceRoot) :-
160
267
  kb:kb_attached(KbPath),
@@ -180,12 +287,20 @@ branch_path_segments(KbPath, BranchesDir, Segments) :-
180
287
  repo_relative_source(SourceAtom, RelativeSource) :-
181
288
  strip_fragment(SourceAtom, NoFragment),
182
289
  \+ sub_atom(NoFragment, _, _, _, '://'),
290
+ source_path_candidate(NoFragment),
183
291
  ( attached_workspace_root(WorkspaceRoot),
184
292
  workspace_relative_path(WorkspaceRoot, NoFragment, RelativePath)
185
293
  -> RelativeSource = RelativePath
186
294
  ; RelativeSource = NoFragment
187
295
  ).
188
296
 
297
+ source_path_candidate(Source) :-
298
+ sub_atom(Source, _, _, _, '/'),
299
+ !.
300
+ source_path_candidate(Source) :-
301
+ file_name_extension(_, Extension, Source),
302
+ Extension \= ''.
303
+
189
304
  workspace_relative_path(WorkspaceRoot, SourcePath, RelativePath) :-
190
305
  atom_concat(WorkspaceRoot, '/', Prefix),
191
306
  atom_concat(Prefix, RelativePath, SourcePath).
@@ -217,8 +332,20 @@ source_value_atom(Val, Atom) :-
217
332
  term_string(Val, Str),
218
333
  atom_string(Atom, Str).
219
334
 
335
+ knowledge_lane(requirements).
336
+ knowledge_lane(scenarios).
337
+ knowledge_lane(tests).
338
+ knowledge_lane(facts).
339
+ knowledge_lane(adr).
340
+ knowledge_lane(flags).
341
+ knowledge_lane(events).
342
+
220
343
  ignored_documentation_file(Path) :-
221
344
  file_base_name(Path, 'README.md').
345
+ ignored_documentation_file(Path) :-
346
+ sub_atom(Path, _, _, _, '/tests/e2e/').
347
+ ignored_documentation_file(Path) :-
348
+ sub_atom(Path, _, _, _, '/tests/benchmarks/').
222
349
 
223
350
  entity_documentation_file(Path) :-
224
351
  read_file_to_string(Path, Content, []),