remove command, which supports dry runs (so does create)
This commit is contained in:
		@@ -3,3 +3,4 @@ active print_active_bottle Get the currently active WINE bottle.
 | 
			
		||||
activate switch_active_bottle Switch the active WINE bottle.
 | 
			
		||||
config config_command Change configuration options.
 | 
			
		||||
create create_bottle Create a new WINE bottle.
 | 
			
		||||
remove remove_bottle Remove a WINE bottle.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										45
									
								
								src/bottles/remove.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/bottles/remove.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,45 @@
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include <boost/filesystem/operations.hpp>
 | 
			
		||||
#include <boost/filesystem/path.hpp>
 | 
			
		||||
 | 
			
		||||
#include "bottles.hpp"
 | 
			
		||||
#include "internal/bottles.hpp"
 | 
			
		||||
#include "fs.hpp"
 | 
			
		||||
#include "output.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace cellar;
 | 
			
		||||
 | 
			
		||||
void cellar::bottles::remove_bottle(int argc, vector<string> argv) {
 | 
			
		||||
    string homepath = getenv("HOME");
 | 
			
		||||
    string bottlechoice = argv[1];
 | 
			
		||||
    string fullbottlepath;
 | 
			
		||||
    if (bottlechoice.substr(0,1) == "/" || bottlechoice.substr(0,1) == ".") { // absolute or relative path
 | 
			
		||||
        fullbottlepath = bottlechoice;
 | 
			
		||||
    } else if (bottlechoice.substr(0,1) == "~") { // "absolute" path in home directory, not expanded by the shell for some reason (i've seen some shit)
 | 
			
		||||
        // this is a naive replacement and will fail if the user tries something like ~nick/.wine
 | 
			
		||||
        // i'm figuring at that point if you're doing that, you'll also recognize if your shell
 | 
			
		||||
        // isn't actually expanding your path...
 | 
			
		||||
        bottlechoice.replace(0,1,getenv("HOME"));
 | 
			
		||||
        // or at least you'll think to use verbose mode to make sure it's loading the right directory
 | 
			
		||||
        output::warning("your shell didn't expand your given path properly, doing a naive replacement", true);
 | 
			
		||||
        fullbottlepath = bottlechoice;
 | 
			
		||||
    } else {
 | 
			
		||||
        if (bottlechoice.substr(0,6) == ".wine.") {
 | 
			
		||||
            output::statement("tip: cellar can add the \".wine.\" prefix automatically");
 | 
			
		||||
            bottlechoice.replace(0,6,"");
 | 
			
		||||
        }
 | 
			
		||||
       
 | 
			
		||||
        fullbottlepath = homepath + "/.wine." + bottlechoice;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (!boost::filesystem::exists(fullbottlepath)) {
 | 
			
		||||
        output::error(bottlechoice + " doesn't exist");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fs::recursive_remove(fullbottlepath);
 | 
			
		||||
}
 | 
			
		||||
@@ -28,6 +28,7 @@ using namespace std;
 | 
			
		||||
using namespace cellar;
 | 
			
		||||
using json = nlohmann::json;
 | 
			
		||||
 | 
			
		||||
bool cellar::dryrun;
 | 
			
		||||
bool cellar::verbose;
 | 
			
		||||
 | 
			
		||||
bottles::Bottle cellar::active_bottle;
 | 
			
		||||
@@ -52,6 +53,9 @@ int main(int argc, char* argv[]) {
 | 
			
		||||
        TCLAP::ValueArg<string> bottlearg("b", "bottle", "Use a wine bottle other than the one at ~/.wine", false, "", "bottle");
 | 
			
		||||
        cmdparse.add(bottlearg);
 | 
			
		||||
        
 | 
			
		||||
        TCLAP::SwitchArg dryrunarg("d", "dry-run", "Doesn't actually do anything");
 | 
			
		||||
        cmdparse.add(dryrunarg);
 | 
			
		||||
        
 | 
			
		||||
        TCLAP::SwitchArg verbosearg("v", "verbose", "Enables extra output");
 | 
			
		||||
        cmdparse.add(verbosearg);
 | 
			
		||||
        
 | 
			
		||||
@@ -63,6 +67,7 @@ int main(int argc, char* argv[]) {
 | 
			
		||||
 | 
			
		||||
        cmdparse.parse(argc, argv);
 | 
			
		||||
 | 
			
		||||
        dryrun = dryrunarg.getValue();
 | 
			
		||||
        verbose = verbosearg.getValue();
 | 
			
		||||
 | 
			
		||||
        // BULLSHIT: trying to use str.format on this string causes bizarre compiler errors
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										54
									
								
								src/fs.cpp
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								src/fs.cpp
									
									
									
									
									
								
							@@ -5,13 +5,22 @@
 | 
			
		||||
#include <boost/filesystem/operations.hpp>
 | 
			
		||||
#include <boost/filesystem/path.hpp>
 | 
			
		||||
 | 
			
		||||
#include "cellar.hpp"
 | 
			
		||||
#include "fs.hpp"
 | 
			
		||||
#include "output.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace std;
 | 
			
		||||
using namespace boost;
 | 
			
		||||
using namespace cellar;
 | 
			
		||||
using namespace fs;
 | 
			
		||||
 | 
			
		||||
vector<string> cellar::fs::listdir(string path) {
 | 
			
		||||
// these are not necessarily the final function signatures for callbacks
 | 
			
		||||
// this only exists so i don't have to come back and do the ductwork for
 | 
			
		||||
// callback functionality later
 | 
			
		||||
void cbnull_copy(string src, string dst) { return; }
 | 
			
		||||
void cbnull_remove(string src) { return; }
 | 
			
		||||
 | 
			
		||||
vector<string> fs::listdir(string path) {
 | 
			
		||||
	vector<string> result;
 | 
			
		||||
    filesystem::path cwd(path);
 | 
			
		||||
    filesystem::directory_iterator iter_end;
 | 
			
		||||
@@ -24,42 +33,61 @@ vector<string> cellar::fs::listdir(string path) {
 | 
			
		||||
	return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cellar::fs::recursive_copy(string src, string dst) {
 | 
			
		||||
bool fs::recursive_copy(string src, string dst, CopyCallbackFunc callback) {
 | 
			
		||||
    if (!filesystem::exists(dst)) {
 | 
			
		||||
        bool success = filesystem::create_directory(dst);
 | 
			
		||||
        if (!success) { return false; }
 | 
			
		||||
        if (dryrun) { output::statement("mkdir:   " + dst); }
 | 
			
		||||
        else {
 | 
			
		||||
            bool success = filesystem::create_directory(dst);
 | 
			
		||||
            if (!success) { return false; }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (string itemrel : cellar::fs::listdir(src)) {
 | 
			
		||||
    for (string itemrel : listdir(src)) {
 | 
			
		||||
        string itemabs = src + "/" + itemrel;
 | 
			
		||||
        string targetabs = dst + "/" + itemrel;
 | 
			
		||||
 | 
			
		||||
        auto itemstat = filesystem::symlink_status(itemabs);
 | 
			
		||||
 | 
			
		||||
        if (filesystem::is_directory(itemstat)) { recursive_copy(itemabs, targetabs); }
 | 
			
		||||
        if (filesystem::is_directory(itemstat)) { recursive_copy(itemabs, targetabs, callback); }
 | 
			
		||||
        else if (filesystem::is_symlink(itemstat)) { 
 | 
			
		||||
            auto symlinkpath = filesystem::read_symlink(itemabs);
 | 
			
		||||
            filesystem::create_symlink(symlinkpath, targetabs);
 | 
			
		||||
            if (dryrun) { output::statement("symlink: " + symlinkpath.native() + " => " + targetabs); }
 | 
			
		||||
            else { filesystem::create_symlink(symlinkpath, targetabs); }
 | 
			
		||||
        }
 | 
			
		||||
        else { filesystem::copy(itemabs, targetabs); }
 | 
			
		||||
        else { 
 | 
			
		||||
            if (dryrun) { output::statement("copy:    " + itemabs + " => " + targetabs); }
 | 
			
		||||
            else { filesystem::copy(itemabs, targetabs); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        callback(itemabs, targetabs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool cellar::fs::recursive_remove(string target) {
 | 
			
		||||
bool fs::recursive_copy(string src, string dst) { return recursive_copy(src, dst, cbnull_copy); }
 | 
			
		||||
 | 
			
		||||
bool fs::recursive_remove(string target, RemoveCallbackFunc callback) {
 | 
			
		||||
    if (!filesystem::exists(target)) { return false; }
 | 
			
		||||
 | 
			
		||||
    for (string itemrel : cellar::fs::listdir(target)) {
 | 
			
		||||
    for (string itemrel : listdir(target)) {
 | 
			
		||||
        string itemabs = target + "/" + itemrel;
 | 
			
		||||
 | 
			
		||||
        auto itemstat = filesystem::symlink_status(itemabs);
 | 
			
		||||
 | 
			
		||||
        if (filesystem::is_directory(itemstat)) { recursive_remove(itemabs); }
 | 
			
		||||
        else { filesystem::remove(itemabs); }
 | 
			
		||||
        if (filesystem::is_directory(itemstat)) { recursive_remove(itemabs, callback); }
 | 
			
		||||
        else {
 | 
			
		||||
            if (dryrun) { output::error("rm:      " + itemabs); } 
 | 
			
		||||
            else { filesystem::remove(itemabs); }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        callback(itemabs);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    filesystem::remove(target);
 | 
			
		||||
    if (dryrun) { output::error("rm:      " + target); }
 | 
			
		||||
    else { filesystem::remove(target); }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool fs::recursive_remove(string target) { return recursive_remove(target, cbnull_remove); }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user