# incremented the version number to 0.3.0 to begin working on the 0.3.0 release

# added svn_tag_property to support soft tagging/labeling
# changed some code views to show the tag
# enhanced the revision view to tag/untag the revision
This commit is contained in:
hyung-hwan 2015-04-12 15:31:09 +00:00
parent f915bca6d5
commit a950cb9e30
12 changed files with 268 additions and 54 deletions

20
codepot/configure vendored
View File

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for codepot 0.2.0. # Generated by GNU Autoconf 2.69 for codepot 0.3.0.
# #
# #
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@ -576,8 +576,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='codepot' PACKAGE_NAME='codepot'
PACKAGE_TARNAME='codepot' PACKAGE_TARNAME='codepot'
PACKAGE_VERSION='0.2.0' PACKAGE_VERSION='0.3.0'
PACKAGE_STRING='codepot 0.2.0' PACKAGE_STRING='codepot 0.3.0'
PACKAGE_BUGREPORT='' PACKAGE_BUGREPORT=''
PACKAGE_URL='http://code.abiyo.net/@codepot' PACKAGE_URL='http://code.abiyo.net/@codepot'
@ -1227,7 +1227,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures codepot 0.2.0 to adapt to many kinds of systems. \`configure' configures codepot 0.3.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@ -1293,7 +1293,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of codepot 0.2.0:";; short | recursive ) echo "Configuration of codepot 0.3.0:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@ -1373,7 +1373,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
codepot configure 0.2.0 codepot configure 0.3.0
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@ -1390,7 +1390,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by codepot $as_me 0.2.0, which was It was created by codepot $as_me 0.3.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@ -2209,7 +2209,7 @@ fi
# Define the identity of the package. # Define the identity of the package.
PACKAGE='codepot' PACKAGE='codepot'
VERSION='0.2.0' VERSION='0.3.0'
cat >>confdefs.h <<_ACEOF cat >>confdefs.h <<_ACEOF
@ -3776,7 +3776,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by codepot $as_me 0.2.0, which was This file was extended by codepot $as_me 0.3.0, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@ -3839,7 +3839,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
codepot config.status 0.2.0 codepot config.status 0.3.0
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@ -1,7 +1,7 @@
dnl AC_PREREQ(2.59) dnl AC_PREREQ(2.59)
AC_INIT([codepot],[0.2.0],,,[http://code.abiyo.net/@codepot]) AC_INIT([codepot],[0.3.0],,,[http://code.abiyo.net/@codepot])
AC_CONFIG_HEADER([./config.h]) AC_CONFIG_HEADER([./config.h])
AC_CONFIG_AUX_DIR([ac/aux]) AC_CONFIG_AUX_DIR([ac/aux])
AC_CONFIG_MACRO_DIR([ac/m4]) AC_CONFIG_MACRO_DIR([ac/m4])

View File

@ -223,6 +223,11 @@ cloc_command_path = "@CFGDIR@/cloc.pl"
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
code_folder_readme = "README.wiki,README.txt,README" code_folder_readme = "README.wiki,README.txt,README"
;------------------------------------------------------------------------------
; Codepot sets this revision property to assign a tag to a specific revision.
;------------------------------------------------------------------------------
svn_tag_property = "codepot:tag"
;------------------------------------------------------------------------------ ;------------------------------------------------------------------------------
; Subversion read access is limited to the specified user type. The types ; Subversion read access is limited to the specified user type. The types
; include anonymous, authenticated, member. This applies to a public project ; include anonymous, authenticated, member. This applies to a public project

View File

@ -89,15 +89,27 @@ class Code extends Controller
$file['next_rev'] = $this->subversion->getNextRev ( $file['next_rev'] = $this->subversion->getNextRev (
$projectid, $path, $file['created_rev']); $projectid, $path, $file['created_rev']);
$file['created_tag'] = $this->subversion->getRevProp ($projectid, $file['created_rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($file['created_tag'] === FALSE) $file['created_tag'] = '';
$file['head_tag'] = $this->subversion->getRevProp ($projectid, $file['head_rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($file['head_tag'] === FALSE) $file['head_tag'] = '';
$data['project'] = $project; $data['project'] = $project;
$data['headpath'] = $path; $data['headpath'] = $path;
$data['file'] = $file; $data['file'] = $file;
$data['revision'] = $rev; $data['revision'] = $rev;
$this->load->view ($this->VIEW_FILE, $data); $this->load->view ($this->VIEW_FILE, $data);
} }
} }
else else
{ {
$file['created_tag'] = $this->subversion->getRevProp ($projectid, $file['created_rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($file['created_tag'] === FALSE) $file['created_tag'] = '';
$data['project'] = $project; $data['project'] = $project;
$data['headpath'] = $path; $data['headpath'] = $path;
$data['file'] = $file; $data['file'] = $file;
@ -188,11 +200,19 @@ class Code extends Controller
$file['next_rev'] = $this->subversion->getNextRev ( $file['next_rev'] = $this->subversion->getNextRev (
$projectid, $path, $file['created_rev']); $projectid, $path, $file['created_rev']);
$file['created_tag'] = $this->subversion->getRevProp ($projectid, $file['created_rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($file['created_tag'] === FALSE) $file['created_tag'] = '';
$file['head_tag'] = $this->subversion->getRevProp ($projectid, $file['head_rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($file['head_tag'] === FALSE) $file['head_tag'] = '';
$data['project'] = $project; $data['project'] = $project;
$data['headpath'] = $path; $data['headpath'] = $path;
$data['file'] = $file; $data['file'] = $file;
$data['revision'] = $rev; $data['revision'] = $rev;
$this->load->view ($this->VIEW_BLAME, $data); $this->load->view ($this->VIEW_BLAME, $data);
} }
} }
@ -243,6 +263,21 @@ class Code extends Controller
} }
else else
{ {
if (array_key_exists('history', $file))
{
// Inject the codepot defined tag.
foreach ($file['history'] as &$h)
{
if (array_key_exists('rev', $h))
{
$h['tag'] = $this->subversion->getRevProp ($projectid, $h['rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($h['tag'] === FALSE) $h['tag'] = '';
}
else $h['tag'] = '';
}
}
$data['project'] = $project; $data['project'] = $project;
$data['fullpath'] = $path; $data['fullpath'] = $path;
$data['file'] = $file; $data['file'] = $file;
@ -295,38 +330,64 @@ class Code extends Controller
} }
$data['popup_error_message'] = ''; $data['popup_error_message'] = '';
if ($login['id'] != '' && if ($login['id'] != '')
$login['id'] == $this->subversion->getRevProp($projectid, $rev, 'svn:author') &&
$this->input->post('edit_log_message'))
{ {
// the current user must be the author of the revision to be able to $tag = $this->input->post('tag_revision');
// change the log message. if ($tag !== FALSE)
$this->load->helper ('form');
$this->load->library ('form_validation');
$this->form_validation->set_rules ('edit_log_message', 'Message', 'required|min_length[2]');
$this->form_validation->set_error_delimiters('<span class="form_field_error">','</span>');
if ($this->form_validation->run())
{ {
$logmsg = $this->input->post('edit_log_message'); $tag = trim($tag);
if ($logmsg != $this->subversion->getRevProp ($projectid, $rev, 'svn:log')) if (empty($tag))
{ {
$actual_rev = $this->subversion->setRevProp ( // delete the tag if the value is empty
$projectid, $rev, 'svn:log', $logmsg, $login['id']); $affected_rev = $this->subversion->killRevProp (
if ($actual_rev === FALSE) $projectid, $rev, CODEPOT_SVN_TAG_PROPERTY, $login['id']);
{ }
$data['popup_error_message'] = 'Cannot change revision log message'; else
} {
else $affected_rev = $this->subversion->setRevProp (
{ $projectid, $rev, CODEPOT_SVN_TAG_PROPERTY, $tag, $login['id']);
$this->form_validation->_field_data = array(); }
} if ($affected_rev === FALSE)
{
$data['popup_error_message'] = 'Cannot tag revision';
}
else
{
$this->form_validation->_field_data = array();
} }
} }
else else if ($login['id'] == $this->subversion->getRevProp($projectid, $rev, 'svn:author') &&
$this->input->post('edit_log_message'))
{ {
$data['popup_error_message'] = 'Invalid revision log message'; // the current user must be the author of the revision to be able to
// change the log message.
$this->load->helper ('form');
$this->load->library ('form_validation');
$this->form_validation->set_rules ('edit_log_message', 'Message', 'required|min_length[2]');
$this->form_validation->set_error_delimiters('<span class="form_field_error">','</span>');
if ($this->form_validation->run())
{
$logmsg = $this->input->post('edit_log_message');
if ($logmsg != $this->subversion->getRevProp ($projectid, $rev, 'svn:log'))
{
$affected_rev = $this->subversion->setRevProp (
$projectid, $rev, 'svn:log', $logmsg, $login['id']);
if ($affected_rev === FALSE)
{
$data['popup_error_message'] = 'Cannot change revision log message';
}
else
{
$this->form_validation->_field_data = array();
}
}
}
else
{
$data['popup_error_message'] = 'Invalid revision log message';
}
} }
} }
@ -421,6 +482,18 @@ class Code extends Controller
} }
else else
{ {
if (array_key_exists('history', $file))
{
// Inject the codepot defined tag.
$h = &$file['history'];
if (array_key_exists('rev', $h))
{
$h['tag'] = $this->subversion->getRevProp ($projectid, $h['rev'], CODEPOT_SVN_TAG_PROPERTY);
if ($h['tag'] === FALSE) $h['tag'] = '';
}
else $h['tag'] = '';
}
$data['project'] = $project; $data['project'] = $project;
$data['headpath'] = $path; $data['headpath'] = $path;
$data['file'] = $file; $data['file'] = $file;
@ -431,7 +504,7 @@ class Code extends Controller
$this->subversion->getPrevRev ($projectid, $path, $rev); $this->subversion->getPrevRev ($projectid, $path, $rev);
$data['next_revision'] = $data['next_revision'] =
$this->subversion->getNextRev ($projectid, $path, $rev); $this->subversion->getNextRev ($projectid, $path, $rev);
$this->load->view ($this->VIEW_REVISION, $data); $this->load->view ($this->VIEW_REVISION, $data);
} }
} }

View File

@ -179,7 +179,7 @@ class SubversionModel extends Model
if ($info === FALSE || count($info) != 1) if ($info === FALSE || count($info) != 1)
{ {
// //
// Try further with a given operatal revision // Try further with the original revision
// //
$rev = $orgrev; $rev = $orgrev;
$info = @svn_info ($url, FALSE, $rev); $info = @svn_info ($url, FALSE, $rev);
@ -839,6 +839,19 @@ class SubversionModel extends Model
return $result; return $result;
} }
function killRevProp ($projectid, $rev, $prop, $user)
{
$url = 'file://'.$this->_canonical_path(CODEPOT_SVNREPO_DIR."/{$projectid}");
$orguser = @svn_auth_get_parameter (SVN_AUTH_PARAM_DEFAULT_USERNAME);
@svn_auth_set_parameter (SVN_AUTH_PARAM_DEFAULT_USERNAME, $user);
$result = @svn_revprop_delete ($url, $rev, $prop);
@svn_auth_set_parameter (SVN_AUTH_PARAM_DEFAULT_USERNAME, $orguser);
return $result;
}
function _cloc_revision ($projectid, $path, $rev) function _cloc_revision ($projectid, $path, $rev)
{ {

View File

@ -170,10 +170,20 @@ print anchor ("code/fetch/{$project->id}/${xpar}{$revreq}", $this->lang->line('D
</div> <!-- code_blame_mainarea_menu --> </div> <!-- code_blame_mainarea_menu -->
<div class="infostrip" id="code_blame_mainarea_infostrip"> <div class="infostrip" id="code_blame_mainarea_infostrip">
<?php print anchor ("code/blame/{$project->id}/${xpar}/{$file['prev_rev']}", '<<')?> <?php
<?php print $this->lang->line('Revision')?>: <?php print $file['created_rev']?> print anchor ("code/blame/{$project->id}/${xpar}/{$file['prev_rev']}", '<<');
<?php print anchor ("code/blame/{$project->id}/${xpar}/{$file['next_rev']}", '>>')?> | printf ('%s: %s', $this->lang->line('Revision'), $file['created_rev']);
<?php print $this->lang->line('Size')?>: <?php print $file['size']?> | if (!empty($file['created_tag']))
{
print ('<span class="left_arrow_indicator">');
print htmlspecialchars($file['created_tag']);
print ('</span>');
}
print anchor ("code/blame/{$project->id}/${xpar}/{$file['next_rev']}", '>>');
print ' | ';
printf ('%s: %s', $this->lang->line('Size'), $file['size']);
?>
<a id="code_blame_mainarea_details_button" href='#'><?php print $this->lang->line('Details')?></a> <a id="code_blame_mainarea_details_button" href='#'><?php print $this->lang->line('Details')?></a>
</div> </div>

View File

@ -212,10 +212,21 @@ $this->load->view (
</div> <!-- code_file_mainarea_menu --> </div> <!-- code_file_mainarea_menu -->
<div class="infostrip" id="code_file_mainarea_infostrip"> <div class="infostrip" id="code_file_mainarea_infostrip">
<?php print anchor ("code/file/{$project->id}/${xpar}/{$file['prev_rev']}", '<<')?>
<?php print $this->lang->line('Revision')?>: <?php print $file['created_rev']?> <?php
<?php print anchor ("code/file/{$project->id}/${xpar}/{$file['next_rev']}", '>>')?> | print anchor ("code/file/{$project->id}/${xpar}/{$file['prev_rev']}", '<<');
<?php print $this->lang->line('Size')?>: <?php print $file['size']?> | printf ('%s: %s', $this->lang->line('Revision'), $file['created_rev']);
if (!empty($file['created_tag']))
{
print ('<span class="left_arrow_indicator">');
print htmlspecialchars($file['created_tag']);
print ('</span>');
}
print anchor ("code/file/{$project->id}/${xpar}/{$file['next_rev']}", '>>');
print ' | ';
printf ('%s: %s', $this->lang->line('Size'), $file['size']);
?>
<a id="code_file_mainarea_details_button" href='#'><?php print $this->lang->line('Details')?></a> <a id="code_file_mainarea_details_button" href='#'><?php print $this->lang->line('Details')?></a>
</div> </div>

View File

@ -292,7 +292,15 @@ $this->load->view (
| |
<?php endif; ?> <?php endif; ?>
<?php print $this->lang->line('Revision')?>: <?php print $file['created_rev']?> <?php
printf ('%s: %s', $this->lang->line('Revision'), $file['created_rev']);
if (!empty($file['created_tag']))
{
print ('<span class="left_arrow_indicator">');
print htmlspecialchars($file['created_tag']);
print ('</span>');
}
?>
<?php if ($file_count > 0): ?> <?php if ($file_count > 0): ?>
| |
<a id="code_folder_mainarea_details_button" href='#'><?php print $this->lang->line('Details')?></a> <a id="code_folder_mainarea_details_button" href='#'><?php print $this->lang->line('Details')?></a>

View File

@ -120,6 +120,13 @@ $this->load->view (
($fullpath == '')? '.': $fullpath); ($fullpath == '')? '.': $fullpath);
print anchor ("code/file/{$project->id}/{$xfullpath}/{$h['rev']}", $h['rev']); print anchor ("code/file/{$project->id}/{$xfullpath}/{$h['rev']}", $h['rev']);
if (!empty($h['tag']))
{
print '<span class="left_arrow_indicator">';
print htmlspecialchars($h['tag']);
print '</span>';
}
print '</td>'; print '</td>';
print '<td>'; print '<td>';
@ -139,7 +146,6 @@ $this->load->view (
print '</pre>'; print '</pre>';
print '</td>'; print '</td>';
if ($file['type'] == 'file') if ($file['type'] == 'file')
{ {
print '<td>'; print '<td>';

View File

@ -20,6 +20,27 @@
<?php if ($can_edit): ?> <?php if ($can_edit): ?>
$(function() { $(function() {
$("#code_revision_tag_div").dialog (
{
title: '<?php print $this->lang->line('Tag')?>',
width: 'auto',
height: 'auto',
resizable: false,
autoOpen: false,
modal: true,
buttons: {
'<?php print $this->lang->line('OK')?>': function () {
$('#code_revision_tag_form').submit ();
$(this).dialog('close');
},
'<?php print $this->lang->line('Cancel')?>': function () {
$(this).dialog('close');
}
},
close: function() { }
}
);
$("#code_revision_edit_div").dialog ( $("#code_revision_edit_div").dialog (
{ {
title: '<?php print $this->lang->line('Edit')?>', title: '<?php print $this->lang->line('Edit')?>',
@ -41,6 +62,13 @@ $(function() {
} }
); );
$("#code_revision_tag_button").button().click (
function () {
$("#code_revision_tag_div").dialog('open');
return false;
}
);
$("#code_revision_edit_logmsg_button").button().click ( $("#code_revision_edit_logmsg_button").button().click (
function () { function () {
$("#code_revision_edit_div").dialog('open'); $("#code_revision_edit_div").dialog('open');
@ -281,11 +309,30 @@ $history = $file['history'];
</div> <!-- code_revision_mainarea_menu --> </div> <!-- code_revision_mainarea_menu -->
<div class="infostrip" id="code_revision_mainarea_infostrip"> <div class="infostrip" id="code_revision_mainarea_infostrip">
<?php print anchor ("code/revision/{$project->id}/${xpar}/{$prev_revision}", '<<')?> <?php
<?php print $this->lang->line('Revision')?>: <?php print $history['rev']?> print anchor ("code/revision/{$project->id}/${xpar}/{$prev_revision}", '<<');
<?php print anchor ("code/revision/{$project->id}/${xpar}/{$next_revision}", '>>')?> | printf ('%s: %s', $this->lang->line('Revision'), $history['rev']);
<?php print $this->lang->line('Committer')?>: <?php print htmlspecialchars($history['author'])?> | if (!empty($history['tag']))
<?php print $this->lang->line('Last updated on')?>: <?php print date('r', strtotime($history['date']))?> {
print ('<span class="left_arrow_indicator">');
print htmlspecialchars($history['tag']);
print ('</span>');
}
print anchor ("code/revision/{$project->id}/${xpar}/{$next_revision}", '>>');
if ($can_edit)
{
print '<span class="anchor">';
print anchor ("#", $this->lang->line('Tag'), array ('id' => 'code_revision_tag_button'));
print '</span>';
}
print ' | ';
printf ('%s: %s', $this->lang->line('Committer'), htmlspecialchars($history['author']));
print ' | ';
printf ('%s: %s', $this->lang->line('Last updated on'), date('r', strtotime($history['date'])));
?>
</div> </div>
@ -407,6 +454,19 @@ $history = $file['history'];
</div> <!-- code_revision_content --> </div> <!-- code_revision_content -->
<?php if ($can_edit): ?> <?php if ($can_edit): ?>
<div id="code_revision_tag_div">
<?php print form_open("code/revision/{$project->id}${revreqroot}", 'id="code_revision_tag_form"')?>
<?php print
form_input (
array ('name' => 'tag_revision',
'value' => $history['tag'],
'id' => 'code_revision_tag')
)
?>
<?php print form_close()?>
</div>
<div id="code_revision_edit_div"> <div id="code_revision_edit_div">
<?php print form_open("code/revision/{$project->id}${revreqroot}", 'id="code_revision_edit_logmsg_form"')?> <?php print form_open("code/revision/{$project->id}${revreqroot}", 'id="code_revision_edit_logmsg_form"')?>
<?php print <?php print

View File

@ -82,6 +82,8 @@ function load_ini ($file)
array ('footer', 'string', ''), array ('footer', 'string', ''),
array ('cloc_command_path', 'string', CODEPOT_CFG_DIR.'/cloc.pl'), array ('cloc_command_path', 'string', CODEPOT_CFG_DIR.'/cloc.pl'),
array ('code_folder_readme', 'string', 'README'), array ('code_folder_readme', 'string', 'README'),
array ('svn_tag_property', 'string', 'codepot:tag'),
// these items are not used by php but by subersion hooks written in perl. // these items are not used by php but by subersion hooks written in perl.
array ('svn_read_access', 'string', 'member'), array ('svn_read_access', 'string', 'member'),

View File

@ -699,6 +699,32 @@ pre.prettyprint li.L9 { background: #eee }
font-style: italic; font-style: italic;
} }
.content span.left_arrow_indicator {
position: relative;
background: #FA5240;
color: #FFFFFF;;
font-size: 0.9em;
margin-left: 0.5em;
padding-left: 0.5em;
padding-right: 0.5em;
}
.content span.left_arrow_indicator:after {
right: 100%;
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
border-color: rgba(245, 230, 17, 0);
border-right-color: #FA5240;
border-width: 5px;
margin-top: -5px;
}
/* === signin panel === */ /* === signin panel === */
#taskbar_signin_panel { #taskbar_signin_panel {
position: absolute; position: absolute;