From 487f79a6eb788280ec175c44e000b7dd3ee189cf Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Wed, 22 Sep 2021 15:10:11 +0800 Subject: [PATCH 1/2] Fix: change git tree object format --- classes/Collection.js | 42 +++++++++++++++++++++++++------ classes/MediaSubfolder.js | 32 ++++++++++++------------ classes/Resource.js | 29 +++++++++------------- classes/ResourceRoom.js | 30 ++++++++++++++++------ routes/folders.js | 52 +++++++++++++++++---------------------- utils/utils.js | 2 ++ 6 files changed, 110 insertions(+), 77 deletions(-) diff --git a/classes/Collection.js b/classes/Collection.js index f0794a294..286c37fd7 100644 --- a/classes/Collection.js +++ b/classes/Collection.js @@ -89,10 +89,24 @@ class Collection { async delete(collectionName, currentCommitSha, treeSha) { const commitMessage = `Delete collection ${collectionName}` - const gitTree = await getTree(this.siteName, this.accessToken, treeSha) - const newGitTree = gitTree.filter((item) => item.path !== `_${collectionName}`) + const gitTree = await getTree( + this.siteName, + this.accessToken, + treeSha, + true + ) + const newGitTree = gitTree + .filter( + (item) => + item.type !== "tree" && item.path.startsWith(`_${collectionName}/`) + ) + .map((item) => ({ + ...item, + sha: null, + })) await sendTree( newGitTree, + treeSha, currentCommitSha, this.siteName, this.accessToken, @@ -125,20 +139,34 @@ class Collection { ) { const commitMessage = `Rename collection from ${oldCollectionName} to ${newCollectionName}` - const gitTree = await getTree(this.siteName, this.accessToken, treeSha) + const gitTree = await getTree( + this.siteName, + this.accessToken, + treeSha, + true + ) const oldCollectionDirectoryName = `_${oldCollectionName}` const newCollectionDirectoryName = `_${newCollectionName}` - const newGitTree = gitTree.map((item) => { + const newGitTree = [] + gitTree.forEach((item) => { if (item.path === oldCollectionDirectoryName) { - return { + newGitTree.push({ ...item, path: newCollectionDirectoryName, - } + }) + } else if ( + item.path.startsWith(`${oldCollectionDirectoryName}/`) && + item.type !== "tree" + ) { + newGitTree.push({ + ...item, + sha: null, + }) } - return item }) await sendTree( newGitTree, + treeSha, currentCommitSha, this.siteName, this.accessToken, diff --git a/classes/MediaSubfolder.js b/classes/MediaSubfolder.js index 0bc81389c..7da2a0ddb 100644 --- a/classes/MediaSubfolder.js +++ b/classes/MediaSubfolder.js @@ -36,17 +36,17 @@ class MediaSubfolder { ) const directoryName = `${this.mediaFolderName}/${subfolderPath}` const newGitTree = gitTree - .filter((item) => { - return !item.path.includes(directoryName) - }) - .filter((item) => { - return !( - item.type === "tree" && item.path.includes(this.mediaFolderName) - ) - }) - + .filter( + (item) => + item.type !== "tree" && item.path.startsWith(`${directoryName}/`) + ) + .map((item) => ({ + ...item, + sha: null, + })) await sendTree( newGitTree, + treeSha, currentCommitSha, this.siteName, this.accessToken, @@ -72,19 +72,19 @@ class MediaSubfolder { ...item, path: newDirectoryName, }) - } else if (item.path.includes(oldDirectoryName)) { - // We don't want to include these because they use the old path, they are included with the renamed tree } else if ( - item.type === "tree" && - item.path.includes(this.mediaFolderName) + item.path.startsWith(`${oldDirectoryName}/`) && + item.type !== "tree" ) { - // We don't include any other trees - we reconstruct them by adding all their individual files instead - } else { - newGitTree.push(item) + newGitTree.push({ + ...item, + sha: null, + }) } }) await sendTree( newGitTree, + treeSha, currentCommitSha, this.siteName, this.accessToken, diff --git a/classes/Resource.js b/classes/Resource.js index 57cd3696a..9a11085e8 100644 --- a/classes/Resource.js +++ b/classes/Resource.js @@ -59,38 +59,33 @@ class Resource { this.siteName, this.accessToken ) - const gitTree = await getTree(this.siteName, this.accessToken, treeSha) - const newGitTree = [] - let resourceRoomTreeSha - // Retrieve all git trees of other items - gitTree.forEach((item) => { - if (item.path === resourceRoomName) { - resourceRoomTreeSha = item.sha - } else { - newGitTree.push(item) - } - }) - const resourceRoomTree = await getTree( + const gitTree = await getTree( this.siteName, this.accessToken, - resourceRoomTreeSha + treeSha, + true ) - resourceRoomTree.forEach((item) => { + const newGitTree = [] + gitTree.forEach((item) => { // We need to append resource room to the file path because the path is relative to the subtree - if (item.path === resourceName) { + if (item.path === `${resourceRoomName}/${resourceName}`) { newGitTree.push({ ...item, path: `${resourceRoomName}/${newResourceName}`, }) - } else { + } else if ( + item.path.startsWith(`${resourceRoomName}/${resourceName}/`) && + item.type !== "tree" + ) { newGitTree.push({ ...item, - path: `${resourceRoomName}/${item.path}`, + sha: null, }) } }) await sendTree( newGitTree, + treeSha, currentCommitSha, this.siteName, this.accessToken, diff --git a/classes/ResourceRoom.js b/classes/ResourceRoom.js index 3a112028b..d223e2597 100644 --- a/classes/ResourceRoom.js +++ b/classes/ResourceRoom.js @@ -121,18 +121,32 @@ class ResourceRoom { this.siteName, this.accessToken ) - const gitTree = await getTree(this.siteName, this.accessToken, treeSha) - const newGitTree = gitTree.map((item) => { + const gitTree = await getTree( + this.siteName, + this.accessToken, + treeSha, + true + ) + const newGitTree = [] + gitTree.forEach((item) => { if (item.path === resourceRoomName) { - return { + newGitTree.push({ ...item, path: newResourceRoom, - } + }) + } else if ( + item.path.startsWith(`${resourceRoomName}/`) && + item.type !== "tree" + ) { + newGitTree.push({ + ...item, + sha: null, + }) } - return item }) await sendTree( newGitTree, + treeSha, currentCommitSha, this.siteName, this.accessToken, @@ -197,9 +211,9 @@ class ResourceRoom { const resources = await IsomerResource.list(resourceRoomName) if (!_.isEmpty(resources)) { - await Bluebird.map(resources, async (resource) => { - return IsomerResource.delete(resourceRoomName, resource.dirName) - }) + await Bluebird.map(resources, async (resource) => + IsomerResource.delete(resourceRoomName, resource.dirName) + ) } // Delete index file in resourceRoom diff --git a/routes/folders.js b/routes/folders.js index 5d7ea6f70..8de52df8f 100644 --- a/routes/folders.js +++ b/routes/folders.js @@ -12,8 +12,11 @@ const { Collection } = require("@classes/Collection") const { CollectionConfig } = require("@classes/Config") const { File, CollectionPageType } = require("@classes/File") -const { getTree, sendTree, deslugifyCollectionName } = require("@utils/utils.js") - +const { + getTree, + sendTree, + deslugifyCollectionName, +} = require("@utils/utils.js") const router = express.Router() @@ -45,31 +48,19 @@ async function deleteSubfolder(req, res) { const commitMessage = `Delete subfolder ${folderName}/${subfolderName}` const isRecursive = true const gitTree = await getTree(siteName, accessToken, treeSha, isRecursive) - const baseTreeWithoutFolder = gitTree.filter( - (item) => - // keep all root-level items except for tree object of folder whose subfolder is to be deleted - !item.path.includes("/") && item.path !== `_${folderName}` - ) - const folderTreeWithoutSubfolder = gitTree - .filter((item) => - // get all folder items - item.path.includes(`_${folderName}`) - ) + const newGitTree = gitTree .filter( (item) => - // remove tree objects of folder and subfolder to be renamed - item.path !== `_${folderName}` && - item.path !== `_${folderName}/${subfolderName}` + item.type !== "tree" && + item.path.startsWith(`_${folderName}/${subfolderName}/`) ) - .filter( - (item) => - // exclude all subfolder items - !item.path.includes(`_${folderName}/${subfolderName}`) - ) - - const newGitTree = [...baseTreeWithoutFolder, ...folderTreeWithoutSubfolder] + .map((item) => ({ + ...item, + sha: null, + })) await sendTree( newGitTree, + treeSha, currentCommitSha, siteName, accessToken, @@ -108,14 +99,14 @@ async function renameSubfolder(req, res) { const filesToBeModified = await CurrentIsomerFile.list() - await Bluebird.mapSeries(filesToBeModified, async(fileInfo) => { + await Bluebird.mapSeries(filesToBeModified, async (fileInfo) => { const { fileName } = fileInfo // Read existing file content const { content, sha } = await CurrentIsomerFile.read(fileName) // Handle keep file differently - if (fileName === '.keep') { + if (fileName === ".keep") { await NewIsomerFile.create(fileName, content) return CurrentIsomerFile.delete(fileName, sha) } @@ -128,21 +119,24 @@ async function renameSubfolder(req, res) { // Modify `third_nav_title` and save as new file in newSubfolderName const newFrontMatter = { ...frontMatter, - third_nav_title: deslugifyCollectionName(newSubfolderName) + third_nav_title: deslugifyCollectionName(newSubfolderName), } - const newContent = ["---\n", yaml.stringify(newFrontMatter), "---\n", mdBody].join("") + const newContent = [ + "---\n", + yaml.stringify(newFrontMatter), + "---\n", + mdBody, + ].join("") const encodedNewContent = Base64.encode(newContent) - + await NewIsomerFile.create(fileName, encodedNewContent) // Delete existing file in subfolderName return CurrentIsomerFile.delete(fileName, sha) - }) - // // Update collection config const collectionConfig = new CollectionConfig( accessToken, diff --git a/utils/utils.js b/utils/utils.js index 575357b55..bb33a1f4e 100644 --- a/utils/utils.js +++ b/utils/utils.js @@ -63,6 +63,7 @@ async function getTree( // send the new tree object back to Github and point the latest commit on the staging branch to it async function sendTree( gitTree, + baseTreeSha, currentCommitSha, repo, accessToken, @@ -77,6 +78,7 @@ async function sendTree( `https://api.github.com/repos/${GITHUB_ORG_NAME}/${repo}/git/trees`, { tree: gitTree, + base_tree: baseTreeSha, }, { headers, From 23848842dd9d4abee29d8b711488d5db69cb32f8 Mon Sep 17 00:00:00 2001 From: Alexander Lee Date: Thu, 23 Sep 2021 14:31:53 +0800 Subject: [PATCH 2/2] Nit: add comments --- classes/Collection.js | 4 +++- classes/MediaSubfolder.js | 4 +++- classes/Resource.js | 7 ++++++- classes/ResourceRoom.js | 4 +++- 4 files changed, 15 insertions(+), 4 deletions(-) diff --git a/classes/Collection.js b/classes/Collection.js index 286c37fd7..1999f4355 100644 --- a/classes/Collection.js +++ b/classes/Collection.js @@ -149,7 +149,8 @@ class Collection { const newCollectionDirectoryName = `_${newCollectionName}` const newGitTree = [] gitTree.forEach((item) => { - if (item.path === oldCollectionDirectoryName) { + if (item.path === oldCollectionDirectoryName && item.type === "tree") { + // Rename old subdirectory to new name newGitTree.push({ ...item, path: newCollectionDirectoryName, @@ -158,6 +159,7 @@ class Collection { item.path.startsWith(`${oldCollectionDirectoryName}/`) && item.type !== "tree" ) { + // Delete old subdirectory items newGitTree.push({ ...item, sha: null, diff --git a/classes/MediaSubfolder.js b/classes/MediaSubfolder.js index 7da2a0ddb..92327d022 100644 --- a/classes/MediaSubfolder.js +++ b/classes/MediaSubfolder.js @@ -67,7 +67,8 @@ class MediaSubfolder { const newDirectoryName = `${this.mediaFolderName}/${newSubfolderPath}` const newGitTree = [] gitTree.forEach((item) => { - if (item.path === oldDirectoryName) { + if (item.path === oldDirectoryName && item.type === "tree") { + // Rename old subdirectory to new name newGitTree.push({ ...item, path: newDirectoryName, @@ -76,6 +77,7 @@ class MediaSubfolder { item.path.startsWith(`${oldDirectoryName}/`) && item.type !== "tree" ) { + // Delete old subdirectory items newGitTree.push({ ...item, sha: null, diff --git a/classes/Resource.js b/classes/Resource.js index 9a11085e8..b993fb412 100644 --- a/classes/Resource.js +++ b/classes/Resource.js @@ -68,7 +68,11 @@ class Resource { const newGitTree = [] gitTree.forEach((item) => { // We need to append resource room to the file path because the path is relative to the subtree - if (item.path === `${resourceRoomName}/${resourceName}`) { + if ( + item.path === `${resourceRoomName}/${resourceName}` && + item.type === "tree" + ) { + // Rename old subdirectory to new name newGitTree.push({ ...item, path: `${resourceRoomName}/${newResourceName}`, @@ -77,6 +81,7 @@ class Resource { item.path.startsWith(`${resourceRoomName}/${resourceName}/`) && item.type !== "tree" ) { + // Delete old subdirectory items newGitTree.push({ ...item, sha: null, diff --git a/classes/ResourceRoom.js b/classes/ResourceRoom.js index d223e2597..5eab979d2 100644 --- a/classes/ResourceRoom.js +++ b/classes/ResourceRoom.js @@ -129,7 +129,8 @@ class ResourceRoom { ) const newGitTree = [] gitTree.forEach((item) => { - if (item.path === resourceRoomName) { + if (item.path === resourceRoomName && item.type === "tree") { + // Rename old subdirectory to new name newGitTree.push({ ...item, path: newResourceRoom, @@ -138,6 +139,7 @@ class ResourceRoom { item.path.startsWith(`${resourceRoomName}/`) && item.type !== "tree" ) { + // Delete old subdirectory items newGitTree.push({ ...item, sha: null,