Skip to content

Commit

Permalink
Show Subversion status in file listing
Browse files Browse the repository at this point in the history
  • Loading branch information
jcheng5 committed Jun 22, 2011
1 parent bd78ac2 commit 13b1ed1
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 19 deletions.
144 changes: 127 additions & 17 deletions src/cpp/session/modules/SessionSourceControl.cpp
Expand Up @@ -31,6 +31,7 @@ class VCSImpl
public:
VCSImpl()
{
root_ = module_context::initialWorkingDirectory();
}

virtual ~VCSImpl()
Expand All @@ -43,6 +44,37 @@ class VCSImpl
*pStatusResult = StatusResult();
return Success();
}

// TODO: Figure out why compile fails when args is const&

This comment has been minimized.

Copy link
@jjallaire

jjallaire Jun 22, 2011

Member

The compile fails because the iterator used in the for loop needs to be a std::vectorstd::string::const_iterator

virtual core::Error runCommand(const std::string& command,
std::vector<std::string> args,
std::vector<std::string>* pOutputLines)
{
std::string cmd("cd ");
cmd.append(string_utils::bash_escape(root_));
cmd.append("; ");
cmd.append(command);
for (std::vector<std::string>::iterator it = args.begin();
it != args.end();
it++)
{
cmd.append(" ");
cmd.append(string_utils::bash_escape(*it));
}

std::string output;
Error error = core::system::captureCommand(cmd, &output);
if (error)
return error;

boost::algorithm::split(*pOutputLines, output,
boost::algorithm::is_any_of("\r\n"));

return Success();
}

protected:
FilePath root_;
};

boost::scoped_ptr<VCSImpl> s_pVcsImpl_;
Expand All @@ -52,7 +84,6 @@ class GitVCSImpl : public VCSImpl
public:
GitVCSImpl()
{
root_ = module_context::initialWorkingDirectory();
}

core::Error status(const FilePath& dir, StatusResult* pStatusResult)
Expand All @@ -61,21 +92,17 @@ class GitVCSImpl : public VCSImpl

std::vector<FileWithStatus> files;

std::string cmd("cd ");
cmd.append(string_utils::bash_escape(root_));
cmd.append("; git status --porcelain -- ");
cmd.append(string_utils::bash_escape(dir));
std::vector<std::string> args;
args.push_back("status");
args.push_back("--porcelain");
args.push_back("--");
args.push_back(string_utils::utf8ToSystem(dir.absolutePath()));

std::string output;
Error error = core::system::captureCommand(cmd, &output);
std::vector<std::string> lines;
Error error = runCommand("git", args, &lines);
if (error)
return error;

std::vector<std::string> lines;

boost::algorithm::split(lines, output,
boost::algorithm::is_any_of("\r\n"));

for (std::vector<std::string>::iterator it = lines.begin();
it != lines.end();
it++)
Expand Down Expand Up @@ -123,13 +150,84 @@ class GitVCSImpl : public VCSImpl

return Success();
}

private:
FilePath root_;
};

class SubversionVCSImpl : public GitVCSImpl
class SubversionVCSImpl : public VCSImpl
{
core::Error status(const FilePath& dir, StatusResult* pStatusResult)
{
using namespace boost;

std::vector<FileWithStatus> files;

std::vector<std::string> args;
args.push_back("status");
args.push_back("--non-interactive");
args.push_back("--depth=immediates");
args.push_back("--");
args.push_back(string_utils::utf8ToSystem(dir.absolutePath()));

std::vector<std::string> lines;
Error error = runCommand("svn", args, &lines);
if (error)
return error;

for (std::vector<std::string>::iterator it = lines.begin();

This comment has been minimized.

Copy link
@jjallaire

jjallaire Jun 22, 2011

Member

can also be a const_iterator

it != lines.end();
it++)
{
std::string line = *it;
if (line.length() < 4)
continue;
FileWithStatus file;
switch (line[0])
{
case ' ':
file.status = VCSStatusUnmodified;
break;
case 'A':
file.status = VCSStatusAdded;
break;
case 'C':
file.status = VCSStatusUnmerged;
break;
case 'D':
file.status = VCSStatusDeleted;
break;
case 'I':
file.status = VCSStatusIgnored;
break;
case 'M':
file.status = VCSStatusModified;
break;
case 'R':
file.status = VCSStatusReplaced;
break;
case 'X':
file.status = VCSStatusExternal;
break;
case '?':
file.status = VCSStatusUntracked;
break;
case '!':
file.status = VCSStatusMissing;
break;
case '~':
file.status = VCSStatusObstructed;
break;
default:
LOG_WARNING_MESSAGE("Unparseable svn-status line: " + line);
continue;
}

file.path = FilePath(string_utils::systemToUtf8(line.substr(8)));
files.push_back(file);
}

*pStatusResult = StatusResult(files);

return Success();
}
};

} // anonymous namespace
Expand Down Expand Up @@ -157,7 +255,19 @@ core::Error status(const FilePath& dir, StatusResult* pStatusResult)

core::Error initialize()
{
s_pVcsImpl_.reset(new GitVCSImpl());
switch (activeVCS())
{
case VCSGit:
s_pVcsImpl_.reset(new GitVCSImpl());
break;
case VCSSubversion:
s_pVcsImpl_.reset(new SubversionVCSImpl());
break;
default:
s_pVcsImpl_.reset(new VCSImpl());
break;
}

return Success();
}

Expand Down
9 changes: 8 additions & 1 deletion src/cpp/session/modules/SessionSourceControl.hpp
Expand Up @@ -34,6 +34,7 @@ enum VCS
VCSSubversion
};

// Must stay in sync with VCSStatus enum in VCSStatus.java
enum VCSStatus
{
VCSStatusUnmodified,
Expand All @@ -43,7 +44,13 @@ enum VCSStatus
VCSStatusDeleted,
VCSStatusRenamed,
VCSStatusCopied,
VCSStatusUnmerged
VCSStatusUnmerged,
// SVN specific
VCSStatusIgnored,
VCSStatusReplaced,
VCSStatusExternal,
VCSStatusMissing,
VCSStatusObstructed
};

struct FileWithStatus
Expand Down
Expand Up @@ -16,14 +16,20 @@

public enum VCSStatus
{
// Must stay in sync with VCSStatus enum in SessionSourceControl.hpp
Unmodified,
Untracked,
Modified,
Added,
Deleted,
Renamed,
Copied,
Unmerged;
Unmerged,
Ignored,
Replaced,
External,
Missing,
Obstructed;

private static VCSStatus[] all = values();

Expand Down

0 comments on commit 13b1ed1

Please sign in to comment.