diff --git a/src/IDF/Form/Admin/ProjectCreate.php b/src/IDF/Form/Admin/ProjectCreate.php index 182c737..7f767e5 100644 --- a/src/IDF/Form/Admin/ProjectCreate.php +++ b/src/IDF/Form/Admin/ProjectCreate.php @@ -38,6 +38,7 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form 'git' => __('git'), 'svn' => __('Subversion'), 'mercurial' => __('mercurial'), + 'mtn' => __('monotone'), ); foreach (Pluf::f('allowed_scm', array()) as $key => $class) { $choices[$options[$key]] = $key; @@ -92,6 +93,14 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form 'widget' => 'Pluf_Form_Widget_PasswordInput', )); + $this->fields['mtn_master_branch'] = new Pluf_Form_Field_Varchar( + array('required' => false, + 'label' => __('Master branch'), + 'initial' => '', + 'widget' => 'Pluf_Form_Widget_Input', + 'help_text' => __('This should be a world-wide unique identifier for your project. A reverse DNS notation like "com.my-domain.my-project" is a good idea.'), + )); + $this->fields['owners'] = new Pluf_Form_Field_Varchar( array('required' => false, 'label' => __('Project owners'), @@ -156,6 +165,21 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form return $url; } + public function clean_mtn_master_branch() + { + $mtn_master_branch = mb_strtolower($this->cleaned_data['mtn_master_branch']); + if (!preg_match('/^([\w\d]+([-][\w\d]+)*)(\.[\w\d]+([-][\w\d]+)*)*$/', $mtn_master_branch)) { + throw new Pluf_Form_Invalid(__('This master branch contains illegal characters, please use only letters, digits, dashs and dots as separators.')); + } + + $sql = new Pluf_SQL('vkey=%s AND vdesc=%s', array("mtn_master_branch", $mtn_master_branch)); + $l = Pluf::factory('IDF_Conf')->getList(array('filter'=>$sql->gen())); + if ($l->count() > 0) { + throw new Pluf_Form_Invalid(__('This master branch is already used. Please select another one.')); + } + return $mtn_master_branch; + } + public function clean_shortname() { $shortname = mb_strtolower($this->cleaned_data['shortname']); @@ -184,6 +208,11 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form $this->cleaned_data[$key] = ''; } } + + if ($this->cleaned_data['scm'] != 'mtn') { + $this->cleaned_data['mtn_master_branch'] = ''; + } + /** * [signal] * @@ -222,15 +251,15 @@ class IDF_Form_Admin_ProjectCreate extends Pluf_Form $project->create(); $conf = new IDF_Conf(); $conf->setProject($project); - $keys = array('scm', 'svn_remote_url', - 'svn_username', 'svn_password'); + $keys = array('scm', 'svn_remote_url', 'svn_username', + 'svn_password', 'mtn_master_branch'); foreach ($keys as $key) { - $this->cleaned_data[$key] = (!empty($this->cleaned_data[$key])) ? + $this->cleaned_data[$key] = (!empty($this->cleaned_data[$key])) ? $this->cleaned_data[$key] : ''; $conf->setVal($key, $this->cleaned_data[$key]); } $project->created(); - IDF_Form_MembersConf::updateMemberships($project, + IDF_Form_MembersConf::updateMemberships($project, $this->cleaned_data); $project->membershipsUpdated(); return $project; diff --git a/src/IDF/Project.php b/src/IDF/Project.php index d9895db..762bbde 100644 --- a/src/IDF/Project.php +++ b/src/IDF/Project.php @@ -39,7 +39,7 @@ class IDF_Project extends Pluf_Model * * @see self::isRestricted */ - protected $_isRestricted = null; + protected $_isRestricted = null; function init() { @@ -52,7 +52,7 @@ class IDF_Project extends Pluf_Model 'id' => array( 'type' => 'Pluf_DB_Field_Sequence', - 'blank' => true, + 'blank' => true, ), 'name' => array( @@ -113,7 +113,7 @@ class IDF_Project extends Pluf_Model return ''; } - + function preSave($create=false) { if ($this->id == '') { @@ -181,7 +181,7 @@ class IDF_Project extends Pluf_Model */ public function getTagIdsByStatus($status='open', $cache_refresh=false) { - if (!$cache_refresh + if (!$cache_refresh and isset($this->_extra_cache['getTagIdsByStatus-'.$status])) { return $this->_extra_cache['getTagIdsByStatus-'.$status]; } @@ -197,7 +197,7 @@ class IDF_Project extends Pluf_Model break; } $tags = array(); - foreach ($this->getTagsFromConfig($key, $default, 'Status') as $tag) { + foreach ($this->getTagsFromConfig($key, $default, 'Status') as $tag) { $tags[] = (int) $tag->id; } $this->_extra_cache['getTagIdsByStatus-'.$status] = $tags; @@ -289,9 +289,9 @@ class IDF_Project extends Pluf_Model if ($fmt == 'objects') { return new Pluf_Template_ContextVars(array('members' => $members, 'owners' => $owners, 'authorized' => $authorized)); } else { - return array('members' => implode("\n", (array) $members), + return array('members' => implode("\n", (array) $members), 'owners' => implode("\n", (array) $owners), - 'authorized' => implode("\n", (array) $authorized), + 'authorized' => implode("\n", (array) $authorized), ); } } @@ -385,7 +385,7 @@ class IDF_Project extends Pluf_Model public function getSourceAccessUrl($user=null) { $right = $this->getConf()->getVal('source_access_rights', 'all'); - if (($user == null or $user->isAnonymous()) + if (($user == null or $user->isAnonymous()) and $right == 'all' and !$this->private) { return $this->getRemoteAccessUrl(); } @@ -433,9 +433,10 @@ class IDF_Project extends Pluf_Model { $conf = $this->getConf(); $roots = array( - 'git' => 'master', - 'svn' => 'HEAD', - 'mercurial' => 'tip' + 'git' => 'master', + 'svn' => 'HEAD', + 'mercurial' => 'tip', + 'mtn' => 'h:', ); $scm = $conf->getVal('scm', 'git'); return $roots[$scm]; @@ -448,7 +449,7 @@ class IDF_Project extends Pluf_Model * By convention, all the objects belonging to a project have the * 'project' property set, so this is easy to check. * - * @param Pluf_Model + * @param Pluf_Model */ public function inOr404($obj) { @@ -505,7 +506,7 @@ class IDF_Project extends Pluf_Model * * [description] * - * This signal allows an application to update the statistics + * This signal allows an application to update the statistics * array of a project. For example to add the on disk size * of the repository if available. * @@ -649,7 +650,7 @@ class IDF_Project extends Pluf_Model ); $conf = $this->getConf(); foreach ($tabs as $tab) { - if (!in_array($conf->getVal($tab, 'all'), + if (!in_array($conf->getVal($tab, 'all'), array('all', 'none'))) { $this->_isRestricted = true; return true; diff --git a/src/IDF/Views/Project.php b/src/IDF/Views/Project.php index d66e0ea..edee410 100644 --- a/src/IDF/Views/Project.php +++ b/src/IDF/Views/Project.php @@ -44,12 +44,12 @@ class IDF_Views_Project if ($request->rights['hasDownloadsAccess']) { $tags = IDF_Views_Download::getDownloadTags($prj); // the first tag is the featured, the last is the deprecated. - $downloads = $tags[0]->get_idf_upload_list(); + $downloads = $tags[0]->get_idf_upload_list(); } $pages = array(); if ($request->rights['hasWikiAccess']) { $tags = IDF_Views_Wiki::getWikiTags($prj); - $pages = $tags[0]->get_idf_wikipage_list(); + $pages = $tags[0]->get_idf_wikipage_list(); } return Pluf_Shortcuts_RenderToResponse('idf/project/home.html', array( @@ -100,7 +100,7 @@ class IDF_Views_Project $rights[] = '\'IDF_Dummy\''; } $sql = sprintf('model_class IN (%s)', implode(', ', $rights)); - $pag->forced_where = new Pluf_SQL('project=%s AND '.$sql, + $pag->forced_where = new Pluf_SQL('project=%s AND '.$sql, array($prj->id)); $pag->sort_order = array('creation_dtime', 'ASC'); $pag->sort_reverse_order = array('creation_dtime'); @@ -117,16 +117,16 @@ class IDF_Views_Project if ($request->rights['hasDownloadsAccess']) { $tags = IDF_Views_Download::getDownloadTags($prj); // the first tag is the featured, the last is the deprecated. - $downloads = $tags[0]->get_idf_upload_list(); + $downloads = $tags[0]->get_idf_upload_list(); } $pages = array(); if ($request->rights['hasWikiAccess']) { $tags = IDF_Views_Wiki::getWikiTags($prj); - $pages = $tags[0]->get_idf_wikipage_list(); + $pages = $tags[0]->get_idf_wikipage_list(); } if (!$request->user->isAnonymous() and $prj->isRestricted()) { $feedurl = Pluf_HTTP_URL_urlForView('idf_project_timeline_feed_auth', - array($prj->shortname, + array($prj->shortname, IDF_Precondition::genFeedToken($prj, $request->user))); } else { $feedurl = Pluf_HTTP_URL_urlForView('idf_project_timeline_feed', @@ -188,7 +188,7 @@ class IDF_Views_Project 'nb' => 20, ); $items = Pluf::factory('IDF_Timeline')->getList($params); - $set = new Pluf_Model_Set($items, + $set = new Pluf_Model_Set($items, array('public_dtime' => 'public_dtime')); $out = array(); foreach ($set as $item) { @@ -207,7 +207,7 @@ class IDF_Views_Project $feedurl = Pluf::f('url_base').Pluf::f('idf_base').$request->query; $viewurl = Pluf_HTTP_URL_urlForView('IDF_Views_Project::timeline', array($prj->shortname)); - $context = new Pluf_Template_Context_Request($request, + $context = new Pluf_Template_Context_Request($request, array('body' => $out, 'date' => $date, 'title' => $title, @@ -235,7 +235,7 @@ class IDF_Views_Project if ($form->isValid()) { $prj = $form->save(); $request->user->setMessage(__('The project has been updated.')); - $url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::admin', + $url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::admin', array($prj->shortname)); return new Pluf_HTTP_Response_Redirect($url); } @@ -445,7 +445,7 @@ class IDF_Views_Project } else { $params = array(); $keys = array('downloads_access_rights', 'source_access_rights', - 'issues_access_rights', 'review_access_rights', + 'issues_access_rights', 'review_access_rights', 'wiki_access_rights', 'downloads_notification_email', 'review_notification_email', @@ -519,6 +519,7 @@ class IDF_Views_Project 'git' => __('git'), 'svn' => __('Subversion'), 'mercurial' => __('mercurial'), + 'mtn' => __('monotone'), ); $repository_type = $options[$scm]; return Pluf_Shortcuts_RenderToResponse('idf/admin/source.html', diff --git a/src/IDF/conf/idf.php-dist b/src/IDF/conf/idf.php-dist index 36d69b2..412826d 100644 --- a/src/IDF/conf/idf.php-dist +++ b/src/IDF/conf/idf.php-dist @@ -27,14 +27,14 @@ $cfg = array(); # You must set them to false once everything is running ok. # $cfg['debug'] = true; -# It will help you catch errors at beginning when configuring your +# It will help you catch errors at beginning when configuring your # SCM backend. It must be turned off in production. -$cfg['debug_scm'] = false; +$cfg['debug_scm'] = false; # -# Note: By default, InDefero will not manage the repositories for -# you, you can enable the repositories management with the -# built-in plugins. The documentation of the plugins is available +# Note: By default, InDefero will not manage the repositories for +# you, you can enable the repositories management with the +# built-in plugins. The documentation of the plugins is available # in the `doc/` folder. # @@ -44,9 +44,9 @@ $cfg['debug_scm'] = false; # For example: '/path/to/my/project/.git' # # If you have multiple repositories, you need to put %s where you -# want the shortname of the project to be replaced. +# want the shortname of the project to be replaced. # For example: -# - You have many projects on your local computer and want to use +# - You have many projects on your local computer and want to use # InDefero to see them. Put: '/home/yourlogin/Projects/%s/.git' # - You have many projects on a remote server with only "bare" git # repositories. Put: '/home/git/repositories/%s.git' @@ -64,7 +64,7 @@ $cfg['git_remote_url'] = 'git://localhost/%s.git'; $cfg['git_write_remote_url'] = 'git@localhost:%s.git'; # Same as for git, you can have multiple repositories, one for each -# project or a single one for all the projects. +# project or a single one for all the projects. # # In the case of subversion, the admin of a project can also select a # remote repository from the web interface. From the web interface @@ -73,6 +73,12 @@ $cfg['git_write_remote_url'] = 'git@localhost:%s.git'; $cfg['svn_repositories'] = 'file:///home/svn/repositories/%s'; $cfg['svn_remote_url'] = 'http://localhost/svn/%s'; +# Same as for git, you can have multiple repositories, one for each +# project or a single one for all the projects. +$cfg['mtn_repositories'] = '/home/mtn/repositories/%s.mtn'; +$cfg['mtn_branch_prefix'] = 'com.indefero.projects.'; +$cfg['mtn_remote_url'] = 'mtn://localhost/~%s/%s%s'; + # Mercurial repositories path #$cfg['mercurial_repositories'] = '/home/mercurial/repositories/%s'; #$cfg['mercurial_remote_url'] = 'http://projects.ceondo.com/hg/%s'; @@ -90,15 +96,15 @@ $cfg['mail_host'] = 'localhost'; $cfg['mail_port'] = 25; # Paths/Url configuration. -# +# # Examples: -# You have: +# You have: # http://www.mydomain.com/myfolder/index.php # Put: # $cfg['idf_base'] = '/myfolder/index.php'; # $cfg['url_base'] = 'http://www.mydomain.com'; # -# You have mod_rewrite: +# You have mod_rewrite: # http://www.mydomain.com/ # Put: # $cfg['idf_base'] = ''; @@ -109,7 +115,7 @@ $cfg['mail_port'] = 25; $cfg['idf_base'] = '/index.php'; $cfg['url_base'] = 'http://localhost'; -# Url to access the media folder which is in the www folder +# Url to access the media folder which is in the www folder # of the archive $cfg['url_media'] = 'http://localhost/media'; @@ -120,9 +126,9 @@ $cfg['url_upload'] = 'http://localhost/media/upload'; $cfg['upload_path'] = '/home/www/indefero/www/media/upload'; # -# The following path *MUST NOT* be accessible through a web browser -# as user will be able to upload .html, .php files and this can -# create *TERRIBLE* security issues. In this folder, the attachments +# The following path *MUST NOT* be accessible through a web browser +# as user will be able to upload .html, .php files and this can +# create *TERRIBLE* security issues. In this folder, the attachments # to the issues will be uploaded and we do not restrict the content type. # $cfg['upload_issue_path'] = '/home/www/indefero/attachments'; @@ -130,10 +136,10 @@ $cfg['upload_issue_path'] = '/home/www/indefero/attachments'; # # write here a long random string unique for this installation. This # is critical to put a long string, with at least 40 characters. -$cfg['secret_key'] = ''; +$cfg['secret_key'] = ''; # the sender of all the emails. -$cfg['from_email'] = 'sender@example.com'; +$cfg['from_email'] = 'sender@example.com'; # Email address for the bounced messages. $cfg['bounce_email'] = 'no-reply@example.com'; @@ -150,22 +156,22 @@ $cfg['db_password'] = ''; $cfg['db_server'] = ''; $cfg['db_version'] = '5.1'; # Only needed for MySQL # If you want to have different installations with the same DB -$cfg['db_table_prefix'] = 'indefero_'; -# ** DO NOT USE SQLITE IN PRODUCTION ** +$cfg['db_table_prefix'] = 'indefero_'; +# ** DO NOT USE SQLITE IN PRODUCTION ** # This is not because of problems with the quality of the SQLite # driver or with SQLite itself, this is due to the lack of migration # support in Pluf for SQLite, this means we cannot modify the DB # easily once it is loaded with data. $cfg['db_engine'] = 'PostgreSQL'; # SQLite is also well tested or MySQL $cfg['db_database'] = 'website'; # put absolute path to the db if you - # are using SQLite. + # are using SQLite. # # The extension of the downloads are limited. You can add extra # extensions here. The list must start with a space. # $cfg['idf_extra_upload_ext'] = ' ext1 ext2'; # # By default, the size of the downloads is limited to 2MB. -# The php.ini upload_max_filesize configuration setting will +# The php.ini upload_max_filesize configuration setting will # always have precedence. # $cfg['max_upload_size'] = 2097152; // Size in bytes @@ -203,12 +209,13 @@ $cfg['template_context_processors'] = array('IDF_Middleware_ContextPreProcessor' $cfg['idf_views'] = dirname(__FILE__).'/urls.php'; # available languages -$cfg['languages'] = array('en', 'fr'); +$cfg['languages'] = array('en', 'fr'); # SCM base configuration $cfg['allowed_scm'] = array('git' => 'IDF_Scm_Git', 'svn' => 'IDF_Scm_Svn', 'mercurial' => 'IDF_Scm_Mercurial', + 'mtn' => 'IDF_Scm_Monotone', ); # If you want to use another memtypes database @@ -218,8 +225,8 @@ $cfg['allowed_scm'] = array('git' => 'IDF_Scm_Git', # $cfg['idf_extra_text_ext'] = 'ext1 ext2 ext3'; # If you can execute the shell commands executed to get info -# from the scm with the user of your PHP process but it is -# not working from within PHP, this can be due to the environment +# from the scm with the user of your PHP process but it is +# not working from within PHP, this can be due to the environment # variables not being set correctly. Note the trailing space. # $cfg['idf_exec_cmd_prefix'] = '/usr/bin/env -i '; @@ -229,10 +236,10 @@ $cfg['allowed_scm'] = array('git' => 'IDF_Scm_Git', # To know which path you need to provide, just run: # $ which git # from the command line. This will give you the path to git. -# $cfg['svn_path'] = 'svn'; -# $cfg['svnlook_path'] = 'svnlook'; +# $cfg['svn_path'] = 'svn'; +# $cfg['svnlook_path'] = 'svnlook'; # $cfg['svnadmin_path'] = 'svnadmin'; # $cfg['hg_path'] = 'hg'; -# $cfg['git_path'] = 'git'; +# $cfg['git_path'] = 'git'; return $cfg; diff --git a/src/IDF/templates/idf/gadmin/projects/create.html b/src/IDF/templates/idf/gadmin/projects/create.html index 1affd7d..d542e7e 100644 --- a/src/IDF/templates/idf/gadmin/projects/create.html +++ b/src/IDF/templates/idf/gadmin/projects/create.html @@ -52,6 +52,13 @@ {$form.f.svn_password|unsafe} + +{$form.f.mtn_master_branch.labelTag}: +{if $form.f.mtn_master_branch.errors}{$form.f.mtn_master_branch.fieldErrors}{/if} +{$form.f.mtn_master_branch|unsafe}
+{$form.f.mtn_master_branch.help_text} + + {$form.f.owners.labelTag}: @@ -76,7 +83,7 @@   - + @@ -112,12 +119,22 @@ $(document).ready(function() { if ($("#id_scm option:selected").val() != "svn") { $(".svn-form").hide(); } + // Hide if not mtn + if ($("#id_scm option:selected").val() != "mtn") { + $(".mtn-form").hide(); + } $("#id_scm").change(function () { if ($("#id_scm option:selected").val() == "svn") { $(".svn-form").show(); } else { $(".svn-form").hide(); } + if ($("#id_scm option:selected").val() == "mtn") { + $(".mtn-form").show(); + } else { + $(".mtn-form").hide(); + } + }); }); diff --git a/src/IDF/templates/idf/source/mtn/help.html b/src/IDF/templates/idf/source/mtn/help.html index 9e72ba9..34d0e83 100644 --- a/src/IDF/templates/idf/source/mtn/help.html +++ b/src/IDF/templates/idf/source/mtn/help.html @@ -3,15 +3,12 @@ {block body}

{blocktrans}The team behind {$project} is using -the git software to manage the source +the monotone software to manage the source code.{/blocktrans}

{trans 'Command-Line Access'}

-

git clone {$project.getSourceAccessUrl($user)}

- -{aurl 'url', 'IDF_Views_User::myAccount'} -

{blocktrans}You may need to provide your SSH key. The synchronization of your SSH key can take a couple of minutes. You can learn more about SSH key authentification.{/blocktrans}

+

mtn clone {$project.getSourceAccessUrl()}

{if $isOwner or $isMember}

{trans 'First Commit'}

@@ -19,11 +16,9 @@ code.{/blocktrans}

{blocktrans}To make a first commit in the repository, perform the following steps:{/blocktrans}

-git init
-git add .
-git commit -m "initial import"
-git remote add origin {$project.getWriteRemoteAccessUrl($url)}
-git push origin master
+mtn add -R .
+mtn commit -m "initial import"
+mtn push {$project.getSourceAccessUrl()}
 
{/if}