create wine bottles
This commit is contained in:
		| @@ -10,6 +10,7 @@ using namespace std; | ||||
| namespace cellar { | ||||
| 	namespace fs { | ||||
| 		extern vector<string> listdir(string path); | ||||
|         extern bool recursive_copy(string, string); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -2,3 +2,4 @@ list print_bottles List all available WINE bottles. | ||||
| 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 | ||||
|   | ||||
							
								
								
									
										79
									
								
								src/bottles/create.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/bottles/create.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| #include <cstdlib> | ||||
| #include <string> | ||||
| #include <vector> | ||||
|  | ||||
| #include <boost/filesystem/operations.hpp> | ||||
| #include <boost/filesystem/path.hpp> | ||||
| #include <tclap/CmdLine.h> | ||||
|  | ||||
| #include "bottles.hpp" | ||||
| #include "internal/bottles.hpp" | ||||
| #include "internal/launch.hpp" | ||||
| #include "fs.hpp" | ||||
| #include "output.hpp" | ||||
|  | ||||
| using namespace std; | ||||
| using namespace cellar; | ||||
|  | ||||
| void cellar::bottles::create_bottle(int argc, vector<string> argv) { | ||||
|     TCLAP::CmdLine cmdparse("create a new WINE bottle", ' ', "", false); | ||||
|  | ||||
|     TCLAP::ValueArg<string> namearg("n", "name", "Friendly name for the bottle.", false, "", "name"); | ||||
|     cmdparse.add(namearg); | ||||
|  | ||||
|     TCLAP::ValueArg<string> descarg("d", "desc", "Short (or longer) description for the bottle.", false, "", "desc"); | ||||
|     cmdparse.add(descarg); | ||||
|  | ||||
|     TCLAP::UnlabeledValueArg<string> bottlearg("bottle", "Bottle name. Follows the rules of -b.", true, "", "bottle"); | ||||
|     cmdparse.add(bottlearg); | ||||
|  | ||||
|     cmdparse.parse(argv); | ||||
|  | ||||
|  | ||||
|     string homepath = getenv("HOME"); | ||||
|     string bottlechoice = bottlearg.getValue(); | ||||
|     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 + " already exists"); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     if (fullbottlepath != homepath + "/.wine.template") { | ||||
|         // all this gets skipped if we're creating the template bottle | ||||
|         if (boost::filesystem::exists(homepath + "/.wine.template")) { | ||||
|             fs::recursive_copy(homepath + "/.wine.template", fullbottlepath); | ||||
|             return; | ||||
|         } else { | ||||
|             output::error("no template bottle"); | ||||
|             return; | ||||
|         } | ||||
|     } else { | ||||
|         if (boost::filesystem::exists(homepath + "/.wine")) { | ||||
|             output::statement("using existing bottle at ~/.wine as template bottle"); | ||||
|             fs::recursive_copy(homepath + "/.wine", fullbottlepath); | ||||
|         } else { | ||||
|             output::statement("creating template bottle from scratch"); | ||||
|             setenv("WINEPREFIX", fullbottlepath.c_str(), 1); | ||||
|             launch::popen("wineboot -u"); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										35
									
								
								src/fs.cpp
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/fs.cpp
									
									
									
									
									
								
							| @@ -9,23 +9,40 @@ | ||||
| #include "output.hpp" | ||||
|  | ||||
| using namespace std; | ||||
| using namespace boost; | ||||
|  | ||||
| vector<string> cellar::fs::listdir(string path) { | ||||
| 	vector<string> result; | ||||
|     boost::filesystem::path cwd(path); | ||||
|     boost::filesystem::directory_iterator iter_end; | ||||
|     filesystem::path cwd(path); | ||||
|     filesystem::directory_iterator iter_end; | ||||
|  | ||||
|     for (boost::filesystem::directory_iterator iter_cwd(cwd); iter_cwd != iter_end; ++iter_cwd) { | ||||
|         try { | ||||
|     for (filesystem::directory_iterator iter_cwd(cwd); iter_cwd != iter_end; ++iter_cwd) { | ||||
|         string item = iter_cwd->path().filename().native(); | ||||
| 		 | ||||
| 		result.push_back(item); | ||||
|         } | ||||
|         catch (const exception& exc) { | ||||
|             // TODO: better error handling | ||||
|             cellar::output::error("[1;31mfuck[0m"); | ||||
|         } | ||||
|     } | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| bool cellar::fs::recursive_copy(string src, string dst) { | ||||
|     if (!filesystem::exists(dst)) { | ||||
|         bool success = filesystem::create_directory(dst); | ||||
|         if (!success) { return false; } | ||||
|     } | ||||
|  | ||||
|     for (string itemrel : cellar::fs::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); } | ||||
|         else if (filesystem::is_symlink(itemstat)) {  | ||||
|             auto symlinkpath = filesystem::read_symlink(itemabs); | ||||
|             filesystem::create_symlink(symlinkpath, targetabs); | ||||
|         } | ||||
|         else { filesystem::copy(itemabs, targetabs); } | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user