Merge branch 'szzh' of http://repository.trustie.net/xianbo/trustie2 into szzh
	
		
	
				
					
				
			Conflicts: db/schema.rbdev_xiangzheng
						commit
						61dc979ee4
					
				| @ -0,0 +1,259 @@ | ||||
| #coding=utf-8 | ||||
| 
 | ||||
| require 'redmine/scm/adapters/git_adapter' | ||||
| 
 | ||||
| class Repository::Gitlab < Repository | ||||
|    | ||||
|   attr_protected :root_url | ||||
|   validates_presence_of :url | ||||
| 
 | ||||
|   def self.human_attribute_name(attribute_key_name, *args) | ||||
|     attr_name = attribute_key_name.to_s | ||||
|     if attr_name == "url" | ||||
|       attr_name = "path_to_repository" | ||||
|     end | ||||
|     super(attr_name, *args) | ||||
|   end | ||||
| 
 | ||||
|   def self.scm_adapter_class | ||||
|     Redmine::Scm::Adapters::GitlabAdapter | ||||
|   end | ||||
| 
 | ||||
|   def self.scm_name | ||||
|     'Gitlab' | ||||
|   end | ||||
| 
 | ||||
|   def commits(authors, start_date, end_date, branch='master') | ||||
|     scm.commits(authors, start_date, end_date,branch).map {|commit| | ||||
|       [commit[:author], commit[:num]] | ||||
|     } | ||||
|   end | ||||
| 
 | ||||
|   def report_last_commit | ||||
|     extra_report_last_commit | ||||
|   end | ||||
| 
 | ||||
|   def extra_report_last_commit | ||||
|     return false if extra_info.nil? | ||||
|     v = extra_info["extra_report_last_commit"] | ||||
|     return false if v.nil? | ||||
|     v.to_s != '0' | ||||
|   end | ||||
| 
 | ||||
|   def supports_directory_revisions? | ||||
|     true | ||||
|   end | ||||
| 
 | ||||
|   def supports_revision_graph? | ||||
|     true | ||||
|   end | ||||
| 
 | ||||
|   def repo_log_encoding | ||||
|     'UTF-8' | ||||
|   end | ||||
| 
 | ||||
|   # Returns the identifier for the given git changeset | ||||
|   def self.changeset_identifier(changeset) | ||||
|     changeset.scmid | ||||
|   end | ||||
| 
 | ||||
|   # Returns the readable identifier for the given git changeset | ||||
|   def self.format_changeset_identifier(changeset) | ||||
|     changeset.revision[0, 8] | ||||
|   end | ||||
| 
 | ||||
|   def branches | ||||
|     scm.branches | ||||
|   end | ||||
| 
 | ||||
|   def tags | ||||
|     scm.tags | ||||
|   end | ||||
| 
 | ||||
|   def default_branch | ||||
|     scm.default_branch | ||||
|   rescue Exception => e | ||||
|     logger.error "git: error during get default branch: #{e.message}" | ||||
|     nil | ||||
|   end | ||||
| 
 | ||||
|   def find_changeset_by_name(name) | ||||
|     if name.present? | ||||
|       changesets.where(:revision => name.to_s).first || | ||||
|         changesets.where('scmid LIKE ?', "#{name}%").first | ||||
|     end | ||||
|   end | ||||
| 
 | ||||
|   def entries(path=nil, identifier=nil) | ||||
|     entries = scm.entries(path, identifier, :report_last_commit => extra_report_last_commit) | ||||
|     load_entries_changesets(entries) | ||||
|     entries | ||||
|   end | ||||
| 
 | ||||
|   # With SCMs that have a sequential commit numbering, | ||||
|   # such as Subversion and Mercurial, | ||||
|   # Redmine is able to be clever and only fetch changesets | ||||
|   # going forward from the most recent one it knows about. | ||||
|   # | ||||
|   # However, Git does not have a sequential commit numbering. | ||||
|   # | ||||
|   # In order to fetch only new adding revisions, | ||||
|   # Redmine needs to save "heads". | ||||
|   # | ||||
|   # In Git and Mercurial, revisions are not in date order. | ||||
|   # Redmine Mercurial fixed issues. | ||||
|   #    * Redmine Takes Too Long On Large Mercurial Repository | ||||
|   #      http://www.redmine.org/issues/3449 | ||||
|   #    * Sorting for changesets might go wrong on Mercurial repos | ||||
|   #      http://www.redmine.org/issues/3567 | ||||
|   # | ||||
|   # Database revision column is text, so Redmine can not sort by revision. | ||||
|   # Mercurial has revision number, and revision number guarantees revision order. | ||||
|   # Redmine Mercurial model stored revisions ordered by database id to database. | ||||
|   # So, Redmine Mercurial model can use correct ordering revisions. | ||||
|   # | ||||
|   # Redmine Mercurial adapter uses "hg log -r 0:tip --limit 10" | ||||
|   # to get limited revisions from old to new. | ||||
|   # But, Git 1.7.3.4 does not support --reverse with -n or --skip. | ||||
|   # | ||||
|   # The repository can still be fully reloaded by calling #clear_changesets | ||||
|   # before fetching changesets (eg. for offline resync) | ||||
|   def fetch_changesets | ||||
|     scm_brs = branches | ||||
|     return if scm_brs.nil? || scm_brs.empty? | ||||
| 
 | ||||
|     h1 = extra_info || {} | ||||
|     h  = h1.dup | ||||
|     repo_heads = scm_brs.map{ |br| br.scmid } | ||||
|     h["heads"] ||= [] | ||||
|     prev_db_heads = h["heads"].dup | ||||
|     if prev_db_heads.empty? | ||||
|       prev_db_heads += heads_from_branches_hash | ||||
|     end | ||||
|     return if prev_db_heads.sort == repo_heads.sort | ||||
| 
 | ||||
|     h["db_consistent"]  ||= {} | ||||
|     if changesets.count == 0 | ||||
|       h["db_consistent"]["ordering"] = 1 | ||||
|       merge_extra_info(h) | ||||
|       self.save | ||||
|     elsif ! h["db_consistent"].has_key?("ordering") | ||||
|       h["db_consistent"]["ordering"] = 0 | ||||
|       merge_extra_info(h) | ||||
|       self.save | ||||
|     end | ||||
|     save_revisions(prev_db_heads, repo_heads) | ||||
|   end | ||||
| 
 | ||||
|   def save_revisions(prev_db_heads, repo_heads) | ||||
|     h = {} | ||||
|     opts = {} | ||||
|     opts[:reverse]  = true | ||||
|     opts[:excludes] = prev_db_heads | ||||
|     opts[:includes] = repo_heads | ||||
| 
 | ||||
|     revisions = scm.revisions('', nil, nil, opts) | ||||
|     return if revisions.blank? | ||||
| 
 | ||||
|     # Make the search for existing revisions in the database in a more sufficient manner | ||||
|     # | ||||
|     # Git branch is the reference to the specific revision. | ||||
|     # Git can *delete* remote branch and *re-push* branch. | ||||
|     # | ||||
|     #  $ git push remote :branch | ||||
|     #  $ git push remote branch | ||||
|     # | ||||
|     # After deleting branch, revisions remain in repository until "git gc". | ||||
|     # On git 1.7.2.3, default pruning date is 2 weeks. | ||||
|     # So, "git log --not deleted_branch_head_revision" return code is 0. | ||||
|     # | ||||
|     # After re-pushing branch, "git log" returns revisions which are saved in database. | ||||
|     # So, Redmine needs to scan revisions and database every time. | ||||
|     # | ||||
|     # This is replacing the one-after-one queries. | ||||
|     # Find all revisions, that are in the database, and then remove them from the revision array. | ||||
|     # Then later we won't need any conditions for db existence. | ||||
|     # Query for several revisions at once, and remove them from the revisions array, if they are there. | ||||
|     # Do this in chunks, to avoid eventual memory problems (in case of tens of thousands of commits). | ||||
|     # If there are no revisions (because the original code's algorithm filtered them), | ||||
|     # then this part will be stepped over. | ||||
|     # We make queries, just if there is any revision. | ||||
|     limit = 100 | ||||
|     offset = 0 | ||||
|     revisions_copy = revisions.clone # revisions will change | ||||
|     while offset < revisions_copy.size | ||||
|       recent_changesets_slice = changesets.find( | ||||
|                                      :all, | ||||
|                                      :conditions => [ | ||||
|                                         'scmid IN (?)', | ||||
|                                         revisions_copy.slice(offset, limit).map{|x| x.scmid} | ||||
|                                       ] | ||||
|                                     ) | ||||
|       # Subtract revisions that redmine already knows about | ||||
|       recent_revisions = recent_changesets_slice.map{|c| c.scmid} | ||||
|       revisions.reject!{|r| recent_revisions.include?(r.scmid)} | ||||
|       offset += limit | ||||
|     end | ||||
| 
 | ||||
|     revisions.each do |rev| | ||||
|       transaction do | ||||
|         # There is no search in the db for this revision, because above we ensured, | ||||
|         # that it's not in the db. | ||||
|         save_revision(rev) | ||||
|       end | ||||
|     end | ||||
|     h["heads"] = repo_heads.dup | ||||
|     merge_extra_info(h) | ||||
|     self.save | ||||
|   end | ||||
|   private :save_revisions | ||||
| 
 | ||||
|   def save_revision(rev) | ||||
|     parents = (rev.parents || []).collect{|rp| find_changeset_by_name(rp)}.compact | ||||
|     changeset = Changeset.create( | ||||
|               :repository   => self, | ||||
|               :revision     => rev.identifier, | ||||
|               :scmid        => rev.scmid, | ||||
|               :committer    => rev.author, | ||||
|               :committed_on => rev.time, | ||||
|               :comments     => rev.message, | ||||
|               :parents      => parents | ||||
|               ) | ||||
|     unless changeset.new_record? | ||||
|       rev.paths.each { |change| changeset.create_change(change) } | ||||
|     end | ||||
|     changeset | ||||
|   end | ||||
|   private :save_revision | ||||
| 
 | ||||
|   def heads_from_branches_hash | ||||
|     h1 = extra_info || {} | ||||
|     h  = h1.dup | ||||
|     h["branches"] ||= {} | ||||
|     h['branches'].map{|br, hs| hs['last_scmid']} | ||||
|   end | ||||
| 
 | ||||
|   def latest_changesets(path,rev,limit=10) | ||||
|     revisions = scm.revisions(path, nil, rev, :limit => limit, :all => false) | ||||
|     return [] if revisions.nil? || revisions.empty? | ||||
| 
 | ||||
|     changesets.find( | ||||
|       :all, | ||||
|       :conditions => [ | ||||
|         "scmid IN (?)", | ||||
|         revisions.map!{|c| c.scmid} | ||||
|       ] | ||||
|     ) | ||||
|   end | ||||
| 
 | ||||
|   def clear_extra_info_of_changesets | ||||
|     return if extra_info.nil? | ||||
|     v = extra_info["extra_report_last_commit"] | ||||
|     write_attribute(:extra_info, nil) | ||||
|     h = {} | ||||
|     h["extra_report_last_commit"] = v | ||||
|     merge_extra_info(h) | ||||
|     self.save | ||||
|   end | ||||
|   private :clear_extra_info_of_changesets | ||||
| end | ||||
| @ -1,2 +1,7 @@ | ||||
| <% if @in_user_center%> | ||||
|     $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/user_blog', :locals => {:activity => @article,:user_activity_id =>@user_activity_id}) %>"); | ||||
|     init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); | ||||
| <% else%> | ||||
| $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'blogs/article', :locals => {:activity => @article,:user_activity_id =>@user_activity_id,:first_user_activity =>@first_user_activity,:page => @page}) %>"); | ||||
| init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); | ||||
| init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); | ||||
| <% end %> | ||||
| @ -1,6 +1,10 @@ | ||||
| $('#ajax-modal').html('<%= escape_javascript(render :partial => 'homework_common/set_evalutation_att') %>'); | ||||
| var datepickerOptions={dateFormat: 'yy-mm-dd', firstDay: 0, showOn: 'button', buttonImageOnly: true, buttonImage: '/images/public_icon.png', showButtonPanel: true, showWeek: true, showOtherMonths: true, selectOtherMonths: true}; | ||||
| showModal('ajax-modal', '350px'); | ||||
| $('#ajax-modal').siblings().remove(); | ||||
| $('#ajax-modal').before("<span style='float: right;cursor:pointer;'>" + | ||||
| "<a href='javascript:' onclick='clickCanel();'><img src='/images/bid/close.png' width='26px' height='26px' /></a></span>"); | ||||
| $('#ajax-modal').parent().css("top","25%").css("left","35%").css("position","fixed"); | ||||
| $('#ajax-modal').parent().css("top","25%").css("left","35%").css("position","fixed"); | ||||
| $(function() { $('#evaluation_start_time').datepicker(datepickerOptions); | ||||
|     $('#evaluation_end_time').datepicker(datepickerOptions); | ||||
| }); | ||||
| @ -1,32 +1,13 @@ | ||||
| <%= link_to @repository.identifier.present? ? h(@repository.identifier) : 'root', | ||||
|             {:action => 'show', :id => @project, | ||||
|             :repository_id => @repository.identifier_param, | ||||
|             :path => nil, :rev => @rev }, | ||||
|             :class=>"fl c_blue f14 fb" %> | ||||
| <% | ||||
|    dirs = path.split('/') | ||||
|    if 'file' == kind | ||||
|      filename = dirs.pop | ||||
|    end | ||||
|    link_path = '' | ||||
|    dirs.each do |dir| | ||||
|      next if dir.blank? | ||||
|      link_path << '/' unless link_path.empty? | ||||
|      link_path << "#{dir}" | ||||
| %> | ||||
|     / <%= link_to h(dir), :action => 'show', :id => @project, :repository_id => @repository.identifier_param, | ||||
|                   :path => to_path_param(link_path), :rev => @rev  %> | ||||
| <% end %> | ||||
| <% if filename %> | ||||
|     / <%= link_to h(filename), | ||||
|                   :action => 'changes', :id => @project, :repository_id => @repository.identifier_param, | ||||
|                   :path => to_path_param("#{link_path}/#{filename}"), :rev => @rev %> | ||||
| <% end %> | ||||
| <% | ||||
|    # @rev is revsion or Git and Mercurial branch or tag. | ||||
|    # For Mercurial *tip*, @rev and @changeset are nil. | ||||
|    rev_text = @changeset.nil? ? @rev : format_revision(@changeset) | ||||
| %> | ||||
| <p class="fl f14 fb c_grey02"><%= "@ #{h rev_text}" unless rev_text.blank? %></p> | ||||
| <div class="git_usr_title"> | ||||
|   <span><%= link_to @repository.identifier.present? ? h(@repository.identifier) : 'root', | ||||
|                     {:action => 'show', :id => @project, | ||||
|                      :repository_id => @repository.identifier_param, | ||||
|                      :path => nil, :rev => @rev }, | ||||
|                      :class => "repository-title-dec" | ||||
|   %> | ||||
|     / | ||||
|     <%=link_to @project.owner, user_path(@project.owner), :class => "repository-title-dec" %> | ||||
|   </span> | ||||
| </div> | ||||
| 
 | ||||
| <% html_title(with_leading_slash(path)) -%> | ||||
|  | ||||
| @ -1,34 +1,33 @@ | ||||
| <% content_for :header_tags do %> | ||||
|     <%= javascript_include_tag 'repository_navigation' %> | ||||
| <% end %> | ||||
| <a  href="javascript:void(0);" class="pic_stats fl ml20 mt3"></a> | ||||
| <%= link_to l(:label_statistics), | ||||
| <!--<a  href="javascript:void(0);" class="pic_stats fl ml20 mt3"></a>--> | ||||
| <%#= link_to l(:label_statistics), | ||||
|             {:action => 'stats', :id => @project, :repository_id => @repository.identifier_param}, | ||||
|             :class => 'mt3 c_blue fl' if @repository.supports_all_revisions? %> | ||||
| <div class="repositorytitle mr15"> | ||||
|   <% content_for :header_tags do %> | ||||
|       <%= javascript_include_tag 'repository_navigation' %> | ||||
|   <% end %> | ||||
| 
 | ||||
| <%= form_tag({:action => controller.action_name, | ||||
|               :id => @project, | ||||
|               :repository_id => @repository.identifier_param, | ||||
|               :path => to_path_param(@path), | ||||
|               :rev => nil}, | ||||
|              {:method => :get, :id => 'revision_selector', :class => "fl c_grey02 ml5"}) do -%> | ||||
|     <!-- Branches Dropdown --> | ||||
|     <% if !@repository.branches.nil? && @repository.branches.length > 0 -%> | ||||
|         | <%= l(:label_branch) %>: | ||||
|         <%= select_tag :branch, | ||||
|                        options_for_select([''] + @repository.branches, @rev), | ||||
|                        :id => 'branch' %> | ||||
|     <% end -%> | ||||
| 
 | ||||
|     <% if !@repository.tags.nil? && @repository.tags.length > 0 -%> | ||||
|         | <%= l(:label_tag) %>: | ||||
|         <%= select_tag :tag, | ||||
|                        options_for_select([''] + @repository.tags, @rev), | ||||
|                        :id => 'tag' %> | ||||
|     <% end -%> | ||||
| 
 | ||||
|     <% if @repository.supports_all_revisions? %> | ||||
|         | <%= l(:label_revision) %>: | ||||
|         <%= text_field_tag 'rev', @rev, :size => 8 %> | ||||
|     <% end %> | ||||
| <% end -%> | ||||
|   <%= form_tag({:action => controller.action_name, | ||||
|                 :id => @project, | ||||
|                 :repository_id => @repository.identifier_param, | ||||
|                 :path => to_path_param(@path), | ||||
|                 :rev => nil}, | ||||
|                {:method => :get, :id => 'revision_selector'}) do -%> | ||||
|       <!-- Branches Dropdown --> | ||||
|       <% if !@repository.branches.nil? && @repository.branches.length > 0 -%> | ||||
|           <%= l(:label_branch) %>: | ||||
|           <%= select_tag :branch, options_for_select([''] + @repository.branches, @rev), :id => 'branch' %> | ||||
|       <% end -%> | ||||
| 
 | ||||
|       <% if !@repository.tags.nil? && @repository.tags.length > 0 -%> | ||||
|           <%= select_tag :tag, options_for_select([''] + @repository.tags, @rev), :id => 'tag', :style=>" display:none" %> | ||||
|       <% end -%> | ||||
| 
 | ||||
|       <% if @repository.supports_all_revisions? %> | ||||
|           <%= hidden_field_tag 'rev', @rev, :size => 8 %> | ||||
|       <% end %> | ||||
|   <% end -%> | ||||
| 
 | ||||
| </div> | ||||
|  | ||||
| @ -0,0 +1,37 @@ | ||||
| <div class="overall-summary overall-summary-bottomless"> | ||||
| 
 | ||||
|   <div class="stats-switcher-viewport js-stats-switcher-viewport"> | ||||
|     <div class="stats-switcher-wrapper"> | ||||
|       <ul class="numbers-summary"> | ||||
|         <li class="commits"> | ||||
|           <a data-pjax="" href="/redmine/redmine/commits/0.6-stable"> | ||||
|             <span class="octicon octicon-history"></span> | ||||
|             <span class="num text-emphasized"> | ||||
|               <%=link_to @changesets.count, {:action => 'changes', :path => to_path_param(@path), :id => @project, :repository_id => @repository.identifier_param, :rev => @rev}, :class => "num text-emphasized c_blue" %> | ||||
|             </span> | ||||
|             commits | ||||
|           </a> | ||||
|         </li> | ||||
| 
 | ||||
|         <li> | ||||
|           <span class="octicon image-type"></span> | ||||
|           <span class="num text-emphasized" style="color: #269AC9"> | ||||
|             <%= @repository.branches.count %> | ||||
|           </span> | ||||
|           branches | ||||
|         </li> | ||||
| 
 | ||||
|         <li> | ||||
|             <span class="octicon octicon-organization"></span> | ||||
|             <span class="num text-emphasized"> | ||||
|                <%=link_to @repository.committers.count, committers_repository_path(@repository), :class => "c_blue" %> | ||||
|             </span> | ||||
|             contributors | ||||
|         </li> | ||||
|       </ul> | ||||
| 
 | ||||
| 
 | ||||
|     </div> | ||||
|   </div> | ||||
| 
 | ||||
| </div> | ||||
| @ -0,0 +1,12 @@ | ||||
| <div class="repository-update-dec"> | ||||
|   <p class="c_orange"> | ||||
|     <%= l(:label_repository_migrate_dec) %> | ||||
|   </p> | ||||
| <%= form_for(@repository, url: to_gitlab_project_repository_path(@project, @repository)) do |f| %> | ||||
| <input type="text" name="repo_name"/> | ||||
|     <button type="submit">转换到新版本</button> | ||||
| <% end %> | ||||
| <span class="c_grey"> | ||||
|   <%= l(:label_repository_name_dec) %> | ||||
| </span> | ||||
| </div> | ||||
| @ -1,66 +1,9 @@ | ||||
| <%= form_for('new_form',:url =>  {:controller => 'student_work',:action => 'set_score_rule',:homework => homework.id},:method => "post") do |f|%> | ||||
|     <% if student_path %> | ||||
|         <%=hidden_field_tag 'student_path', params[:student_path], :value => student_path  %> | ||||
|     <% end %> | ||||
|     <div class="markPopup" id="popbox02"> | ||||
|       <span class="uploadText">评分设置</span> | ||||
|       <div class="mt15"> | ||||
|         <span class="f14 fontGrey3 mr10">迟交扣分</span> | ||||
|         <input type="text" name="late_penalty" id="late_penalty_num" placeholder="请输入0-50数值" class=" markInput"  value="<%= homework.late_penalty%>" onkeyup="check_late_penalty('late_penalty_num')"/> | ||||
|       </div> | ||||
|       <div> | ||||
|         <span class="f14 fontGrey3 mr10">缺评扣分</span> | ||||
|         <input type="text" name="absence_penalty" id="absence_penalty_num" placeholder="请输入0-50数值" class="markInput" value="<%= homework.homework_detail_manual.absence_penalty%>" onkeyup="check_late_penalty('absence_penalty_num')"/> | ||||
|       </div> | ||||
| 
 | ||||
|       <% if homework.homework_type == 2%> | ||||
|           <div> | ||||
|             <span class="f14 fontGrey3 mr10">系统评分</span> | ||||
|             <%= select_tag :sy_proportion,options_for_select(ta_proportion_option,homework.homework_detail_programing.ta_proportion), {:class => "markPercentage"}  %> | ||||
|           </div> | ||||
| 
 | ||||
|           <script> | ||||
|               $("#sy_proportion").change(function(){ | ||||
|                   var ta_proportion = 100 - parseInt($("#sy_proportion").val() * 100); | ||||
|                   $("#ta_proportion").replaceWith(build_selector(ta_proportion)); | ||||
|                   $("#student_proportion").val("0%"); | ||||
|               }); | ||||
| 
 | ||||
|               $("#ta_proportion").live("change",function(){ | ||||
|                   var ta_proportion = 100 - parseInt($("#sy_proportion").val() * 100) - parseInt($("#ta_proportion").val() * 100); | ||||
|                   $("#student_proportion").val(ta_proportion  + "%"); | ||||
|               }); | ||||
|           </script> | ||||
|       <% else%> | ||||
|           <script> | ||||
|               $("#ta_proportion").change(function(){ | ||||
|                   var ta_proportion = $("#ta_proportion").val(); | ||||
|                   $("#student_proportion").val((100 - parseInt(ta_proportion * 100)) + "%"); | ||||
|               }); | ||||
|           </script> | ||||
|       <% end%> | ||||
| 
 | ||||
|       <div> | ||||
|         <span class="f14 fontGrey3 mr10">教辅评分</span> | ||||
|         <%= select_tag :ta_proportion,options_for_select(ta_proportion_option_to(100-(homework.homework_detail_programing ? homework.homework_detail_programing.ta_proportion * 100 : 0).to_i),homework.homework_detail_manual.ta_proportion), {:class => "markPercentage"}  %> | ||||
|       </div> | ||||
|       <div> | ||||
|         <span class="f14 fontGrey3 mr10">学生匿评</span> | ||||
|         <input type="text" id="student_proportion" value="<%= (100 - homework.homework_detail_manual.ta_proportion * 100).to_i - (homework.homework_detail_programing ? homework.homework_detail_programing.ta_proportion * 100 : 0).to_i%>%" class="markPercentage" readonly> | ||||
|       </div> | ||||
|       <div class="mb20"> | ||||
|         <span class="f14 fontGrey3 mr10">教师优先</span> | ||||
|         <input type="checkbox" name="teacher_priority" <%= homework.teacher_priority == 1 ? 'checked' : ''%>/> | ||||
|         <span class="f12 c_red ml10">教师评分为最终评分</span> | ||||
|       </div> | ||||
|       <div> | ||||
|         <div class="courseSendSubmit"> | ||||
|           <a href="javascript:void(0);" class="sendSourceText" onclick="$('#ajax-modal').find('form').submit();">确定</a> | ||||
|         </div> | ||||
|         <div class="courseSendCancel"> | ||||
|           <a href="javascript:void(0);" class="sendSourceText linkGrey6" onclick="clickCanel();">取消</a> | ||||
|         </div> | ||||
|       </div> | ||||
|       <div class="cl"></div> | ||||
|     </div> | ||||
| <% end%> | ||||
| <% if student_path%> | ||||
|     <%= form_for('new_form',:url =>  {:controller => 'student_work',:action => 'set_score_rule',:homework => homework.id,:student_path => student_path},:method => "post") do |f|%> | ||||
|         <% render :partial => 'student_work/set_score_rule_detail', :locals => {:homework => homework, :f => f}%> | ||||
|     <% end%> | ||||
| <% else %> | ||||
|     <%= form_for('new_form',:url =>  {:controller => 'student_work',:action => 'set_score_rule',:homework => homework.id,:user_activity_id=>user_activity_id,:is_in_course=>is_in_course},:method => "post",:remote => true) do |f|%> | ||||
|         <% render :partial => 'student_work/set_score_rule_detail', :locals => {:homework => homework, :f => f}%> | ||||
|     <% end%> | ||||
| <% end %> | ||||
| @ -0,0 +1,61 @@ | ||||
| <div class="markPopup" id="popbox02"> | ||||
|   <span class="uploadText">评分设置</span> | ||||
|   <div class="mt15"> | ||||
|     <span class="f14 fontGrey3 mr10">迟交扣分</span> | ||||
|     <input type="text" name="late_penalty" id="late_penalty_num" placeholder="请输入0-50数值" class=" markInput"  value="<%= homework.late_penalty%>" onkeyup="check_late_penalty('late_penalty_num')"/> | ||||
|   </div> | ||||
|   <div> | ||||
|     <span class="f14 fontGrey3 mr10">缺评扣分</span> | ||||
|     <input type="text" name="absence_penalty" id="absence_penalty_num" placeholder="请输入0-50数值" class="markInput" value="<%= homework.homework_detail_manual.absence_penalty%>" onkeyup="check_late_penalty('absence_penalty_num')"/> | ||||
|   </div> | ||||
| 
 | ||||
|   <% if homework.homework_type == 2%> | ||||
|       <div> | ||||
|         <span class="f14 fontGrey3 mr10">系统评分</span> | ||||
|         <%= select_tag :sy_proportion,options_for_select(ta_proportion_option,homework.homework_detail_programing.ta_proportion), {:class => "markPercentage"}  %> | ||||
|       </div> | ||||
| 
 | ||||
|       <script> | ||||
|           $("#sy_proportion").change(function(){ | ||||
|               var ta_proportion = 100 - parseInt($("#sy_proportion").val() * 100); | ||||
|               $("#ta_proportion").replaceWith(build_selector(ta_proportion)); | ||||
|               $("#student_proportion").val("0%"); | ||||
|           }); | ||||
| 
 | ||||
|           $("#ta_proportion").live("change",function(){ | ||||
|               var ta_proportion = 100 - parseInt($("#sy_proportion").val() * 100) - parseInt($("#ta_proportion").val() * 100); | ||||
|               $("#student_proportion").val(ta_proportion  + "%"); | ||||
|           }); | ||||
|       </script> | ||||
|   <% else%> | ||||
|       <script> | ||||
|           $("#ta_proportion").change(function(){ | ||||
|               var ta_proportion = $("#ta_proportion").val(); | ||||
|               $("#student_proportion").val((100 - parseInt(ta_proportion * 100)) + "%"); | ||||
|           }); | ||||
|       </script> | ||||
|   <% end%> | ||||
| 
 | ||||
|   <div> | ||||
|     <span class="f14 fontGrey3 mr10">教辅评分</span> | ||||
|     <%= select_tag :ta_proportion,options_for_select(ta_proportion_option_to(100-(homework.homework_detail_programing ? homework.homework_detail_programing.ta_proportion * 100 : 0).to_i),homework.homework_detail_manual.ta_proportion), {:class => "markPercentage"}  %> | ||||
|   </div> | ||||
|   <div> | ||||
|     <span class="f14 fontGrey3 mr10">学生匿评</span> | ||||
|     <input type="text" id="student_proportion" value="<%= (100 - homework.homework_detail_manual.ta_proportion * 100).to_i - (homework.homework_detail_programing ? homework.homework_detail_programing.ta_proportion * 100 : 0).to_i%>%" class="markPercentage" readonly> | ||||
|   </div> | ||||
|   <div class="mb20"> | ||||
|     <span class="f14 fontGrey3 mr10">教师优先</span> | ||||
|     <input type="checkbox" name="teacher_priority" <%= homework.teacher_priority == 1 ? 'checked' : ''%>/> | ||||
|     <span class="f12 c_red ml10">教师评分为最终评分</span> | ||||
|   </div> | ||||
|   <div> | ||||
|     <div class="courseSendSubmit"> | ||||
|       <a href="javascript:void(0);" class="sendSourceText" onclick="$('#ajax-modal').find('form').submit();">确定</a> | ||||
|     </div> | ||||
|     <div class="courseSendCancel"> | ||||
|       <a href="javascript:void(0);" class="sendSourceText linkGrey6" onclick="clickCanel();">取消</a> | ||||
|     </div> | ||||
|   </div> | ||||
|   <div class="cl"></div> | ||||
| </div> | ||||
| @ -0,0 +1,8 @@ | ||||
| clickCanel(); | ||||
| <% if @user_activity_id %> | ||||
|     $("#user_activity_<%= @user_activity_id%>").replaceWith("<%= escape_javascript(render :partial => 'users/course_homework', :locals => {:activity => @homework,:user_activity_id =>@user_activity_id}) %>"); | ||||
|     init_activity_KindEditor_data(<%= @user_activity_id%>,"","87%"); | ||||
| <% else %> | ||||
|     $("#homework_common_<%= @homework.id %>").replaceWith("<%= escape_javascript(render :partial => 'users/user_homework_detail', :locals => {:homework_common => @homework,:is_in_course => @is_in_course}) %>"); | ||||
|     init_activity_KindEditor_data(<%= @homework.id%>,"","87%"); | ||||
| <% end %> | ||||
| @ -0,0 +1,9 @@ | ||||
| Gitlab.configure do |config| | ||||
|   # config.endpoint       = 'http://192.168.41.130:3000/trustie/api/v3' # API endpoint URL, default: ENV['GITLAB_API_ENDPOINT'] | ||||
|   # config.private_token  = 'cK15gUDwvt8EEkzwQ_63'       # user's private token, default: ENV['GITLAB_API_PRIVATE_TOKEN'] | ||||
|   config.endpoint       = 'http://git.trustie.net/trustie/api/v3' # API endpoint URL, default: ENV['GITLAB_API_ENDPOINT'] | ||||
|   config.private_token  = 'fPc_gBmEiSANve8TCfxW'       # user's private token, default: ENV['GITLAB_API_PRIVATE_TOKEN'] | ||||
|   # Optional | ||||
|   # config.user_agent   = 'Custom User Agent'          # user agent, default: 'Gitlab Ruby Gem [version]' | ||||
|   # config.sudo         = 'user'                       # username for sudo mode, default: nil | ||||
| end | ||||
| @ -0,0 +1,5 @@ | ||||
| class AddGitlabUserIdToUsers < ActiveRecord::Migration | ||||
|   def change | ||||
|     add_column :users, :gid, :integer | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,5 @@ | ||||
| class AddGpidToProject < ActiveRecord::Migration | ||||
|   def change | ||||
|     add_column :projects, :gpid, :integer | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,4 @@ | ||||
| source 'https://rubygems.org' | ||||
| 
 | ||||
| # Specify your gem's dependencies in gitlab.gemspec | ||||
| gemspec | ||||
| @ -0,0 +1,24 @@ | ||||
| Copyright (c) 2012-2014 Nihad Abbasov <mail@narkoz.me> | ||||
| All rights reserved. | ||||
| 
 | ||||
| Redistribution and use in source and binary forms, with or without | ||||
| modification, are permitted provided that the following conditions are met: | ||||
| 
 | ||||
| 1. Redistributions of source code must retain the above copyright notice, | ||||
| this list of conditions and the following disclaimer. | ||||
| 
 | ||||
| 2. Redistributions in binary form must reproduce the above copyright notice, | ||||
| this list of conditions and the following disclaimer in the documentation | ||||
| and/or other materials provided with the distribution. | ||||
| 
 | ||||
| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
| AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
| ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||||
| LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
| CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
| SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
| INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
| CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
| ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
| POSSIBILITY OF SUCH DAMAGE. | ||||
| @ -0,0 +1,121 @@ | ||||
| # Gitlab | ||||
| 
 | ||||
| [](http://travis-ci.org/NARKOZ/gitlab) | ||||
| 
 | ||||
| [website](http://narkoz.github.io/gitlab) | | ||||
| [documentation](http://rubydoc.info/gems/gitlab/frames) | ||||
| 
 | ||||
| Gitlab is a Ruby wrapper and CLI for the [GitLab API](https://github.com/gitlabhq/gitlabhq/tree/master/doc/api#gitlab-api). | ||||
| 
 | ||||
| ## Installation | ||||
| 
 | ||||
| Install it from rubygems: | ||||
| 
 | ||||
| ```sh | ||||
| gem install gitlab | ||||
| ``` | ||||
| 
 | ||||
| Or add to a Gemfile: | ||||
| 
 | ||||
| ```ruby | ||||
| gem 'gitlab' | ||||
| # gem 'gitlab', :git => 'git://github.com/NARKOZ/gitlab.git' | ||||
| ``` | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| Configuration example: | ||||
| 
 | ||||
| ```ruby | ||||
| Gitlab.configure do |config| | ||||
|   config.endpoint       = 'https://example.net/api/v3' # API endpoint URL, default: ENV['GITLAB_API_ENDPOINT'] | ||||
|   config.private_token  = 'qEsq1pt6HJPaNciie3MG'       # user's private token, default: ENV['GITLAB_API_PRIVATE_TOKEN'] | ||||
|   # Optional | ||||
|   # config.user_agent   = 'Custom User Agent'          # user agent, default: 'Gitlab Ruby Gem [version]' | ||||
|   # config.sudo         = 'user'                       # username for sudo mode, default: nil | ||||
| end | ||||
| ``` | ||||
| 
 | ||||
| (Note: If you are using Gitlab.com's hosted service, your endpoint will be `https://gitlab.com/api/v3`) | ||||
| 
 | ||||
| Usage examples: | ||||
| 
 | ||||
| ```ruby | ||||
| # set an API endpoint | ||||
| Gitlab.endpoint = 'http://example.net/api/v3' | ||||
| # => "http://example.net/api/v3" | ||||
| 
 | ||||
| # set a user private token | ||||
| Gitlab.private_token = 'qEsq1pt6HJPaNciie3MG' | ||||
| # => "qEsq1pt6HJPaNciie3MG" | ||||
| 
 | ||||
| # list projects | ||||
| Gitlab.projects(:per_page => 5) | ||||
| # => [#<Gitlab::ObjectifiedHash:0x000000023326e0 @data={"id"=>1, "code"=>"brute", "name"=>"Brute", "description"=>nil, "path"=>"brute", "default_branch"=>nil, "owner"=>#<Gitlab::ObjectifiedHash:0x00000002331600 @data={"id"=>1, "email"=>"john@example.com", "name"=>"John Smith", "blocked"=>false, "created_at"=>"2012-09-17T09:41:56Z"}>, "private"=>true, "issues_enabled"=>true, "merge_requests_enabled"=>true, "wall_enabled"=>true, "wiki_enabled"=>true, "created_at"=>"2012-09-17T09:41:56Z"}>, #<Gitlab::ObjectifiedHash:0x000000023450d8 @data={"id"=>2, "code"=>"mozart", "name"=>"Mozart", "description"=>nil, "path"=>"mozart", "default_branch"=>nil, "owner"=>#<Gitlab::ObjectifiedHash:0x00000002344ca0 @data={"id"=>1, "email"=>"john@example.com", "name"=>"John Smith", "blocked"=>false, "created_at"=>"2012-09-17T09:41:56Z"}>, "private"=>true, "issues_enabled"=>true, "merge_requests_enabled"=>true, "wall_enabled"=>true, "wiki_enabled"=>true, "created_at"=>"2012-09-17T09:41:57Z"}>, #<Gitlab::ObjectifiedHash:0x00000002344958 @data={"id"=>3, "code"=>"gitlab", "name"=>"Gitlab", "description"=>nil, "path"=>"gitlab", "default_branch"=>nil, "owner"=>#<Gitlab::ObjectifiedHash:0x000000023447a0 @data={"id"=>1, "email"=>"john@example.com", "name"=>"John Smith", "blocked"=>false, "created_at"=>"2012-09-17T09:41:56Z"}>, "private"=>true, "issues_enabled"=>true, "merge_requests_enabled"=>true, "wall_enabled"=>true, "wiki_enabled"=>true, "created_at"=>"2012-09-17T09:41:58Z"}>] | ||||
| 
 | ||||
| # initialize a new client | ||||
| g = Gitlab.client(:endpoint => 'https://api.example.com', :private_token => 'qEsq1pt6HJPaNciie3MG') | ||||
| # => #<Gitlab::Client:0x00000001e62408 @endpoint="https://api.example.com", @private_token="qEsq1pt6HJPaNciie3MG", @user_agent="Gitlab Ruby Gem 2.0.0"> | ||||
| 
 | ||||
| # get a user | ||||
| user = g.user | ||||
| # => #<Gitlab::ObjectifiedHash:0x00000002217990 @data={"id"=>1, "email"=>"john@example.com", "name"=>"John Smith", "bio"=>nil, "skype"=>"", "linkedin"=>"", "twitter"=>"john", "dark_scheme"=>false, "theme_id"=>1, "blocked"=>false, "created_at"=>"2012-09-17T09:41:56Z"}> | ||||
| 
 | ||||
| # get a user's email | ||||
| user.email | ||||
| # => "john@example.com" | ||||
| 
 | ||||
| # set a sudo mode to perform API calls as another user | ||||
| Gitlab.sudo = 'other_user' | ||||
| # => "other_user" | ||||
| 
 | ||||
| # disable a sudo mode | ||||
| Gitlab.sudo = nil | ||||
| # => nil | ||||
| ``` | ||||
| 
 | ||||
| For more information, refer to [documentation](http://rubydoc.info/gems/gitlab/frames). | ||||
| 
 | ||||
| ## CLI | ||||
| 
 | ||||
| Usage examples: | ||||
| 
 | ||||
| ```sh | ||||
| # list users | ||||
| gitlab users | ||||
| 
 | ||||
| # get current user | ||||
| gitlab user | ||||
| 
 | ||||
| # get a user | ||||
| gitlab user 2 | ||||
| 
 | ||||
| # filter output | ||||
| gitlab user --only=id,username | ||||
| 
 | ||||
| gitlab user --except=email,bio | ||||
| ``` | ||||
| 
 | ||||
| ## CLI Shell | ||||
| 
 | ||||
| Usage examples: | ||||
| 
 | ||||
| ```sh | ||||
| # start shell session | ||||
| gitlab shell | ||||
| 
 | ||||
| # list available commands | ||||
| gitlab> help | ||||
| 
 | ||||
| # list groups | ||||
| gitlab> groups | ||||
| 
 | ||||
| # protect a branch | ||||
| gitlab> protect_branch 1 master | ||||
| ``` | ||||
| 
 | ||||
| For more information, refer to [website](http://narkoz.github.io/gitlab). | ||||
| 
 | ||||
| ## License | ||||
| 
 | ||||
| Released under the BSD 2-clause license. See LICENSE.txt for details. | ||||
| @ -0,0 +1,9 @@ | ||||
| require "bundler/gem_tasks" | ||||
| 
 | ||||
| require 'rspec/core/rake_task' | ||||
| RSpec::Core::RakeTask.new(:spec) do |spec| | ||||
|   spec.pattern    = FileList['spec/**/*_spec.rb'] | ||||
|   spec.rspec_opts = ['--color', '--format d'] | ||||
| end | ||||
| 
 | ||||
| task :default => :spec | ||||
| @ -0,0 +1,7 @@ | ||||
| #!/usr/bin/env ruby | ||||
| 
 | ||||
| $:.unshift File.expand_path('../../lib', __FILE__) | ||||
| 
 | ||||
| require 'gitlab/cli' | ||||
| 
 | ||||
| Gitlab::CLI.start(ARGV) | ||||
| @ -0,0 +1,26 @@ | ||||
| # -*- encoding: utf-8 -*- | ||||
| lib = File.expand_path('../lib', __FILE__) | ||||
| $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) | ||||
| require 'gitlab/version' | ||||
| 
 | ||||
| Gem::Specification.new do |gem| | ||||
|   gem.name          = "gitlab" | ||||
|   gem.version       = Gitlab::VERSION | ||||
|   gem.authors       = ["Nihad Abbasov"] | ||||
|   gem.email         = ["mail@narkoz.me"] | ||||
|   gem.description   = %q{Ruby client and CLI for GitLab API} | ||||
|   gem.summary       = %q{A Ruby wrapper and CLI for the GitLab API} | ||||
|   gem.homepage      = "https://github.com/narkoz/gitlab" | ||||
| 
 | ||||
|   gem.files         = `git ls-files`.split($/) | ||||
|   gem.executables   = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } | ||||
|   gem.test_files    = gem.files.grep(%r{^(test|spec|features)/}) | ||||
|   gem.require_paths = ["lib"] | ||||
| 
 | ||||
|   gem.add_runtime_dependency 'httparty' | ||||
|   gem.add_runtime_dependency 'terminal-table' | ||||
| 
 | ||||
|   gem.add_development_dependency 'rake' | ||||
|   gem.add_development_dependency 'rspec' | ||||
|   gem.add_development_dependency 'webmock' | ||||
| end | ||||
| @ -0,0 +1,37 @@ | ||||
| require 'gitlab/version' | ||||
| require 'gitlab/objectified_hash' | ||||
| require 'gitlab/configuration' | ||||
| require 'gitlab/error' | ||||
| require 'gitlab/request' | ||||
| require 'gitlab/api' | ||||
| require 'gitlab/client' | ||||
| 
 | ||||
| module Gitlab | ||||
|   extend Configuration | ||||
| 
 | ||||
|   # Alias for Gitlab::Client.new | ||||
|   # | ||||
|   # @return [Gitlab::Client] | ||||
|   def self.client(options={}) | ||||
|     Gitlab::Client.new(options) | ||||
|   end | ||||
| 
 | ||||
|   # Delegate to Gitlab::Client | ||||
|   def self.method_missing(method, *args, &block) | ||||
|     return super unless client.respond_to?(method) | ||||
|     client.send(method, *args, &block) | ||||
|   end | ||||
| 
 | ||||
|   # Delegate to Gitlab::Client | ||||
|   def self.respond_to?(method) | ||||
|     return client.respond_to?(method) || super | ||||
|   end | ||||
| 
 | ||||
|   # Returns an unsorted array of available client methods. | ||||
|   # | ||||
|   # @return [Array<Symbol>] | ||||
|   def self.actions | ||||
|     hidden = /endpoint|private_token|user_agent|sudo|get|post|put|\Adelete\z|validate|set_request_defaults/ | ||||
|     (Gitlab::Client.instance_methods - Object.methods).reject {|e| e[hidden]} | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,17 @@ | ||||
| module Gitlab | ||||
|   # @private | ||||
|   class API < Request | ||||
|     # @private | ||||
|     attr_accessor(*Configuration::VALID_OPTIONS_KEYS) | ||||
| 
 | ||||
|     # Creates a new API. | ||||
|     # @raise [Error:MissingCredentials] | ||||
|     def initialize(options={}) | ||||
|       options = Gitlab.options.merge(options) | ||||
|       Configuration::VALID_OPTIONS_KEYS.each do |key| | ||||
|         send("#{key}=", options[key]) | ||||
|       end | ||||
|       set_request_defaults @endpoint, @private_token, @sudo | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,47 @@ | ||||
| require 'gitlab' | ||||
| require 'terminal-table/import' | ||||
| require_relative 'cli_helpers' | ||||
| require_relative 'shell' | ||||
| 
 | ||||
| class Gitlab::CLI | ||||
|   extend Helpers | ||||
| 
 | ||||
|   def self.start(args) | ||||
|     command = args.shift.strip rescue 'help' | ||||
|     run(command, args) | ||||
|   end | ||||
| 
 | ||||
|   def self.run(cmd, args=[]) | ||||
|     case cmd | ||||
|     when 'help' | ||||
|       puts actions_table | ||||
|     when 'info' | ||||
|       endpoint = Gitlab.endpoint ? Gitlab.endpoint : 'not set' | ||||
|       private_token = Gitlab.private_token ? Gitlab.private_token : 'not set' | ||||
|       puts "Gitlab endpoint is #{endpoint}" | ||||
|       puts "Gitlab private token is #{private_token}" | ||||
|       puts "Ruby Version is #{RUBY_VERSION}" | ||||
|       puts "Gitlab Ruby Gem #{Gitlab::VERSION}" | ||||
|     when '-v', '--version' | ||||
|       puts "Gitlab Ruby Gem #{Gitlab::VERSION}" | ||||
|     when 'shell' | ||||
|       Gitlab::Shell.start | ||||
|     else | ||||
|       unless valid_command?(cmd) | ||||
|         puts "Unknown command. Run `gitlab help` for a list of available commands." | ||||
|         exit(1) | ||||
|       end | ||||
| 
 | ||||
|       if args.any? && (args.last.start_with?('--only=') || args.last.start_with?('--except=')) | ||||
|         command_args = args[0..-2] | ||||
|       else | ||||
|         command_args = args | ||||
|       end | ||||
| 
 | ||||
|       confirm_command(cmd) | ||||
| 
 | ||||
|       data = gitlab_helper(cmd, command_args) { exit(1) } | ||||
|       output_table(cmd, args, data) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,175 @@ | ||||
| class Gitlab::CLI | ||||
|   # Defines methods related to CLI output and formatting. | ||||
|   module Helpers | ||||
|     extend self | ||||
| 
 | ||||
|     # Returns filtered required fields. | ||||
|     # | ||||
|     # @return [Array] | ||||
|     def required_fields(args) | ||||
|       if args.any? && args.last.start_with?('--only=') | ||||
|         args.last.gsub('--only=', '').split(',') | ||||
|       else | ||||
|         [] | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Returns filtered excluded fields. | ||||
|     # | ||||
|     # @return [Array] | ||||
|     def excluded_fields(args) | ||||
|       if args.any? && args.last.start_with?('--except=') | ||||
|         args.last.gsub('--except=', '').split(',') | ||||
|       else | ||||
|         [] | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Confirms command is valid. | ||||
|     # | ||||
|     # @return [Boolean] | ||||
|     def valid_command?(cmd) | ||||
|       command = cmd.is_a?(Symbol) ? cmd : cmd.to_sym | ||||
|       Gitlab.actions.include?(command) | ||||
|     end | ||||
| 
 | ||||
|     # Confirms command with a desctructive action. | ||||
|     # | ||||
|     # @return [String] | ||||
|     def confirm_command(cmd) | ||||
|       if cmd.start_with?('remove_') || cmd.start_with?('delete_') | ||||
|         puts "Are you sure? (y/n)" | ||||
|         if %w(y yes).include?($stdin.gets.to_s.strip.downcase) | ||||
|           puts 'Proceeding..' | ||||
|         else | ||||
|           puts 'Command aborted.' | ||||
|           exit(1) | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Table with available commands. | ||||
|     # | ||||
|     # @return [String] | ||||
|     def actions_table | ||||
|       client = Gitlab::Client.new(endpoint: '') | ||||
|       actions = Gitlab.actions | ||||
|       methods = [] | ||||
| 
 | ||||
|       actions.each do |action| | ||||
|         methods << { | ||||
|           name: action, | ||||
|           owner: client.method(action).owner.to_s.gsub('Gitlab::Client::', '') | ||||
|         } | ||||
|       end | ||||
| 
 | ||||
|       owners = methods.map {|m| m[:owner]}.uniq.sort | ||||
|       methods_c = methods.group_by {|m| m[:owner]} | ||||
|       methods_c = methods_c.map {|_, v| [_, v.sort_by {|hv| hv[:name]}] } | ||||
|       methods_c = Hash[methods_c.sort_by(&:first).map {|k, v| [k, v]}] | ||||
|       max_column_length = methods_c.values.max_by(&:size).size | ||||
| 
 | ||||
|       rows = max_column_length.times.map do |i| | ||||
|         methods_c.keys.map do |key| | ||||
|           methods_c[key][i] ? methods_c[key][i][:name] : '' | ||||
|         end | ||||
|       end | ||||
| 
 | ||||
|       table do |t| | ||||
|         t.title = "Available commands (#{actions.size} total)" | ||||
|         t.headings = owners | ||||
| 
 | ||||
|         rows.each do |row| | ||||
|           t.add_row row | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Decides which table to use. | ||||
|     # | ||||
|     # @return [String] | ||||
|     def output_table(cmd, args, data) | ||||
|       case data | ||||
|       when Gitlab::ObjectifiedHash | ||||
|         puts single_record_table(data, cmd, args) | ||||
|       when Array | ||||
|         puts multiple_record_table(data, cmd, args) | ||||
|       else | ||||
|         puts data.inspect | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Table for a single record. | ||||
|     # | ||||
|     # @return [String] | ||||
|     def single_record_table(data, cmd, args) | ||||
|       hash = data.to_h | ||||
|       keys = hash.keys.sort {|x, y| x.to_s <=> y.to_s } | ||||
|       keys = keys & required_fields(args) if required_fields(args).any? | ||||
|       keys = keys - excluded_fields(args) | ||||
| 
 | ||||
|       table do |t| | ||||
|         t.title = "Gitlab.#{cmd} #{args.join(', ')}" | ||||
| 
 | ||||
|         keys.each_with_index do |key, index| | ||||
|           case value = hash[key] | ||||
|           when Hash | ||||
|             value = 'Hash' | ||||
|           when nil | ||||
|             value = 'null' | ||||
|           end | ||||
| 
 | ||||
|           t.add_row [key, value] | ||||
|           t.add_separator unless keys.size - 1 == index | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Table for multiple records. | ||||
|     # | ||||
|     # @return [String] | ||||
|     def multiple_record_table(data, cmd, args) | ||||
|       return 'No data' if data.empty? | ||||
| 
 | ||||
|       arr = data.map(&:to_h) | ||||
|       keys = arr.first.keys.sort {|x, y| x.to_s <=> y.to_s } | ||||
|       keys = keys & required_fields(args) if required_fields(args).any? | ||||
|       keys = keys - excluded_fields(args) | ||||
| 
 | ||||
|       table do |t| | ||||
|         t.title = "Gitlab.#{cmd} #{args.join(', ')}" | ||||
|         t.headings = keys | ||||
| 
 | ||||
|         arr.each_with_index do |hash, index| | ||||
|           values = [] | ||||
| 
 | ||||
|           keys.each do |key| | ||||
|             case value = hash[key] | ||||
|             when Hash | ||||
|               value = 'Hash' | ||||
|             when nil | ||||
|               value = 'null' | ||||
|             end | ||||
| 
 | ||||
|             values << value | ||||
|           end | ||||
| 
 | ||||
|           t.add_row values | ||||
|           t.add_separator unless arr.size - 1 == index | ||||
|         end | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Helper function to call Gitlab commands with args. | ||||
|     def gitlab_helper(cmd, args=[]) | ||||
|       begin | ||||
|         data = args.any? ? Gitlab.send(cmd, *args) : Gitlab.send(cmd) | ||||
|       rescue => e | ||||
|         puts e.message | ||||
|         yield if block_given? | ||||
|       end | ||||
| 
 | ||||
|       data | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,18 @@ | ||||
| module Gitlab | ||||
|   # Wrapper for the Gitlab REST API. | ||||
|   class Client < API | ||||
|     Dir[File.expand_path('../client/*.rb', __FILE__)].each {|f| require f} | ||||
| 
 | ||||
|     include Branches | ||||
|     include Groups | ||||
|     include Issues | ||||
|     include MergeRequests | ||||
|     include Milestones | ||||
|     include Notes | ||||
|     include Projects | ||||
|     include Repositories | ||||
|     include Snippets | ||||
|     include SystemHooks | ||||
|     include Users | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,79 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to repositories. | ||||
|   module Branches | ||||
|     # Gets a list of project repositiory branches. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.branches(42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def branches(project, options={}) | ||||
|       get("/projects/#{project}/repository/branches", :query => options) | ||||
|     end | ||||
|     alias_method :repo_branches, :branches | ||||
| 
 | ||||
|     # Gets information about a repository branch. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.branch(3, 'api') | ||||
|     #   Gitlab.repo_branch(5, 'master') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] branch The name of the branch. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def branch(project, branch) | ||||
|       get("/projects/#{project}/repository/branches/#{branch}") | ||||
|     end | ||||
|      | ||||
|     alias_method :repo_branch, :branch | ||||
| 
 | ||||
|     # Protects a repository branch. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.protect_branch(3, 'api') | ||||
|     #   Gitlab.repo_protect_branch(5, 'master') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] branch The name of the branch. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def protect_branch(project, branch) | ||||
|       put("/projects/#{project}/repository/branches/#{branch}/protect") | ||||
|     end | ||||
|     alias_method :repo_protect_branch, :protect_branch | ||||
| 
 | ||||
|     # Unprotects a repository branch. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.unprotect_branch(3, 'api') | ||||
|     #   Gitlab.repo_unprotect_branch(5, 'master') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] branch The name of the branch. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def unprotect_branch(project, branch) | ||||
|       put("/projects/#{project}/repository/branches/#{branch}/unprotect") | ||||
|     end | ||||
|     alias_method :repo_unprotect_branch, :unprotect_branch | ||||
| 
 | ||||
|     # Creates a repository branch.  Requires Gitlab >= 6.8.x | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_branch(3, 'api') | ||||
|     #   Gitlab.repo_create_branch(5, 'master') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] branch The name of the new branch. | ||||
|     # @param  [String] ref Create branch from commit sha or existing branch | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def create_branch(project, branch, ref) | ||||
|       post("/projects/#{project}/repository/branches",:body => {:branch_name => branch, :ref => ref}) | ||||
|     end | ||||
|     alias_method :repo_create_branch, :create_branch | ||||
| 
 | ||||
|   end | ||||
| end | ||||
| 
 | ||||
| @ -0,0 +1,88 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to groups. | ||||
|   module Groups | ||||
|     # Gets a list of groups. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.groups | ||||
|     #   Gitlab.groups(:per_page => 40) | ||||
|     # | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def groups(options={}) | ||||
|       get("/groups", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single group. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.group(42) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a group. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def group(id) | ||||
|       get("/groups/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new group. | ||||
|     # | ||||
|     # @param  [String] name The name of a group. | ||||
|     # @param  [String] path The path of a group. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created group. | ||||
|     def create_group(name, path) | ||||
|       body = {:name => name, :path => path} | ||||
|       post("/groups", :body => body) | ||||
|     end | ||||
| 
 | ||||
|     # Get a list of group members. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.group_members(1) | ||||
|     #   Gitlab.group_members(1, :per_page => 40) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a group. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def group_members(id, options={}) | ||||
|       get("/groups/#{id}/members", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Adds a user to group. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.add_group_member(1, 2, 40) | ||||
|     # | ||||
|     # @param  [Integer] team_id The group id to add a member to. | ||||
|     # @param  [Integer] user_id The user id of the user to add to the team. | ||||
|     # @param  [Integer] access_level Project access level. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about added team member. | ||||
|     def add_group_member(team_id, user_id, access_level) | ||||
|       post("/groups/#{team_id}/members", :body => {:user_id => user_id, :access_level => access_level}) | ||||
|     end | ||||
| 
 | ||||
|     # Removes user from user group. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.remove_group_member(1, 2) | ||||
|     # | ||||
|     # @param  [Integer] team_id The group ID. | ||||
|     # @param  [Integer] user_id The ID of a user. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about removed team member. | ||||
|     def remove_group_member(team_id, user_id) | ||||
|       delete("/groups/#{team_id}/members/#{user_id}") | ||||
|     end | ||||
| 
 | ||||
|     # Transfers a project to a group | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a group. | ||||
|     # @param  [Integer] project_id The ID of a project. | ||||
|     def transfer_project_to_group(id, project_id) | ||||
|       body = {:id => id, :project_id => project_id} | ||||
|       post("/groups/#{id}/projects/#{project_id}", :body => body) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,92 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to issues. | ||||
|   module Issues | ||||
|     # Gets a list of user's issues. | ||||
|     # Will return a list of project's issues if project ID passed. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.issues | ||||
|     #   Gitlab.issues(5) | ||||
|     #   Gitlab.issues(:per_page => 40) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def issues(project=nil, options={}) | ||||
|       if project.to_i.zero? | ||||
|         get("/issues", :query => options) | ||||
|       else | ||||
|         get("/projects/#{project}/issues", :query => options) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single issue. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.issue(5, 42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of an issue. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def issue(project, id) | ||||
|       get("/projects/#{project}/issues/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new issue. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] title The title of an issue. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :description The description of an issue. | ||||
|     # @option options [Integer] :assignee_id The ID of a user to assign issue. | ||||
|     # @option options [Integer] :milestone_id The ID of a milestone to assign issue. | ||||
|     # @option options [String] :labels Comma-separated label names for an issue. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created issue. | ||||
|     def create_issue(project, title, options={}) | ||||
|       body = {:title => title}.merge(options) | ||||
|       post("/projects/#{project}/issues", :body => body) | ||||
|     end | ||||
| 
 | ||||
|     # Updates an issue. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of an issue. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :title The title of an issue. | ||||
|     # @option options [String] :description The description of an issue. | ||||
|     # @option options [Integer] :assignee_id The ID of a user to assign issue. | ||||
|     # @option options [Integer] :milestone_id The ID of a milestone to assign issue. | ||||
|     # @option options [String] :labels Comma-separated label names for an issue. | ||||
|     # @option options [String] :state_event The state event of an issue ('close' or 'reopen'). | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about updated issue. | ||||
|     def edit_issue(project, id, options={}) | ||||
|       put("/projects/#{project}/issues/#{id}", :body => options) | ||||
|     end | ||||
| 
 | ||||
|     # Closes an issue. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.close_issue(3, 42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of an issue. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about closed issue. | ||||
|     def close_issue(project, id) | ||||
|       put("/projects/#{project}/issues/#{id}", :body => {:state_event => 'close'}) | ||||
|     end | ||||
| 
 | ||||
|     # Reopens an issue. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.reopen_issue(3, 42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of an issue. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about reopened issue. | ||||
|     def reopen_issue(project, id) | ||||
|       put("/projects/#{project}/issues/#{id}", :body => {:state_event => 'reopen'}) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,107 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to merge requests. | ||||
|   module MergeRequests | ||||
|     # Gets a list of project merge requests. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.merge_requests(5) | ||||
|     #   Gitlab.merge_requests(:per_page => 40) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def merge_requests(project, options={}) | ||||
|       get("/projects/#{project}/merge_requests", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single merge request. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.merge_request(5, 36) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a merge request. | ||||
|     # @return <Gitlab::ObjectifiedHash] | ||||
|     def merge_request(project, id) | ||||
|       get("/projects/#{project}/merge_request/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a merge request. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_merge_request(5, 'New merge request', | ||||
|     #     :source_branch => 'source_branch', :target_branch => 'target_branch') | ||||
|     #   Gitlab.create_merge_request(5, 'New merge request', | ||||
|     #     :source_branch => 'source_branch', :target_branch => 'target_branch', :assignee_id => 42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] title The title of a merge request. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :source_branch (required) The source branch name. | ||||
|     # @option options [String] :target_branch (required) The target branch name. | ||||
|     # @option options [Integer] :assignee_id (optional) The ID of a user to assign merge request. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created merge request. | ||||
|     def create_merge_request(project, title, options={}) | ||||
|       check_attributes!(options, [:source_branch, :target_branch]) | ||||
| 
 | ||||
|       body = {:title => title}.merge(options) | ||||
|       post("/projects/#{project}/merge_requests", :body => body) | ||||
|     end | ||||
| 
 | ||||
|     # Updates a merge request. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.update_merge_request(5, 42, :title => 'New title') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a merge request. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :title The title of a merge request. | ||||
|     # @option options [String] :source_branch The source branch name. | ||||
|     # @option options [String] :target_branch The target branch name. | ||||
|     # @option options [Integer] :assignee_id The ID of a user to assign merge request. | ||||
|     # @option options [String] :state_event New state (close|reopen|merge). | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about updated merge request. | ||||
|     def update_merge_request(project, id, options={}) | ||||
|       put("/projects/#{project}/merge_request/#{id}", :body => options) | ||||
|     end | ||||
| 
 | ||||
|     # Adds a comment to a merge request. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_merge_request_comment(5, 1, "Awesome merge!") | ||||
|     #   Gitlab.create_merge_request_comment('gitlab', 1, "Awesome merge!") | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a merge request. | ||||
|     # @param  [String] note The content of a comment. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created merge request comment. | ||||
|     def create_merge_request_comment(project, id, note) | ||||
|       post("/projects/#{project}/merge_request/#{id}/comments", :body => {:note => note}) | ||||
|     end | ||||
| 
 | ||||
|     # Gets the comments on a merge request. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.merge_request_comments(5, 1) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a merge request. | ||||
|     # @return [Gitlab::ObjectifiedHash] The merge request's comments. | ||||
|     def merge_request_comments(project, id) | ||||
|       get("/projects/#{project}/merge_request/#{id}/comments") | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def check_attributes!(options, attrs) | ||||
|       attrs.each do |attr| | ||||
|         unless options.has_key?(attr) || options.has_key?(attr.to_s) | ||||
|           raise Gitlab::Error::MissingAttributes.new("Missing '#{attr}' parameter") | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,57 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to milestones. | ||||
|   module Milestones | ||||
|     # Gets a list of project's milestones. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.milestones(5) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def milestones(project, options={}) | ||||
|       get("/projects/#{project}/milestones", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single milestone. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.milestone(5, 36) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a milestone. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def milestone(project, id) | ||||
|       get("/projects/#{project}/milestones/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new milestone. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] title The title of a milestone. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :description The description of a milestone. | ||||
|     # @option options [String] :due_date The due date of a milestone. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created milestone. | ||||
|     def create_milestone(project, title, options={}) | ||||
|       body = {:title => title}.merge(options) | ||||
|       post("/projects/#{project}/milestones", :body => body) | ||||
|     end | ||||
| 
 | ||||
|     # Updates a milestone. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a milestone. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :title The title of a milestone. | ||||
|     # @option options [String] :description The description of a milestone. | ||||
|     # @option options [String] :due_date The due date of a milestone. | ||||
|     # @option options [String] :state_event The state of a milestone ('close' or 'activate'). | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about updated milestone. | ||||
|     def edit_milestone(project, id, options={}) | ||||
|       put("/projects/#{project}/milestones/#{id}", :body => options) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,106 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to notes. | ||||
|   module Notes | ||||
|     # Gets a list of projects notes. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.notes(5) | ||||
|     # | ||||
|     # @param [Integer] project The ID of a project. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def notes(project) | ||||
|       get("/projects/#{project}/notes") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a list of notes for a issue. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.issue_notes(5, 10) | ||||
|     # | ||||
|     # @param [Integer] project The ID of a project. | ||||
|     # @param [Integer] issue The ID of an issue. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def issue_notes(project, issue) | ||||
|       get("/projects/#{project}/issues/#{issue}/notes") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a list of notes for a snippet. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.snippet_notes(5, 1) | ||||
|     # | ||||
|     # @param [Integer] project The ID of a project. | ||||
|     # @param [Integer] snippet The ID of a snippet. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def snippet_notes(project, snippet) | ||||
|       get("/projects/#{project}/snippets/#{snippet}/notes") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single wall note. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.note(5, 15) | ||||
|     # | ||||
|     # @param [Integer] project The ID of a project. | ||||
|     # @param [Integer] id The ID of a note. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def note(project, id) | ||||
|       get("/projects/#{project}/notes/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single issue note. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.issue_note(5, 10, 1) | ||||
|     # | ||||
|     # @param [Integer] project The ID of a project. | ||||
|     # @param [Integer] issue The ID of an issue. | ||||
|     # @param [Integer] id The ID of a note. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def issue_note(project, issue, id) | ||||
|       get("/projects/#{project}/issues/#{issue}/notes/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single snippet note. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.snippet_note(5, 11, 3) | ||||
|     # | ||||
|     # @param [Integer] project The ID of a project. | ||||
|     # @param [Integer] snippet The ID of a snippet. | ||||
|     # @param [Integer] id The ID of an note. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def snippet_note(project, snippet, id) | ||||
|       get("/projects/#{project}/snippets/#{snippet}/notes/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new wall note. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] body The body of a note. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created note. | ||||
|     def create_note(project, body) | ||||
|       post("/projects/#{project}/notes", :body => {:body => body}) | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new issue note. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] issue The ID of an issue. | ||||
|     # @param  [String] body The body of a note. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created note. | ||||
|     def create_issue_note(project, issue, body) | ||||
|       post("/projects/#{project}/issues/#{issue}/notes", :body => {:body => body}) | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new snippet note. | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] snippet The ID of a snippet. | ||||
|     # @param  [String] body The body of a note. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created note. | ||||
|     def create_snippet_note(project, snippet, body) | ||||
|       post("/projects/#{project}/snippets/#{snippet}/notes", :body => {:body => body}) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,300 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to projects. | ||||
|   module Projects | ||||
|     # Gets a list of projects owned by the authenticated user. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.projects | ||||
|     # | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @option options [String] :scope Scope of projects. 'owned' for list of projects owned by the authenticated user, 'all' to get all projects (admin only) | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def projects(options={}) | ||||
|       if (options[:scope]) | ||||
|         get("/projects/#{options[:scope]}", :query => options) | ||||
|       else | ||||
|         get("/projects", :query => options) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Gets information about a project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.project(3) | ||||
|     #   Gitlab.project('gitlab') | ||||
|     # | ||||
|     # @param  [Integer, String] id The ID or name of a project. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def project(id) | ||||
|       get("/projects/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a list of project events. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.project_events(42) | ||||
|     #   Gitlab.project_events('gitlab') | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def project_events(project, options={}) | ||||
|       get("/projects/#{project}/events", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_project('gitlab') | ||||
|     #   Gitlab.create_project('viking', :description => 'Awesome project') | ||||
|     #   Gitlab.create_project('Red', :wall_enabled => false) | ||||
|     # | ||||
|     # @param  [String] name The name of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :description The description of a project. | ||||
|     # @option options [String] :default_branch The default branch of a project. | ||||
|     # @option options [String] :group_id The group in which to create a project. | ||||
|     # @option options [String] :namespace_id The namespace in which to create a project. | ||||
|     # @option options [Boolean] :wiki_enabled The wiki integration for a project (0 = false, 1 = true). | ||||
|     # @option options [Boolean] :wall_enabled The wall functionality for a project (0 = false, 1 = true). | ||||
|     # @option options [Boolean] :issues_enabled The issues integration for a project (0 = false, 1 = true). | ||||
|     # @option options [Boolean] :snippets_enabled The snippets integration for a project (0 = false, 1 = true). | ||||
|     # @option options [Boolean] :merge_requests_enabled The merge requests functionality for a project (0 = false, 1 = true). | ||||
|     # @option options [Boolean] :public The setting for making a project public (0 = false, 1 = true). | ||||
|     # @option options [Integer] :user_id The user/owner id of a project. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created project. | ||||
|     def create_project(name, options={}) | ||||
|       url = options[:user_id] ? "/projects/user/#{options[:user_id]}" : "/projects" | ||||
|       post(url, :body => {:name => name}.merge(options)) | ||||
|     end | ||||
| 
 | ||||
|     # Deletes a project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.delete_project(4) | ||||
|     # | ||||
|     # @param  [Integer, String] id The ID or name of a project. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about deleted project. | ||||
|     def delete_project(id) | ||||
|       delete("/projects/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a list of project team members. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.team_members(42) | ||||
|     #   Gitlab.team_members('gitlab') | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :query The search query. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def team_members(project, options={}) | ||||
|       get("/projects/#{project}/members", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a project team member. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.team_member('gitlab', 2) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of a project team member. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def team_member(project, id) | ||||
|       get("/projects/#{project}/members/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Adds a user to project team. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.add_team_member('gitlab', 2, 40) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of a user. | ||||
|     # @param  [Integer] access_level The access level to project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about added team member. | ||||
|     def add_team_member(project, id, access_level) | ||||
|       post("/projects/#{project}/members", :body => {:user_id => id, :access_level => access_level}) | ||||
|     end | ||||
| 
 | ||||
|     # Updates a team member's project access level. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.edit_team_member('gitlab', 3, 20) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of a user. | ||||
|     # @param  [Integer] access_level The access level to project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] Information about updated team member. | ||||
|     def edit_team_member(project, id, access_level) | ||||
|       put("/projects/#{project}/members/#{id}", :body => {:access_level => access_level}) | ||||
|     end | ||||
| 
 | ||||
|     # Removes a user from project team. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.remove_team_member('gitlab', 2) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of a user. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about removed team member. | ||||
|     def remove_team_member(project, id) | ||||
|       delete("/projects/#{project}/members/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a list of project hooks. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.project_hooks(42) | ||||
|     #   Gitlab.project_hooks('gitlab') | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def project_hooks(project, options={}) | ||||
|       get("/projects/#{project}/hooks", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a project hook. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.project_hook(42, 5) | ||||
|     #   Gitlab.project_hook('gitlab', 5) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of a hook. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def project_hook(project, id) | ||||
|       get("/projects/#{project}/hooks/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Adds a new hook to the project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.add_project_hook(42, 'https://api.example.net/v1/webhooks/ci') | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [String] url The hook URL. | ||||
|     # @param  [Hash] options Events list (`{push_events: true, merge_requests_events: false}`). | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about added hook. | ||||
|     def add_project_hook(project, url, options = {}) | ||||
|       available_events = [:push_events, :merge_requests_events, :issues_events] | ||||
|       passed_events = available_events.select { |event| options[event] } | ||||
|       events = Hash[passed_events.map { |event| [event, options[event]] }] | ||||
| 
 | ||||
|       post("/projects/#{project}/hooks", :body => {:url => url}.merge(events)) | ||||
|     end | ||||
| 
 | ||||
|     # Updates a project hook URL. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.edit_project_hook(42, 1, 'https://api.example.net/v1/webhooks/ci') | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of the hook. | ||||
|     # @param  [String] url The hook URL. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about updated hook. | ||||
|     def edit_project_hook(project, id, url) | ||||
|       put("/projects/#{project}/hooks/#{id}", :body => {:url => url}) | ||||
|     end | ||||
| 
 | ||||
|     # Deletes a hook from project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.delete_project_hook('gitlab', 4) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [String] id The ID of the hook. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about deleted hook. | ||||
|     def delete_project_hook(project, id) | ||||
|       delete("/projects/#{project}/hooks/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Mark this project as forked from the other | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.make_forked(42, 24) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] id The ID of the project it is forked from. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about the forked project. | ||||
|     def make_forked_from(project, id) | ||||
|       post("/projects/#{project}/fork/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Remove a forked_from relationship for a project. | ||||
|     # | ||||
|     # @example | ||||
|     #  Gitlab.remove_forked(42) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID or name of a project. | ||||
|     # @param  [Integer] project The ID of the project it is forked from | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about the forked project. | ||||
|     def remove_forked(project) | ||||
|       delete("/projects/#{project}/fork") | ||||
|     end | ||||
| 
 | ||||
|     # Gets a project deploy keys. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.deploy_keys(42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def deploy_keys(project, options={}) | ||||
|       get("/projects/#{project}/keys", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a single project deploy key. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.deploy_key(42, 1) | ||||
|     # | ||||
|     # @param  [Integer, String] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a deploy key. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def deploy_key(project, id) | ||||
|       get("/projects/#{project}/keys/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new deploy key. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_deploy_key(42, 'My Key', 'Key contents') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] title The title of a deploy key. | ||||
|     # @param  [String] key The content of a deploy key. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created deploy key. | ||||
|     def create_deploy_key(project, title, key) | ||||
|       post("/projects/#{project}/keys", body: {title: title, key: key}) | ||||
|     end | ||||
| 
 | ||||
|     # Deletes a deploy key from project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.delete_deploy_key(42, 1) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a deploy key. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about deleted deploy key. | ||||
|     def delete_deploy_key(project, id) | ||||
|       delete("/projects/#{project}/keys/#{id}") | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,89 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to repositories. | ||||
|   module Repositories | ||||
| 
 | ||||
|     def trees(project, options={}) | ||||
|       get "/projects/#{project}/repository/tree", query: options | ||||
|     end | ||||
|     alias_method :repo_trees, :trees | ||||
| 
 | ||||
|     def files(project, file_path, ref) | ||||
|       get "/projects/#{project}/repository/files", query: {file_path: file_path, ref: ref} | ||||
|     end | ||||
|     alias_method :repo_files, :files | ||||
| 
 | ||||
|     # Gets a list of project repository tags. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.tags(42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def tags(project, options={}) | ||||
|       get("/projects/#{project}/repository/tags", :query => options) | ||||
|     end | ||||
|     alias_method :repo_tags, :tags | ||||
| 
 | ||||
|     # Creates a new project repository tag. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_tag(42,'new_tag','master') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String]  tag_name The name of the new tag. | ||||
|     # @param  [String]  ref The ref (commit sha, branch name, or another tag) the tag will point to. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def create_tag(project, tag_name, ref) | ||||
|       post("/projects/#{project}/repository/tags", body: {tag_name: tag_name, ref: ref}) | ||||
|     end | ||||
|     alias_method :repo_create_tag, :create_tag | ||||
| 
 | ||||
|     # Gets a list of project commits. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.commits('viking') | ||||
|     #   Gitlab.repo_commits('gitlab', :ref_name => 'api') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :ref_name The branch or tag name of a project repository. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def commits(project, options={}) | ||||
|       get("/projects/#{project}/repository/commits", :query => options) | ||||
|     end | ||||
|     alias_method :repo_commits, :commits | ||||
| 
 | ||||
|     # Gets a specific commit identified by the commit hash or name of a branch or tag. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.commit(42, '6104942438c14ec7bd21c6cd5bd995272b3faff6') | ||||
|     #   Gitlab.repo_commit(3, 'ed899a2f4b50b4370feeea94676502b42383c746') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] sha The commit hash or name of a repository branch or tag | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def commit(project, sha) | ||||
|       get("/projects/#{project}/repository/commits/#{sha}") | ||||
|     end | ||||
|     alias_method :repo_commit, :commit | ||||
| 
 | ||||
|     # Get the diff of a commit in a project. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.commit_diff(42, '6104942438c14ec7bd21c6cd5bd995272b3faff6') | ||||
|     #   Gitlab.repo_commit_diff(3, 'ed899a2f4b50b4370feeea94676502b42383c746') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [String] sha The name of a repository branch or tag or if not given the default branch. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def commit_diff(project, sha) | ||||
|       get("/projects/#{project}/repository/commits/#{sha}/diff")  | ||||
|     end | ||||
|     alias_method :repo_commit_diff, :commit_diff | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,86 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to snippets. | ||||
|   module Snippets | ||||
|     # Gets a list of project's snippets. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.snippets(42) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def snippets(project, options={}) | ||||
|       get("/projects/#{project}/snippets", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets information about a snippet. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.snippet(2, 14) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a snippet. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def snippet(project, id) | ||||
|       get("/projects/#{project}/snippets/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new snippet. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_snippet(42, {:title => 'REST', :file_name => 'api.rb', :code => 'some code'}) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :title (required) The title of a snippet. | ||||
|     # @option options [String] :file_name (required) The name of a snippet file. | ||||
|     # @option options [String] :code (required) The content of a snippet. | ||||
|     # @option options [String] :lifetime (optional) The expiration date of a snippet. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created snippet. | ||||
|     def create_snippet(project, options={}) | ||||
|       check_attributes!(options, [:title, :file_name, :code]) | ||||
|       post("/projects/#{project}/snippets", :body => options) | ||||
|     end | ||||
| 
 | ||||
|     # Updates a snippet. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.edit_snippet(42, 34, :file_name => 'README.txt') | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a snippet. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :title The title of a snippet. | ||||
|     # @option options [String] :file_name The name of a snippet file. | ||||
|     # @option options [String] :code The content of a snippet. | ||||
|     # @option options [String] :lifetime The expiration date of a snippet. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about updated snippet. | ||||
|     def edit_snippet(project, id, options={}) | ||||
|       put("/projects/#{project}/snippets/#{id}", :body => options) | ||||
|     end | ||||
| 
 | ||||
|     # Deletes a snippet. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.delete_snippet(2, 14) | ||||
|     # | ||||
|     # @param  [Integer] project The ID of a project. | ||||
|     # @param  [Integer] id The ID of a snippet. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about deleted snippet. | ||||
|     def delete_snippet(project, id) | ||||
|       delete("/projects/#{project}/snippets/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     def check_attributes!(options, attrs) | ||||
|       attrs.each do |attr| | ||||
|         unless options.has_key?(attr) || options.has_key?(attr.to_s) | ||||
|           raise Gitlab::Error::MissingAttributes.new("Missing '#{attr}' parameter") | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,58 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to system hooks. | ||||
|   module SystemHooks | ||||
|     # Gets a list of system hooks. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.hooks | ||||
|     #   Gitlab.system_hooks | ||||
|     # | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def hooks(options={}) | ||||
|       get("/hooks", query: options) | ||||
|     end | ||||
|     alias_method :system_hooks, :hooks | ||||
| 
 | ||||
|     # Adds a new system hook. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.add_hook('http://example.com/hook') | ||||
|     #   Gitlab.add_system_hook('https://api.example.net/v1/hook') | ||||
|     # | ||||
|     # @param  [String] url The hook URL. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def add_hook(url) | ||||
|       post("/hooks", :body => {:url => url}) | ||||
|     end | ||||
|     alias_method :add_system_hook, :add_hook | ||||
| 
 | ||||
|     # Tests a system hook. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.hook(3) | ||||
|     #   Gitlab.system_hook(12) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a system hook. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def hook(id) | ||||
|       get("/hooks/#{id}") | ||||
|     end | ||||
|     alias_method :system_hook, :hook | ||||
| 
 | ||||
|     # Deletes a new system hook. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.delete_hook(3) | ||||
|     #   Gitlab.delete_system_hook(12) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a system hook. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def delete_hook(id) | ||||
|       delete("/hooks/#{id}") | ||||
|     end | ||||
|     alias_method :delete_system_hook, :delete_hook | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,123 @@ | ||||
| class Gitlab::Client | ||||
|   # Defines methods related to users. | ||||
|   module Users | ||||
|     # Gets a list of users. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.users | ||||
|     # | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def users(options={}) | ||||
|       get("/users", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets information about a user. | ||||
|     # Will return information about an authorized user if no ID passed. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.user | ||||
|     #   Gitlab.user(2) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a user. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def user(id=nil) | ||||
|       id.to_i.zero? ? get("/user") : get("/users/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new user. | ||||
|     # Requires authentication from an admin account. | ||||
|     # | ||||
|     # @param  [String] email The email of a user. | ||||
|     # @param  [String] password The password of a user. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] :name The name of a user. Defaults to email. | ||||
|     # @option options [String] :skype The skype of a user. | ||||
|     # @option options [String] :linkedin The linkedin of a user. | ||||
|     # @option options [String] :twitter The twitter of a user. | ||||
|     # @option options [Integer] :projects_limit The limit of projects for a user. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created user. | ||||
|     def create_user(email, password, options={}) | ||||
|       body = {:email => email, :password => password, :name => email}.merge(options) | ||||
|       post("/users", :body => body) | ||||
|     end | ||||
| 
 | ||||
|     # Updates a user. | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a user. | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [String] email The email of a user. | ||||
|     # @option options [String] password The password of a user. | ||||
|     # @option options [String] :name The name of a user. Defaults to email. | ||||
|     # @option options [String] :skype The skype of a user. | ||||
|     # @option options [String] :linkedin The linkedin of a user. | ||||
|     # @option options [String] :twitter The twitter of a user. | ||||
|     # @option options [Integer] :projects_limit The limit of projects for a user. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created user. | ||||
|     def edit_user(user_id, options={}) | ||||
|       put("/users/#{user_id}", :body => options) | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new user session. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.session('jack@example.com', 'secret12345') | ||||
|     # | ||||
|     # @param  [String] email The email of a user. | ||||
|     # @param  [String] password The password of a user. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     # @note This method doesn't require private_token to be set. | ||||
|     def session(email, password) | ||||
|       post("/session", :body => {:email => email, :password => password}) | ||||
|     end | ||||
| 
 | ||||
|     # Gets a list of user's SSH keys. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.ssh_keys | ||||
|     # | ||||
|     # @param  [Hash] options A customizable set of options. | ||||
|     # @option options [Integer] :page The page number. | ||||
|     # @option options [Integer] :per_page The number of results per page. | ||||
|     # @return [Array<Gitlab::ObjectifiedHash>] | ||||
|     def ssh_keys(options={}) | ||||
|       get("/user/keys", :query => options) | ||||
|     end | ||||
| 
 | ||||
|     # Gets information about SSH key. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.ssh_key(1) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a user's SSH key. | ||||
|     # @return [Gitlab::ObjectifiedHash] | ||||
|     def ssh_key(id) | ||||
|       get("/user/keys/#{id}") | ||||
|     end | ||||
| 
 | ||||
|     # Creates a new SSH key. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.create_ssh_key('key title', 'key body') | ||||
|     # | ||||
|     # @param  [String] title The title of an SSH key. | ||||
|     # @param  [String] key The SSH key body. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about created SSH key. | ||||
|     def create_ssh_key(title, key) | ||||
|       post("/user/keys", :body => {:title => title, :key => key}) | ||||
|     end | ||||
| 
 | ||||
|     # Deletes an SSH key. | ||||
|     # | ||||
|     # @example | ||||
|     #   Gitlab.delete_ssh_key(1) | ||||
|     # | ||||
|     # @param  [Integer] id The ID of a user's SSH key. | ||||
|     # @return [Gitlab::ObjectifiedHash] Information about deleted SSH key. | ||||
|     def delete_ssh_key(id) | ||||
|       delete("/user/keys/#{id}") | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,39 @@ | ||||
| module Gitlab | ||||
|   # Defines constants and methods related to configuration. | ||||
|   module Configuration | ||||
|     # An array of valid keys in the options hash when configuring a Gitlab::API. | ||||
|     VALID_OPTIONS_KEYS = [:endpoint, :private_token, :user_agent, :sudo, :httparty].freeze | ||||
| 
 | ||||
|     # The user agent that will be sent to the API endpoint if none is set. | ||||
|     DEFAULT_USER_AGENT = "Gitlab Ruby Gem #{Gitlab::VERSION}".freeze | ||||
| 
 | ||||
|     # @private | ||||
|     attr_accessor(*VALID_OPTIONS_KEYS) | ||||
| 
 | ||||
|     # Sets all configuration options to their default values | ||||
|     # when this module is extended. | ||||
|     def self.extended(base) | ||||
|       base.reset | ||||
|     end | ||||
| 
 | ||||
|     # Convenience method to allow configuration options to be set in a block. | ||||
|     def configure | ||||
|       yield self | ||||
|     end | ||||
| 
 | ||||
|     # Creates a hash of options and their values. | ||||
|     def options | ||||
|       VALID_OPTIONS_KEYS.inject({}) do |option, key| | ||||
|         option.merge!(key => send(key)) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Resets all configuration options to the defaults. | ||||
|     def reset | ||||
|       self.endpoint       = ENV['GITLAB_API_ENDPOINT'] | ||||
|       self.private_token  = ENV['GITLAB_API_PRIVATE_TOKEN'] | ||||
|       self.sudo           = nil | ||||
|       self.user_agent     = DEFAULT_USER_AGENT | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,42 @@ | ||||
| module Gitlab | ||||
|   module Error | ||||
|     # Custom error class for rescuing from all Gitlab errors. | ||||
|     class Error < StandardError; end | ||||
| 
 | ||||
|     # Raise when attributes are missing. | ||||
|     class MissingAttributes < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint credentials not configured. | ||||
|     class MissingCredentials < Error; end | ||||
| 
 | ||||
|     # Raised when impossible to parse response body. | ||||
|     class Parsing < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 400. | ||||
|     class BadRequest < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 401. | ||||
|     class Unauthorized < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 403. | ||||
|     class Forbidden < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 404. | ||||
|     class NotFound < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 405. | ||||
|     class MethodNotAllowed < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 409. | ||||
|     class Conflict < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 500. | ||||
|     class InternalServerError < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 502. | ||||
|     class BadGateway < Error; end | ||||
| 
 | ||||
|     # Raised when API endpoint returns the HTTP status code 503. | ||||
|     class ServiceUnavailable < Error; end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,44 @@ | ||||
| require 'gitlab' | ||||
| require 'gitlab/cli_helpers' | ||||
| 
 | ||||
| module Gitlab::Help | ||||
|   extend Gitlab::CLI::Helpers | ||||
| 
 | ||||
|   def self.get_help(methods,cmd=nil) | ||||
|     help = '' | ||||
| 
 | ||||
|     if cmd.nil? || cmd == 'help' | ||||
|       help = actions_table | ||||
|     else | ||||
|       ri_cmd = `which ri`.chomp | ||||
| 
 | ||||
|       if $? == 0 | ||||
|         namespace = methods.select {|m| m[:name] === cmd }.map {|m| m[:owner]+'.'+m[:name] }.shift | ||||
| 
 | ||||
|         if namespace | ||||
|           begin | ||||
|             ri_output = `#{ri_cmd} -T #{namespace} 2>&1`.chomp | ||||
| 
 | ||||
|             if $? == 0 | ||||
|               ri_output.gsub!(/#{cmd}\((.*?)\)/, cmd+' \1') | ||||
|               ri_output.gsub!(/Gitlab\./, 'gitlab> ') | ||||
|               ri_output.gsub!(/Gitlab\..+$/, '') | ||||
|               ri_output.gsub!(/\,\s?/, ' ') | ||||
|               help = ri_output | ||||
|             else | ||||
|               help = "Ri docs not found for #{namespace}, please install the docs to use 'help'" | ||||
|             end | ||||
|           rescue => e | ||||
|             puts e.message | ||||
|           end | ||||
|         else | ||||
|           help = "Unknown command: #{cmd}" | ||||
|         end | ||||
|       else | ||||
|         help = "'ri' tool not found in your PATH, please install it to use the help." | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     puts help | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,24 @@ | ||||
| module Gitlab | ||||
|   # Converts hashes to the objects. | ||||
|   class ObjectifiedHash | ||||
|     # Creates a new ObjectifiedHash object. | ||||
|     def initialize(hash) | ||||
|       @hash = hash | ||||
|       @data = hash.inject({}) do |data, (key,value)| | ||||
|         value = ObjectifiedHash.new(value) if value.is_a? Hash | ||||
|         data[key.to_s] = value | ||||
|         data | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def to_hash | ||||
|       @hash | ||||
|     end | ||||
|     alias_method :to_h, :to_hash | ||||
| 
 | ||||
|     # Delegate to ObjectifiedHash. | ||||
|     def method_missing(key) | ||||
|       @data.key?(key.to_s) ? @data[key.to_s] : nil | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,113 @@ | ||||
| require 'httparty' | ||||
| require 'json' | ||||
| 
 | ||||
| module Gitlab | ||||
|   # @private | ||||
|   class Request | ||||
|     include HTTParty | ||||
|     format :json | ||||
|     headers 'Accept' => 'application/json' | ||||
|     parser Proc.new { |body, _| parse(body) } | ||||
| 
 | ||||
|     attr_accessor :private_token | ||||
| 
 | ||||
|     # Converts the response body to an ObjectifiedHash. | ||||
|     def self.parse(body) | ||||
|       body = decode(body) | ||||
| 
 | ||||
|       if body.is_a? Hash | ||||
|         ObjectifiedHash.new body | ||||
|       elsif body.is_a? Array | ||||
|         body.collect! { |e| ObjectifiedHash.new(e) } | ||||
|       else | ||||
|         raise Error::Parsing.new "Couldn't parse a response body" | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Decodes a JSON response into Ruby object. | ||||
|     def self.decode(response) | ||||
|       begin | ||||
|         JSON.load response | ||||
|       rescue JSON::ParserError | ||||
|         raise Error::Parsing.new "The response is not a valid JSON" | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def get(path, options={}) | ||||
|       set_httparty_config(options) | ||||
|       set_private_token_header(options) | ||||
|       validate self.class.get(path, options) | ||||
|     end | ||||
| 
 | ||||
|     def post(path, options={}) | ||||
|       set_httparty_config(options) | ||||
|       set_private_token_header(options, path) | ||||
|       validate self.class.post(path, options) | ||||
|     end | ||||
| 
 | ||||
|     def put(path, options={}) | ||||
|       set_httparty_config(options) | ||||
|       set_private_token_header(options) | ||||
|       validate self.class.put(path, options) | ||||
|     end | ||||
| 
 | ||||
|     def delete(path, options={}) | ||||
|       set_httparty_config(options) | ||||
|       set_private_token_header(options) | ||||
|       validate self.class.delete(path, options) | ||||
|     end | ||||
| 
 | ||||
|     # Checks the response code for common errors. | ||||
|     # Returns parsed response for successful requests. | ||||
|     def validate(response) | ||||
|       case response.code | ||||
|         when 400; raise Error::BadRequest.new error_message(response) | ||||
|         when 401; raise Error::Unauthorized.new error_message(response) | ||||
|         when 403; raise Error::Forbidden.new error_message(response) | ||||
|         when 404; raise Error::NotFound.new error_message(response) | ||||
|         when 405; raise Error::MethodNotAllowed.new error_message(response) | ||||
|         when 409; raise Error::Conflict.new error_message(response) | ||||
|         when 500; raise Error::InternalServerError.new error_message(response) | ||||
|         when 502; raise Error::BadGateway.new error_message(response) | ||||
|         when 503; raise Error::ServiceUnavailable.new error_message(response) | ||||
|       end | ||||
| 
 | ||||
|       response.parsed_response | ||||
|     end | ||||
| 
 | ||||
|     # Sets a base_uri and default_params for requests. | ||||
|     # @raise [Error::MissingCredentials] if endpoint not set. | ||||
|     def set_request_defaults(endpoint, private_token, sudo=nil) | ||||
|       raise Error::MissingCredentials.new("Please set an endpoint to API") unless endpoint | ||||
|       @private_token = private_token | ||||
| 
 | ||||
|       self.class.base_uri endpoint | ||||
|       self.class.default_params :sudo => sudo | ||||
|       self.class.default_params.delete(:sudo) if sudo.nil? | ||||
|     end | ||||
| 
 | ||||
|     private | ||||
| 
 | ||||
|     # Sets a PRIVATE-TOKEN header for requests. | ||||
|     # @raise [Error::MissingCredentials] if private_token not set. | ||||
|     def set_private_token_header(options, path=nil) | ||||
|       unless path == '/session' | ||||
|         raise Error::MissingCredentials.new("Please set a private_token for user") unless @private_token | ||||
|         options[:headers] = {'PRIVATE-TOKEN' => @private_token} | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     # Set HTTParty configuration | ||||
|     # @see https://github.com/jnunemaker/httparty | ||||
|     def set_httparty_config(options) | ||||
|       if self.httparty | ||||
|         options.merge!(self.httparty) | ||||
|       end | ||||
|     end | ||||
| 
 | ||||
|     def error_message(response) | ||||
|       "Server responded with code #{response.code}, message: #{response.parsed_response.message}. " \ | ||||
|       "Request URI: #{response.request.base_uri}#{response.request.path}" | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,51 @@ | ||||
| require 'gitlab' | ||||
| require 'gitlab/help' | ||||
| require 'gitlab/cli_helpers' | ||||
| require 'readline' | ||||
| 
 | ||||
| class Gitlab::Shell | ||||
|   extend Gitlab::CLI::Helpers | ||||
| 
 | ||||
|   def self.start | ||||
|     actions = Gitlab.actions | ||||
| 
 | ||||
|     comp = proc { |s| actions.map(&:to_s).grep(/^#{Regexp.escape(s)}/) } | ||||
| 
 | ||||
|     Readline.completion_proc = comp | ||||
|     Readline.completion_append_character = ' ' | ||||
| 
 | ||||
|     client = Gitlab::Client.new(endpoint: '') | ||||
| 
 | ||||
|     while buf = Readline.readline('gitlab> ', true) | ||||
|       next if buf.nil? || buf.empty? | ||||
|       break if buf == 'exit' | ||||
| 
 | ||||
|       buf = buf.scan(/["][^"]+["]|\S+/).map { |word| word.gsub(/^['"]|['"]$/,'') } | ||||
|       cmd = buf.shift | ||||
|       args = buf.count > 0 ? buf : [] | ||||
| 
 | ||||
|       if cmd == 'help' | ||||
|         methods = [] | ||||
| 
 | ||||
|         actions.each do |action| | ||||
|           methods << { | ||||
|             name: action.to_s, | ||||
|             owner: client.method(action).owner.to_s | ||||
|           } | ||||
|         end | ||||
| 
 | ||||
|         args[0].nil? ? Gitlab::Help.get_help(methods) : Gitlab::Help.get_help(methods, args[0]) | ||||
|         next | ||||
|       end | ||||
| 
 | ||||
|       data = if actions.include?(cmd.to_sym) | ||||
|         confirm_command(cmd) | ||||
|         gitlab_helper(cmd, args) | ||||
|       else | ||||
|         "'#{cmd}' is not a valid command.  See the 'help' for a list of valid commands." | ||||
|       end | ||||
| 
 | ||||
|       output_table(cmd, args, data) | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,3 @@ | ||||
| module Gitlab | ||||
|   VERSION = "3.2.0" | ||||
| end | ||||
| @ -0,0 +1 @@ | ||||
| {"name":"api","commit":{"id":"f7dd067490fe57505f7226c3b54d3127d2f7fd46","parents":[{"id":"949b1df930bedace1dbd755aaa4a82e8c451a616"}],"tree":"f8c4b21c036339f92fcc5482aa28a41250553b27","message":"API: expose issues project id","author":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"committer":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"authored_date":"2012-07-25T04:22:21-07:00","committed_date":"2012-07-25T04:22:21-07:00"},"protected": true} | ||||
| @ -0,0 +1 @@ | ||||
| [{"name":"api","commit":{"id":"f7dd067490fe57505f7226c3b54d3127d2f7fd46","parents":[{"id":"949b1df930bedace1dbd755aaa4a82e8c451a616"}],"tree":"f8c4b21c036339f92fcc5482aa28a41250553b27","message":"API: expose issues project id","author":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"committer":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"authored_date":"2012-07-25T04:22:21-07:00","committed_date":"2012-07-25T04:22:21-07:00"}},{"name":"dashboard-feed","commit":{"id":"f8f6ff065eccc6ede4d35ed87a09bb962b84ca25","parents":[{"id":"2cf8010792c3075824ee27d0f037aeb178cbbf7e"}],"tree":"e17f2157143d550891d4669c10b7446e4739bc6d","message":"add projects atom feed","author":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"committer":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"authored_date":"2012-05-31T23:42:02-07:00","committed_date":"2012-05-31T23:42:02-07:00"}},{"name":"master","commit":{"id":"2cf8010792c3075824ee27d0f037aeb178cbbf7e","parents":[{"id":"af226ae9c9af406c8a0e0bbdf364563495c2f432"},{"id":"e851cb07762aa464aae10e8b4b28de87c1a6f925"}],"tree":"6c6845838039f01723d91f395a1d2fa1dcc82522","message":"Merge pull request #868 from SaitoWu/bugfix/encoding\n\nBugfix/encoding","author":{"name":"Dmitriy Zaporozhets","email":"dmitriy.zaporozhets@gmail.com"},"committer":{"name":"Dmitriy Zaporozhets","email":"dmitriy.zaporozhets@gmail.com"},"authored_date":"2012-05-30T00:24:43-07:00","committed_date":"2012-05-30T00:24:43-07:00"}},{"name":"preview_notes","commit":{"id":"3749e0d99ac6bfbc65889b1b7a5310e14e7fe89a","parents":[{"id":"2483181f2c3d4ea7d2c68147b19bc07fc3937b0c"}],"tree":"f8c56161b0d6561568f088df9961362eb1ece88b","message":"pass project_id to notes preview path","author":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"committer":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"authored_date":"2012-08-09T23:46:27-07:00","committed_date":"2012-08-09T23:46:27-07:00"}},{"name":"refactoring","commit":{"id":"7c7761099cae83f59fe5780340e100be890847b2","parents":[{"id":"058d80b3363dd4fc4417ca4f60f76119188a2470"}],"tree":"d7d4a94c700dc0e84ee943019213d2358a49c413","message":"fix deprecation warnings","author":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"committer":{"name":"Nihad Abbasov","email":"narkoz.2008@gmail.com"},"authored_date":"2012-05-29T07:16:28-07:00","committed_date":"2012-05-29T07:16:28-07:00"}}] | ||||
| @ -0,0 +1 @@ | ||||
| {"note":"Cool Merge Request!","author":{"id":1,"username":"jsmith","email":"john@example.com","name":"John Smith","blocked":false,"created_at":"2012-07-11T01:32:18Z"}} | ||||
| @ -0,0 +1 @@ | ||||
| {"name":"api","commit":{ "id":"f7dd067490fe57505f7226c3b54d3127d2f7fd46","message":"API: expose issues project id","parent_ids":["949b1df930bedace1dbd755aaa4a82e8c451a616"],"authored_date":"2012-07-25T04:22:21-07:00","author_name":"Nihad Abbasov","author_email":"narkoz.2008@gmail.com","committed_date":"2012-07-25T04:22:21-07:00","committer_name":"Nihad Abbasov","committer_email":"narkoz.2008@gmail.com"},"protected": false} | ||||
| @ -0,0 +1 @@ | ||||
| {"id":2,"target_branch":"master","source_branch":"api","project_id":3,"title":"New feature","closed":false,"merged":false,"author":{"id":1,"email":"john@example.com","name":"John Smith","blocked":false,"created_at":"2012-10-19T05:56:05Z"},"assignee":{"id":2,"email":"jack@example.com","name":"Jack Smith","blocked":false,"created_at":"2012-10-19T05:56:14Z"}} | ||||
| @ -0,0 +1 @@ | ||||
| {"message": "409 Already exists"} | ||||
| @ -0,0 +1,60 @@ | ||||
| {"id": 10, "name": "GitLab-Group", "path": "gitlab-group", "owner_id": 6, "projects": [ | ||||
|     { | ||||
|         "id": 9, | ||||
|         "name": "mojito", | ||||
|         "description": null, | ||||
|         "default_branch": "master", | ||||
|         "owner": { | ||||
|             "id": 6, | ||||
|             "username": "jose", | ||||
|             "email": "jose@abc.com", | ||||
|             "name": "Jose Jose", | ||||
|             "blocked": false, | ||||
|             "created_at": "2013-02-06T06:54:06Z" | ||||
|         }, | ||||
|         "path": "mojito", | ||||
|         "path_with_namespace": "gitlab-group/mojito", | ||||
|         "issues_enabled": true, | ||||
|         "merge_requests_enabled": true, | ||||
|         "wall_enabled": true, | ||||
|         "wiki_enabled": true, | ||||
|         "created_at": "2013-02-06T16:59:15Z", | ||||
|         "namespace": { | ||||
|             "created_at": "2013-02-06T16:58:22Z", | ||||
|             "id": 10, | ||||
|             "name": "GitLab-Group", | ||||
|             "owner_id": 6, | ||||
|             "path": "gitlab-group", | ||||
|             "updated_at": "2013-02-06T16:58:22Z" | ||||
|         } | ||||
|     }, | ||||
|     { | ||||
|         "id": 10, | ||||
|         "name": "gitlabhq", | ||||
|         "description": null, | ||||
|         "default_branch": null, | ||||
|         "owner": { | ||||
|             "id": 6, | ||||
|             "username": "randx", | ||||
|             "email": "randx@github.com", | ||||
|             "name": "Dmitry Z", | ||||
|             "blocked": false, | ||||
|             "created_at": "2013-02-06T06:54:06Z" | ||||
|         }, | ||||
|         "path": "gitlabhq", | ||||
|         "path_with_namespace": "gitlab-group/gitlabhq", | ||||
|         "issues_enabled": true, | ||||
|         "merge_requests_enabled": true, | ||||
|         "wall_enabled": true, | ||||
|         "wiki_enabled": true, | ||||
|         "created_at": "2013-02-06T17:02:31Z", | ||||
|         "namespace": { | ||||
|             "created_at": "2013-02-06T16:58:22Z", | ||||
|             "id": 10, | ||||
|             "name": "GitLab-Group", | ||||
|             "owner_id": 6, | ||||
|             "path": "gitlab-group", | ||||
|             "updated_at": "2013-02-06T16:58:22Z" | ||||
|         } | ||||
|     } | ||||
| ]} | ||||
| @ -0,0 +1 @@ | ||||
| {"id":3,"name":"Gitlab-Group","path":"gitlab-group","owner_id":1} | ||||
| @ -0,0 +1 @@ | ||||
| {"id":2,"username":"jsmith","email":"jsmith@local.host","name":"John Smith","state":"active","created_at":"2013-09-04T18:15:30Z","access_level":10} | ||||
| @ -0,0 +1 @@ | ||||
| {"created_at":"2013-09-04T18:18:15Z","group_access":10,"group_id":3,"id":2,"notification_level":3,"updated_at":"2013-09-04T18:18:15Z","user_id":2} | ||||
| @ -0,0 +1 @@ | ||||
| [{"id":1,"username":"eraymond","email":"eraymond@local.host","name":"Edward Raymond","state":"active","created_at":"2013-08-30T16:16:22Z","access_level":50},{"id":1,"username":"jsmith","email":"jsmith@local.host","name":"John Smith","state":"active","created_at":"2013-08-30T16:16:22Z","access_level":50}] | ||||
| @ -0,0 +1,2 @@ | ||||
| [{"id": 3,"name": "ThreeGroup","path": "threegroup","owner_id": 1},{"id": 5,"name": "Five-Group","path": "five-group","owner_id": 2},{"id": 8,"name": "Eight Group","path": "eight-group","owner_id": 6} | ||||
| ] | ||||
Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue