Skip to content

Commit

Permalink
good wip on .syncslocal, .syncshare
Browse files Browse the repository at this point in the history
  • Loading branch information
nocke committed Aug 27, 2024
1 parent 9351754 commit 32e51fe
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 46 deletions.
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,26 @@ tbd

## configuration

your SHARE repo (in 1 single place, i.e. storage media on your NAS) needs to provide a `.syncshare.json`file with ... TODO
// NEXT
The “topology” here is very simply a „star“ with 1 central SHARE repo (in which you may indeed work, too!) and an arbitrary number of LOCAL repos. Where that “arbitrary” number might very well be 1, if you happen to have one desktop for home (as SHARE) and 1 laptop on the go. It's easy to later on add additional members.

your SHARE repo (in 1 single place, i.e. storage media on your NAS) needs to provide a `.syncshare.json`file with global settings relating to your entire system

→ if you are happy with [the default settings](./defaultConfig.json), e.g. for `excludedExtensions`, `MAX_FILE_SIZE_MB`, it's sheer presence is enough (with or without empty curly brackets inside). Then it's just a marker file.

```json
{

"excludedExtensions": [... ,
"MAX_FILE_SIZE_MB": 30,
}
```

if not overriden, regarding `excludedExtensions`, `MAX_FILE_SIZE_MB` [these defaults](./defaultConfig.json) will “rule”...


your LOCAL repo (on every one of your machines) needs to provide a `.synclocal.json`file with EXACTLY these 2 entries:
your LOCAL repo (on every one of your machines) however does need to provide a `.synclocal.json` file with EXACTLY these 2 entries:

```json
{
machineName: os.hostname(), // what uname -n delivers, just a safety measure
shareRepo: SHARE // the share repo to connect to
machineName: os.hostname(), // what uname -n delivers, localRepo: '/home/user/'
localRepo: 'mySyncDocsFolder', // again, ensuring the right place
shareRepo: '/fritzbox/usb-stick/SHARE' // the share repo to connect to
}
```

Expand Down
36 changes: 27 additions & 9 deletions src/getConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ function loadJsonC(path) {
try {
const jsoncfile = fs.readFileSync(path, 'utf8')
const withoutComments = jsoncfile.replace(/(?<=(^|[^"]*"[^"]*")*[^"]*)\/\/.*$/gm, '')
const withoutTrailingCommas = withoutComments.replace(/,\s*([\]}])/g, '$1'); // Remove trailing commas
const withoutTrailingCommas = withoutComments.replace(/,\s*([\]}])/g, '$1') // Remove trailing commas
return JSON.parse(withoutTrailingCommas)
} catch (error) {
fail(`failed on loading/parsing JSON/JSONC-File '${path}': ${error.message}`)
Expand Down Expand Up @@ -53,27 +53,45 @@ const getConfig = (cwd) => {
info(`Test Mode: ${testMode}`)

// check if there is a .syncdocs.json in the CURRENT dir
const syncdocsJsonPath = '.syncdocs.json'
const hasSyncdocsJson = fs.existsSync(syncdocsJsonPath)
if (!hasSyncdocsJson) {
const localJsonPath = '.synclocal.json'
if (!fs.existsSync(localJsonPath)) {
fail(`No .syncdocs.json found in current directory ${cwd} — not a syncdocs folder?`)
}
ensureFolderExists('.git',`No .git folder in current directory ${cwd}, only a .syncdocs.json — trouble?`)

const defaultJson = loadJsonC(path.join(PROJECTROOT, 'defaultConfig.json'))
const projectJson = loadJsonC(syncdocsJsonPath)
const localJson = loadJsonC(localJsonPath)

const mustBeInProjectJson = ['machineName', 'localRepo', 'shareRepo']
mustBeInProjectJson.forEach((prop) => {
const mandatoryLocalKeys = ['machineName', 'localRepo', 'shareRepo']

ensureTrue(Object.keys(localJson).length ==mandatoryLocalKeys.length,
`local '.syncdocs.json' must have exactly ${mandatoryLocalKeys.length} keys: ${mandatoryLocalKeys.join(', ')}`)

mandatoryLocalKeys.forEach((prop) => {
ensureTrue( defaultJson[prop] === undefined, `key: ${prop} must not be in defaultJson`)
ensureTruthy( projectJson[prop] && projectJson[prop].length > 0, `key: ${prop} must be in .syncdocs.json`)
ensureTruthy( localJson[prop] && localJson[prop].length > 0, `key: ${prop} must be in .syncdocs.json`)
})

ensureFolderExists(localJson.shareRepo, `folder given as 'shareRepo' '${localJson.shareRepo}' does not exist`)
const shareJsonPath = path.join(localJson.shareRepo, '.syncshare.json')
ensureFileExists(shareJsonPath, `central .syncshare json: '${shareJsonPath}' does not exist`)

const shareJson = loadJsonC(shareJsonPath)
mandatoryLocalKeys.forEach((prop) => { // ensure absence in shareJson
ensureFalse(!!shareJson[prop], `key: ${prop} must not be in shareJson`)
})

const minimumAggregateKeys = [ ...mandatoryLocalKeys, 'excludedExtensions', 'MAX_FILE_SIZE_MB']

const combinedJSON = {
...defaultJson,
...projectJson
...localJson
}

minimumAggregateKeys.forEach((prop) => {
ensureTruthy(combinedJSON[prop], `key: ${prop} must be in combinedJSON`)
})

return combinedJSON
}

Expand Down
File renamed without changes.
71 changes: 43 additions & 28 deletions test/simpleRun.spec.js → test/testConfig.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,63 +24,78 @@ const wipeAndRecreateDir = (dir, label) => {
ensureTrue(fs.readdirSync(dir).length === 0, 'test directory not empty')
}

let synclocal // overriden in some (negative) tests

beforeEach(done => {
wipeAndRecreateDir(LOCAL, 'LOCAL TESTDIR')
wipeAndRecreateDir(SHARE, 'SHARE TESTDIR')

// make up a local repo, including syncdocs file:
const syncdocs = {
// prepare .synclocal.json
synclocal = {
machineName: os.hostname(),
// NEXT: localRepo is not needed !
localRepo: LOCAL,
shareRepo: SHARE
}

fs.writeFileSync(
path.join(LOCAL, '.synclocal.json'),
JSON.stringify(syncdocs, null, 2))
JSON.stringify(synclocal, null, 2))

// prepare .syncshare.json
const syncshare = {
"MAX_FILE_SIZE_MB": 42,
}

fs.writeFileSync(
path.join(SHARE, '.syncshare.json'),
JSON.stringify(syncshare, null, 2))

const DIRS = [LOCAL, SHARE]
DIRS.forEach(DIR => {
warn(`setting up ${DIR}`)
process.chdir(DIR)
guard('git init', { mute: true })

// NEXT `cp -r some stuff to both sides, then deviate
})

process.chdir(LOCAL) // crucial for testing !
done()
})

describe('Main Script Execution', () => {
// const testFilePath = path.join(LOCAL, 'howdy.txt')

// guard('ls -l .', {})
// TEMP LATER guard(`node ${PROJECTROOT}/src/main.js`, {})
// assert(fs.existsSync(testFilePath), `did not find ${testFilePath}`)
// if (error) {
// console.error(`exec error: ${error}`)
// return done(error)
// }
// // Check if howdy.txt has been created
// assert(fs.existsSync(testFilePath))
// done()
// })
describe('Config Tests', () => {

it.only('should get reasonable config', function() {
console.log('howdy, partner!')
console.log('Current working directory:', process.cwd())

assert.strictEqual(process.cwd(), LOCAL) // ensure setup did not mess up
const config = getConfig(process.cwd())
// console.log('config:', config)

ensureTrue(typeof config.machineName === 'string' && config.machineName.length > 0, 'machineName is missing or empty');
assert.strictEqual(config.localRepo, LOCAL);
ensureTrue(typeof config.machineName === 'string' && config.machineName.length > 0, 'machineName is missing or empty')
assert.strictEqual(config.localRepo, LOCAL)
assert.strictEqual(config.shareRepo, SHARE)
assert.deepStrictEqual(config.excludedExtensions, defaultConfig.excludedExtensions)

assert(Number.isInteger(config.MAX_FILE_SIZE_MB), 'MAX_FILE_SIZE_MB is not a whole number');
assert(config.MAX_FILE_SIZE_MB >= 5 && config.MAX_FILE_SIZE_MB <= 300, 'MAX_FILE_SIZE_MB is not between 5 and 300');
assert(Number.isInteger(config.MAX_FILE_SIZE_MB), 'MAX_FILE_SIZE_MB is not a whole number')
assert(config.MAX_FILE_SIZE_MB >= 5 && config.MAX_FILE_SIZE_MB <= 300, 'MAX_FILE_SIZE_MB is not between 5 and 300')
})

it('negative: referenced non-existing .syncshare', function() {
// TODO !!!
const config = getConfig(process.cwd())
})

it('negative: to little in .synclocal', function() {
// TODO !!!
const config = getConfig(process.cwd())
})

it('negative: to much in .synclocal', function() {
// TODO !!!
const config = getConfig(process.cwd())
})

it('negative: to much in .synclocal', function() {
// TODO !!!
const config = getConfig(process.cwd())
})



})

0 comments on commit 32e51fe

Please sign in to comment.