UNPKG

@mieweb/wikigdrive

Version:

Google Drive to MarkDown synchronization

415 lines (336 loc) 15 kB
import fs from 'node:fs'; import path from 'node:path'; import {execSync} from 'node:child_process'; import winston from 'winston'; // eslint-disable-next-line import/no-unresolved import {assertStrictEquals} from 'asserts'; import {GitScanner} from '../../src/git/GitScanner.ts'; import {createTmpDir} from '../utils.ts'; import {instrumentLogger} from '../../src/utils/logger/logger.ts'; const COMMITER1 = { name: 'John', email: 'john@example.tld' }; const COMMITER2 = { name: 'Bob', email: 'bob@example.tld' }; const logger = winston.createLogger({ level: 'debug', defaultMeta: {}, transports: [ new winston.transports.Console() ] }); instrumentLogger(logger); Deno.test('test clone', async () => { // t.timeout(5000); const localRepoDir: string = createTmpDir(); const githubRepoDir: string = createTmpDir(); const secondRepoDir: string = createTmpDir(); execSync(`git init -b main --bare ${githubRepoDir}`); try { const scannerLocal = new GitScanner(logger, localRepoDir, COMMITER1.email); await scannerLocal.initialize(); fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Initial content'); { const changes = await scannerLocal.changes(); assertStrictEquals(2, (await scannerLocal.changes()).length); await scannerLocal.commit('First commit', changes.map(change => change.path), COMMITER1); } { const changes = await scannerLocal.changes(); assertStrictEquals(0, changes.length); } await scannerLocal.setRemoteUrl(githubRepoDir); await scannerLocal.pushBranch('main'); //// const scannerSecond = new GitScanner(logger, secondRepoDir, COMMITER2.email); await scannerSecond.initialize(); fs.unlinkSync(secondRepoDir + '/.gitignore'); await scannerSecond.setRemoteUrl(githubRepoDir); await scannerSecond.pullBranch('main'); { const files = fs.readdirSync(scannerSecond.rootPath); assertStrictEquals(3, files.length); assertStrictEquals(true, files.includes('.git')); assertStrictEquals(true, files.includes('.gitignore')); assertStrictEquals(true, files.includes('file1.txt')); } const headCommit = await scannerLocal.getBranchCommit('HEAD'); const masterCommit = await scannerLocal.getBranchCommit('main'); const remoteCommit = await scannerLocal.getBranchCommit('refs/remotes/origin/main'); assertStrictEquals(headCommit, masterCommit); assertStrictEquals(headCommit, remoteCommit); } finally { fs.rmSync(localRepoDir, { recursive: true, force: true }); fs.rmSync(githubRepoDir, { recursive: true, force: true }); fs.rmSync(secondRepoDir, { recursive: true, force: true }); } }); Deno.test('test fast forward', async () => { // t.timeout(5000); const localRepoDir: string = createTmpDir(); const githubRepoDir: string = createTmpDir(); const secondRepoDir: string = createTmpDir(); execSync(`git init -b main --bare ${githubRepoDir}`); try { const scannerLocal = new GitScanner(logger, localRepoDir, COMMITER1.email); await scannerLocal.initialize(); { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Initial content'); const changes = await scannerLocal.changes(); assertStrictEquals(2, (await scannerLocal.changes()).length); await scannerLocal.commit('First commit', changes.map(change => change.path), COMMITER1); } { const changes = await scannerLocal.changes(); assertStrictEquals(0, changes.length); } await scannerLocal.setRemoteUrl(githubRepoDir); await scannerLocal.pushBranch('main'); //// const scannerSecond = new GitScanner(logger, secondRepoDir, COMMITER2.email); await scannerSecond.initialize(); fs.unlinkSync(secondRepoDir + '/.gitignore'); await scannerSecond.setRemoteUrl(githubRepoDir); await scannerSecond.pullBranch('main'); { fs.writeFileSync(path.join(secondRepoDir, 'file1.txt'), 'Change on second repo'); const changes = await scannerSecond.changes(); assertStrictEquals(1, (await scannerSecond.changes()).length); await scannerSecond.commit('Change on second repo', changes.map(change => change.path), COMMITER2); await scannerSecond.pushBranch('main'); } await scannerLocal.pullBranch('main'); { // const history = await scannerLocal.history(''); // const files = fs.readdirSync(scannerLocal.rootPath); /* assertStrictEquals(3, files.length); assertStrictEquals(true, files.includes('.git')); assertStrictEquals(true, files.includes('.gitignore')); assertStrictEquals(true, files.includes('file1.txt')); */ } const headCommit = await scannerLocal.getBranchCommit('HEAD'); const masterCommit = await scannerLocal.getBranchCommit('main'); const remoteCommit = await scannerLocal.getBranchCommit('refs/remotes/origin/main'); assertStrictEquals(headCommit, masterCommit); assertStrictEquals(headCommit, remoteCommit); } finally { fs.rmSync(localRepoDir, { recursive: true, force: true }); fs.rmSync(githubRepoDir, { recursive: true, force: true }); fs.rmSync(secondRepoDir, { recursive: true, force: true }); } }); Deno.test('test local fast forward', async () => { // t.timeout(5000); const localRepoDir: string = createTmpDir(); const githubRepoDir: string = createTmpDir(); const secondRepoDir: string = createTmpDir(); execSync(`git init -b main --bare ${githubRepoDir}`); try { const scannerLocal = new GitScanner(logger, localRepoDir, COMMITER1.email); await scannerLocal.initialize(); { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Initial content'); const changes = await scannerLocal.changes(); assertStrictEquals(2, (await scannerLocal.changes()).length); await scannerLocal.commit('First commit', changes.map(change => change.path), COMMITER1); } { const changes = await scannerLocal.changes(); assertStrictEquals(0, changes.length); } await scannerLocal.setRemoteUrl(githubRepoDir); await scannerLocal.pushBranch('main'); const scannerSecond = new GitScanner(logger, secondRepoDir, COMMITER2.email); await scannerSecond.initialize(); fs.unlinkSync(secondRepoDir + '/.gitignore'); await scannerSecond.setRemoteUrl(githubRepoDir); await scannerSecond.pullBranch('main'); { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Change on local repo'); const changes = await scannerLocal.changes(); assertStrictEquals(1, (await scannerLocal.changes()).length); await scannerLocal.commit('Change on local repo', changes.map(change => change.path), COMMITER1); await scannerLocal.pushBranch('main'); } await scannerSecond.pullBranch('main'); { // const history = await scannerSecond.history(''); // const files = fs.readdirSync(scannerSecond.rootPath); /* assertStrictEquals(3, files.length); assertStrictEquals(true, files.includes('.git')); assertStrictEquals(true, files.includes('.gitignore')); assertStrictEquals(true, files.includes('file1.txt')); */ } const headCommit = await scannerSecond.getBranchCommit('HEAD'); const masterCommit = await scannerSecond.getBranchCommit('main'); const remoteCommit = await scannerSecond.getBranchCommit('refs/remotes/origin/main'); assertStrictEquals(headCommit, masterCommit); assertStrictEquals(headCommit, remoteCommit); } finally { fs.rmSync(localRepoDir, { recursive: true, force: true }); fs.rmSync(githubRepoDir, { recursive: true, force: true }); fs.rmSync(secondRepoDir, { recursive: true, force: true }); } }); Deno.test('test non conflict', async () => { // t.timeout(5000); const localRepoDir: string = createTmpDir(); const githubRepoDir: string = createTmpDir(); const secondRepoDir: string = createTmpDir(); execSync(`git init -b main --bare ${githubRepoDir}`); try { const scannerLocal = new GitScanner(logger, localRepoDir, COMMITER1.email); await scannerLocal.initialize(); { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Initial content'); const changes = await scannerLocal.changes(); assertStrictEquals(2, (await scannerLocal.changes()).length); await scannerLocal.commit('First commit', changes.map(change => change.path), COMMITER1); } { const changes = await scannerLocal.changes(); assertStrictEquals(0, changes.length); } await scannerLocal.setRemoteUrl(githubRepoDir); await scannerLocal.pushBranch('main'); //// const scannerSecond = new GitScanner(logger, secondRepoDir, COMMITER2.email); await scannerSecond.initialize(); fs.unlinkSync(secondRepoDir + '/.gitignore'); await scannerSecond.setRemoteUrl(githubRepoDir); await scannerSecond.pullBranch('main'); { fs.writeFileSync(path.join(secondRepoDir, 'file2.txt'), 'Change on second repo'); const changes = await scannerSecond.changes(); assertStrictEquals(1, (await scannerSecond.changes()).length); await scannerSecond.commit('Change on second repo', changes.map(change => change.path), COMMITER2); logger.info('Push second'); await scannerSecond.pushBranch('main'); logger.info('Pushed second'); } { const history = await scannerSecond.history(''); assertStrictEquals(2, history.length); const files = fs.readdirSync(scannerSecond.rootPath); assertStrictEquals(4, files.length); assertStrictEquals(true, files.includes('.git')); assertStrictEquals(true, files.includes('.gitignore')); assertStrictEquals(true, files.includes('file1.txt')); assertStrictEquals(true, files.includes('file2.txt')); } { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Change on local repo'); const changes = await scannerLocal.changes(); assertStrictEquals(1, (await scannerLocal.changes()).length); await scannerLocal.commit('Change on local repo', changes.map(change => change.path), COMMITER1); logger.info('Push local'); await scannerLocal.pushBranch('main'); logger.info('Pushed local'); } await scannerSecond.pullBranch('main'); { const history = await scannerSecond.history(''); assertStrictEquals(3, history.length); const files = fs.readdirSync(scannerSecond.rootPath); assertStrictEquals(4, files.length); assertStrictEquals(true, files.includes('.git')); assertStrictEquals(true, files.includes('.gitignore')); assertStrictEquals(true, files.includes('file1.txt')); assertStrictEquals(true, files.includes('file2.txt')); } const headCommit = await scannerSecond.getBranchCommit('HEAD'); const masterCommit = await scannerSecond.getBranchCommit('main'); const remoteCommit = await scannerSecond.getBranchCommit('refs/remotes/origin/main'); assertStrictEquals(headCommit, masterCommit); assertStrictEquals(headCommit, remoteCommit); } finally { // fs.rmSync(localRepoDir, { recursive: true, force: true }); // fs.rmSync(githubRepoDir, { recursive: true, force: true }); // fs.rmSync(secondRepoDir, { recursive: true, force: true }); } }); Deno.test('test conflict', async () => { // t.timeout(5000); const localRepoDir: string = createTmpDir(); const githubRepoDir: string = createTmpDir(); const secondRepoDir: string = createTmpDir(); execSync(`git init -b main --bare ${githubRepoDir}`); try { const scannerLocal = new GitScanner(logger, localRepoDir, COMMITER1.email); await scannerLocal.initialize(); { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Initial content'); const changes = await scannerLocal.changes(); assertStrictEquals(2, (await scannerLocal.changes()).length); await scannerLocal.commit('First commit', changes.map(change => change.path), COMMITER1); } { const changes = await scannerLocal.changes(); assertStrictEquals(0, changes.length); } await scannerLocal.setRemoteUrl(githubRepoDir); await scannerLocal.pushBranch('main'); //// const scannerSecond = new GitScanner(logger, secondRepoDir, COMMITER2.email); await scannerSecond.initialize(); fs.unlinkSync(secondRepoDir + '/.gitignore'); await scannerSecond.setRemoteUrl(githubRepoDir); await scannerSecond.pullBranch('main'); { fs.writeFileSync(path.join(secondRepoDir, 'file1.txt'), 'Change on second repo'); const changes = await scannerSecond.changes(); assertStrictEquals(1, (await scannerSecond.changes()).length); await scannerSecond.commit('Change on second repo', changes.map(change => change.path), COMMITER2); await scannerSecond.pushBranch('main'); } { fs.writeFileSync(path.join(localRepoDir, 'file1.txt'), 'Change on local repo'); const changes = await scannerLocal.changes(); assertStrictEquals(1, (await scannerLocal.changes()).length); await scannerLocal.commit('Change on local repo', changes.map(change => change.path), COMMITER1); try { await scannerLocal.pushBranch('main'); assertStrictEquals(true, false, 'Should fail because of conflict'); } catch (err) { if (err.message.indexOf('conflict') === -1) { console.error(err); t.fail(err); } assertStrictEquals(true, err.message.indexOf('conflict') > -1); } } await scannerLocal.resetToRemote('main'); await scannerLocal.pushBranch('main'); { const headCommit = await scannerLocal.getBranchCommit('HEAD'); const masterCommit = await scannerLocal.getBranchCommit('main'); const remoteCommit = await scannerLocal.getBranchCommit('refs/remotes/origin/main'); assertStrictEquals(headCommit, masterCommit); assertStrictEquals(headCommit, remoteCommit); } { const history = await scannerLocal.history(''); assertStrictEquals(2, history.length); assertStrictEquals('Change on second repo', history[0].message); const files = fs.readdirSync(scannerLocal.rootPath); assertStrictEquals(3, files.length); assertStrictEquals(true, files.includes('.git')); assertStrictEquals(true, files.includes('.gitignore')); assertStrictEquals(true, files.includes('file1.txt')); } const headCommit = await scannerSecond.getBranchCommit('HEAD'); const masterCommit = await scannerSecond.getBranchCommit('main'); const remoteCommit = await scannerSecond.getBranchCommit('refs/remotes/origin/main'); assertStrictEquals(headCommit, masterCommit); assertStrictEquals(headCommit, remoteCommit); } finally { fs.rmSync(localRepoDir, { recursive: true, force: true }); fs.rmSync(githubRepoDir, { recursive: true, force: true }); fs.rmSync(secondRepoDir, { recursive: true, force: true }); } });