File: GitModule.cpp

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (143 lines) | stat: -rw-r--r-- 3,837 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "GitModule.h"

#include "i18n.h"
#include "igame.h"
#include "ui/imainframe.h"
#include "imap.h"
#include "ipreferencesystem.h"
#include "ui/istatusbarmanager.h"
#include "icommandsystem.h"
#include <git2.h>
#include "Repository.h"
#include "Commit.h"
#include "GitException.h"
#include "Remote.h"
#include "ui/VcsStatus.h"
#include "VersionControlLib.h"
#include "command/ExecutionFailure.h"

namespace vcs
{

std::string GitModule::getUriPrefix()
{
    return UriPrefix;
}

ArchiveTextFilePtr GitModule::openTextFile(const std::string& vcsUri)
{
    try
    {
        assert(getVcsPrefix(vcsUri) == UriPrefix);

        if (!_repository)
        {
            return ArchiveTextFilePtr();
        }

        auto tree = _repository->getTreeByRevision(vcs::getVcsRevision(vcsUri));
        
        return tree->openTextFile(vcs::getVcsFilePath(vcsUri), *_repository);
    }
    catch (const git::GitException& ex)
    {
        rWarning() << "git::openTextFile failed: " << ex.what() << std::endl;
        return ArchiveTextFilePtr();
    }
}

const std::string& GitModule::getName() const
{
    static std::string _name("GitIntegration");
    return _name;
}

const StringSet& GitModule::getDependencies() const
{
    static StringSet _dependencies{ MODULE_MAINFRAME, MODULE_STATUSBARMANAGER, 
        MODULE_PREFERENCESYSTEM, MODULE_MAP, MODULE_VERSION_CONTROL_MANAGER };
    return _dependencies;
}

void GitModule::initialiseModule(const IApplicationContext& ctx)
{
    // Register commands
    registerCommands();
    createPreferencePage();

    // Initialise libgit2 to have the memory handlers etc. set up
    git_libgit2_init();

    auto modPath = GlobalGameManager().getModPath();
    _repository = std::make_unique<git::Repository>(modPath);
    
    if (_repository->isOk())
    {
        rMessage() << "Opened repository at " << modPath << std::endl;
        rMessage() << "Repository is currently on branch " << _repository->getCurrentBranchName() << std::endl;
    }
    else
    {
        _repository.reset();
    }

    GlobalMainFrame().signal_MainFrameConstructed().connect([&]()
    {
        _statusBarWidget = std::make_unique<ui::VcsStatus>(GlobalStatusBarManager().getStatusBar());
        GlobalStatusBarManager().addElement(ui::VcsStatus::Name, _statusBarWidget->getWidget(),
            ::ui::statusbar::StandardPosition::MapEditStopwatch + 10);

        _statusBarWidget->setRepository(_repository);
    });

    GlobalVersionControlManager().registerModule(shared_from_this());
}

void GitModule::shutdownModule()
{
    rMessage() << getName() << "::shutdownModule called." << std::endl;

    GlobalVersionControlManager().unregisterModule(shared_from_this());

    _statusBarWidget.reset();
    _repository.reset();

    git_libgit2_shutdown();
}

void GitModule::registerCommands()
{
    GlobalCommandSystem().addCommand("GitFetch", std::bind(&GitModule::fetch, this, std::placeholders::_1));
}

void GitModule::fetch(const cmd::ArgumentList& args)
{
    if (!_repository)
    {
        rWarning() << "Project is not under version control" << std::endl;
        return;
    }

    _statusBarWidget->startFetchTask();
}

void GitModule::createPreferencePage()
{
    auto& page = GlobalPreferenceSystem().getPage(_("Settings/Version Control"));

    page.appendCheckBox(_("Enable Auto-Fetch"), RKEY_AUTO_FETCH_ENABLED);
    page.appendSpinner(_("Fetch Interval (Minutes)"), RKEY_AUTO_FETCH_INTERVAL, 0.25, 900, 2);
}

}

/**
 * greebo: This is the module entry point which the main binary will look for.
 * The symbol RegisterModule is called with the singleton ModuleRegistry as argument.
 */
extern "C" void DARKRADIANT_DLLEXPORT RegisterModule(IModuleRegistry& registry)
{
    module::performDefaultInitialisation(registry);

    registry.registerModule(std::make_shared<vcs::GitModule>());
}