gitprep / templates / compare.html.ep /
ff1f87f 8 years ago
2 contributor
390 lines | 12.678kb
<%
  # API
  my $api = gitprep_api;

  # Parameters
  my $user = param('user');
  my $project = param('project');
  my $from_rev = param('rev1');
  my $rev = param('rev2');
  my $page = param('page') || 0;
  my $expand = param('expand');
  
  unless ($from_rev) {
    $from_rev = app->manager->default_branch($user, $project);
  }
  
  # Git
  my $git = $self->app->git;
  
  if (lc $self->req->method eq 'post') {
    my $op = param('op');
    
    if ($op eq 'create-pull-request') {
      my $title = param('title');
      my $message = param('message');
      
      my $project_row_id = app->dbi->model('project')->select(
        'row_id',
        where => {user_id => $user, name => $project}
      )->value;
      
      my $pull_request = app->dbi->model('pull_request')->select(
        where => {project => $project_row_id, branch1 => $from_rev, branch2 => $rev}
      )->one;
      
      if ($pull_request) {
        $self->redirect_to("/$user/$project/pulls/$pull_request->{row_id}");
        return;
      }
      else {
        my $new_pull_request_params = {
          project => $project_row_id,
          branch1 => $from_rev,
          branch2 => $rev,
          title => $title,
          message => $message,
          open => 1
        };
        
        app->dbi->model('pull_request')->insert($new_pull_request_params);
        
        my $new_pull_request_row_id = app->dbi->model('pull_request')->select(
          'row_id',
          where => {
            project => $project_row_id,
            branch1 => $from_rev,
            branch2 => $rev
          }
        )->value;
        
        $self->redirect_to("/$user/$project/pulls/$new_pull_request_row_id");
        return;
      }
      
    }
  }
  
  # Commits
  my $commits = $git->forward_commits(app->rep_info($user, $project), $from_rev, $rev);
  my $commits_count = @$commits;
  my $commits_date = {};
  my $authors = {};
  for my $commit (@$commits) {
    my $date = $commit->{age_string_date_local};
    $commits_date->{$date} ||= [];
    $authors->{$commit->{author}} = 1;
    push @{$commits_date->{$date}}, $commit;
  }
  my $authors_count = keys %$authors;

  # Start commit
  my $start_commit = $git->separated_commit(app->rep_info($user, $project), $from_rev, $rev);

  # End commit
  my $end_commit = $git->get_commit(app->rep_info($user, $project), $rev);
  
  if (!$start_commit || !$end_commit) {
    $self->reply->not_found;
    return;
  }
  
  # Branches
  my $branches = $git->branches(app->rep_info($user, $project));
  @$branches = sort { $a->{commit}{age} <=> $b->{commit}{age} } @$branches;
  
  # Variables
  stash id => $end_commit->{id};
  stash from_id => $start_commit->{id};
  stash rev => $end_commit->{id};
  stash from_rev => $start_commit->{id};
  
  # Can open pull request
  my $can_open_pull_request;
  if (keys %$commits_date && $expand) {
    $can_open_pull_request = 1;
  }
  
  # Can merge
  my $merge_automatical;
  if ($can_open_pull_request) {
    
    # Create working repository if it don't exist
    $self->app->manager->create_work_rep($user, $project);
    
    # Fetch repository
    my $work_rep_info = app->work_rep_info($user, $project);
    my @git_fetch_cmd = $self->app->git->cmd($work_rep_info, 'fetch');
    Gitprep::Util::run_command(@git_fetch_cmd)
      or Carp::croak "Can't execute git fetch: @git_fetch_cmd";
    
    # Lock repository
    my $lock = $self->app->manager->lock_rep($work_rep_info);
    
    # Checkout tmp branch and git reset --hard from my remote branch
    my $gitprep_tmp_branch_name = '__gitprep_tmp_branch__';
    my @git_checkout_tmp_branch = $self->app->git->cmd(
      $work_rep_info,
      'checkout',
      $gitprep_tmp_branch_name,
    );
    Gitprep::Util::run_command(@git_checkout_tmp_branch)
      or Carp::croak "Can't execute git checkout: @git_checkout_tmp_branch";
    
    # git reset --hard
    my @git_reset_hard_cmd = $self->app->git->cmd(
      $work_rep_info,
      'reset',
      '--hard',
      "origin/$from_rev"
    );
    Gitprep::Util::run_command(@git_reset_hard_cmd)
      or Carp::croak "Can't execute git reset --hard: @git_reset_hard_cmd";
    
    # Check merge automatically
    $merge_automatical = $self->app->manager->check_merge_automatical(
      app->work_rep_info($user, $project),
      $gitprep_tmp_branch_name,
      "origin/$rev"
    );
  }
  
  layout 'common', title => "Comparing $from_rev...$rev \x{30fb} $user/$project";
%>


%= javascript begin
  $(document).ready(function () {
    
    // Change base branch
    $('#base-branch-btn').on('click', function () {
      $('#base-branch-popup')
        .css('display', 'block')
        .css('top', '40px')
        .css('left', '10px')
      ;
    });
    $('#base-branch-close').on('click', function () {
      $('#base-branch-popup').css('display', 'none');
    });
    $('[name=base-branch]').on('keypress', function (e) {
      // Enter
      if (e.which == 13) {
        var href = '<%= url_for("/$user/$project/compare/") %>' + $(this).val() + '...<%= $rev %>';
        if (<%= $expand ? 1 : 0 %>) {
          href = href + '?expand=1';
        }
        location.href = href;
      }
    });
    
    // Change compare branch
    $('#compare-branch-btn').on('click', function () {
      $('#compare-branch-popup')
        .css('display', 'block')
        .css('top', '40px')
        .css('left', '96px')
      ;
    });
    $('#compare-branch-close').on('click', function () {
      $('#compare-branch-popup').css('display', 'none');
    });
    $('[name=compare-branch]').on('keypress', function (e) {
      // Enter
      if (e.which == 13) {
        var href = '<%= url_for("/$user/$project/compare/") %>' + '<%= $from_rev %>...' + $(this).val();
        if (<%= $expand ? 1 : 0 %>) {
          href = href + '?expand=1';
        }
        location.href = href;
      }
    });
  });
% end

%= include '/include/header';

<div class="container">
  <div class="topic1">
    % if ($can_open_pull_request) {
      Open a pull request
    % } else {
      Comparing changes
    % }
  </div>
  <div class="compare-select">
    <div>
      <div>
        <button id="base-branch-btn" class="btn btn-small">
          <span>base:</span><b> <%= $from_rev %></b><i class="icon-arrow-down"></i>
        </button>
        ...
        <button id="compare-branch-btn" class="btn btn-small">
          <span>compare:</span> <b><%= $rev %></b><i class="icon-arrow-down"></i>
        </button>
        
        % if ($can_open_pull_request) {
          % if ($merge_automatical) {
            <span style="margin-left:10px">
              <span style="color:green;font-weight:bold"><%= "\x{2714}" %>Able to merge.</span> These branches can be automatically merged.
            </span>
          % } else {
            <span style="margin-left:10px">
              <span style="color:red;font-weight:bold"><%= "×" %>Not able to merge.</span> These branches can't be automatically merged.
            </span>
          % }
        % }
      </div>
    </div>

    <div id="base-branch-popup" style="display:none;width:330px;position:absolute">
      <div class="radius-top border-gray" style="background:#E6E6FA;padding:10px">
        <div style="overflow:hidden">
          <div style="float:left;width:90%;">
            <b>Choose a base branch</b>
          </div>
          <div style="float:left:width:10%;text-align:right;">
            <i id="base-branch-close" class="icon-remove-circle"></i>
          </div>
        </div>
      </div>
      <div class="border-gray" style="background:#F5F5F5;border-top:none;border-bottom:none;text-align:center;padding:10px 0">
        %= text_field 'base-branch', style => 'margin-bottom:0;width:270px', placeholder => 'Branch, tag, commit, or history marker';
      </div>
      <div style="background:white;max-height:500px;overflow:auto;">
        <ul class="nav nav-tabs nav-stacked">
          % for (my $i = 0; $i < @$branches; $i++) {
            % my $branch = $branches->[$i];
              <li>
                <a style="border-top-left-radius:0px;border-top-right-radius:0px;"
                  href="<%= url_with("/$user/$project/compare/$branch->{name}...$rev") %>">
                  <%= $branch->{name} %>
                </a>
              </li>
          % }
        </ul>
      </div>
    </div>

    <div id="compare-branch-popup" style="display:none;width:330px;position:absolute">
      <div class="radius-top border-gray" style="background:#E6E6FA;padding:10px">
        <div style="overflow:hidden">
          <div style="float:left;width:90%;">
            <b>Choose a compare branch</b>
          </div>
          <div style="float:left:width:10%;text-align:right;">
            <i id="compare-branch-close" class="icon-remove-circle"></i>
          </div>
        </div>
      </div>
      <div class="border-gray" style="background:#F5F5F5;border-top:none;border-bottom:none;text-align:center;padding:10px 0">
        %= text_field 'compare-branch', style => 'margin-bottom:0;width:270px', placeholder => 'Branch, tag, commit, or history marker';
      </div>
      <div style="background:white;max-height:500px;overflow:auto;">
      <ul class="nav nav-tabs nav-stacked">
        % for (my $i = 0; $i < @$branches; $i++) {
          % my $branch = $branches->[$i];
            <li>
              <a style="border-top-left-radius:0px;border-top-right-radius:0px;"
                href="<%= url_with("/$user/$project/compare/$from_rev...$branch->{name}") %>">
                <%= $branch->{name} %>
              </a>
            </li>
        % }
      </ul>
      </div>
    </div>
  </div>
  
  % if ($merge_automatical) {
    <div class="compare-open-pull-request">
      <form action="<%= url_for %>" method="post">
        <%= hidden_field op => 'create-pull-request' %>
        <div class="compare-open-pull-request-title">
          <%= text_field 'title' => $commits->[0]{title_short}  %>
        </div>
        <div class="compare-open-pull-request-message">
          <%= text_area 'message' %>
        </div>
        <div class="compare-open-pull-request-button">
          <%= submit_button 'Create pull request', class => 'btn btn-success' %>
        </div>
      </form>
    </div>
  % }

  % if (keys %$commits_date) {
    <ul class="compare-header">
      <li>
        <b><%= @$commits %></b> <span>commit</span>
      </li>
      <li>
        <b><%= $authors_count %></b> <span>contributor</span>
      </li>
      <li>
        
      </li>
      <li>
        
      </li>
    </ul>
    
    <div class="commits">
      % for my $date (reverse sort keys %$commits_date) {
        % my $commits = $commits_date->{$date};
        
        <div class="commit-date">
          <i class="icon-off"></i><span>Commits on <%= $date %></span>
        </div>
        
        <ul class="compare-commits-date-container">
          % for my $commit (sort {$b->{author_epoch} <=> $a->{author_epoch}} @$commits) {
            <%
              my $commit_author_mail = $commit->{author_email};
              my $commit_author_id = app->dbi->model('user')->select(
                'id',
                where => {mail => $commit_author_mail}
              )->value;
            %>
            <li>
              <div class="compare-commits-author">
                <span title="<%= $commit->{author_email} %>">
                  % if (defined $commit_author_id) {
                    <a href="<%= url_for("/$commit_author_id") %>"><%= $commit_author_id %></a>
                  % } else {
                    <%= $commit->{author_name} %>
                  % }
                </span>
              </div>
              <div class="compare-commits-commit-title">
                <a style="color:#333" href="<%= url_for("/$user/$project/commit/$commit->{id}") %>">
                  <%= $commit->{title_short} %>
                </a>
              </div>
              <div class="compare-commits-commit-id">
                <a href="<%= url_for("/$user/$project/commit/$commit->{id}") %>">
                  <%= substr($commit->{id}, 0, 7) %>
                </a>
              </div>
            </li>
          % }
        </ul>
      % }
    </div>
  
    %= include '/include/commit_body';
  % } else {
    <div class="compare-nothing">
      <div>
        <b><big>There isn't anything to compare.</big></b>
      </div>
      <div>
        <b>
          <%= $from_rev %></b> is up to date with all commits from
          <b><%= $rev %></b>.
          Try <a href="<%= url_for("/$user/$project/compare/$rev...$from_rev") %>">switching the base</a> for your comparison.
      </div>
    </div>
  % }
</div>
%= include '/include/footer';