Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[*.cpp,*.hpp]
indent_size = 2
indent_style = space
7 changes: 2 additions & 5 deletions src/data/set.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@
// ----------------------------------------------------------------------------- : Set

Set::Set()
: vcs (make_intrusive<VCS>())
, script_manager(new SetScriptManager(*this))
: script_manager(new SetScriptManager(*this))
{}

Set::Set(const GameP& game)
: game(game)
, vcs (make_intrusive<VCS>())
, script_manager(new SetScriptManager(*this))
{
data.init(game->set_fields);
Expand All @@ -41,7 +39,6 @@ Set::Set(const GameP& game)
Set::Set(const StyleSheetP& stylesheet)
: game(stylesheet->game)
, stylesheet(stylesheet)
, vcs (make_intrusive<VCS>())
, script_manager(new SetScriptManager(*this))
{
data.init(game->set_fields);
Expand Down Expand Up @@ -204,7 +201,7 @@ IMPLEMENT_REFLECTION(Set) {
REFLECT(pack_types);
}
reflect_set_info_get_member(handler,data);
REFLECT_NO_SCRIPT_N("version_control", vcs);
//REFLECT_NO_SCRIPT_N("version_control", vcs);
REFLECT(apprentice_code);
}

Expand Down
6 changes: 0 additions & 6 deletions src/data/set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ class Set : public Packaged {

ActionStack actions; ///< Actions performed on this set and the cards in it
KeywordDatabase keyword_db; ///< Database for matching keywords, must be cleared when keywords change
VCSP vcs; ///< The version control system to use

/// A context for performing scripts
/** Should only be used from the main thread! */
Expand Down Expand Up @@ -118,11 +117,6 @@ class Set : public Packaged {
Version fileVersion() const override;
/// Validate that the set is correctly loaded
void validate(Version = app_version) override;

protected:
VCSP getVCS() override {
return vcs;
}

private:
DECLARE_REFLECTION_OVERRIDE();
Expand Down
21 changes: 20 additions & 1 deletion src/util/io/package.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
#include <wx/wfstream.h>
#include <wx/zipstrm.h>
#include <wx/dir.h>
#include <util\vcs\git.hpp>
#include <util\vcs\git.hpp>
#include <util\vcs\subversion.hpp>

// ----------------------------------------------------------------------------- : Package : outside

Expand All @@ -23,6 +26,7 @@ IMPLEMENT_DYNAMIC_ARG(Package*, clipboard_package, nullptr);

Package::Package()
: zipStream (nullptr)
, vcs (nullptr)
{}

Package::~Package() {
Expand Down Expand Up @@ -372,8 +376,18 @@ void Package::openDirectory(bool fast) {
void Package::openSubdir(const String& name) {
wxDir d(filename + _("/") + name);
if (!d.IsOpened()) return; // ignore errors here
// find files
String f; // filename
if (d.GetFirst(&f, _(".git"))) {
queue_message(MESSAGE_INFO, filename + _(" under git"));
vcs = make_intrusive<GitVCS>();
vcs->pull(filename);
}
if (d.GetFirst(&f, _(".svn"))) {
queue_message(MESSAGE_INFO, filename + _(" under subversion"));
vcs = make_intrusive<SubversionVCS>();
vcs->pull(filename);
}
// find files
for(bool ok = d.GetFirst(&f, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN) ; ok ; ok = d.GetNext(&f)) {
if (ignore_file(f)) continue;
// add file to list of known files
Expand Down Expand Up @@ -425,6 +439,10 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused, bool is_
vcs->addFile(f_out_path);
f.second.created = false;
}
else
{
vcs->updateFile(f_out_path);
}
} else if (filename != saveAs) {
// save as, copy old filess
if (isZipfile()) {
Expand All @@ -441,6 +459,7 @@ void Package::saveToDirectory(const String& saveAs, bool remove_unused, bool is_
// old file, just keep it
}
}
vcs->commit(saveAs);
}

void Package::saveToZipfile(const String& saveAs, bool remove_unused, bool is_copy) {
Expand Down
10 changes: 8 additions & 2 deletions src/util/io/package.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class Package : public IntrusivePtrVirtualBase {
Package();
virtual ~Package();

VCSP vcs; ///< The version control system to use

/// Is a file opened?
bool isOpened() const;
/// Must the package be saved with saveAs()?
Expand Down Expand Up @@ -182,8 +184,11 @@ class Package : public IntrusivePtrVirtualBase {
}

protected:
// TODO: I dislike putting this here very much. There ought to be a better way.
virtual VCSP getVCS() { return make_intrusive<VCS>(); }
virtual VCSP getVCS() {
if (vcs == nullptr)
return make_intrusive<VCS>();
return vcs;
}

/// true if this is a zip file, false if a directory
bool isZipfile() const { return !wxDirExists(filename); }
Expand Down Expand Up @@ -301,6 +306,7 @@ class Packaged : public Package {
DECLARE_REFLECTION_VIRTUAL();
friend void after_reading(Packaged& p, Version file_app_version);


private:
bool fully_loaded; ///< Is the package fully loaded?
friend struct JustAsPackageProxy;
Expand Down
2 changes: 2 additions & 0 deletions src/util/vcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <util/prec.hpp>
#include <util/vcs.hpp>
#include <util/vcs/subversion.hpp>
#include <util/vcs/git.hpp>

// ----------------------------------------------------------------------------- : Reflection

Expand All @@ -19,6 +20,7 @@ VCSP read_new<VCS>(Reader& reader) {
reader.handle(_("type"), type);
if (type == _("none")) return make_intrusive<VCS>();
else if (type == _("subversion")) return make_intrusive<SubversionVCS>();
else if (type == _("git")) return make_intrusive<GitVCS>();
else if (type.empty()) {
reader.warning(_ERROR_1_("expected key", _("version control system")));
throw ParseError(_ERROR_("aborting parsing"));
Expand Down
12 changes: 12 additions & 0 deletions src/util/vcs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ class VCS : public IntrusivePtrVirtualBase
virtual void removeFile (const wxFileName& filename) {
remove_file(filename.GetFullName());
}
/// Mark a file as updated
virtual void updateFile(const wxFileName& filename) {
}

/// Finalize changes and push them.
virtual void commit(const String& directory) {
}

virtual void pull(const String& directory) {
}



DECLARE_REFLECTION_VIRTUAL();
};
Expand Down
111 changes: 111 additions & 0 deletions src/util/vcs/git.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+

// ----------------------------------------------------------------------------- : Includes

#include <util/prec.hpp>
#include <util/vcs/git.hpp>
#include "wx/process.h"

// ----------------------------------------------------------------------------- : SVN File Manipulation

// Maybe consider linking against libgit2, and making this a core feature?
// food for future thought. Could be useful for template devs?
bool run_git(const Char** arguments, const wxString wd) {
wxProcess* process = new wxProcess(wxPROCESS_REDIRECT);
process->Redirect();
wxExecuteEnv* env = new wxExecuteEnv();
env->cwd = wd;
switch (wxExecute(const_cast<Char**>(arguments), wxEXEC_SYNC, process, env)) { // Yuck, const_cast
// Success
case 0:
delete process;
delete env;
return true;
// Couldn't run Git
case -1:
handle_error(String(_("Can't run Git.")));
delete process;
delete env;
return false;
// Git error
default:
String error = String(_("Git encountered an error:\n"));
wxString log;
wxInputStream* err = process->GetErrorStream();

wxTextInputStream tStream(*err);
while (!err->Eof())
{
log = tStream.ReadLine();
error.append(log).append('\n');
}
handle_error(error);
delete process;
delete env;
return false;
}
}

void GitVCS::addFile(const wxFileName& filename)
{
String name = filename.GetFullPath();
wxString wd = filename.GetPath(true);
const Char* name_c[] = { _("git"), _("add"), name.c_str(), nullptr };
if (!run_git(name_c, wd)) {
VCS::addFile(filename);
}
}

void GitVCS::moveFile(const wxFileName& source, const wxFileName& dest)
{
String source_name = source.GetFullPath(), dest_name = dest.GetFullPath();
const Char* name_c[] = { _("git"), _("mv"), source_name.c_str(), dest_name.c_str(), nullptr };
wxString wd = source.GetPath(true);
if (!run_git(name_c, wd)) {
VCS::moveFile(source, dest);
}
}

void GitVCS::removeFile(const wxFileName& filename)
{
String name = filename.GetFullPath();
const Char* name_c[] = { _("git"), _("rm"), name.c_str(), nullptr };
wxString wd = filename.GetPath(true);
// `git rm` only removes it from the index. We still need to removed it from the filesystem.
VCS::removeFile(filename);
if (!run_git(name_c, wd)) {
VCS::removeFile(filename);
}
}

void GitVCS::updateFile(const wxFileName& filename) {
// Git needs you to explicitly stage changes
this->addFile(filename);
}

void GitVCS::commit(const String& directory) {
const Char* name_c[] = { _("git"), _("commit"), nullptr };
run_git(name_c, directory);
const Char* push_c[] = { _("git"), _("push"), nullptr };
run_git(push_c, directory);
}

void GitVCS::pull(const String& directory) {
// TODO: Fetch, check status, and only pull if no conflicts.
const Char* name_c[] = { _("git"), _("pull"), nullptr };
run_git(name_c, directory);
}


IMPLEMENT_REFLECTION(GitVCS) {
REFLECT_IF_NOT_READING{
String type = _("git");
REFLECT(type);
}
}

// ----------------------------------------------------------------------------- : EOF
27 changes: 27 additions & 0 deletions src/util/vcs/git.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//+----------------------------------------------------------------------------+
//| Description: Magic Set Editor - Program to make Magic (tm) cards |
//| Copyright: (C) Twan van Laarhoven and the other MSE developers |
//| License: GNU General Public License 2 or later (see file COPYING) |
//+----------------------------------------------------------------------------+

#pragma once

// ----------------------------------------------------------------------------- : Includes

#include <util/prec.hpp>
#include <util/vcs.hpp>

// ----------------------------------------------------------------------------- : SubversionVCS

class GitVCS : public VCS {
public:
void addFile(const wxFileName& filename) final;
void moveFile(const wxFileName& source, const wxFileName& destination) final;
void removeFile(const wxFileName& filename) final;
void updateFile(const wxFileName& filename) final;
void commit(const String& directory) final;
void pull(const String& directory) final;

DECLARE_REFLECTION();
};

Loading