Class: Pullcrusher::Pullcrusher

Inherits:
Object
  • Object
show all
Includes:
Methadone::CLILogging
Defined in:
lib/pullcrusher.rb

Defined Under Namespace

Classes: Results

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(authclient = nil) ⇒ Pullcrusher

Class constructor

authclient - An initialized Octokit client with authorization. If none is provided, a public client will be used (which cannot perform many actions)



32
33
34
35
36
37
38
39
# File 'lib/pullcrusher.rb', line 32

def initialize(authclient=nil)
  unless authclient.nil?
    @ok_client = authclient
    @github_username = authclient.
  else
    @ok_client = Octokit::Client.new
  end
end

Instance Attribute Details

#github_usernameObject

Returns the value of attribute github_username.



25
26
27
# File 'lib/pullcrusher.rb', line 25

def github_username
  @github_username
end

#ok_clientObject

Returns the value of attribute ok_client.



25
26
27
# File 'lib/pullcrusher.rb', line 25

def ok_client
  @ok_client
end

Instance Method Details

#clone_repo(repo_name) ⇒ Object

Clones a remote git repository to the local filesystem

uri - the URI of the remote git repository

Returns a Git object representing the repository in the local filesystem.



63
64
65
66
67
68
69
70
71
72
73
# File 'lib/pullcrusher.rb', line 63

def clone_repo(repo_name)
  FileUtils.mkdir_p('/tmp/pullcrusher')
  dirname = repo_name.gsub('/','-')
  target = "/tmp/pullcrusher/#{dirname}"
  uri = repo_from_shortname(repo_name).clone_url

  #check if tmp directory already exists, if so, clobber it
  FileUtils.remove_dir(target) if File.directory?(target)

  g = Git.clone(uri,target)
end

#fork_and_pull(fs_repo, repo_name, results) ⇒ Object

Fork and pull baby!

fs_repo - git handle to the filesystem repo repo_name - github style name as a string results - a Pullcrusher::Results object from the optimization

Returns nothing?



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/pullcrusher.rb', line 158

def fork_and_pull(fs_repo, repo_name, results)
  #DONE: commit changed files
  info "*** Git branching and commiting all changed files"
  fs_repo.branch('pullcrushed').checkout
  fs_repo.add('.')
  fs_repo.commit('Optimized image files via pullcrusher')

  #DONE: fork original repo (via octokit)
  info "*** Forking the original repo on github"
  fork = @ok_client.fork(repo_name)

  #DONE: add forked repo as a new remote to git repo (or just change default?)
  fs_repo.add_remote('myfork', fork.ssh_url)

  #DONE: push new commits to GH remote
  info "*** Pushing changes to your forked copy of the repo"
  fs_repo.push( fs_repo.remote('myfork'), 'pullcrushed' )

  info "*** Creating a pull request..."
  #def create_pull_request(repo, base, head, title, body, options={})
  pr = @ok_client.create_pull_request(
    repo_name,
    "master", #BASE
    "#{@github_username}:pullcrushed", #HEAD
    "Optimized image files via pullcrusher",
    "Hi there!  I've used [pullcrusher](http://github.com/mroth/pullcrusher) to optimize images for this this repository losslessly.\n\n
    #{results.filez_optimized} files were optimized for a total savings of #{results.bytes_saved} bytes."
  )
  info "*** Done! Pull request is at #{pr.html_url}"
end

#get_candidate_files(dir) ⇒ Object

Given a directory, identify any files that are possible candidates for optimization. This is naive, and only looks based on filename for now.

dir - the directory to recursively search for candidate files

Returns an array of file paths.



81
82
83
84
# File 'lib/pullcrusher.rb', line 81

def get_candidate_files(dir)
  Dir.chdir(dir)
  Dir.glob("**/*.{jpg,png,gif}")
end

#process_files(filez) ⇒ Object

Given a list of files, process with image_optim to optimized file size. Files are modified in place in file system.

filez - the list of filez to process

Returns a Results object with number of files optimized and bytes saved.



121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/pullcrusher.rb', line 121

def process_files(filez)
  #TODO: reject any files larger than MAXSIZE
  # perhaps use Enumerable reject for this!

  #
  # create an ImageOptim instance
  #
  io = ImageOptim.new(:pngout => false) #, :threads => THREADS)

  filez_optimized = 0
  bytes_saved = 0
  bytes_total = 0

  io.optimize_images!(filez) do |path,optimized|
    if optimized
      filez_optimized += 1
      size_after = File.size(path)
      size_before = optimized.original_size
      size_diff = size_before - size_after
      bytes_total += size_before
      bytes_saved += size_diff
      info "\t#{path}\n\t\t#{size_before} -> #{size_after} (#{size_diff} saved)"
    else
      info "\t#{path}"
    end
  end

  Results.new(:bytes_saved => bytes_saved, :filez_optimized => filez_optimized, :filez_candidates => filez.count)
end

#process_files_from_repo(fs_repo) ⇒ Object

Convenience method to take a Git repository object, identify and process

fs_repo - ruby-git object for the repo on filesystem

Returns a Results object



111
112
113
# File 'lib/pullcrusher.rb', line 111

def process_files_from_repo(fs_repo)
  process_files( get_candidate_files(fs_repo.dir.to_s) )
end

#process_repo(repo_name) ⇒ Object

Convenience method to take a repo by string name, and do all the processing.

repo_name - the github style repository name

Returns an array containing both a Results hash, and the fs_repo reference that was cloned



91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/pullcrusher.rb', line 91

def process_repo(repo_name)
  info "*** Asking GitHub to find us the URI for #{repo_name}"
  orig_repo = repo_from_shortname(repo_name)

  info "*** Cloning #{orig_repo.ssh_url} to local filesystem"
  fs_repo = clone_repo(repo_name)

  info "*** Finding and processing any candidate files"
  results = process_files_from_repo( fs_repo )

  info "*** #{results.filez_candidates} files processed, #{results.filez_optimized} successfully optimized for total savings of #{results.bytes_saved} bytes."
  return results, fs_repo
end

#repo_from_shortname(repo_name) ⇒ Object

Looks up a github style “username/repo” repository name

repo_name - the github style repository name

Returns a octokit repo object



54
55
56
# File 'lib/pullcrusher.rb', line 54

def repo_from_shortname(repo_name)
  @ok_client.repo(repo_name)
end