class Copywriter
github-copywriter/octikit_wrapper.rb
Octokit wrapper for commiting multiple files to a GitHub repo.
Author: Ryan Jacobs <ryan.mjacobs@gmail.com>
github-copywriter/regex.rb
All of the regex that’s behind this amazing project :)
Author: Ryan Jacobs <ryan.mjacobs@gmail.com>
github-copywriter/version.rb
Author: Ryan Jacobs <ryan.mjacobs@gmail.com>
Constants
- COMMIT_MSG
- VERSION
Current version @return [String]
Public Class Methods
# File lib/github-copywriter.rb, line 20 def initialize(username, password) # Auth to GitHub Octokit.auto_paginate = true @client = Octokit::Client.new(:login => username, :password => password) # Check if the basic_auth worked. # TODO: Find a better way to do this # https://github.com/ryanmjacobs/github-copywriter/issues/1 begin @client.authorizations rescue Octokit::Unauthorized puts "error: Bad credentials.".red exit rescue Faraday::ConnectionFailed puts "error: Connection failed.".red exit end end
Public Instance Methods
# File lib/github-copywriter.rb, line 39 def run!(options={}) # Default options options = { all_repos: false, skip_forks: false, dry_run: false, year: nil, branches: nil }.merge(options) if options[:all_repos] then repos = @client.repositories() else repos = Array.new options[:repos].each do |r| name = @client.login+"/"+File.basename(r) if @client.repository?(name) then repos << @client.repository(name) else puts "error: repo \"#{name}\" does not exist!".red exit end end end # Get copyright year cur_year = options[:year] || Time.now.year # Loop through each repo repos.each do |repo| # Skip if repo is a fork and --skip-forks is on next if options[:skip_forks] and repo[:fork] # Repo name repo_name = repo[:full_name] puts "\n#{repo_name}:".cyan # Repo refs (branches) to loop through if options[:branches] == nil then # Get every single ref (branch) by default refs = @client.refs(repo_name, "heads").map { |r| r[:ref].sub("refs/", "") } else # User-supplied branches refs = options[:branches].map { |branch| "heads/#{branch}" } end # Loop through each ref refs.each do |ref| puts " #{ref}:".yellow # Grab the *whole* tree begin latest_commit = @client.ref(repo_name, ref).object root_tree = @client.commit(repo_name, latest_commit.sha).commit.tree whole_tree = @client.tree(repo_name, root_tree.sha, :recursive => true) rescue Octokit::NotFound puts "error: ref #{ref} not found.".red exit end # Warn the user about truncation if whole_tree[:truncated] then puts " warning: tree truncated because number of items exceeded limit.".yellow puts " If you feel like fixing this, see issue #xx".yellow puts " http://github.com/ryanmjacobs/github-copywriter/xx".yellow end # Stores updated files until we commit # @modified_files is a hash {:path, :content} @modified_files = Array.new # Loop through all of whole_tree's blobs whole_tree[:tree].each do |file| next if file[:type] != "blob" if Copywriter::Regex.accepted_name?(file[:path]) then # Grab file from repo file = @client.contents(repo_name, :path => file[:path], :ref => ref) if file[:type] != "file" then raise "error: #{file_path} on #{repo} is not a file!" end # Update the copyright new_content = Copywriter::Regex.update_copyright(cur_year, Base64.decode64(file[:content])) # Skip to the next file if we didn't even find a copyright in the text next if new_content[:copyrights_found] == 0 # Add to list of files to commit, only if the file has changed if new_content[:copyrights_updated] > 0 then @modified_files << {:path => file[:path], :content => new_content[:content]} puts " #{file[:path]} is now up-to-date.".green else puts " #{file[:path]} is already up-to-date." end end end # Commit stored up files if @modified_files.size > 0 then if @modified_files.size == 1 then print " Committing 1 file..." else print " Committing #{@modified_files.size} files..." end commit_files(repo_name, ref, "100644", @modified_files, COMMIT_MSG) puts " done! #{options[:dry_run] ? '(dry run)' : ''}" else puts " No files needed to be commited." end end end end
Private Instance Methods
Commits files to a GitHub repo. Requires @client to be already authorized with Copywriter.login!
@param repo Repo to commit to, e.g. “user/repo_name” @param ref Branch to commit to, e.g. “heads/master” @param file_mode Filemode on repo, e.g. “100644” @param files Array of {:path, :content} @param commit_msg Commit message, e.g. “Update file.rb”
@example
commit_files("user/repo", "heads/master", "100644", [{:path => "file.md", :content => "files content}], "modify file.md")
# File lib/github-copywriter/octikit_wrapper.rb, line 22 def commit_files(repo, ref, file_mode, files, commit_msg) # Return if we don't have any files to commit if files.size == 0 then return false end # Force file_mode to be either 100644 or 100775 if file_mode != "100644" or file_mode != "100775" then file_mode = "100644" end begin # Construct temp. tree of files to commit trees = Array.new files.each do |file| blob_sha = @client.create_blob(repo, Base64.encode64(file[:content]), "base64") trees << { :path => file[:path], :mode => file_mode, :type => "blob", :sha => blob_sha } end # Contruct the commit latest_commit = @client.ref(repo, ref).object base_tree = @client.commit(repo, latest_commit.sha).commit.tree new_tree = @client.create_tree(repo, trees, :base_tree => base_tree.sha) new_commit = @client.create_commit(repo, commit_msg, new_tree.sha, latest_commit.sha) # Commit it! @client.update_ref(repo, ref, new_commit.sha) return true rescue return false end end