Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Add support for the Perforce VCS client via the "git p4" command #135

Closed
wants to merge 1 commit into from

3 participants

Nathaniel Waisbrot Tuncer Ayaz Dave Smith
Nathaniel Waisbrot

As an alternative to pull request #136 (Perforce support via the official "p4" command), this uses the Git subcommand git p4 (http://git-scm.com/docs/git-p4).

The disadvantage of this method of pulling in Perforce-managed dependencies is that git p4 is not present in all Git installations and it adds an extra layer of indirection to things. On the other hand, the messiness of using Perforce for dependencies get hidden behind some code maintained by Someone Else, rather than teaching Rebar to understand a new VCS.

src/rebar_deps.erl
@@ -600,6 +608,7 @@ vcs_client_vsn(Path, VsnArg, VsnRegex) ->
required_vcs_client_vsn(hg) -> {1, 1};
required_vcs_client_vsn(git) -> {1, 5};
+required_vcs_client_vsn(git_p4) -> {1}; % does 'git-p4' exist?
Tuncer Ayaz
tuncer added a note

Isn't git-p4 bundled with git? So, wouldn't it make sense to check for a specific git version?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Tuncer Ayaz tuncer commented on the diff
src/rebar_deps.erl
@@ -626,6 +642,8 @@ vcs_client_vsn(fossil) ->
has_vcs_dir(git, Dir) ->
filelib:is_dir(filename:join(Dir, ".git"));
+has_vcs_dir(git_p4, Dir) ->
+ filelib:is_dir(filename:join(Dir, ".git")); % looks like vanilla git
Tuncer Ayaz
tuncer added a note

Would it be more precise or less ambiguous to say % same as vanilla git?

Maybe. It depends on what your definition of "Git" is. I would say that it is not the same, because a "git p4" repository behaves differently when you talk to the upstream.

My comment was meant to note the potential bug where you have a Git repo but change the dependency to "git_p4" after fetching once. I haven't tested, but I believe that in that case Rebar would behave as if everything was fine, silently ignoring the repository change.

Tuncer Ayaz
tuncer added a note

I see, that wasn't clear to me from the comment alone. I suggest you test that, as it's important to know whether git throws an error when we try to run a git_p4 command on the existing vanilla git repo. This is probably unlikely to happen in practice, but maybe we should handle such a case with an informative error. Thoughts?

Turns out Git provides an error message either way (checked out as {git,git_p4}, updated as {git_p4,git}). I think the messages are sufficient for a user to figure out that the dependency has gotten into a broken state due to some improper change.

Tuncer Ayaz
tuncer added a note

Sounds good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Tuncer Ayaz

Thanks @waisbrot, you should squash the second commit into the first one and fix (imperative present tense) the commit message following https://github.com/rebar/rebar#writing-commit-messages.

Nathaniel Waisbrot

Thanks for the comments, @tuncer. I've squashed, edited the commit, and I changed the version check for git_p4.

The git p4 command does not come standard on all Git distributions that can support it. It's part of my homebrew install, but I didn't find in on the Git RPM that I was working with under RHEL, despite that distribution being a later version of Git than my local one. Therefore, I've set the version requirement to be whatever Rebar needs from Git itself, but also a test for the presence of the git p4 command.

Tuncer Ayaz

Therefore, I've set the version requirement to be whatever Rebar needs from Git itself, but also a test for the presence of the git p4 command.

OK, but if there's a minimum git version for proper git-p4 functionality that's different, you may want to check for that instead.

Can you also please add a sample git-p4 dep to rebar_deps:info/2 after extending the same section in rebar.config.sample?

Dave Smith
Owner

I prefer the pure P4 interaction to this changeset. Which one do you prefer, @waisbrot?

Nathaniel Waisbrot waisbrot Add support for "git_p4" (Perforce via Git) as an SCM method
Perforce is another VCS. A Git connector exists for it, at least
under some installations. Using the "git p4" command is a simple
way to modify the Rebar code and allow dependencies to be stored
in Perforce.
19ca2c1
Nathaniel Waisbrot

@tuncer I can't find any minimum Git version documented. "git p4" is a python script that doesn't appear to have many dependencies on Git.

Examples added.

@dizzyd: as a user, I prefer the pure-p4 way (why should I have to install Git just to access Perforce?). I proffered this patch because I think it's more maintainable, since you can just put your faith in Git and not worry about p4's weird need to read from stdin.

Nathaniel Waisbrot

Closing this in favor of #136.

Nathaniel Waisbrot waisbrot closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 23, 2013
  1. Nathaniel Waisbrot

    Add support for "git_p4" (Perforce via Git) as an SCM method

    waisbrot authored
    Perforce is another VCS. A Git connector exists for it, at least
    under some installations. Using the "git p4" command is a simple
    way to modify the Rebar code and allow dependencies to be stored
    in Perforce.
This page is out of date. Refresh to see the latest.
Showing with 26 additions and 2 deletions.
  1. +2 −0  rebar.config.sample
  2. +24 −2 src/rebar_deps.erl
2  rebar.config.sample
View
@@ -157,6 +157,8 @@
{application_name, "1.0.*"},
{application_name, "1.0.*",
{git, "git://github.com/rebar/rebar.git", {branch, "master"}}},
+ {application_name, ".*",
+ {git_p4, "//depot/path/to/source"}},
%% Dependencies can be marked as 'raw'. Rebar does not require
%% such dependencies to have a standard Erlang/OTP layout
%% which assumes the presence of either
26 src/rebar_deps.erl
View
@@ -234,6 +234,8 @@ info_help(Description) ->
{application_name, "1.0.*"},
{application_name, "1.0.*",
{git, "git://github.com/rebar/rebar.git", {branch, "master"}}},
+ {application_name, ".*",
+ {git_p4, "//depot/path/to/source"}},
{application_name, "",
{git, "git://github.com/rebar/rebar.git", {branch, "master"}},
[raw]}]}
@@ -489,6 +491,11 @@ download_source(AppDir, {git, Url, Rev}) ->
rebar_utils:sh(?FMT("git clone -n ~s ~s", [Url, filename:basename(AppDir)]),
[{cd, filename:dirname(AppDir)}]),
rebar_utils:sh(?FMT("git checkout -q ~s", [Rev]), [{cd, AppDir}]);
+download_source(AppDir, {git_p4, Url}) ->
+ ok = filelib:ensure_dir(AppDir),
+ rebar_utils:sh(?FMT("git p4 clone --silent ~s ~s",
+ [Url, filename:basename(AppDir)]),
+ [{cd, filename:dirname(AppDir)}]);
download_source(AppDir, {bzr, Url, Rev}) ->
ok = filelib:ensure_dir(AppDir),
rebar_utils:sh(?FMT("bzr branch -r ~s ~s ~s",
@@ -549,6 +556,9 @@ update_source1(AppDir, {git, _Url, Refspec}) ->
ShOpts = [{cd, AppDir}],
rebar_utils:sh("git fetch origin", ShOpts),
rebar_utils:sh(?FMT("git checkout -q ~s", [Refspec]), ShOpts);
+update_source1(AppDir, {git_p4, _Url}) ->
+ ShOpts = [{cd, AppDir}],
+ rebar_utils:sh("git p4 sync", ShOpts);
update_source1(AppDir, {svn, _Url, Rev}) ->
rebar_utils:sh(?FMT("svn up -r ~s", [Rev]), [{cd, AppDir}]);
update_source1(AppDir, {hg, _Url, Rev}) ->
@@ -576,8 +586,8 @@ source_engine_avail(Source) ->
source_engine_avail(Name, Source).
source_engine_avail(Name, Source)
- when Name == hg; Name == git; Name == svn; Name == bzr; Name == rsync;
- Name == fossil ->
+ when Name == hg; Name == git; Name == git_p4; Name == svn; Name == bzr;
+ Name == rsync; Name == fossil ->
case vcs_client_vsn(Name) >= required_vcs_client_vsn(Name) of
true ->
true;
@@ -600,6 +610,7 @@ vcs_client_vsn(Path, VsnArg, VsnRegex) ->
required_vcs_client_vsn(hg) -> {1, 1};
required_vcs_client_vsn(git) -> {1, 5};
+required_vcs_client_vsn(git_p4) -> required_vcs_client_vsn(git);
required_vcs_client_vsn(bzr) -> {2, 0};
required_vcs_client_vsn(svn) -> {1, 6};
required_vcs_client_vsn(rsync) -> {2, 0};
@@ -611,6 +622,13 @@ vcs_client_vsn(hg) ->
vcs_client_vsn(git) ->
vcs_client_vsn(rebar_utils:find_executable("git"), " --version",
"git version (\\d+).(\\d+)");
+vcs_client_vsn(git_p4) ->
+ {ok, Info} = rebar_utils:sh(rebar_utils:find_executable("git")++" help -a",
+ [{env,[{"LANG","C"}]},{use_stdout,false}]),
+ case re:run(Info, "\\bp4\\b", [{capture, none}]) of
+ match -> vcs_client_vsn(git);
+ nomatch -> {0}
+ end;
vcs_client_vsn(bzr) ->
vcs_client_vsn(rebar_utils:find_executable("bzr"), " --version",
"Bazaar \\(bzr\\) (\\d+).(\\d+)");
@@ -626,6 +644,8 @@ vcs_client_vsn(fossil) ->
has_vcs_dir(git, Dir) ->
filelib:is_dir(filename:join(Dir, ".git"));
+has_vcs_dir(git_p4, Dir) ->
+ filelib:is_dir(filename:join(Dir, ".git")); % looks like vanilla git
Tuncer Ayaz
tuncer added a note

Would it be more precise or less ambiguous to say % same as vanilla git?

Maybe. It depends on what your definition of "Git" is. I would say that it is not the same, because a "git p4" repository behaves differently when you talk to the upstream.

My comment was meant to note the potential bug where you have a Git repo but change the dependency to "git_p4" after fetching once. I haven't tested, but I believe that in that case Rebar would behave as if everything was fine, silently ignoring the repository change.

Tuncer Ayaz
tuncer added a note

I see, that wasn't clear to me from the comment alone. I suggest you test that, as it's important to know whether git throws an error when we try to run a git_p4 command on the existing vanilla git repo. This is probably unlikely to happen in practice, but maybe we should handle such a case with an informative error. Thoughts?

Turns out Git provides an error message either way (checked out as {git,git_p4}, updated as {git_p4,git}). I think the messages are sufficient for a user to figure out that the dependency has gotten into a broken state due to some improper change.

Tuncer Ayaz
tuncer added a note

Sounds good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
has_vcs_dir(hg, Dir) ->
filelib:is_dir(filename:join(Dir, ".hg"));
has_vcs_dir(bzr, Dir) ->
@@ -649,6 +669,8 @@ format_source(App, {git, Url, {branch, Branch}}) ->
?FMT("~p BRANCH ~s ~s", [App, Branch, Url]);
format_source(App, {git, Url, {tag, Tag}}) ->
?FMT("~p TAG ~s ~s", [App, Tag, Url]);
+format_source(App, {git_p4, Url}) ->
+ format_source(App, {git, Url});
format_source(App, {_, Url, Rev}) ->
?FMT("~p REV ~s ~s", [App, Rev, Url]);
format_source(App, undefined) ->
Something went wrong with that request. Please try again.