@dotinc/ogre 0.2.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,3 +1,20 @@
1
+ # v0.3.0 (Sun Mar 13 2022)
2
+
3
+ #### 🚀 Enhancement
4
+
5
+ - Implement tags [#6](https://github.com/dotindustries/ogre/pull/6) ([@nadilas](https://github.com/nadilas))
6
+ - feat: implement tags ([@nadilas](https://github.com/nadilas))
7
+
8
+ #### 🐛 Bug Fix
9
+
10
+ - doc: update README.md ([@nadilas](https://github.com/nadilas))
11
+
12
+ #### Authors: 1
13
+
14
+ - [@nadilas](https://github.com/nadilas)
15
+
16
+ ---
17
+
1
18
  # v0.2.0 (Sun Mar 13 2022)
2
19
 
3
20
  #### 🚀 Enhancement
package/README.md CHANGED
@@ -7,7 +7,9 @@ keep the history around for a bit longer.
7
7
 
8
8
  - Commit
9
9
  - Branch
10
+ - Tags
10
11
  - Checkout
12
+ - Visualization via `@dotinc/ogre-react`
11
13
  - Merge
12
14
  - fast-forward
13
15
 
@@ -35,6 +37,7 @@ repo.data.name = 'a fancier name'
35
37
  await repo.commit('change name', 'author <author@test.com>')
36
38
  repo.checkout('main')
37
39
  repo.merge('add_details')
40
+ repo.tag('v1.0.0')
38
41
 
39
42
  // or b) discard change and go back
40
43
  // by using the branch name
@@ -45,7 +48,6 @@ repo.data.name = 'a fancier name'
45
48
 
46
49
  ## TODO
47
50
 
48
- - [ ] Visualization
49
51
  - [ ] Merge
50
52
  - [ ] recursive
51
53
  - [ ] octopus
@@ -16,6 +16,7 @@ export interface RepositoryObject<T> {
16
16
  createBranch(name: string): string;
17
17
  merge(source: string | RepositoryObject<T> | History): string;
18
18
  branch(): string;
19
+ tag(tag: string): string;
19
20
  }
20
21
  export interface RespositoryObjectType {
21
22
  new <T>(obj: T, options: RepositoryOptions<T>): RepositoryObject<T>;
@@ -28,7 +29,9 @@ export declare const createHeadRefValue: (refKey: string) => string;
28
29
  export declare const isTagRef: (refKey: string) => boolean;
29
30
  export declare const cleanRefValue: (ref: string) => string;
30
31
  export declare const brancheNameToRef: (name: string) => string;
32
+ export declare const tagToRef: (tag: string) => string;
31
33
  export declare const validateBranchName: (name: string) => void;
34
+ export declare const validateRef: (name: string, oneLevel?: boolean) => void;
32
35
  /**
33
36
  * Prints the underlying changelog of a repository
34
37
  * @param repository
package/lib/repository.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.printChangeLog = exports.validateBranchName = exports.brancheNameToRef = exports.cleanRefValue = exports.isTagRef = exports.createHeadRefValue = exports.Repository = exports.REFS_MAIN_KEY = exports.REFS_HEAD_KEY = void 0;
3
+ 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;
4
4
  const commit_1 = require("./commit");
5
5
  const ref_1 = require("./ref");
6
6
  const hash_1 = require("./hash");
@@ -256,9 +256,7 @@ exports.Repository = function (obj, options) {
256
256
  moveRef(exports.REFS_HEAD_KEY, isRef && refKey !== undefined ? refKey : commit);
257
257
  }
258
258
  };
259
- this.createBranch = (name) => {
260
- (0, exports.validateBranchName)(name);
261
- const refName = (0, exports.brancheNameToRef)(name);
259
+ const saveNewRef = (refKey, name) => {
262
260
  const headCommit = commitAtHead();
263
261
  if (!headCommit) {
264
262
  const headRef = this.head();
@@ -267,8 +265,31 @@ exports.Repository = function (obj, options) {
267
265
  }
268
266
  throw new Error(`fatal: not a valid object name: '${getLastItem(headRef)}'`);
269
267
  }
270
- refs.set(refName, { name: name, value: headCommit.hash });
271
- return refName;
268
+ refs.set(refKey, { name: name, value: headCommit.hash });
269
+ };
270
+ this.createBranch = (name) => {
271
+ (0, exports.validateBranchName)(name);
272
+ const branchRef = (0, exports.brancheNameToRef)(name);
273
+ saveNewRef(branchRef, name);
274
+ return branchRef;
275
+ };
276
+ this.tag = tag => {
277
+ try {
278
+ (0, exports.validateRef)(tag);
279
+ }
280
+ catch (e) {
281
+ throw new Error(`fatal: '${tag}' is not a valid tag name`);
282
+ }
283
+ const tagRef = (0, exports.tagToRef)(tag);
284
+ try {
285
+ saveNewRef(tagRef, tag);
286
+ }
287
+ catch (e) {
288
+ // because git has to make it weird and show a different error
289
+ // unlike when creating a branch on a HEAD pointing to a ref which does not exist yet
290
+ throw new Error(`fatal: failed to resolve 'HEAD' as a valid ref.`);
291
+ }
292
+ return tagRef;
272
293
  };
273
294
  const moveRef = (refName, value) => {
274
295
  let ref = refs.get(refName);
@@ -442,12 +463,22 @@ const brancheNameToRef = (name) => {
442
463
  return `${headsRefPathPrefix}${name}`;
443
464
  };
444
465
  exports.brancheNameToRef = brancheNameToRef;
466
+ const tagToRef = (tag) => {
467
+ return `${tagRefPathPrefix}${tag}`;
468
+ };
469
+ exports.tagToRef = tagToRef;
445
470
  const validateBranchName = (name) => {
446
471
  if (!(0, ref_1.validBranch)(name)) {
447
472
  throw new Error(`invalid ref name`);
448
473
  }
449
474
  };
450
475
  exports.validateBranchName = validateBranchName;
476
+ const validateRef = (name, oneLevel = true) => {
477
+ if (!(0, ref_1.validRef)(name, oneLevel)) {
478
+ throw new Error(`invalid ref name`);
479
+ }
480
+ };
481
+ exports.validateRef = validateRef;
451
482
  /**
452
483
  * Prints the underlying changelog of a repository
453
484
  * @param repository
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.2.0",
7
+ "version": "0.3.0",
8
8
  "description": "Git-like repository for in-memory object versioning",
9
9
  "main": "lib/index.js",
10
10
  "types": "lib/index.d.ts",
@@ -45,5 +45,5 @@
45
45
  "registry": "https://registry.npmjs.org/",
46
46
  "access": "public"
47
47
  },
48
- "gitHead": "fb4343e4c5f6cc2b87eb9204a643b6cd632ada69"
48
+ "gitHead": "ac487e2d4fc3b1a18dd02b20edc89cf0503c3a98"
49
49
  }
package/src/repository.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Change, History, Reference } from './interfaces'
2
2
  import { calculateCommitHash, Commit } from './commit'
3
- import { validBranch } from './ref'
3
+ import {validBranch, validRef} from './ref'
4
4
  import {digest} from './hash'
5
5
 
6
6
  const tagRefPathPrefix = 'refs/tags/'
@@ -38,6 +38,7 @@ export interface RepositoryObject<T> {
38
38
 
39
39
  branch(): string
40
40
 
41
+ tag(tag: string): string
41
42
  }
42
43
 
43
44
  export interface RespositoryObjectType {
@@ -312,9 +313,7 @@ export const Repository = function <T extends { [k: PropertyKey]: any }>(
312
313
  moveRef(REFS_HEAD_KEY, isRef && refKey !== undefined ? refKey : commit)
313
314
  }
314
315
  }
315
- this.createBranch = (name) => {
316
- validateBranchName(name)
317
- const refName = brancheNameToRef(name)
316
+ const saveNewRef = (refKey: string, name: string) => {
318
317
  const headCommit = commitAtHead()
319
318
  if (!headCommit) {
320
319
  const headRef = this.head()
@@ -323,8 +322,29 @@ export const Repository = function <T extends { [k: PropertyKey]: any }>(
323
322
  }
324
323
  throw new Error(`fatal: not a valid object name: '${getLastItem(headRef)}'`)
325
324
  }
326
- refs.set(refName, { name: name, value: headCommit.hash })
327
- return refName
325
+ refs.set(refKey, { name: name, value: headCommit.hash })
326
+ }
327
+ this.createBranch = (name) => {
328
+ validateBranchName(name)
329
+ const branchRef = brancheNameToRef(name)
330
+ saveNewRef(branchRef, name)
331
+ return branchRef
332
+ }
333
+ this.tag = tag => {
334
+ try {
335
+ validateRef(tag)
336
+ } catch (e) {
337
+ throw new Error(`fatal: '${tag}' is not a valid tag name`)
338
+ }
339
+ const tagRef = tagToRef(tag)
340
+ try {
341
+ saveNewRef(tagRef, tag)
342
+ } catch (e) {
343
+ // because git has to make it weird and show a different error
344
+ // unlike when creating a branch on a HEAD pointing to a ref which does not exist yet
345
+ throw new Error(`fatal: failed to resolve 'HEAD' as a valid ref.`)
346
+ }
347
+ return tagRef
328
348
  }
329
349
  const moveRef = (refName: string, value: string | Commit) => {
330
350
  let ref = refs.get(refName)
@@ -510,12 +530,22 @@ export const brancheNameToRef = (name: string) => {
510
530
  return `${headsRefPathPrefix}${name}`
511
531
  }
512
532
 
533
+ export const tagToRef = (tag: string) => {
534
+ return `${tagRefPathPrefix}${tag}`
535
+ }
536
+
513
537
  export const validateBranchName = (name: string) => {
514
538
  if (!validBranch(name)) {
515
539
  throw new Error(`invalid ref name`)
516
540
  }
517
541
  }
518
542
 
543
+ export const validateRef = (name: string, oneLevel: boolean = true) => {
544
+ if (!validRef(name, oneLevel)) {
545
+ throw new Error(`invalid ref name`)
546
+ }
547
+ }
548
+
519
549
  /**
520
550
  * Prints the underlying changelog of a repository
521
551
  * @param repository
@@ -0,0 +1,36 @@
1
+ import test from 'ava'
2
+ import {getBaseline, testAuthor} from './test.utils'
3
+
4
+ test('cannot tag on an empty repo', async t => {
5
+ const [repo] = await getBaseline()
6
+
7
+ t.throws(() => {
8
+ repo.tag('v1.0.0')
9
+ }, {message: `fatal: failed to resolve 'HEAD' as a valid ref.`})
10
+ })
11
+
12
+ test('can create simple tag pointing to HEAD', async t => {
13
+ const [repo] = await getBaseline()
14
+ repo.data.name = 'name'
15
+ const commit = await repo.commit('initial commit', testAuthor)
16
+ const tag = 'v1.0.0'
17
+
18
+ const tagRef = repo.tag(tag)
19
+
20
+ let expectedRefKey = `refs/tags/${tag}`
21
+ t.is(tagRef, expectedRefKey)
22
+ t.is(repo.ref(tagRef), commit, 'tag is not pointing to expected commit')
23
+ const {refs} = repo.getHistory()
24
+ t.true(refs.has(expectedRefKey), 'reference was not present in history')
25
+ })
26
+
27
+ test('cannot create tag with whitespace', async t => {
28
+ const [repo] = await getBaseline()
29
+ repo.data.name = 'name'
30
+ await repo.commit('initial commit', testAuthor)
31
+ const tag = 'first release'
32
+
33
+ t.throws(() => {
34
+ repo.tag(tag)
35
+ }, {message: `fatal: '${tag}' is not a valid tag name`})
36
+ })