Added combining categories (for creating aliases), corrected other small errors

parent 544f68f8
......@@ -13,8 +13,8 @@ endif
ifeq ($(PLANG),D)
DC=ldc2 # dmd, gdc or ldc2
PHOBOS_LINKING=static # static or dynamic
AMALTHEA_LINKING=static # static or dynamic
PHOBOS_LINKING=static # static or dynamic
AMALTHEA_LINKING=static # static or dynamic
RELEASE_ARGS=release $(DC) $(PHOBOS_LINKING) $(AMALTHEA_LINKING)
DEBUG_ARGS=debug $(DC) $(PHOBOS_LINKING) $(AMALTHEA_LINKING)
endif
......
......@@ -117,3 +117,7 @@
"Fragments","Фрагменты","Fragmentoj"
"Replace the file? y/n >: ","Заменить файл? д/н >: ","Anstataŭigi la dosieron?"
": this path is not available.",": этот путь недоступен.",": ĉi tiu vojo estas neatingebla."
"Do you want to combine the categories? y/n >: ","Хотите объединить категории? д/н >: ","Ĉu vi volas unuigi la kategoriojn? j/n >: "
"The categories are combining.","Категории объединяются.","La kategorioj unuiĝas."
": this subcategory already exists.",": такая подкатегория уже существует.",": tiu subkategorio jam ekzistas."
"Exactly the same file already exists in the file space.","Точно такой же файл уже существует в файловом пространстве.","Absolute identa dosiero jam ekzistas en la dosiera spaco."
......@@ -27,16 +27,6 @@ import
module_service,
module_show;
alias
moduleAssign = module_assign,
moduleCopy = module_copy,
moduleCreate = module_create,
moduleDelete = module_delete,
moduleHelp = module_help,
moduleService = module_service,
moduleShow = module_show,
moduleBase = module_vitis_base;
int main(string[] args) {
if (args.length == 1) {
......
......@@ -50,7 +50,6 @@ void mainFn(string[] args) {
string newName = args.extractOptionValue("-n");
//vitis assign [-c] <category> -a <alias>
string[] aliasNames = args.extractOptionRange("-a");
if (!aliasNames.empty) {
......@@ -232,13 +231,63 @@ void assignAliases(string category,
" ", "Skipped."._s);
continue;
}
if (!exists(vpath ~ pseudonym)) {
auto pseudonymPath = vpath ~ pseudonym;
if (!exists(pseudonymPath)) {
symlink(getCatDirPath(category), vpath ~ pseudonym);
continue;
}
"warning".tprint(pseudonym ~ ": this category already exists."._s);
"warning".tprint(" " ~ "The request is skipped."._s, "\n");
"warning".tprintln(pseudonym ~ ": this category already exists."._s);
if (pseudonymPath.isSymlink) {
"warning".tprintln(pseudonymPath, " -> ", pseudonymPath.readLink);
"warning".tprintln("The request is skipped."._s);
return;
}
bool answer = false;
if (!userConfirmation && !userDenial) {
auto q = "Do you want to combine the categories? y/n >: "._s;
answer = getAnswerToTheQuestion(q);
}
if (!userDenial && (answer || userConfirmation)) {
"simple".tprintln("The categories are combining."._s);
combineCategories(category, pseudonym);
symlink(getCatDirPath(category), vpath ~ pseudonym);
} else {
"warning".tprintln("The request is skipped."._s);
}
}
}
void combineCategories(string mainCategory, string oldCategory) {
string pathToMainCategory = getCatDirPath(mainCategory);
string pathToOldCategory = getCatDirPath(oldCategory);
string[] catDirList = amalthea.fs.getDirListRecurse(pathToOldCategory);
catDirList = pathToOldCategory ~ catDirList;
foreach(d; catDirList) {
string currSubcategory = d[pathToOldCategory.length .. $];
string oldSubcategory = oldCategory ~ "/" ~ currSubcategory;
string newSubcategory = mainCategory ~ "/" ~ currSubcategory;
createNonExistentCategory(newSubcategory, true, false);
string pathToNewSubcategory = getCatDirPath(newSubcategory);
if (oldSubcategory.isGlobalSubCategory) {
auto globPath = getCatDirPath(oldSubcategory.baseName);
globPath = globPath.stripRight('/');
module_vitis_base.changeSymlink(globPath, pathToNewSubcategory);
}
string pathToOldSubcategory = getCatDirPath(oldSubcategory);
string[] fileList = amalthea.fs.getFileList(pathToOldSubcategory);
foreach(f; fileList) {
auto newLink = pathToNewSubcategory ~ "/" ~ f.baseName;
if (newLink.exists) {
if (newLink.readLink == f.readLink) continue;
writeDuplicateLink(f.readLink, pathToNewSubcategory);
} else {
symlink(f.readLink, newLink);
}
}
}
std.file.rmdirRecurse(pathToOldCategory);
}
......@@ -379,7 +428,7 @@ void assignCategoriesToVitisFile(string[] categories,
string start,
string finish,
string fragpointerName) {
string filepath = moduleVitisBase.findFileInVitis(vitisFile, number)[0];
string filepath = moduleBase.findFileInVitis(vitisFile, number)[0];
if (fragpointerName.empty) {
assignCategoriesToFiles(categories,
[filepath],
......@@ -500,7 +549,7 @@ void assignNewNameByFile(string file, string newName) {
if (!file.startsWith("/")) {
file = amalthea.fs.getAbsolutePath(file);
}
string[string] allLinks = moduleVitisBase.getAllLinks();
string[string] allLinks = moduleBase.getAllLinks();
size_t counter;
foreach(l, f; allLinks) {
if (file != f) continue;
......@@ -537,7 +586,7 @@ void assignNewNameByFile(string file, string newName) {
void assignNewNameToFileFromVitis(string vitisFile,
string newName,
size_t number) {
string filepath = moduleVitisBase.findFileInVitis(vitisFile, number)[0];
string filepath = moduleBase.findFileInVitis(vitisFile, number)[0];
assignNewNameByFile(filepath, newName);
}
......@@ -550,14 +599,14 @@ void makeSubcategories(string category,
bool flagGlobal,
bool userConfirmation,
bool userDenial) {
string[] subcategories = subcategories_.dup;
auto subcategories = subcategories_.dup;
if (!createNonExistentCategory(category, userConfirmation, userDenial))
return;
foreach(subcategory; subcategories) {
string finCat = category ~ "/" ~ subcategory;
if ("" != getCatDirPath(finCat)) {
auto msg = finCat ~ ": this subcategory already exists."._s ~ " "
~ "The request is skipped."._s ~ "\n";
auto msg = finCat ~ ": this subcategory already exists."._s
~ " " ~ "The request is skipped."._s ~ "\n";
"warning".tprint(msg);
continue;
}
......@@ -601,14 +650,18 @@ private void createNewSymlinks(string[] categories,
"warning".tprintln("The request is skipped."._s);
}
//categories.length < categoriesPaths.length
//checking unnecessary links is not for autocategories
if (i > categories.length-1 || categories.empty) continue;
import module_service : checkUnnecessaryLinks;
auto category = categories[i];
auto topCat = category.split('/')[0];
auto topDir = getCatDirPath(topCat);
auto topDir = getCatDirPath(topCat).stripRight('/');
while (topDir.isSymlink) {
topCat = topDir.readLink()[vpath.length .. $];
topCat = topCat.split('/')[0];
topDir = getCatDirPath(topCat).stripRight('/');
}
checkUnnecessaryLinks([topDir], false, true);
}
}
......@@ -704,8 +757,30 @@ private string createFragPointer(string file,
}
private string addFileInFileSpace(string f, string destFileSpace,
bool userConfirmation, bool userDenial) {
private bool areFilesIdentical(string file1, string file2) {
if (file1.getSize != file2.getSize) {
return false;
}
auto f1 = File(file1, "r");
auto f2 = File(file2, "r");
byte[1024] buffer1;
byte[1024] buffer2;
byte[] slice1, slice2;
do {
slice1 = f1.rawRead(buffer1);
slice2 = f2.rawRead(buffer2);
if (slice1 != slice2) {
return false;
}
} while(!slice1.empty);
return true;
}
private string addFileInFileSpace(string f,
string destFileSpace,
bool userConfirmation,
bool userDenial) {
string[] allFileSpaces = VitisConf.getFileSpaces();
if (allFileSpaces.empty) {
throw new FileSpaceException("File spaces are not configured."._s);
......@@ -713,14 +788,14 @@ private string addFileInFileSpace(string f, string destFileSpace,
if (destFileSpace == "") {
destFileSpace = allFileSpaces[0];
} else {
if (!canFind(allFileSpaces, destFileSpace)) {
throw new FileSpaceException(
destFileSpace ~ ": " ~ "There is no file space."._s);
}
} else if (!canFind(allFileSpaces, destFileSpace)) {
auto err = destFileSpace ~ ": " ~ "There is no file space."._s;
throw new FileSpaceException(err);
}
if (f.startsWith(destFileSpace)) return f; //no save required
if (f.startsWith(destFileSpace)) {
return f; //save is not required
}
if (!destFileSpace.exists) {
mkdirRecurse(destFileSpace);
......@@ -742,32 +817,25 @@ private string addFileInFileSpace(string f, string destFileSpace,
);
"warning".tprintln("The request is skipped."._s);
} else if (f.isFile && newLocation.isFile) {
bool filesAreIdentical = false;
if (newLocation.getSize == f.getSize) {
auto md5sum1 = amalthea.crypto.getFileMD5Sum(f);
auto md5sum2 = amalthea.crypto.getFileMD5Sum(newLocation);
filesAreIdentical = (md5sum1 == md5sum2);
}
if (filesAreIdentical) {
bool answer;
if (!userDenial && !userConfirmation) {
"warning".tprintln(
newLocation, ": ",
"Exactly the same file already exists in the file space."._s
);
answer = getAnswerToTheQuestion(
"Do you want to write a duplicate file? y/n >: "._s
);
}
if (answer || userConfirmation) {
newLocation = writeDuplicateFile(f, destFileSpace);
}
} else {
newLocation = writeDuplicateFile(f, destFileSpace);
if (!areFilesIdentical(f, newLocation)) {
return writeDuplicateFile(f, destFileSpace);
}
if (userDenial) { // no rewrite (--no)
return newLocation;
}
if (userConfirmation) { // autoanswer with --yes
return writeDuplicateFile(f, destFileSpace);
}
auto w = "Exactly the same file already exists in the file space."._s;
"warning".tprintln(newLocation, ": ", w);
auto question = "Do you want to write a duplicate file? y/n >: "._s;
if (getAnswerToTheQuestion(question)) {
return writeDuplicateFile(f, destFileSpace);
}
return newLocation;
} else if (f.isDir && newLocation.isDir) {
newLocation = writeDuplicateFile(f, destFileSpace);
return writeDuplicateFile(f, destFileSpace);
}
return newLocation;
}
......
......@@ -58,7 +58,7 @@ string[] createCategories(string[] categoriesForCreating,
msg = c ~ ": creation of this category is not available."._s;
"warning".tprintln(msg, " ", "Skipped."._s);
}
} else if ("" != getCatDirPath(c)) {
} else if (!getCatDirPath(c).empty) {
if (!silentMode) {
msg = c ~ ": this category already exists."._s;
"warning".tprintln(msg, " ", "Skipped."._s);
......
......@@ -94,7 +94,7 @@ void deleteCategories(string[] categories, bool force = false) {
if (categoryPath.isSymlink) {
if (!force) {
rm(categoryPath);
return;
continue;
}
category = getCategoryByAlias(category);
categoryPath = getCatDirPath(category);
......@@ -111,7 +111,7 @@ void deleteCategoryFromFile(string category,
string vitisFile = category ~ "/" ~ filename;
string linkpath;
try {
linkpath = moduleVitisBase.findFileInVitis(vitisFile, number)[1];
linkpath = moduleBase.findFileInVitis(vitisFile, number)[1];
} catch(FileWarning e) {
"warning".tprintln(e.msg, " ", "The request is skipped."._s);
return;
......
......@@ -648,7 +648,7 @@ private string[] getCategoriesOfFile(string file) {
if (file.isSymlink) file = file.readLink;
else if (!file.startsWith('/')) file = pwd ~ "/" ~ file;
string[string] allLinks = moduleVitisBase.getAllLinks();
string[string] allLinks = moduleBase.getAllLinks();
foreach(l, lf; allLinks) {
if (lf != file) continue;
......
......@@ -17,7 +17,7 @@
*/
module module_vitis_base;
public alias moduleVitisBase = module_vitis_base;
public alias moduleBase = module_vitis_base;
public import amalthea.all, amalthea.phobos;
public import module_conf, module_output;
......@@ -348,7 +348,7 @@ bool isGlobalSubCategory(string thing) {
return false;
}
auto fullPath = getCatDirPath(thing);
auto globPath = getCatDirPath(thing.baseName);
auto globPath = getCatDirPath(thing.baseName).stripRight('/');
if (fullPath.empty || globPath.empty) return false;
if (globPath.isSymlink && globPath.readLink == fullPath) {
return true;
......@@ -357,6 +357,12 @@ bool isGlobalSubCategory(string thing) {
}
void changeSymlink(string link, string newPath) {
std.file.remove(link);
symlink(newPath, link);
}
string[] getTopLevelCategories(Flag!"fullPath" fullPath = Yes.fullPath) {
auto categories = getTopLevelCategoriesAndAliases()
.filter!(a => !a.isSymlink)
......
......@@ -700,10 +700,11 @@ case_2_1_8() {
case_2_1_9() {
subtitle "Case 9: Existent alias"
CMD="$vitis assign Moon -a Luna --yes"
$vitis create Luna $OPTCONF
CMD="$vitis assign Moon -a Luna --no"
$vitis create Moon Luna $OPTCONF
output=$($CMD $OPTCONF 2>&1)
expected="Luna: this category already exists. The request is skipped."
expected="Luna: this category already exists.
The request is skipped."
if [[ "${output}" == "${expected}" && ! -L ${VTS}/Luna ]]; then
pass "${CMD}"
else
......@@ -741,6 +742,30 @@ case_2_1_11() {
rm -rf "${VTS}"
}
case_2_1_12() {
subtitle "Case 12: Combining"
create_file_env
$vitis create Synthwave Retrowave $OPTCONF
$vitis assign Synthwave -s 1 $OPTCONF
$vitis assign Synthwave -f $FILE1 $OPTCONF
$vitis assign Synthwave/1 -f $FILE2 $OPTCONF
CMD="$vitis assign Retrowave -a Synthwave --yes"
output=$($CMD $OPTCONF 2>&1)
if [[ -L "${VTS}/Synthwave" && -L "${VTS}/Synthwave/file1.txt"
&& `readlink "${VTS}/Synthwave"` == "${VTS}/Retrowave/"
&& `readlink "${VTS}/Retrowave/file1.txt"` == $FILE1
&& -L "${VTS}/Retrowave/1/file2.txt"
&& `readlink "${VTS}/Retrowave/1/file2.txt"` == $FILE2
&& `readlink "${VTS}/1"` == "${VTS}/Retrowave/1/" ]]
then
pass "${CMD}"
else
fail "${CMD}"
fi
rm -rf "${VTS}"
destroy_file_env
}
procedure_2_1() {
procedure_title "PROCEDURE 2.1 'Aliases'"
case_2_1_1
......@@ -754,6 +779,7 @@ procedure_2_1() {
case_2_1_9
case_2_1_10
case_2_1_11
case_2_1_12
}
......@@ -2407,14 +2433,16 @@ case_2_12_2() {
$vitis create Audiofiles $OPTCONF
$vitis create Audioclips $OPTCONF
$vitis assign Audioclips -a Music $OPTCONF
CMD="$vitis assign Audiofiles -s Music"
CMD="$vitis assign Audiofiles -s Music --no"
output=$($CMD $OPTCONF 2>&1)
expected="Music: this category already exists. \
expected="Music: this category already exists.
/tmp/Vitis/Music -> /tmp/Vitis/Audioclips/
The request is skipped."
if [[ "$expected" == "$output" ]]; then
pass "${CMD}"
else
fail "${CMD}"
echo -e "$output"
fi
rm -rf "${VTS}"
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment