# 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
# 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.
@ -576,8 +576,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='codepot'
PACKAGE_TARNAME='codepot'
PACKAGE_VERSION='0.2.0'
PACKAGE_STRING='codepot 0.2.0'
PACKAGE_VERSION='0.3.0'
PACKAGE_STRING='codepot 0.3.0'
PACKAGE_BUGREPORT=''
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.
# This message is too long to be a string in the A/UX 3.1 sh.
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]...
@ -1293,7 +1293,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of codepot 0.2.0:";;
short | recursive ) echo "Configuration of codepot 0.3.0:";;
esac
cat <<\_ACEOF
@ -1373,7 +1373,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
codepot configure 0.2.0
codepot configure 0.3.0
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@ -1390,7 +1390,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
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
$ $0 $@
@ -2209,7 +2209,7 @@ fi
# Define the identity of the package.
PACKAGE='codepot'
VERSION='0.2.0'
VERSION='0.3.0'
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
# values after options handling.
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
CONFIG_FILES = $CONFIG_FILES
@ -3839,7 +3839,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
codepot config.status 0.2.0
codepot config.status 0.3.0
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"

View File

@ -1,7 +1,7 @@
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_AUX_DIR([ac/aux])
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"
;------------------------------------------------------------------------------
; 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
; 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 (
$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['headpath'] = $path;
$data['file'] = $file;
$data['revision'] = $rev;
$this->load->view ($this->VIEW_FILE, $data);
}
}
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['headpath'] = $path;
$data['file'] = $file;
@ -188,11 +200,19 @@ class Code extends Controller
$file['next_rev'] = $this->subversion->getNextRev (
$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['headpath'] = $path;
$data['file'] = $file;
$data['revision'] = $rev;
$this->load->view ($this->VIEW_BLAME, $data);
}
}
@ -243,6 +263,21 @@ class Code extends Controller
}
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['fullpath'] = $path;
$data['file'] = $file;
@ -295,38 +330,64 @@ class Code extends Controller
}
$data['popup_error_message'] = '';
if ($login['id'] != '' &&
$login['id'] == $this->subversion->getRevProp($projectid, $rev, 'svn:author') &&
$this->input->post('edit_log_message'))
if ($login['id'] != '')
{
// 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())
$tag = $this->input->post('tag_revision');
if ($tag !== FALSE)
{
$logmsg = $this->input->post('edit_log_message');
if ($logmsg != $this->subversion->getRevProp ($projectid, $rev, 'svn:log'))
$tag = trim($tag);
if (empty($tag))
{
$actual_rev = $this->subversion->setRevProp (
$projectid, $rev, 'svn:log', $logmsg, $login['id']);
if ($actual_rev === FALSE)
{
$data['popup_error_message'] = 'Cannot change revision log message';
}
else
{
$this->form_validation->_field_data = array();
}
// delete the tag if the value is empty
$affected_rev = $this->subversion->killRevProp (
$projectid, $rev, CODEPOT_SVN_TAG_PROPERTY, $login['id']);
}
else
{
$affected_rev = $this->subversion->setRevProp (
$projectid, $rev, CODEPOT_SVN_TAG_PROPERTY, $tag, $login['id']);
}
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
{
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['headpath'] = $path;
$data['file'] = $file;
@ -431,7 +504,7 @@ class Code extends Controller
$this->subversion->getPrevRev ($projectid, $path, $rev);
$data['next_revision'] =
$this->subversion->getNextRev ($projectid, $path, $rev);
$this->load->view ($this->VIEW_REVISION, $data);
}
}

View File

@ -179,7 +179,7 @@ class SubversionModel extends Model
if ($info === FALSE || count($info) != 1)
{
//
// Try further with a given operatal revision
// Try further with the original revision
//
$rev = $orgrev;
$info = @svn_info ($url, FALSE, $rev);
@ -839,6 +839,19 @@ class SubversionModel extends Model
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)
{

View File

@ -170,10 +170,20 @@ print anchor ("code/fetch/{$project->id}/${xpar}{$revreq}", $this->lang->line('D
</div> <!-- code_blame_mainarea_menu -->
<div class="infostrip" id="code_blame_mainarea_infostrip">
<?php print anchor ("code/blame/{$project->id}/${xpar}/{$file['prev_rev']}", '<<')?>
<?php print $this->lang->line('Revision')?>: <?php print $file['created_rev']?>
<?php print anchor ("code/blame/{$project->id}/${xpar}/{$file['next_rev']}", '>>')?> |
<?php print $this->lang->line('Size')?>: <?php print $file['size']?> |
<?php
print anchor ("code/blame/{$project->id}/${xpar}/{$file['prev_rev']}", '<<');
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/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>
</div>

View File

@ -212,10 +212,21 @@ $this->load->view (
</div> <!-- code_file_mainarea_menu -->
<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 print anchor ("code/file/{$project->id}/${xpar}/{$file['next_rev']}", '>>')?> |
<?php print $this->lang->line('Size')?>: <?php print $file['size']?> |
<?php
print anchor ("code/file/{$project->id}/${xpar}/{$file['prev_rev']}", '<<');
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>
</div>

View File

@ -292,7 +292,15 @@ $this->load->view (
|
<?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): ?>
|
<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);
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>';
@ -139,7 +146,6 @@ $this->load->view (
print '</pre>';
print '</td>';
if ($file['type'] == 'file')
{
print '<td>';

View File

@ -20,6 +20,27 @@
<?php if ($can_edit): ?>
$(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 (
{
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 (
function () {
$("#code_revision_edit_div").dialog('open');
@ -281,11 +309,30 @@ $history = $file['history'];
</div> <!-- code_revision_mainarea_menu -->
<div class="infostrip" id="code_revision_mainarea_infostrip">
<?php print anchor ("code/revision/{$project->id}/${xpar}/{$prev_revision}", '<<')?>
<?php print $this->lang->line('Revision')?>: <?php print $history['rev']?>
<?php print anchor ("code/revision/{$project->id}/${xpar}/{$next_revision}", '>>')?> |
<?php print $this->lang->line('Committer')?>: <?php print htmlspecialchars($history['author'])?> |
<?php print $this->lang->line('Last updated on')?>: <?php print date('r', strtotime($history['date']))?>
<?php
print anchor ("code/revision/{$project->id}/${xpar}/{$prev_revision}", '<<');
printf ('%s: %s', $this->lang->line('Revision'), $history['rev']);
if (!empty($history['tag']))
{
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>
@ -407,6 +454,19 @@ $history = $file['history'];
</div> <!-- code_revision_content -->
<?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">
<?php print form_open("code/revision/{$project->id}${revreqroot}", 'id="code_revision_edit_logmsg_form"')?>
<?php print

View File

@ -82,6 +82,8 @@ function load_ini ($file)
array ('footer', 'string', ''),
array ('cloc_command_path', 'string', CODEPOT_CFG_DIR.'/cloc.pl'),
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.
array ('svn_read_access', 'string', 'member'),

View File

@ -699,6 +699,32 @@ pre.prettyprint li.L9 { background: #eee }
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 === */
#taskbar_signin_panel {
position: absolute;