Merge branch 'develop'
This commit is contained in:
commit
f7228ef2ec
@ -187,10 +187,11 @@ Remote commands can be helpful for a user or a 3rd party tool (like
|
||||
contents remotely without having to pull everything in first instance.
|
||||
|
||||
Private projects on the other hand can only be synced by team members
|
||||
or additional invited people. Remote command execution is still enabled
|
||||
by default - if you want to disable that, simply remove the symlink to
|
||||
the file `indefero_authorize_remote_automate.conf` in your project's `hooks.d`
|
||||
directory or copy the file from the original location and adapt it.
|
||||
or additional invited people. Remote command execution is disabled
|
||||
by default. If you want to enable that, simply put the keys of the users
|
||||
you want to give access to in your project's `remote-automate-permissions`
|
||||
file. In the future this plugin might handle this file just as it handles
|
||||
`read-permissions` and `write-permissions`.
|
||||
|
||||
## Notifications
|
||||
|
||||
|
@ -154,7 +154,7 @@ class IDF_Commit extends Pluf_Model
|
||||
$commit->summary = self::toUTF8($change->title);
|
||||
$commit->fullmessage = self::toUTF8($change->full_message);
|
||||
$commit->author = $scm->findAuthor($change->author);
|
||||
$commit->origauthor = $change->author;
|
||||
$commit->origauthor = self::toUTF8($change->author);
|
||||
$commit->creation_dtime = $change->date;
|
||||
$commit->create();
|
||||
$commit->notify($project->getConf());
|
||||
|
@ -117,6 +117,12 @@ class IDF_Plugin_SyncMonotone
|
||||
'hooks.d/indefero_post_push.conf.in',
|
||||
'hooks.d/indefero_post_push.lua',
|
||||
);
|
||||
if (!$project->private) {
|
||||
// this is linked and not copied to be able to update
|
||||
// the list of read-only commands on upgrades
|
||||
$confdir_contents[] = 'hooks.d/indefero_authorize_remote_automate.conf';
|
||||
}
|
||||
|
||||
// check whether we should handle additional files in the config directory
|
||||
$confdir_extra_contents = Pluf::f('mtn_confdir_extra', false);
|
||||
if ($confdir_extra_contents !== false) {
|
||||
@ -383,6 +389,41 @@ class IDF_Plugin_SyncMonotone
|
||||
__('Could not write read-permissions file "%s"'), $rcfile
|
||||
));
|
||||
}
|
||||
|
||||
// link / unlink the read-only automate permissions for the project
|
||||
$confdir = Pluf::f('mtn_confdir', false);
|
||||
if ($confdir === false) {
|
||||
$confdir = dirname(__FILE__).'/SyncMonotone/';
|
||||
}
|
||||
$file = 'hooks.d/indefero_authorize_remote_automate.conf';
|
||||
$projectfile = $projectpath.'/'.$file;
|
||||
$templatefile = $confdir.'/'.$file;
|
||||
|
||||
$serverRestartRequired = false;
|
||||
if ($project->private && file_exists($projectfile) && is_link($projectfile)) {
|
||||
if (!unlink($projectfile)) {
|
||||
IDF_Scm_Exception(sprintf(
|
||||
__('Could not remove symlink "%s"'), $projectfile
|
||||
));
|
||||
}
|
||||
$serverRestartRequired = true;
|
||||
} else
|
||||
if (!$project->private && !file_exists($projectfile)) {
|
||||
if (!symlink($templatefile, $projectfile)) {
|
||||
throw new IDF_Scm_Exception(sprintf(
|
||||
__('Could not create symlink "%s"'), $projectfile
|
||||
));
|
||||
}
|
||||
$serverRestartRequired = true;
|
||||
}
|
||||
|
||||
if ($serverRestartRequired) {
|
||||
// FIXME: we should actually use stopServer() here, but this
|
||||
// seems to be ignored when the server should be started
|
||||
// again immediately afterwards
|
||||
IDF_Scm_Monotone_Usher::killServer($project->shortname);
|
||||
IDF_Scm_Monotone_Usher::startServer($project->shortname);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +55,9 @@ class IDF_Scm_Cache_Git extends Pluf_Model
|
||||
$cache->project = $this->_project;
|
||||
$cache->githash = $blob->hash;
|
||||
$blob->title = IDF_Commit::toUTF8($blob->title);
|
||||
$cache->content = $blob->date.chr(31).$blob->author.chr(31).$blob->title;
|
||||
$cache->content = IDF_Commit::toUTF8($blob->date) . chr(31)
|
||||
. IDF_Commit::toUTF8($blob->author) . chr(31)
|
||||
. IDF_Commit::toUTF8($blob->title);
|
||||
$sql = new Pluf_SQL('project=%s AND githash=%s',
|
||||
array($this->_project->id, $blob->hash));
|
||||
if (0 == Pluf::factory(__CLASS__)->getCount(array('filter' => $sql->gen()))) {
|
||||
|
@ -27,7 +27,7 @@
|
||||
*/
|
||||
class IDF_Scm_Git extends IDF_Scm
|
||||
{
|
||||
public $mediumtree_fmt = 'commit %H%nAuthor: %an <%ae>%nTree: %T%nDate: %ai%n%n%s%n%n%b';
|
||||
public $mediumtree_fmt = 'commit %H%nAuthor: %an <%ae>%nTree: %T%nParents: %P%nDate: %ai%n%n%s%n%n%b';
|
||||
|
||||
/* ============================================== *
|
||||
* *
|
||||
@ -518,6 +518,9 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
$c['full_message'] = trim($c['full_message']);
|
||||
$c['full_message'] = IDF_Commit::toUTF8($c['full_message']);
|
||||
$c['title'] = IDF_Commit::toUTF8($c['title']);
|
||||
if (isset($c['parents'])) {
|
||||
$c['parents'] = explode(' ', trim($c['parents']));
|
||||
}
|
||||
$res[] = (object) $c;
|
||||
}
|
||||
$c = array();
|
||||
@ -553,6 +556,9 @@ class IDF_Scm_Git extends IDF_Scm
|
||||
$c['full_message'] = !empty($c['full_message']) ? trim($c['full_message']) : '';
|
||||
$c['full_message'] = IDF_Commit::toUTF8($c['full_message']);
|
||||
$c['title'] = IDF_Commit::toUTF8($c['title']);
|
||||
if (isset($c['parents'])) {
|
||||
$c['parents'] = explode(' ', trim($c['parents']));
|
||||
}
|
||||
$res[] = (object) $c;
|
||||
return $res;
|
||||
}
|
||||
|
@ -21,9 +21,6 @@
|
||||
#
|
||||
# ***** END LICENSE BLOCK ***** */
|
||||
|
||||
//require_once(dirname(__FILE__) . "/Monotone/Stdio.php");
|
||||
//require_once(dirname(__FILE__) . "/Monotone/BasicIO.php");
|
||||
|
||||
/**
|
||||
* Monotone scm class
|
||||
*
|
||||
@ -677,8 +674,12 @@ class IDF_Scm_Monotone extends IDF_Scm
|
||||
if (count($revs) == 0)
|
||||
return array();
|
||||
|
||||
$certs = $this->_getCerts($revs[0]);
|
||||
$res = array();
|
||||
|
||||
$parents = $this->stdio->exec(array('parents', $revs[0]));
|
||||
$res['parents'] = preg_split("/\n/", $parents, -1, PREG_SPLIT_NO_EMPTY);
|
||||
|
||||
$certs = $this->_getCerts($revs[0]);
|
||||
// FIXME: this assumes that author, date and changelog are always given
|
||||
$res['author'] = implode(', ', $certs['author']);
|
||||
|
||||
@ -749,10 +750,9 @@ class IDF_Scm_Monotone extends IDF_Scm
|
||||
// read in the initial branches we should follow
|
||||
if (count($initialBranches) == 0) {
|
||||
if (!isset($certs['branch'])) {
|
||||
throw new IDF_Scm_Exception(sprintf(
|
||||
__("revision %s has no branch cert - cannot start ".
|
||||
"logging from this revision"), $rev
|
||||
));
|
||||
// this revision has no branch cert, we cannot start logging
|
||||
// from this revision
|
||||
continue;
|
||||
}
|
||||
$initialBranches = $certs['branch'];
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ class IDF_Views_Source
|
||||
if (!$cobject) {
|
||||
throw new Exception('could not retrieve commit object for '. $commit);
|
||||
}
|
||||
$rep = new Pluf_HTTP_Response($cobject->changes, 'text/plain');
|
||||
$rep = new Pluf_HTTP_Response($cobject->diff, 'text/plain');
|
||||
$rep->headers['Content-Disposition'] = 'attachment; filename="'.$commit.'.diff"';
|
||||
return $rep;
|
||||
}
|
||||
|
@ -69,6 +69,7 @@
|
||||
<div id="ft">{block foot}{/block}</div>
|
||||
</div>
|
||||
{include 'idf/js-hotkeys.html'}
|
||||
{include 'idf/list-filter.html'}
|
||||
{block javascript}{/block}
|
||||
{if $project}
|
||||
<script type="text/javascript" charset="utf-8">{literal}
|
||||
|
@ -53,6 +53,7 @@
|
||||
<div id="ft">{block foot}{/block}</div>
|
||||
</div>
|
||||
{include 'idf/js-hotkeys.html'}
|
||||
{include 'idf/list-filter.html'}
|
||||
{block javascript}{/block}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -70,6 +70,7 @@
|
||||
<div id="ft">{block foot}{/block}</div>
|
||||
</div>
|
||||
{include 'idf/js-hotkeys.html'}
|
||||
{include 'idf/list-filter.html'}
|
||||
{block javascript}{/block}
|
||||
{if $project}
|
||||
<script type="text/javascript" charset="utf-8">{literal}
|
||||
|
51
src/IDF/templates/idf/list-filter.html
Normal file
51
src/IDF/templates/idf/list-filter.html
Normal file
@ -0,0 +1,51 @@
|
||||
{**
|
||||
* Looks for input fields like
|
||||
* <input type="text" class="filter-list" rel="target" />
|
||||
* and filters out anchors below $(target) which do not match
|
||||
* the entered input.
|
||||
*}
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
{literal}
|
||||
$(document).ready(function() {
|
||||
$("input.filter-list").each(function() {
|
||||
var lists = $("ul#" + $(this).attr("rel"));
|
||||
if (lists.length == 0)
|
||||
return;
|
||||
var list = $(lists[0]);
|
||||
|
||||
// a list should contain a reasonable amount of items
|
||||
// to be filterable - we also give the filter input a
|
||||
// special class here so we recognize it later in case
|
||||
// we have to hide it when the list view is collapsed
|
||||
if (list.children("li").length > 10) {
|
||||
$(this).addClass("activated");
|
||||
$(this).focus(function() {
|
||||
// ensure that the parent of the list keeps activated / opened
|
||||
list.parent().addClass("activated");
|
||||
if ($(this)[0].value == $(this).attr("title"))
|
||||
$(this).attr("value", "").removeClass("default");
|
||||
});
|
||||
$(this).blur(function() {
|
||||
list.parent().removeClass("activated");
|
||||
if ($(this)[0].value.length == 0)
|
||||
$(this).attr("value", $(this).attr("title")).addClass("default");
|
||||
});
|
||||
$(this).keyup(function(ev) {
|
||||
var filter = $(this)[0];
|
||||
list.children("li").css('display', 'block');
|
||||
list.children("li").filter(function(index) {
|
||||
if (filter.value == "")
|
||||
return false;
|
||||
if ($(this).text().indexOf(filter.value) > -1)
|
||||
return false;
|
||||
return true;
|
||||
}).css('display', 'none');
|
||||
});
|
||||
// initialize it with the default
|
||||
$(this)[0].value = "";
|
||||
$(this).blur();
|
||||
}
|
||||
});
|
||||
});
|
||||
{/literal}
|
||||
</script>
|
@ -15,6 +15,12 @@
|
||||
<tr>
|
||||
<th><strong>{trans 'Commit:'}</strong></th><td class="mono"><a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $commit)}" title="{trans 'View corresponding source tree'}">{$cobject.commit}</a></td>
|
||||
</tr>
|
||||
{if $cobject.parents}<tr>
|
||||
<th><strong>{trans 'Parents:'}</strong></th><td class="mono">{foreach $cobject.parents as $parent}
|
||||
<a href="{url 'IDF_Views_Source::commit', array($project.shortname, $parent)}" title="{trans 'View corresponding commit'}">{$parent}</a><br />
|
||||
{/foreach}
|
||||
</td>
|
||||
</tr>{/if}
|
||||
<tr>
|
||||
<th><strong>{trans 'Message:'}</strong></th><td>{issuetext $cobject.title, $request}{if isset($cobject.full_message)}<br/><br/>{issuetext $cobject.full_message, $request, true, false, true, true, true}{/if}</td>
|
||||
</tr>{if count($changes)}
|
||||
|
@ -1,25 +1,32 @@
|
||||
{extends "idf/source/changelog.html"}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br/>
|
||||
<div class="expander">
|
||||
<div class="gradient"></div>
|
||||
<h1>
|
||||
{trans 'Branches'}
|
||||
<input type="text" rel="branch-list" class="filter-list" title="{trans 'filter branches'}" />
|
||||
</h1>
|
||||
<ul id="branch-list">
|
||||
{foreach $branches as $selector => $branch}
|
||||
{aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $selector)}
|
||||
<span class="label{if in_array($selector, $tree_in)} active{/if}">
|
||||
<a href="{$url}" class="label" title="{$branch}">
|
||||
{$branch|shorten:24}
|
||||
</a>
|
||||
</span><br/>
|
||||
<li class="{if in_array($selector, $tree_in)}active{/if}">
|
||||
<a href="{$url}" class="label">{$branch}</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</p>
|
||||
</ul>
|
||||
{if $tags}
|
||||
<p><strong>{trans 'Tags:'}</strong><br/>
|
||||
<h1>
|
||||
{trans 'Tags'}
|
||||
<input type="text" rel="tag-list" class="filter-list" title="{trans 'filter tags'}" />
|
||||
</h1>
|
||||
<ul id="tag-list">
|
||||
{foreach $tags as $selector => $tag}
|
||||
{aurl 'url', 'IDF_Views_Source::changeLog', array($project.shortname, $selector)}
|
||||
<span class="label{if in_array($selector, $tags_in)} active{/if}">
|
||||
<a href="{$url}" class="label" title="{$tag}">
|
||||
{$tag|shorten:24}
|
||||
</a>
|
||||
</span><br/>
|
||||
<li class="{if in_array($selector, $tags_in)}active{/if}">
|
||||
<a href="{$url}" class="label">{$tag}</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</p>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
{/block}
|
||||
|
@ -1,26 +1,32 @@
|
||||
{extends "idf/source/commit.html"}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br/>
|
||||
<div class="expander">
|
||||
<div class="gradient"></div>
|
||||
<h1>
|
||||
{trans 'Branches'}
|
||||
<input type="text" rel="branch-list" class="filter-list" title="{trans 'filter branches'}" />
|
||||
</h1>
|
||||
<ul id="branch-list">
|
||||
{foreach $branches as $selector => $branch}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $selector)}
|
||||
<span class="label{if in_array($branch, $tree_in)} active{/if}">
|
||||
<a href="{$url}" class="label" title="{$branch}">
|
||||
{$branch|shorten:25}
|
||||
</a>
|
||||
</span><br/>
|
||||
<li class="{if in_array($branch, $tree_in)}active{/if}">
|
||||
<a href="{$url}" class="label">{$branch}</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</p>
|
||||
</ul>
|
||||
{if $tags}
|
||||
<p><strong>{trans 'Tags:'}</strong><br/>
|
||||
<h1>
|
||||
{trans 'Tags'}
|
||||
<input type="text" rel="tag-list" class="filter-list" title="{trans 'filter tags'}" />
|
||||
</h1>
|
||||
<ul id="tag-list">
|
||||
{foreach $tags as $selector => $tag}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $selector)}
|
||||
<span class="label{if in_array($tag, $tags_in)} active{/if}">
|
||||
<a href="{$url}" class="label" title="{$tag}">
|
||||
{$tag|shorten:25}
|
||||
</a>
|
||||
</span><br/>
|
||||
<li class="{if in_array($tag, $tags_in)}active{/if}">
|
||||
<a href="{$url}" class="label">{$tag}</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</p>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
{/block}
|
||||
|
||||
|
@ -55,26 +55,33 @@
|
||||
|
||||
{/block}
|
||||
{block context}
|
||||
<p><strong>{trans 'Branches:'}</strong><br/>
|
||||
<div class="expander">
|
||||
<div class="gradient"></div>
|
||||
<h1>
|
||||
{trans 'Branches'}
|
||||
<input type="text" rel="branch-list" class="filter-list" title="{trans 'filter branches'}" />
|
||||
</h1>
|
||||
<ul id="branch-list">
|
||||
{foreach $branches as $selector => $branch}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $selector)}
|
||||
<span class="label{if in_array($selector, $tree_in)} active{/if}">
|
||||
<a href="{$url}" class="label" title="{$branch}">
|
||||
{$branch|shorten:24}
|
||||
</a>
|
||||
</span><br/>
|
||||
<li class="{if in_array($selector, $tree_in)}active{/if}">
|
||||
<a href="{$url}" class="label">{$branch}</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</p>
|
||||
</ul>
|
||||
{if $tags}
|
||||
<p><strong>{trans 'Tags:'}</strong><br/>
|
||||
<h1>
|
||||
{trans 'Tags'}
|
||||
<input type="text" rel="tag-list" class="filter-list" title="{trans 'filter tags'}" />
|
||||
</h1>
|
||||
<ul id="tag-list">
|
||||
{foreach $tags as $selector => $tag}
|
||||
{aurl 'url', 'IDF_Views_Source::treeBase', array($project.shortname, $selector)}
|
||||
<span class="label{if in_array($selector, $tags_in)} active{/if}">
|
||||
<a href="{$url}" class="label" title="{$tag}">
|
||||
{$tag|shorten:24}
|
||||
</a>
|
||||
</span><br/>
|
||||
<li class="{if in_array($selector, $tags_in)}active{/if}">
|
||||
<a href="{$url}" class="label">{$tag}</a>
|
||||
</li>
|
||||
{/foreach}
|
||||
</p>
|
||||
</ul>
|
||||
{/if}
|
||||
</div>
|
||||
{/block}
|
||||
|
@ -858,3 +858,84 @@ ol > li {
|
||||
color: #2E3436;
|
||||
}
|
||||
|
||||
/**
|
||||
* List expander for tag and branch view
|
||||
*/
|
||||
.context {}
|
||||
|
||||
.context h1 {
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
margin: 10px 0 5px;
|
||||
}
|
||||
|
||||
.context > .expander {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.context > .expander > ul {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.context > .expander > ul > li {
|
||||
white-space: nowrap;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
.context > .expander > ul > li.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.context > .expander > .gradient {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 100%;
|
||||
z-index: 998;
|
||||
background: url(../img/white_gradient.png) repeat-y;
|
||||
}
|
||||
|
||||
.context > .expander:hover,
|
||||
.context > .expander.activated {
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
overflow: visible;
|
||||
-moz-border-radius: 0 10px 10px 0;
|
||||
-webkit-border-radius: 0 10px 10px 0;
|
||||
border-radius: 0 10px 10px 0;
|
||||
-moz-box-shadow: 3px 3px 5px #333;
|
||||
-webkit-box-shadow: 3px 3px 5px #333;
|
||||
box-shadow: 3px 3px 5px #333;
|
||||
padding: 5px 10px;
|
||||
margin: -5px -10px;
|
||||
min-width: 180px;
|
||||
}
|
||||
|
||||
.context > .expander:hover > .gradient,
|
||||
.context > .expander.activated > .gradient {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.context > .expander input.filter-list {
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
color: #333;
|
||||
border: 1px dotted #474747;
|
||||
margin-left: 10px;
|
||||
padding: 2px;
|
||||
width: 80px;
|
||||
display: none;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.context > .expander:hover input.filter-list.activated,
|
||||
.context > .expander.activated input.filter-list.activated {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.context > .expander input.filter-list.default {
|
||||
color: #aaa;
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
BIN
www/media/idf/img/white_gradient.png
Normal file
BIN
www/media/idf/img/white_gradient.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 201 B |
Loading…
Reference in New Issue
Block a user