diff --git a/doc/syncmonotone.mdtext b/doc/syncmonotone.mdtext index c21a325..4a25b50 100644 --- a/doc/syncmonotone.mdtext +++ b/doc/syncmonotone.mdtext @@ -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 diff --git a/src/IDF/Plugin/SyncMonotone.php b/src/IDF/Plugin/SyncMonotone.php index f75f530..bc12e2a 100644 --- a/src/IDF/Plugin/SyncMonotone.php +++ b/src/IDF/Plugin/SyncMonotone.php @@ -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); + } } /** diff --git a/src/IDF/Scm/Monotone.php b/src/IDF/Scm/Monotone.php index fb39d5b..39e2fc2 100644 --- a/src/IDF/Scm/Monotone.php +++ b/src/IDF/Scm/Monotone.php @@ -749,10 +749,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']; } diff --git a/src/IDF/Views/Source.php b/src/IDF/Views/Source.php index a0748da..472d710 100644 --- a/src/IDF/Views/Source.php +++ b/src/IDF/Views/Source.php @@ -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; } diff --git a/src/IDF/templates/idf/base-full.html b/src/IDF/templates/idf/base-full.html index 5f505d8..d2e69fa 100644 --- a/src/IDF/templates/idf/base-full.html +++ b/src/IDF/templates/idf/base-full.html @@ -69,6 +69,7 @@
{block foot}{/block}
{include 'idf/js-hotkeys.html'} +{include 'idf/list-filter.html'} {block javascript}{/block} {if $project} diff --git a/src/IDF/templates/idf/source/mtn/changelog.html b/src/IDF/templates/idf/source/mtn/changelog.html index 5747ea4..3db65d6 100644 --- a/src/IDF/templates/idf/source/mtn/changelog.html +++ b/src/IDF/templates/idf/source/mtn/changelog.html @@ -1,25 +1,32 @@ {extends "idf/source/changelog.html"} {block context} -

{trans 'Branches:'}
+

+
+

+ {trans 'Branches'} + +

+ {if $tags} -

{trans 'Tags:'}
+

+ {trans 'Tags'} + +

+ {/if} +
{/block} diff --git a/src/IDF/templates/idf/source/mtn/commit.html b/src/IDF/templates/idf/source/mtn/commit.html index a0b3eeb..ee97616 100644 --- a/src/IDF/templates/idf/source/mtn/commit.html +++ b/src/IDF/templates/idf/source/mtn/commit.html @@ -1,26 +1,32 @@ {extends "idf/source/commit.html"} {block context} -

{trans 'Branches:'}
+

+
+

+ {trans 'Branches'} + +

+ {if $tags} -

{trans 'Tags:'}
+

+ {trans 'Tags'} + +

+ {/if} +
{/block} - diff --git a/src/IDF/templates/idf/source/mtn/tree.html b/src/IDF/templates/idf/source/mtn/tree.html index 3851c1a..24462f6 100644 --- a/src/IDF/templates/idf/source/mtn/tree.html +++ b/src/IDF/templates/idf/source/mtn/tree.html @@ -55,26 +55,33 @@ {/block} {block context} -

{trans 'Branches:'}
+

+
+

+ {trans 'Branches'} + +

+ {if $tags} -

{trans 'Tags:'}
+

+ {trans 'Tags'} + +

+ {/if} +
{/block} diff --git a/www/media/idf/css/style.css b/www/media/idf/css/style.css index 942a1b7..511ad93 100644 --- a/www/media/idf/css/style.css +++ b/www/media/idf/css/style.css @@ -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; +} diff --git a/www/media/idf/img/white_gradient.png b/www/media/idf/img/white_gradient.png new file mode 100644 index 0000000..667bc00 Binary files /dev/null and b/www/media/idf/img/white_gradient.png differ