Skip to content

Commit

Permalink
Add scm method to get source control date
Browse files Browse the repository at this point in the history
Summary: Add a method to the existing SCM abstraction so we can get the source control date for a given commit hash.

Reviewed By: wez

Differential Revision: D8224127

fbshipit-source-id: 7de51cb8eb502253b2b890905b63fbfd3bd27522
  • Loading branch information
kcoons authored and facebook-github-bot committed Aug 2, 2018
1 parent ed6049e commit 3d2c032
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 0 deletions.
33 changes: 33 additions & 0 deletions scm/Mercurial.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
/* Copyright 2017-present Facebook, Inc.
* Licensed under the Apache License, Version 2.0 */
#include "Mercurial.h"
#include <chrono>
#include <cmath>
#include <cstdio>
#include "ChildProcess.h"
#include "Logging.h"
#include "watchman.h"

// Capability indicating support for the mercurial SCM
W_CAP_REG("scm-hg")

using namespace std::chrono;

namespace watchman {

std::string hgExecutablePath() {
Expand Down Expand Up @@ -260,4 +265,32 @@ SCM::StatusResult Mercurial::getFilesChangedBetweenCommits(
return result;
}

time_point<system_clock> Mercurial::getCommitDate(
w_string_piece commitId,
w_string requestId) const {
ChildProcess proc(
{hgExecutablePath(), "log", "-r", commitId.data(), "-T", "{date}\n"},
makeHgOptions(requestId));
auto outputs = proc.communicate();
auto status = proc.wait();
if (status) {
throw std::runtime_error(to<std::string>(
"failed query for hg log; command returned with status ",
status,
" out=",
outputs.first,
" err=",
outputs.second));
}
return Mercurial::convertCommitDate(outputs.first.c_str());
}

time_point<system_clock> Mercurial::convertCommitDate(const char* commitDate) {
double date;
if (std::sscanf(commitDate, "%lf", &date) != 1) {
throw std::runtime_error(to<std::string>(
"failed to parse date value `", commitDate, "` into a double"));
}
return system_clock::from_time_t(date);
}
} // namespace watchman
6 changes: 6 additions & 0 deletions scm/Mercurial.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ class Mercurial : public SCM {
w_string_piece commitA,
w_string_piece commitB,
w_string requestId = nullptr) const override;
std::chrono::time_point<std::chrono::system_clock> getCommitDate(
w_string_piece commitId,
w_string requestId = nullptr) const override;
// public for testing
static std::chrono::time_point<std::chrono::system_clock> convertCommitDate(
const char* commitDate);

private:
// Returns options for invoking hg
Expand Down
7 changes: 7 additions & 0 deletions scm/SCM.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* Licensed under the Apache License, Version 2.0 */
#pragma once
#include "watchman_system.h"
#include <chrono>
#include <memory>
#include <vector>
#include "watchman_string.h"
Expand Down Expand Up @@ -62,6 +63,12 @@ class SCM {
w_string_piece commitB,
w_string requestId = nullptr) const = 0;

// Compute the source control date associated with the specified
// commit.
virtual std::chrono::time_point<std::chrono::system_clock> getCommitDate(
w_string_piece commitId,
w_string requestId = nullptr) const = 0;

private:
w_string rootPath_;
w_string scmRoot_;
Expand Down
22 changes: 22 additions & 0 deletions tests/MercurialTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/* Copyright 2016-present Facebook, Inc.
* Licensed under the Apache License, Version 2.0. */

#include "scm/Mercurial.h"
#include "thirdparty/tap.h"
#include "watchman.h"

using namespace std::chrono;

void test_convert_date() {
auto date = watchman::Mercurial::convertCommitDate("1529420960.025200");
auto result = duration_cast<seconds>(date.time_since_epoch()).count();
auto expected = 1529420960;
ok(result == expected, "Expected %d but observed %d", expected, result);
}

int main(int, char**) {
plan_tests(1);
test_convert_date();

return exit_status();
}
10 changes: 10 additions & 0 deletions tests/TARGETS
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,13 @@ t_test(
"//watchman:testsupport",
],
)

t_test(
name = "mercurialTest",
srcs = [
"MercurialTest.cpp",
],
deps = [
"//watchman:watchmanlib",
],
)
6 changes: 6 additions & 0 deletions watcher/eden.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,12 @@ class EdenWrappedSCM : public SCM {
return inner_->getFilesChangedBetweenCommits(commitA, commitB);
}

std::chrono::time_point<std::chrono::system_clock> getCommitDate(
w_string_piece commitId,
w_string requestId = nullptr) const override {
return inner_->getCommitDate(commitId, requestId);
}

static std::unique_ptr<EdenWrappedSCM> wrap(std::unique_ptr<SCM> inner) {
if (!inner) {
return nullptr;
Expand Down

0 comments on commit 3d2c032

Please sign in to comment.