/*
* This file is part of PKM (Persistent Knowledge Monitor).
* Copyright (c) 2020 Capgemini Group, Commissariat à l'énergie atomique et aux énergies alternatives,
* OW2, Sysgo AG, Technikon, Tree Technology, Universitat Politècnica de València.
*
* PKM is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License version 3 as published by
* the Free Software Foundation.
*
* PKM is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with PKM. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* Delete Git Working Trees together with Git working trees while optionally leaving intact Files in PKM.
*
* @memberof PKM
* @instance
* @param {string} dbName - database name
* @param {Object} [query] - query
*
* @return {Promise} a promise
*/
function delete_git_working_trees(dbName, query = {}, options = {})
{
return new Promise(function(resolve, reject)
{
const debug = this.debug;
const dont_delete_pkm_files = options.dont_delete_pkm_files;
let git_file_system = this.get_git_file_system(dbName);
let git_working_trees;
const { list_git_versioned_files } = require('../util/git');
const asyncPool = require('tiny-async-pool');
new Promise((resolve, reject) =>
{
// (1) Get then delete the Git working trees in the PKM
this.get_git_working_trees(dbName, query).then((_git_working_trees) =>
{
git_working_trees = _git_working_trees;
// delete the Git working tree
this.delete_documents(dbName, 'GitWorkingTrees', query).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}).catch((err) =>
{
reject(this.Error(err));
});
}).then(() => new Promise((resolve, reject) =>
{
// (2) Unbind PKM Files from Git working trees:
// - starting with the files of the linked Git working trees
// - then finishing with the files of the main Git working tree
let unbind_or_delete_files = function(git_working_tree)
{
return new Promise((resolve, reject) =>
{
this.get_any_files(dbName, { gitWorkingTree: git_working_tree.directory }, { filecontent : 0 }).then((abbrev_files) =>
{
asyncPool(1, abbrev_files, (abbrev_file) => new Promise((resolve, reject) =>
{
if(dont_delete_pkm_files)
{
this.get_any_files(dbName, { filename: abbrev_file.rel_path }).then((files) =>
{
let file = files[0];
// Unbind the file
delete file.git_working_tree;
delete file.git_unmerged;
// Put the file in the PKM (this sets the git_dirty flag)
this.update_any_files(dbName, [ file ], { git : true }).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}).catch((err) =>
{
reject(this.Error(err));
});
}
else
{
this.delete_any_files(dbName, { filename: abbrev_file.rel_path }).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}
})).then(() =>
{
resolve();
}).catch((err) =>
{
reject(err);
});
}).catch((err) =>
{
const error = require('./error');
if(err instanceof error.PKM_NotFound)
{
resolve();
}
else
{
reject(this.Error(err));
}
});
});
}.bind(this);
asyncPool(1, git_working_trees, (git_working_tree) => new Promise((resolve, reject) =>
{
((git_working_tree.linked === undefined) ? Promise.resolve()
: asyncPool(1, git_working_tree.linked, (linked_git_working_tree) => unbind_or_delete_files(linked_git_working_tree)))
.then(() => asyncPool(1, git_working_trees, (git_working_tree) => unbind_or_delete_files(git_working_tree)))
.then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
})).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
})).then(() => new Promise((resolve, reject) =>
{
// (3) Delete the on-disk directories
let delete_working_tree = function(git_working_tree)
{
return new Promise((resolve, reject) =>
{
// delete the Git directory associated to the Git working tree
// Note: the Git directory can be inside or outside of the Git working tree
git_file_system.rmdir_r(git_working_tree.git_directory).then(() =>
{
// the Git directory has been deleted, no more git commands can work from now on
// delete the Git working tree
git_file_system.rmdir_r(git_working_tree.directory).then(() =>
{
// the Git working tree has been deleted
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
}).catch((err) =>
{
reject(this.Error(err));
});
});
}.bind(this);
asyncPool(1, git_working_trees, (git_working_tree) => new Promise((resolve, reject) =>
{
((git_working_tree.linked === undefined) ? Promise.resolve()
: asyncPool(1, git_working_tree.linked, (linked_git_working_tree) => delete_working_tree(linked_git_working_tree)))
.then(() => asyncPool(1, git_working_trees, (git_working_tree) => delete_working_tree(git_working_tree)))
.then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
})).then(() =>
{
resolve();
}).catch((err) =>
{
reject(this.Error(err));
});
})).then(() =>
{
// job's done
resolve();
}).catch((err) =>
{
reject(err);
});
}.bind(this));
}
exports.delete_git_working_trees = delete_git_working_trees;