Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move formatgit2json to core lib #130

Merged
merged 2 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,3 @@
#### Authors: 1

- [@nadilas](https://github.com/nadilas)

40 changes: 20 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ogre

An in-memory git-like repository for objects for when you need to
An in-memory git-like repository for objects for when you need to
keep the history around for a bit longer.

[![codecov](https://codecov.io/gh/dotindustries/ogre/branch/main/graph/badge.svg?token=23M014CWLK)](https://codecov.io/gh/dotindustries/ogre) [![Test coverage](https://github.com/dotindustries/ogre/actions/workflows/coverage.yml/badge.svg)](https://github.com/dotindustries/ogre/actions/workflows/coverage.yml)
Expand All @@ -13,43 +13,43 @@ keep the history around for a bit longer.
- Checkout
- Visualization via `@dotinc/ogre-react`
- Merge
- fast-forward
- fast-forward

## Usage

```typescript
const repo = new Repository(new ComplexObject())
const repo = new Repository(new ComplexObject());

// apply changes
repo.data.name = 'my name'
repo.data.description = 'now we have a description'
repo.data.name = "my name";
repo.data.description = "now we have a description";

// commit changes
const init = await repo.commit('initial commit', 'author <author@test.com>')
// commit changes
const init = await repo.commit("initial commit", "author <author@test.com>");
// create a branch named savepoint pointing to the last commit
repo.createBranch('savepoint')
repo.createBranch("savepoint");

// switch to new branch
repo.checkout('add_details', true)
repo.checkout("add_details", true);

// apply changes
repo.data.name = 'a fancier name'
repo.data.name = "a fancier name";

// a) commit & merge
await repo.commit('change name', 'author <author@test.com>')
repo.checkout('main')
repo.merge('add_details')
repo.tag('v1.0.0')
await repo.commit("change name", "author <author@test.com>");
repo.checkout("main");
repo.merge("add_details");
repo.tag("v1.0.0");

// or b) discard change and go back
// by using the branch name
repo.checkout('main')
// by using the commit hash in a detached state
repo.checkout(init)
// by using the branch name
repo.checkout("main");
// by using the commit hash in a detached state
repo.checkout(init);
```

## TODO

- [ ] Merge
- [ ] recursive
- [ ] octopus
- [ ] recursive
- [ ] octopus
12 changes: 12 additions & 0 deletions apps/ogre-cli/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root = true

[*]
indent_style = tab
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.yml]
indent_style = space
indent_size = 2
1 change: 1 addition & 0 deletions apps/ogre-cli/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
* text=auto eol=lf
2 changes: 2 additions & 0 deletions apps/ogre-cli/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
1 change: 1 addition & 0 deletions apps/ogre-cli/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
60 changes: 60 additions & 0 deletions apps/ogre-cli/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
{
"name": "@dotinc/ogre-cli",
"version": "0.0.0",
"license": "MIT",
"bin": "dist/cli.js",
"type": "module",
"engines": {
"node": ">=16"
},
"scripts": {
"build": "tsc",
"dev": "tsc --watch",
"test": "prettier --check . && xo && ava"
},
"files": [
"dist"
],
"dependencies": {
"meow": "^11.0.0",
"@gitgraph/core": "1.5.0",
"chalk": "^5.3.0",
"color-convert": "^2.0.1",
"lodash": "^4.17.21"
},
"devDependencies": {
"@sindresorhus/tsconfig": "^3.0.1",
"@types/react": "^18.0.32",
"@vdemedes/prettier-config": "^2.0.1",
"ava": "^5.2.0",
"chalk": "^5.2.0",
"eslint-config-xo-react": "^0.27.0",
"eslint-plugin-react": "^7.32.2",
"eslint-plugin-react-hooks": "^4.6.0",
"prettier": "^2.8.7",
"ts-node": "^10.9.1",
"typescript": "^5.0.3",
"xo": "^0.53.1",
"@types/lodash": "^4.14.202",
"@types/node": "^20.11.17",
"auto-changelog": "^2.4.0",
"@types/color-convert": "^2.0.3"
},
"ava": {
"extensions": {
"ts": "module",
"tsx": "module"
},
"nodeArguments": [
"--loader=ts-node/esm"
]
},
"xo": {
"extends": "xo-react",
"prettier": true,
"rules": {
"react/prop-types": "off"
}
},
"prettier": "@vdemedes/prettier-config"
}
25 changes: 25 additions & 0 deletions apps/ogre-cli/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# ogre-cli

> This readme is automatically generated by [create-ink-app](https://github.com/vadimdemedes/create-ink-app)

## Install

```bash
$ npm install --global ogre-cli
```

## CLI

```
$ ogre-cli --help

Usage
$ ogre-cli

Options
--name Your name

Examples
$ ogre-cli --name=Jane
Hello, Jane
```
70 changes: 70 additions & 0 deletions apps/ogre-cli/source/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#!/usr/bin/env node
import meow from 'meow';

import {formatGit2Json, Repository} from '@dotinc/ogre';
import {GitgraphUserApi} from '@gitgraph/core';

import {Gitgraph, render} from './graph/index.js';

const cli = meow(
`
Usage
$ ogre-cli

Options
--name Your name

Examples
$ ogre-cli --name=Jane
Hello, Jane
`,
{
importMeta: import.meta,
flags: {
name: {
type: 'string',
},
},
},
);

interface someClass {
name: string;
description: string;
}

const run = async ({name = 'author'}: {name?: string}) => {
const graph = new Gitgraph();

let author = `${name} <${name}@email.info>`;
const r = new Repository<someClass>({description: '', name}, {});
r.data.name = 'new name';
r.data.description = 'first description';
await r.commit('initial commit', author);

r.checkout('desc-up', true);
r.data.description = 'some longer different description';
await r.commit('change desc', author);

r.data.description = 'correct mistake made in prev description';
await r.commit('fix desc', author);

r.createBranch('another_branch');

r.data.description = 'yet another correction';
await r.commit('typo fix', author);

r.checkout('main');
r.merge('desc-up');

const history = r.getHistory();

// workaround to give an empty update method, otherwise we have window not defined issues
const graphuserapi = new GitgraphUserApi(graph, () => {});
graphuserapi.import(formatGit2Json(history));

render(graph);
console.log('finished rendering');
};

run({name: cli.flags.name});
123 changes: 123 additions & 0 deletions apps/ogre-cli/source/graph/buffer-graph-logger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import * as readline from 'readline';

import {GraphMap, ILogGraph} from './compute-graph-map/index.js';
import consoleGraphLogger from './console-graph-logger.js';

const DEFAULT_BUFFER_LENGTH = 10;

const bufferGraphLogger: ILogGraph = graph => {
let start = 0;

readline.emitKeypressEvents(process.stdin);

// Capture keypress events without having to hit "Enter".
if (process.stdin.setRawMode) {
process.stdin.setRawMode(true);
}

process.stdin.on('keypress', (_str, key: readline.Key) => {
// Implement `less`-style commands.
// https://en.wikipedia.org/wiki/Less_(Unix)#Frequently_used_commands
if (key.name === 'q') process.exit();
if (key.ctrl && key.name === 'c') process.exit();

if (key.name === 'up') moveOneLineUp();
if (key.name === 'k') moveOneLineUp();
if (key.name === 'b') moveOnePageUp();
if (key.name === 'g') moveToTop();
if (key.sequence === '<') moveToTop();

if (key.name === 'down') moveOneLineDown();
if (key.name === 'j') moveOneLineDown();
if (key.name === 'return') moveOneLineDown();
if (key.name === 'space') moveOnePageDown();
if (key.shift && key.name === 'g') moveToBottom();
if (key.sequence === '>') moveToBottom();
});

process.stdout.on('resize', () => {
const displayedBufferLength = graph.length - start;
if (bufferLength() >= displayedBufferLength) {
start = Math.max(top(), bottom());
}

render();
});

render();

function top() {
return 0;
}

function bottom() {
return graph.length - bufferLength();
}

function moveOneLineUp() {
moveUpOf(1);
}

function moveOnePageUp() {
moveUpOf(bufferLength());
}

function moveToTop() {
moveUpOf(start);
}

function moveUpOf(lines: number) {
if (start === 0) return;
start = Math.max(start - lines, top());
render();
}

function moveOneLineDown() {
moveDownOf(1);
}

function moveOnePageDown() {
moveDownOf(bufferLength());
}

function moveToBottom() {
moveDownOf(graph.length);
}

function moveDownOf(lines: number) {
if (end() >= graph.length) return;
start = Math.min(start + lines, bottom());
render();
}

function render() {
clear();
consoleGraphLogger(getBuffer());
}

function clear() {
// ANSI Escape Sequence for `<ESC>c` which is the escape code
// for resetting the terminal (clears the screen and buffer).
// https://en.wikipedia.org/wiki/ANSI_escape_code
process.stdout.write('\x1b[2J');
}

function getBuffer(): GraphMap {
return graph.slice(start, end());
}

function end() {
return start + bufferLength();
}
};

export function bufferLength(): number {
const length = process.env['BUFFER_LENGTH']
? parseInt(process.env['BUFFER_LENGTH'], 10)
: process.stdout.rows || DEFAULT_BUFFER_LENGTH;

// Length should be 0-indexed to compare with arrays.
return length - 1;
}

export default bufferGraphLogger;
Loading
Loading