@dotinc/ogre 0.7.0 → 0.8.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.
Files changed (26) hide show
  1. package/.tap/processinfo/{21e0110c-397c-4c38-a84a-89c55de41e7e.json → 12fba5c1-f3d6-4b95-865b-9251ded2f6e3.json} +7 -6
  2. package/.tap/processinfo/{51b87298-fd44-42a9-b0f8-d4533e58fd1c.json → 38a3e28a-f045-4a32-bfc3-ca756e9457eb.json} +35 -34
  3. package/.tap/processinfo/{d1b618cb-a921-4f1c-ae4a-6bca359b5909.json → 594c45a4-6863-423e-9759-b092527c8ac4.json} +23 -22
  4. package/.tap/processinfo/{36da4059-ca5e-4b70-a993-7f99f94f7588.json → 671766c2-87ab-40cf-8051-2b74d41d0bc5.json} +7 -6
  5. package/.tap/processinfo/{75459f57-2341-476b-8576-587b93699d8b.json → a2952f0b-bb22-4fd6-a729-f9c500431030.json} +7 -6
  6. package/.tap/processinfo/{4aa37d99-4038-4033-9d38-beea00272892.json → cfca41ce-a29e-4cef-9564-b1f52749806b.json} +7 -6
  7. package/.tap/processinfo/{9656a0a0-72ab-4ea7-abb7-7415cd3842b4.json → d116ec0f-f197-434d-8a14-1f09a4b274ea.json} +23 -22
  8. package/.tap/test-results/src/branch.test.ts.tap +6 -6
  9. package/.tap/test-results/src/checkout.test.ts.tap +9 -9
  10. package/.tap/test-results/src/commit.test.ts.tap +18 -18
  11. package/.tap/test-results/src/merge.test.ts.tap +2 -2
  12. package/.tap/test-results/src/repository.test.ts.tap +23 -23
  13. package/.tap/test-results/src/tag.test.ts.tap +3 -3
  14. package/.tap/test-results/src/utils.test.ts.tap +7 -7
  15. package/CHANGELOG.md +13 -0
  16. package/lib/git2json.js +3 -4
  17. package/lib/repository.d.ts +1 -18
  18. package/lib/repository.js +39 -196
  19. package/lib/utils.d.ts +55 -0
  20. package/lib/utils.js +183 -2
  21. package/package.json +2 -2
  22. package/src/commit.test.ts +2 -1
  23. package/src/git2json.ts +6 -2
  24. package/src/repository.test.ts +2 -1
  25. package/src/repository.ts +28 -195
  26. package/src/utils.ts +194 -0
package/lib/repository.js CHANGED
@@ -1,15 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.printChange = exports.printChangeLog = exports.validateRef = exports.validateBranchName = exports.tagToRef = exports.brancheNameToRef = exports.cleanRefValue = exports.isTagRef = exports.createHeadRefValue = exports.Repository = exports.REFS_MAIN_KEY = exports.REFS_HEAD_KEY = void 0;
3
+ exports.Repository = void 0;
4
4
  const fast_json_patch_1 = require("fast-json-patch");
5
5
  const commit_1 = require("./commit");
6
- const ref_1 = require("./ref");
7
6
  const fflate_1 = require("fflate");
8
- const tagRefPathPrefix = "refs/tags/";
9
- const headsRefPathPrefix = "refs/heads/";
10
- const headValueRefPrefix = "ref: ";
11
- exports.REFS_HEAD_KEY = "HEAD";
12
- exports.REFS_MAIN_KEY = `${headsRefPathPrefix}main`;
7
+ const utils_1 = require("./utils");
13
8
  /**
14
9
  * A repository recording and managing the state transitions of an object
15
10
  */
@@ -25,10 +20,10 @@ class Repository {
25
20
  this.refs =
26
21
  (_c = (_b = options.history) === null || _b === void 0 ? void 0 : _b.refs) !== null && _c !== void 0 ? _c : new Map([
27
22
  [
28
- exports.REFS_HEAD_KEY,
23
+ utils_1.REFS_HEAD_KEY,
29
24
  {
30
- name: exports.REFS_HEAD_KEY,
31
- value: `ref: ${exports.REFS_MAIN_KEY}`,
25
+ name: utils_1.REFS_HEAD_KEY,
26
+ value: `ref: ${utils_1.REFS_MAIN_KEY}`,
32
27
  },
33
28
  ],
34
29
  ]);
@@ -45,7 +40,7 @@ class Repository {
45
40
  return this.remoteRefs;
46
41
  }
47
42
  moveTo(commit) {
48
- const targetTree = treeToObject(commit.tree);
43
+ const targetTree = (0, utils_1.treeToObject)(commit.tree);
49
44
  const patchToTarget = (0, fast_json_patch_1.compare)(this.data, targetTree);
50
45
  if (!patchToTarget || patchToTarget.length < 1) {
51
46
  return;
@@ -86,15 +81,15 @@ class Repository {
86
81
  (0, fast_json_patch_1.applyPatch)(this.data, patch);
87
82
  // const changed = patch.reduce(applyReducer, this.data);
88
83
  }
89
- reset(mode = "hard", shaish = exports.REFS_HEAD_KEY) {
84
+ reset(mode = "hard", shaish = utils_1.REFS_HEAD_KEY) {
90
85
  if (mode === "hard") {
91
86
  (0, fast_json_patch_1.unobserve)(this.data, this.observer);
92
87
  }
93
- const [commit] = shaishToCommit(shaish, this.refs, this.commits);
88
+ const [commit] = (0, utils_1.shaishToCommit)(shaish, this.refs, this.commits);
94
89
  this.moveTo(commit);
95
- const refs = refsAtCommit(this.refs, commit);
90
+ const refs = (0, utils_1.refsAtCommit)(this.refs, commit);
96
91
  // reset only moves heads and not tags
97
- const moveableRefs = refs.filter((r) => r.name.startsWith(headsRefPathPrefix));
92
+ const moveableRefs = refs.filter((r) => r.name.startsWith((0, utils_1.localHeadPathPrefix)()));
98
93
  for (const ref of moveableRefs) {
99
94
  this.moveRef(ref.name, commit);
100
95
  }
@@ -103,16 +98,16 @@ class Repository {
103
98
  }
104
99
  }
105
100
  branch() {
106
- const currentHeadRef = this.refs.get(exports.REFS_HEAD_KEY);
101
+ const currentHeadRef = this.refs.get(utils_1.REFS_HEAD_KEY);
107
102
  if (!currentHeadRef) {
108
103
  throw new Error("unreachable: ref HEAD not available");
109
104
  }
110
- if (currentHeadRef.value.includes(headValueRefPrefix)) {
111
- const refName = (0, exports.cleanRefValue)(currentHeadRef.value);
105
+ if (currentHeadRef.value.includes(utils_1.headValueRefPrefix)) {
106
+ const refName = (0, utils_1.cleanRefValue)(currentHeadRef.value);
112
107
  if (this.refs.has(refName))
113
- return getLastItem(refName);
108
+ return (0, utils_1.getLastRefPathElement)(refName);
114
109
  }
115
- return exports.REFS_HEAD_KEY; // detached state
110
+ return utils_1.REFS_HEAD_KEY; // detached state
116
111
  }
117
112
  status() {
118
113
  const commit = this.commitAtHead();
@@ -123,32 +118,32 @@ class Repository {
123
118
  return this.diff(commit.hash);
124
119
  }
125
120
  diff(shaishFrom, shaishTo) {
126
- const [cFrom] = shaishToCommit(shaishFrom, this.refs, this.commits);
121
+ const [cFrom] = (0, utils_1.shaishToCommit)(shaishFrom, this.refs, this.commits);
127
122
  let target;
128
123
  if (shaishTo) {
129
- const [cTo] = shaishToCommit(shaishTo, this.refs, this.commits);
130
- target = treeToObject(cTo.tree);
124
+ const [cTo] = (0, utils_1.shaishToCommit)(shaishTo, this.refs, this.commits);
125
+ target = (0, utils_1.treeToObject)(cTo.tree);
131
126
  }
132
127
  else {
133
128
  target = this.data;
134
129
  }
135
- const targetTree = treeToObject(cFrom.tree);
130
+ const targetTree = (0, utils_1.treeToObject)(cFrom.tree);
136
131
  return (0, fast_json_patch_1.compare)(targetTree, target);
137
132
  }
138
133
  checkout(shaish, createBranch) {
139
134
  if (createBranch) {
140
- (0, exports.validateBranchName)(shaish);
141
- let branchRef = (0, exports.brancheNameToRef)(shaish);
135
+ (0, utils_1.validateBranchName)(shaish);
136
+ let branchRef = (0, utils_1.brancheNameToRef)(shaish);
142
137
  const commit = this.commitAtHead();
143
138
  if (commit) {
144
139
  this.moveRef(branchRef, commit);
145
140
  }
146
- this.moveRef(exports.REFS_HEAD_KEY, branchRef);
141
+ this.moveRef(utils_1.REFS_HEAD_KEY, branchRef);
147
142
  }
148
143
  else {
149
- const [commit, isRef, refKey] = shaishToCommit(shaish, this.refs, this.commits);
144
+ const [commit, isRef, refKey] = (0, utils_1.shaishToCommit)(shaish, this.refs, this.commits);
150
145
  this.moveTo(commit);
151
- this.moveRef(exports.REFS_HEAD_KEY, isRef && refKey !== undefined ? refKey : commit);
146
+ this.moveRef(utils_1.REFS_HEAD_KEY, isRef && refKey !== undefined ? refKey : commit);
152
147
  }
153
148
  }
154
149
  async commit(message, author, amend) {
@@ -160,7 +155,7 @@ class Repository {
160
155
  if (parent) {
161
156
  if (amend) {
162
157
  [parent] = parent.parent
163
- ? shaishToCommit(parent.parent, this.refs, this.commits)
158
+ ? (0, utils_1.shaishToCommit)(parent.parent, this.refs, this.commits)
164
159
  : [parent]; // we are the very first commit in the repository
165
160
  }
166
161
  }
@@ -203,13 +198,13 @@ class Repository {
203
198
  }
204
199
  else {
205
200
  // move detached HEAD to new commit
206
- this.moveRef(exports.REFS_HEAD_KEY, commit);
201
+ this.moveRef(utils_1.REFS_HEAD_KEY, commit);
207
202
  }
208
203
  return sha;
209
204
  }
210
205
  // region Commit lookups
211
206
  commitAtHead() {
212
- return commitAtRefIn(exports.REFS_HEAD_KEY, this.refs, this.commits);
207
+ return (0, utils_1.commitAtRefIn)(utils_1.REFS_HEAD_KEY, this.refs, this.commits);
213
208
  }
214
209
  mustCommitAtHead() {
215
210
  const commitHead = this.commitAtHead();
@@ -220,17 +215,17 @@ class Repository {
220
215
  }
221
216
  // endregion
222
217
  createBranch(name) {
223
- (0, exports.validateBranchName)(name);
224
- const branchRef = (0, exports.brancheNameToRef)(name);
218
+ (0, utils_1.validateBranchName)(name);
219
+ const branchRef = (0, utils_1.brancheNameToRef)(name);
225
220
  this.saveNewRef(branchRef, name);
226
221
  return branchRef;
227
222
  }
228
223
  head() {
229
- const ref = this.refs.get(exports.REFS_HEAD_KEY);
224
+ const ref = this.refs.get(utils_1.REFS_HEAD_KEY);
230
225
  if (!ref) {
231
226
  throw new Error(`unreachable: HEAD is not present`);
232
227
  }
233
- return (0, exports.cleanRefValue)(ref.value);
228
+ return (0, utils_1.cleanRefValue)(ref.value);
234
229
  }
235
230
  // region History functions
236
231
  collectCommits() {
@@ -276,7 +271,7 @@ class Repository {
276
271
  // const srcHead = commitAtRefIn(REFS_HEAD, src.refs, src.commits)
277
272
  throw new Error(`fatal: source type (${source instanceof Repository ? "Repository" : "History"}) not implemented`);
278
273
  }
279
- const [srcCommit] = shaishToCommit(source, this.refs, this.commits);
274
+ const [srcCommit] = (0, utils_1.shaishToCommit)(source, this.refs, this.commits);
280
275
  const headCommit = this.mustCommitAtHead();
281
276
  // no change
282
277
  // *---* (master)
@@ -293,7 +288,7 @@ class Repository {
293
288
  // *---*
294
289
  // \
295
290
  // *---*---* (master, foo)
296
- const [isAncestor] = mapPath(headCommit, srcCommit, this.commits);
291
+ const [isAncestor] = (0, utils_1.mapPath)(headCommit, srcCommit, this.commits);
297
292
  if (isAncestor) {
298
293
  this.moveRef(this.head(), srcCommit);
299
294
  this.moveTo(srcCommit);
@@ -316,9 +311,9 @@ class Repository {
316
311
  // region Ref methods
317
312
  moveRef(refName, value) {
318
313
  let ref = this.refs.get(refName);
319
- const val = typeof value === "string" ? (0, exports.createHeadRefValue)(value) : value.hash;
314
+ const val = typeof value === "string" ? (0, utils_1.createHeadRefValue)(value) : value.hash;
320
315
  if (!ref) {
321
- ref = { name: getLastItem(refName), value: val };
316
+ ref = { name: (0, utils_1.getLastRefPathElement)(refName), value: val };
322
317
  }
323
318
  else {
324
319
  ref.value = val;
@@ -332,24 +327,24 @@ class Repository {
332
327
  if (!headRef) {
333
328
  throw new Error(`unreachable: HEAD not present`);
334
329
  }
335
- throw new Error(`fatal: not a valid object name: '${getLastItem(headRef)}'`);
330
+ throw new Error(`fatal: not a valid object name: '${(0, utils_1.getLastRefPathElement)(headRef)}'`);
336
331
  }
337
332
  this.refs.set(refKey, { name: name, value: headCommit.hash });
338
333
  }
339
334
  ref(reference) {
340
335
  var _a;
341
336
  const ref = (_a = this.refs.get(reference)) === null || _a === void 0 ? void 0 : _a.value;
342
- return ref ? (0, exports.cleanRefValue)(ref) : undefined;
337
+ return ref ? (0, utils_1.cleanRefValue)(ref) : undefined;
343
338
  }
344
339
  // endregion
345
340
  tag(tag) {
346
341
  try {
347
- (0, exports.validateRef)(tag);
342
+ (0, utils_1.validateRef)(tag);
348
343
  }
349
344
  catch (e) {
350
345
  throw new Error(`fatal: '${tag}' is not a valid tag name`);
351
346
  }
352
- const tagRef = (0, exports.tagToRef)(tag);
347
+ const tagRef = (0, utils_1.tagToRef)(tag);
353
348
  try {
354
349
  this.saveNewRef(tagRef, tag);
355
350
  }
@@ -362,155 +357,3 @@ class Repository {
362
357
  }
363
358
  }
364
359
  exports.Repository = Repository;
365
- const treeToObject = (tree) => {
366
- return JSON.parse((0, fflate_1.strFromU8)((0, fflate_1.decompressSync)(Buffer.from(tree, "base64"))));
367
- };
368
- const getLastItem = (thePath) => thePath.substring(thePath.lastIndexOf("/") + 1);
369
- const mapPath = (from, to, commits) => {
370
- let c = to;
371
- while (c !== undefined) {
372
- c = commits.find((parent) => parent.hash === (c === null || c === void 0 ? void 0 : c.parent));
373
- if ((c === null || c === void 0 ? void 0 : c.hash) === from.hash) {
374
- return [true];
375
- }
376
- }
377
- return [false];
378
- };
379
- /**
380
- * Returns the commit to which the provided ref is pointing
381
- * @param ref - needs to be in key format, e.g. refs/heads/... or refs/tags/...
382
- * @param references
383
- * @param commitsList
384
- */
385
- const commitAtRefIn = (ref, references, commitsList) => {
386
- const reference = references.get(ref);
387
- if (!reference) {
388
- throw new Error(`unreachable: '${ref}' is not present`);
389
- }
390
- let commitHash;
391
- if (reference.value.includes(headValueRefPrefix)) {
392
- const refKey = (0, exports.cleanRefValue)(reference.value);
393
- const targetRef = references.get(refKey);
394
- if (!targetRef) {
395
- // target branch may not have been saved yet
396
- return undefined;
397
- }
398
- commitHash = targetRef.value;
399
- }
400
- else {
401
- commitHash = reference.value;
402
- }
403
- for (const c of commitsList) {
404
- if (c.hash === commitHash) {
405
- return c;
406
- }
407
- }
408
- return undefined;
409
- };
410
- const refsAtCommit = (references, commit) => {
411
- const list = [];
412
- for (const [name, ref] of references.entries()) {
413
- if (ref.value === commit.hash) {
414
- list.push(ref);
415
- }
416
- }
417
- return list;
418
- };
419
- /**
420
- * Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
421
- * - a commit of type Commit
422
- * - isRef boolean whether it is a direct reference
423
- * - ref the key of the reference
424
- */
425
- const shaishToCommit = (shaish, references, commitsList) => {
426
- let sha = shaish;
427
- let isRef = false;
428
- let refKey = undefined;
429
- // check for refs
430
- for (const [name, ref] of references.entries()) {
431
- // match on
432
- if (ref.name === shaish || name === shaish) {
433
- isRef = true;
434
- refKey = name;
435
- sha = ref.value;
436
- if (sha.includes(headValueRefPrefix)) {
437
- const cleanedRef = (0, exports.cleanRefValue)(sha);
438
- const c = commitAtRefIn(cleanedRef, references, commitsList);
439
- if (!c) {
440
- throw new Error(`${cleanedRef} points to non-existing commit`);
441
- }
442
- return [c, isRef, refKey];
443
- }
444
- break;
445
- }
446
- }
447
- // check for partial sha matches
448
- const found = commitsList.filter((c) => c.hash.indexOf(sha) > -1);
449
- if (found.length === 0) {
450
- throw new Error(`pathspec '${shaish}' did not match any known refs`);
451
- }
452
- // but sha should be specific enough to resolve to 1 commit
453
- if (found.length > 1) {
454
- throw new Error(`commit `);
455
- }
456
- return [found[0], isRef, refKey];
457
- };
458
- const createHeadRefValue = (refKey) => {
459
- return `${headValueRefPrefix}${refKey}`;
460
- };
461
- exports.createHeadRefValue = createHeadRefValue;
462
- const isTagRef = (refKey) => refKey.indexOf(tagRefPathPrefix) > -1;
463
- exports.isTagRef = isTagRef;
464
- const cleanRefValue = (ref) => ref.replace(headValueRefPrefix, "");
465
- exports.cleanRefValue = cleanRefValue;
466
- const brancheNameToRef = (name) => {
467
- return `${headsRefPathPrefix}${name}`;
468
- };
469
- exports.brancheNameToRef = brancheNameToRef;
470
- const tagToRef = (tag) => {
471
- return `${tagRefPathPrefix}${tag}`;
472
- };
473
- exports.tagToRef = tagToRef;
474
- const validateBranchName = (name) => {
475
- if (!(0, ref_1.validBranch)(name)) {
476
- throw new Error(`invalid ref name`);
477
- }
478
- };
479
- exports.validateBranchName = validateBranchName;
480
- const validateRef = (name, oneLevel = true) => {
481
- if (!(0, ref_1.validRef)(name, oneLevel)) {
482
- throw new Error(`invalid ref name`);
483
- }
484
- };
485
- exports.validateRef = validateRef;
486
- /**
487
- * Prints the underlying changelog of a repository
488
- * @param repository
489
- */
490
- const printChangeLog = (repository) => {
491
- console.log("----------------------------------------------------------");
492
- console.log("Changelog");
493
- console.log("----------------------------------------------------------");
494
- const history = repository.getHistory();
495
- const head = commitAtRefIn(repository.head(), history.refs, history.commits);
496
- if (!head) {
497
- throw new Error(`fatal: HEAD is not defined`);
498
- }
499
- let c = head;
500
- while (c) {
501
- console.log(`${c.hash} ${refsAtCommit(history.refs, c)
502
- .map((r) => r.name)
503
- .join(" ")}`);
504
- for (const chg of c.changes) {
505
- (0, exports.printChange)(chg);
506
- }
507
- c = history.commits.find((parent) => parent.hash === (c === null || c === void 0 ? void 0 : c.parent));
508
- }
509
- console.log("End of changelog");
510
- console.log("----------------------------------------------------------");
511
- };
512
- exports.printChangeLog = printChangeLog;
513
- const printChange = (chg) => {
514
- console.log(` ${JSON.stringify(chg)}`);
515
- };
516
- exports.printChange = printChange;
package/lib/utils.d.ts CHANGED
@@ -1 +1,56 @@
1
+ import { Commit } from "./commit";
2
+ import { Reference } from "./interfaces";
3
+ import { Operation } from "fast-json-patch";
4
+ import { RepositoryObject } from "./repository";
1
5
  export declare const cleanAuthor: (author: string) => [name: string, email: string];
6
+ export declare const localRefPrefix = "refs/";
7
+ export declare const remoteRefPrefix = "refs/remotes/origin/";
8
+ export declare const tagRefPathPrefix = "tags/";
9
+ export declare const headsRefPathPrefix = "heads/";
10
+ export declare const headValueRefPrefix = "ref: ";
11
+ export declare const localHeadPathPrefix: () => string;
12
+ export declare const remoteHeadPathPrefix: () => string;
13
+ export declare const localTagPathPrefix: () => string;
14
+ export declare const remoteTagPathPrefix: () => string;
15
+ export declare const REFS_HEAD_KEY = "HEAD";
16
+ /**
17
+ * Should only be used in local context
18
+ */
19
+ export declare const REFS_MAIN_KEY: string;
20
+ export declare const treeToObject: <T = any>(tree: string) => T;
21
+ export declare const mapPath: (from: Commit, to: Commit, commits: Commit[]) => [isAncestor: boolean];
22
+ /**
23
+ * Returns the commit to which the provided ref is pointing
24
+ * @param ref - needs to be in key format, e.g. refs/heads/... or refs/tags/...
25
+ * @param references
26
+ * @param commitsList
27
+ */
28
+ export declare const commitAtRefIn: (ref: string, references: Map<string, Reference>, commitsList: Commit[]) => Commit | undefined;
29
+ export declare const refsAtCommit: (references: Map<string, Reference>, commit: Commit) => Reference[];
30
+ /**
31
+ * Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
32
+ * - a commit of type Commit
33
+ * - isRef boolean whether it is a direct reference
34
+ * - ref the key of the reference
35
+ */
36
+ export declare const shaishToCommit: (shaish: string, references: Map<string, Reference>, commitsList: Commit[]) => [commit: Commit, isRef: boolean, ref: string | undefined];
37
+ export declare const createHeadRefValue: (refKey: string) => string;
38
+ export declare const isTagRef: (refKey: string) => boolean;
39
+ export declare const cleanRefValue: (ref: string) => string;
40
+ export declare const brancheNameToRef: (name: string) => string;
41
+ export declare const tagToRef: (tag: string) => string;
42
+ export declare const validateBranchName: (name: string) => void;
43
+ export declare const validateRef: (name: string, oneLevel?: boolean) => void;
44
+ /**
45
+ * Prints the underlying changelog of a repository
46
+ * @param repository
47
+ */
48
+ export declare const printChangeLog: <T extends {
49
+ [k: string]: any;
50
+ }>(repository: RepositoryObject<T>) => void;
51
+ export declare const printChange: (chg: Operation) => void;
52
+ /**
53
+ * Should be called with a `/` delimited ref path. E.g. refs/heads/main
54
+ * @param thePath
55
+ */
56
+ export declare const getLastRefPathElement: (thePath: string) => string;
package/lib/utils.js CHANGED
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.cleanAuthor = void 0;
4
- // [RFC5322](https://www.ietf.org/rfc/rfc5322.txt)
3
+ exports.getLastRefPathElement = exports.printChange = exports.printChangeLog = exports.validateRef = exports.validateBranchName = exports.tagToRef = exports.brancheNameToRef = exports.cleanRefValue = exports.isTagRef = exports.createHeadRefValue = exports.shaishToCommit = exports.refsAtCommit = exports.commitAtRefIn = exports.mapPath = exports.treeToObject = exports.REFS_MAIN_KEY = exports.REFS_HEAD_KEY = exports.remoteTagPathPrefix = exports.localTagPathPrefix = exports.remoteHeadPathPrefix = exports.localHeadPathPrefix = exports.headValueRefPrefix = exports.headsRefPathPrefix = exports.tagRefPathPrefix = exports.remoteRefPrefix = exports.localRefPrefix = exports.cleanAuthor = void 0;
4
+ const fflate_1 = require("fflate");
5
+ const ref_1 = require("./ref");
5
6
  const emailRegex = /(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/;
6
7
  const cleanAuthor = (author) => {
7
8
  if (author === "") {
@@ -25,3 +26,183 @@ const cleanAuthor = (author) => {
25
26
  return [author, ""];
26
27
  };
27
28
  exports.cleanAuthor = cleanAuthor;
29
+ exports.localRefPrefix = `refs/`;
30
+ exports.remoteRefPrefix = `refs/remotes/origin/`;
31
+ exports.tagRefPathPrefix = "tags/";
32
+ exports.headsRefPathPrefix = "heads/";
33
+ exports.headValueRefPrefix = "ref: ";
34
+ const localHeadPathPrefix = () => `${exports.localRefPrefix}${exports.headsRefPathPrefix}`;
35
+ exports.localHeadPathPrefix = localHeadPathPrefix;
36
+ const remoteHeadPathPrefix = () => `${exports.remoteRefPrefix}${exports.headsRefPathPrefix}`;
37
+ exports.remoteHeadPathPrefix = remoteHeadPathPrefix;
38
+ const localTagPathPrefix = () => `${exports.localRefPrefix}${exports.tagRefPathPrefix}`;
39
+ exports.localTagPathPrefix = localTagPathPrefix;
40
+ const remoteTagPathPrefix = () => `${exports.remoteRefPrefix}${exports.tagRefPathPrefix}`;
41
+ exports.remoteTagPathPrefix = remoteTagPathPrefix;
42
+ exports.REFS_HEAD_KEY = "HEAD";
43
+ /**
44
+ * Should only be used in local context
45
+ */
46
+ exports.REFS_MAIN_KEY = `${(0, exports.localHeadPathPrefix)()}main`;
47
+ const treeToObject = (tree) => {
48
+ return JSON.parse((0, fflate_1.strFromU8)((0, fflate_1.decompressSync)(Buffer.from(tree, "base64"))));
49
+ };
50
+ exports.treeToObject = treeToObject;
51
+ const mapPath = (from, to, commits) => {
52
+ let c = to;
53
+ while (c !== undefined) {
54
+ c = commits.find((parent) => parent.hash === (c === null || c === void 0 ? void 0 : c.parent));
55
+ if ((c === null || c === void 0 ? void 0 : c.hash) === from.hash) {
56
+ return [true];
57
+ }
58
+ }
59
+ return [false];
60
+ };
61
+ exports.mapPath = mapPath;
62
+ /**
63
+ * Returns the commit to which the provided ref is pointing
64
+ * @param ref - needs to be in key format, e.g. refs/heads/... or refs/tags/...
65
+ * @param references
66
+ * @param commitsList
67
+ */
68
+ const commitAtRefIn = (ref, references, commitsList) => {
69
+ const reference = references.get(ref);
70
+ if (!reference) {
71
+ throw new Error(`unreachable: '${ref}' is not present`);
72
+ }
73
+ let commitHash;
74
+ if (reference.value.includes(exports.headValueRefPrefix)) {
75
+ const refKey = (0, exports.cleanRefValue)(reference.value);
76
+ const targetRef = references.get(refKey);
77
+ if (!targetRef) {
78
+ // target branch may not have been saved yet
79
+ return undefined;
80
+ }
81
+ commitHash = targetRef.value;
82
+ }
83
+ else {
84
+ commitHash = reference.value;
85
+ }
86
+ for (const c of commitsList) {
87
+ if (c.hash === commitHash) {
88
+ return c;
89
+ }
90
+ }
91
+ return undefined;
92
+ };
93
+ exports.commitAtRefIn = commitAtRefIn;
94
+ const refsAtCommit = (references, commit) => {
95
+ const list = [];
96
+ for (const [name, ref] of references.entries()) {
97
+ if (ref.value === commit.hash) {
98
+ list.push(ref);
99
+ }
100
+ }
101
+ return list;
102
+ };
103
+ exports.refsAtCommit = refsAtCommit;
104
+ /**
105
+ * Accepts a shaish expression (e.g. refs (branches, tags), commitSha) and returns
106
+ * - a commit of type Commit
107
+ * - isRef boolean whether it is a direct reference
108
+ * - ref the key of the reference
109
+ */
110
+ const shaishToCommit = (shaish, references, commitsList) => {
111
+ let sha = shaish;
112
+ let isRef = false;
113
+ let refKey = undefined;
114
+ // check for refs
115
+ for (const [name, ref] of references.entries()) {
116
+ // match on
117
+ if (ref.name === shaish || name === shaish) {
118
+ isRef = true;
119
+ refKey = name;
120
+ sha = ref.value;
121
+ if (sha.includes(exports.headValueRefPrefix)) {
122
+ const cleanedRef = (0, exports.cleanRefValue)(sha);
123
+ const c = (0, exports.commitAtRefIn)(cleanedRef, references, commitsList);
124
+ if (!c) {
125
+ throw new Error(`${cleanedRef} points to non-existing commit`);
126
+ }
127
+ return [c, isRef, refKey];
128
+ }
129
+ break;
130
+ }
131
+ }
132
+ // check for partial sha matches
133
+ const found = commitsList.filter((c) => c.hash.indexOf(sha) > -1);
134
+ if (found.length === 0) {
135
+ throw new Error(`pathspec '${shaish}' did not match any known refs`);
136
+ }
137
+ // but sha should be specific enough to resolve to 1 commit
138
+ if (found.length > 1) {
139
+ throw new Error(`commit `);
140
+ }
141
+ return [found[0], isRef, refKey];
142
+ };
143
+ exports.shaishToCommit = shaishToCommit;
144
+ const createHeadRefValue = (refKey) => {
145
+ return `${exports.headValueRefPrefix}${refKey}`;
146
+ };
147
+ exports.createHeadRefValue = createHeadRefValue;
148
+ const isTagRef = (refKey) => refKey.indexOf((0, exports.localTagPathPrefix)()) > -1;
149
+ exports.isTagRef = isTagRef;
150
+ const cleanRefValue = (ref) => ref.replace(exports.headValueRefPrefix, "");
151
+ exports.cleanRefValue = cleanRefValue;
152
+ const brancheNameToRef = (name) => {
153
+ return `${(0, exports.localHeadPathPrefix)()}${name}`;
154
+ };
155
+ exports.brancheNameToRef = brancheNameToRef;
156
+ const tagToRef = (tag) => {
157
+ return `${(0, exports.localTagPathPrefix)()}${tag}`;
158
+ };
159
+ exports.tagToRef = tagToRef;
160
+ const validateBranchName = (name) => {
161
+ if (!(0, ref_1.validBranch)(name)) {
162
+ throw new Error(`invalid ref name`);
163
+ }
164
+ };
165
+ exports.validateBranchName = validateBranchName;
166
+ const validateRef = (name, oneLevel = true) => {
167
+ if (!(0, ref_1.validRef)(name, oneLevel)) {
168
+ throw new Error(`invalid ref name`);
169
+ }
170
+ };
171
+ exports.validateRef = validateRef;
172
+ /**
173
+ * Prints the underlying changelog of a repository
174
+ * @param repository
175
+ */
176
+ const printChangeLog = (repository) => {
177
+ console.log("----------------------------------------------------------");
178
+ console.log("Changelog");
179
+ console.log("----------------------------------------------------------");
180
+ const history = repository.getHistory();
181
+ const head = (0, exports.commitAtRefIn)(repository.head(), history.refs, history.commits);
182
+ if (!head) {
183
+ throw new Error(`fatal: HEAD is not defined`);
184
+ }
185
+ let c = head;
186
+ while (c) {
187
+ console.log(`${c.hash} ${(0, exports.refsAtCommit)(history.refs, c)
188
+ .map((r) => r.name)
189
+ .join(" ")}`);
190
+ for (const chg of c.changes) {
191
+ (0, exports.printChange)(chg);
192
+ }
193
+ c = history.commits.find((parent) => parent.hash === (c === null || c === void 0 ? void 0 : c.parent));
194
+ }
195
+ console.log("End of changelog");
196
+ console.log("----------------------------------------------------------");
197
+ };
198
+ exports.printChangeLog = printChangeLog;
199
+ const printChange = (chg) => {
200
+ console.log(` ${JSON.stringify(chg)}`);
201
+ };
202
+ exports.printChange = printChange;
203
+ /**
204
+ * Should be called with a `/` delimited ref path. E.g. refs/heads/main
205
+ * @param thePath
206
+ */
207
+ const getLastRefPathElement = (thePath) => thePath.substring(thePath.lastIndexOf("/") + 1);
208
+ exports.getLastRefPathElement = getLastRefPathElement;
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "type": "git",
5
5
  "url": "https://github.com/dotindustries/ogre.git"
6
6
  },
7
- "version": "0.7.0",
7
+ "version": "0.8.0",
8
8
  "description": "Git-like repository for in-memory object versioning",
9
9
  "private": false,
10
10
  "main": "lib/index.js",
@@ -37,5 +37,5 @@
37
37
  "registry": "https://registry.npmjs.org/",
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "09b9f4937721eae3bbf38bce555a0a3000f82eba"
40
+ "gitHead": "8745cba07d9dc502ee7b0fc595d660a5de58f64f"
41
41
  }
@@ -8,7 +8,8 @@ import {
8
8
  testAuthor,
9
9
  updateHeaderData,
10
10
  } from "./test.utils";
11
- import { printChangeLog, Repository } from "./repository";
11
+ import { Repository } from "./repository";
12
+ import { printChangeLog } from "./utils";
12
13
 
13
14
  test("baseline with 1 commit and zero changelog entries", async (t) => {
14
15
  const [repo] = await getBaseline();
package/src/git2json.ts CHANGED
@@ -1,7 +1,11 @@
1
1
  import { Commit } from "./commit";
2
2
  import { History, Reference } from "./interfaces";
3
- import { createHeadRefValue, isTagRef, REFS_HEAD_KEY } from "./repository";
4
- import { cleanAuthor } from "./utils";
3
+ import {
4
+ cleanAuthor,
5
+ createHeadRefValue,
6
+ isTagRef,
7
+ REFS_HEAD_KEY,
8
+ } from "./utils";
5
9
 
6
10
  const findRefs = (commit: Commit, refs: Map<string, Reference>) => {
7
11
  const list = [];