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

Huge improvements #9

Merged
merged 6 commits into from
Sep 22, 2023
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
.idea
.vscode

data
docker-compose.override.yml

Expand All @@ -8,6 +11,7 @@ npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
tests/backups

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
Expand Down
5 changes: 0 additions & 5 deletions .idea/.gitignore

This file was deleted.

61 changes: 0 additions & 61 deletions .idea/codeStyles/Project.xml

This file was deleted.

5 changes: 0 additions & 5 deletions .idea/codeStyles/codeStyleConfig.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/inspectionProfiles/Project_Default.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/jsLibraryMappings.xml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/jsLinters/eslint.xml

This file was deleted.

12 changes: 0 additions & 12 deletions .idea/misc.xml

This file was deleted.

8 changes: 0 additions & 8 deletions .idea/modules.xml

This file was deleted.

12 changes: 0 additions & 12 deletions .idea/super-easy-file-backups.iml

This file was deleted.

6 changes: 0 additions & 6 deletions .idea/vcs.xml

This file was deleted.

6 changes: 5 additions & 1 deletion docker-compose-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,9 @@ services:
- START_COMMAND=test
volumes:
- ./tests/logs:/app/logs

- ./tests/projects/test-project:/app/projects/test-project:ro
- ./tests/projects/some-project2:/app/projects/some-project2:ro
- ./tests/projects/single-project:/app/projects/single-project:ro

- ./tests/backups/test-project:/app/backups/test-project
- ./tests/backups/single-project:/app/backups/single-project
9 changes: 5 additions & 4 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ async function run() {
logger.log(`----- Backups completed -----`);
}

setTimeout(async () => {
await run();
}, 1000);

cron.schedule('0 3 * * *', run);

// Wait 1 second to spin up environment
await new Promise((resolve) => setTimeout(resolve, 1000));

await run();
15 changes: 7 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,25 +32,24 @@
"data"
],
"dependencies": {
"@babel/core": "^7.22.9",
"@babel/core": "^7.22.20",
"@babel/eslint-parser": "^7.22.9",
"@types/fs-extra": "^11.0.1",
"@types/fs-extra": "^11.0.2",
"babel-core": "^6.26.3",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.0.6",
"babel-loader": "^9.1.3",
"babel-preset-env": "^1.7.0",
"current-week-number": "^1.0.7",
"eslint": "^8.49.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"fs-extra": "^10.1.0",
"fs-extra": "^11.1.1",
"lodash": "^4.17.21",
"megajs": "^1.0.5",
"megajs": "^1.1.4",
"node-cron": "^3.0.2",
"prettier": "^3.0.3",
"randomstring": "^1.2.2",
"recursive-copy": "^2.0.14",
"temp-dir": "^2.0.0",
"zip-a-folder": "^1.1.5"
"temp-dir": "^3.0.0",
"zip-a-folder": "^2.0.2"
}
}
2 changes: 1 addition & 1 deletion src/backups.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,4 @@ async function startBackups(rewriteDate = undefined, synchronously = false) {
}
}

export { startBackups, handeBackup, backupsPath };
export { startBackups, handeBackup, backupsPath, projectsPath };
71 changes: 55 additions & 16 deletions src/class/Asserts.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,75 @@
import fs from 'fs-extra';
import assert from 'node:assert';
import path from 'path';

/**
* Checks if a file exists.
* Checks if a folder is not empty.
*
* @param {string} filePath - The path to the file.
* @return {undefined}
* @param {string} folderPath - The path to the folder.
* @return {void} Throws an exception if the folder is empty.
*/
export function fileExists(filePath) {
// Check if the file exists
if (!fs.existsSync(filePath)) {
export function folderIsNotEmpty(folderPath) {
// Get the list of files in the folder
const files = fs.readdirSync(folderPath);
if (files.length === 0) {
throw new assert.AssertionError({
message: `File ${filePath} does not exist.`,
message: `Folder ${folderPath} is empty.`,
});
}
}

/**
* Asserts that the number of files in a given folder is equal to a specified length.
* Clears the contents of a folder.
*
* @param {string} folderPath - The path to the folder.
* @param {number} length - The expected number of files.
* @throws {assert.AssertionError} If the number of files is greater than the specified length.
* @throws {AssertionError} If the folder is not empty.
*/
export function filesLength(folderPath, length) {
// Get the list of files in the folder
export function ensureToClearFolder(folderPath) {
fs.emptyDirSync(folderPath);
const files = fs.readdirSync(folderPath);
if (files.length > length) {
if (files.length !== 0) {
throw new assert.AssertionError({
message: `Folder ${folderPath} does not contain the expected number of files.`,
actual: files.length,
expected: length,
message: `Folder ${folderPath} must be empty.`,
});
}
}

/**
* Checks if the given folder structure matches the expected structure.
*
* @param {Array|string} folders - The folders to check the structure for. If a string is provided, it is converted to an array with a single element.
* @param {Array} structure - The expected structure of the folders.
* @throws {AssertionError} Throws an error if the actual structure does not match the expected structure.
*/
export function structureMatch(folders, structure) {
if (!Array.isArray(folders)) folders = [folders];

function actualStructure(folderPath) {
let structure = [];
const objects = fs.readdirSync(folderPath);
objects.forEach((obj) => {
const isDir = fs.lstatSync(path.join(folderPath, obj)).isDirectory();
if (isDir) {
const subFolderStructure = actualStructure(path.join(folderPath, obj));
subFolderStructure.forEach((subObj) => {
structure.push(obj + '/' + subObj);
});
} else structure.push(obj);
});
return structure;
}

folders.forEach((folderPath) => {
const actualStructureResult = actualStructure(folderPath);
actualStructureResult.sort();
structure.sort();

if (JSON.stringify(actualStructureResult) !== JSON.stringify(structure)) {
throw new assert.AssertionError({
message: `Folder ${folderPath} does not match the expected structure.`,
actual: actualStructureResult,
expected: structure,
});
}
});
}
37 changes: 17 additions & 20 deletions src/class/FolderBackup.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import currentWeekNumber from 'current-week-number';
import { COMPRESSION_LEVEL, tar } from 'zip-a-folder';
import tempDirectory from 'temp-dir';
import randomString from 'randomstring';
Expand Down Expand Up @@ -104,29 +103,27 @@ export default class FolderBackup {

let files = (await this.fm.readDir(pathToBackups)) || [];

let doNotCreate = false;
let oldestFileDate;

for (const file of files) {
let fileDate = file.match(/(?<=bkp_).*?(?=\.tgz)/);
fileDate = new Date(fileDate[0]);
if (!oldestFileDate || fileDate < oldestFileDate) {
oldestFileDate = fileDate;
}
}
let doNotCreate = false;

if (oldestFileDate && oldestFileDate < this.today) {
const todayDays = this.today.getTime() / (1000 * 60 * 60 * 24);
const oldestDays = oldestFileDate.getTime() / (1000 * 60 * 60 * 24);

if (type === 'weekly') {
const week = currentWeekNumber(this.today);
const week2 = currentWeekNumber(fileDate);
if (week === week2) {
doNotCreate = true;
break;
}
} else if (type === 'monthly') {
if (this.today.getMonth() === fileDate.getMonth()) {
doNotCreate = true;
break;
}
} else if (type === 'annually') {
if (this.today.getFullYear() === fileDate.getFullYear()) {
doNotCreate = true;
break;
}
if (type === 'weekly' && todayDays - oldestDays < 7) {
doNotCreate = true;
} else if (type === 'monthly' && todayDays - oldestDays < 30) {
doNotCreate = true;
} else if (type === 'annually' && todayDays - oldestDays < 365) {
doNotCreate = true;
}
}

Expand All @@ -144,7 +141,7 @@ export default class FolderBackup {
filter: this.filter,
});

if (!this.fm.exists(pathToBackup) && !doNotCreate) {
if (!doNotCreate) {
const tmpArchive = path.normalize(tmpArchiveDir + '/temp.tgz');

await tar(tmpBackupDir, tmpArchive, {
Expand Down
Loading