create wine bottles
This commit is contained in:
parent
70fa9f4cf7
commit
166395681c
@ -10,6 +10,7 @@ using namespace std;
|
|||||||
namespace cellar {
|
namespace cellar {
|
||||||
namespace fs {
|
namespace fs {
|
||||||
extern vector<string> listdir(string path);
|
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.
|
active print_active_bottle Get the currently active WINE bottle.
|
||||||
activate switch_active_bottle Switch the active WINE bottle.
|
activate switch_active_bottle Switch the active WINE bottle.
|
||||||
config config_command Change configuration options.
|
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"
|
#include "output.hpp"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
using namespace boost;
|
||||||
|
|
||||||
vector<string> cellar::fs::listdir(string path) {
|
vector<string> cellar::fs::listdir(string path) {
|
||||||
vector<string> result;
|
vector<string> result;
|
||||||
boost::filesystem::path cwd(path);
|
filesystem::path cwd(path);
|
||||||
boost::filesystem::directory_iterator iter_end;
|
filesystem::directory_iterator iter_end;
|
||||||
|
|
||||||
for (boost::filesystem::directory_iterator iter_cwd(cwd); iter_cwd != iter_end; ++iter_cwd) {
|
for (filesystem::directory_iterator iter_cwd(cwd); iter_cwd != iter_end; ++iter_cwd) {
|
||||||
try {
|
|
||||||
string item = iter_cwd->path().filename().native();
|
string item = iter_cwd->path().filename().native();
|
||||||
|
|
||||||
result.push_back(item);
|
result.push_back(item);
|
||||||
}
|
|
||||||
catch (const exception& exc) {
|
|
||||||
// TODO: better error handling
|
|
||||||
cellar::output::error("[1;31mfuck[0m");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
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;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user