jekyll-github-pages-gem 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ddae3765c69834ad6ce99f7877b24a82763b84091ef1a37f89e5cc59b9f33af9
4
- data.tar.gz: 5e870fffed02cb6406dad46486f2ee27c89b1a3e2974f4c017550c0f992c5631
3
+ metadata.gz: '098a19ac5d1add1794fdeefedfb016295cc8425252f6fef8d779131d607c6e6f'
4
+ data.tar.gz: ded2b48d54fb483856e8f68f513bc43f6684991ae840fa8a52484ecefa88cd58
5
5
  SHA512:
6
- metadata.gz: 89d97db24baa0f986183f43332e5932a29562057f2af5003bbd51a8e1a6de7f51227c5ee36c2d7ff13f4f30520d08f83bff8bb473b014b9ba1af4f7e573e9605
7
- data.tar.gz: b913a38f11818fc3b92180e14858d54f5c72b522ba278b7fd8d314bbba2a6f855c336558c99bbcfafa52fa3ef21f03fae106f1d6836b5f3cdfe0433ef8a3f453
6
+ metadata.gz: cd88085069bfbc591964cd4b2e88149fcaba6ecfc5d2b36d75c7bfe90362f13c8983ee1dcf641d17951eb580e4d106aa806796bc3a59a00d6caf9751ca00d22a
7
+ data.tar.gz: 17eec0bca32dfa3671f5b44c50a80bdd3cba86ac266487b66a4c3e9c96f882d86352760971b486e666e5558b739c3b2f0430af193a2d5daa42ebf7f5de13a14d
data/Gemfile CHANGED
@@ -3,7 +3,7 @@
3
3
  source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
- gem 'kramdown'
6
+ gem 'kramdown', '~> 2.3.0'
7
7
 
8
8
  gem 'octokit', '~> 4.18'
9
9
 
@@ -16,6 +16,8 @@ gem 'faraday', '~> 0.17.1'
16
16
 
17
17
  gem 'rake'
18
18
 
19
+ gem 'rdoc'
20
+
19
21
  group :test do
20
22
  gem 'minitest'
21
23
  gem 'mocha'
@@ -1,14 +1,17 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- jekyll-github-pages-gem (1.0.0)
4
+ jekyll-github-pages-gem (1.1.0)
5
+ carrierwave (>= 2.0.0.rc, < 3.0)
6
+ kramdown (~> 2.3.0)
7
+ octokit (~> 4.18)
5
8
 
6
9
  GEM
7
10
  remote: https://rubygems.org/
8
11
  specs:
9
- activemodel (6.0.3.1)
10
- activesupport (= 6.0.3.1)
11
- activesupport (6.0.3.1)
12
+ activemodel (6.0.3.2)
13
+ activesupport (= 6.0.3.2)
14
+ activesupport (6.0.3.2)
12
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
13
16
  i18n (>= 0.7, < 2)
14
17
  minitest (~> 5.1)
@@ -16,7 +19,7 @@ GEM
16
19
  zeitwerk (~> 2.2, >= 2.2.2)
17
20
  addressable (2.7.0)
18
21
  public_suffix (>= 2.0.2, < 5.0)
19
- ast (2.4.0)
22
+ ast (2.4.1)
20
23
  carrierwave (2.1.0)
21
24
  activemodel (>= 5.0.0)
22
25
  activesupport (>= 5.0.0)
@@ -24,43 +27,47 @@ GEM
24
27
  image_processing (~> 1.1)
25
28
  mimemagic (>= 0.3.0)
26
29
  mini_mime (>= 0.1.3)
27
- concurrent-ruby (1.1.6)
30
+ concurrent-ruby (1.1.7)
28
31
  docile (1.3.2)
29
32
  faraday (0.17.3)
30
33
  multipart-post (>= 1.2, < 3)
31
- ffi (1.12.2)
32
- ffi (1.12.2-x64-mingw32)
33
- i18n (1.8.2)
34
+ ffi (1.13.1-x64-mingw32)
35
+ i18n (1.8.5)
34
36
  concurrent-ruby (~> 1.0)
35
- image_processing (1.10.3)
37
+ image_processing (1.11.0)
36
38
  mini_magick (>= 4.9.5, < 5)
37
39
  ruby-vips (>= 2.0.17, < 3)
38
- jaro_winkler (1.5.4)
39
- kramdown (2.1.0)
40
- mimemagic (0.3.4)
40
+ kramdown (2.3.0)
41
+ rexml
42
+ mimemagic (0.3.5)
41
43
  mini_magick (4.10.1)
42
44
  mini_mime (1.0.2)
43
- minitest (5.14.0)
45
+ minitest (5.14.1)
44
46
  mocha (1.11.2)
45
47
  multipart-post (2.1.1)
46
48
  octokit (4.18.0)
47
49
  faraday (>= 0.9)
48
50
  sawyer (~> 0.8.0, >= 0.5.3)
49
- parallel (1.19.1)
50
- parser (2.7.1.0)
51
- ast (~> 2.4.0)
52
- public_suffix (4.0.4)
51
+ parallel (1.19.2)
52
+ parser (2.7.1.4)
53
+ ast (~> 2.4.1)
54
+ public_suffix (4.0.5)
53
55
  rainbow (3.0.0)
54
56
  rake (13.0.1)
57
+ rdoc (6.2.1)
58
+ regexp_parser (1.7.1)
55
59
  rexml (3.2.4)
56
- rubocop (0.81.0)
57
- jaro_winkler (~> 1.5.1)
60
+ rubocop (0.89.1)
58
61
  parallel (~> 1.10)
59
- parser (>= 2.7.0.1)
62
+ parser (>= 2.7.1.1)
60
63
  rainbow (>= 2.2.2, < 4.0)
64
+ regexp_parser (>= 1.7)
61
65
  rexml
66
+ rubocop-ast (>= 0.3.0, < 1.0)
62
67
  ruby-progressbar (~> 1.7)
63
68
  unicode-display_width (>= 1.4.0, < 2.0)
69
+ rubocop-ast (0.3.0)
70
+ parser (>= 2.7.1.4)
64
71
  ruby-progressbar (1.10.1)
65
72
  ruby-vips (2.0.17)
66
73
  ffi (~> 1.9)
@@ -75,21 +82,21 @@ GEM
75
82
  tzinfo (1.2.7)
76
83
  thread_safe (~> 0.1)
77
84
  unicode-display_width (1.7.0)
78
- zeitwerk (2.3.0)
85
+ zeitwerk (2.4.0)
79
86
 
80
87
  PLATFORMS
81
- ruby
82
88
  x64-mingw32
83
89
 
84
90
  DEPENDENCIES
85
91
  carrierwave (>= 2.0.0.rc, < 3.0)
86
92
  faraday (~> 0.17.1)
87
93
  jekyll-github-pages-gem!
88
- kramdown
94
+ kramdown (~> 2.3.0)
89
95
  minitest
90
96
  mocha
91
97
  octokit (~> 4.18)
92
98
  rake
99
+ rdoc
93
100
  rubocop (~> 0.71)
94
101
  simplecov
95
102
 
data/README.md CHANGED
@@ -9,8 +9,11 @@
9
9
  Our git flow process is typical--we have a master branch that gets released to the public, and feature branches for individual tasks. We don't have a development branch yet since this isn't used in production yet.
10
10
  If you have questions on how to contribute, please contact admin@msoe-sse.com or msoe.sg.hosting@gmail.com and we will get back to you at our earliest convenience.
11
11
 
12
+ ## Generating HTML Documentation
13
+ To generate HTML documentation for the Gem run the command `rake rdoc` and the HTML will then be available in the `html/` directory in the project.
14
+
12
15
  ## Continuous Integration
13
16
  There are checks that will be performed whenever Pull Requests are opened. To save time on the build server, please run the tests locally to check for errors that will occur in the CI builds.
14
17
 
15
- 1. To run [Rubocop](https://github.com/ashmaroli/rubocop-jekyll), run the command `bundle exec rubocop`
18
+ 1. To run [Rubocop](https://github.com/ashmaroli/rubocop-jekyll), run the command `bundle exec rubocop`. Note the command `bundle exec rubocop -a` will attempt to automatically fix any offenses found by rubocop but some still need to be resolved manually.
16
19
  2. To run all unit tests, run the command `rake`
data/Rakefile CHANGED
@@ -1,9 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'rake/testtask'
4
+ require 'rdoc/task'
4
5
 
5
6
  task default: 'test'
6
7
 
7
8
  Rake::TestTask.new do |t|
8
9
  t.test_files = FileList['tests/**/*_test.rb']
9
10
  end
11
+
12
+ RDoc::Task.new do |rdoc|
13
+ rdoc.rdoc_files.include('lib/**/*.rb')
14
+ end
@@ -2,10 +2,14 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = 'jekyll-github-pages-gem'
5
- s.version = '1.0.1'
5
+ s.version = '1.1.0'
6
6
  s.summary = 'A gem that uses the github API to make edits with a jekyll blog'
7
7
  s.files = Dir['*', 'lib/**/*']
8
8
  s.require_paths = ['lib']
9
9
  s.licenses = ['MIT']
10
10
  s.authors = ['MSOE SSE Web Team']
11
+ s.add_runtime_dependency('carrierwave', '>= 2.0.0.rc', '< 3.0')
12
+ s.add_runtime_dependency('kramdown', '~> 2.3.0')
13
+ s.add_runtime_dependency('octokit', '~> 4.18')
14
+ s.required_ruby_version = '>= 2.5.1'
11
15
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'kramdown'
4
+
5
+ module Factories
6
+ ##
7
+ # The base class for all jekyll factories
8
+ class BaseFactory
9
+ protected
10
+
11
+ def fix_header_syntax(text)
12
+ document = Kramdown::Document.new(text)
13
+ header_elements = document.root.children.select { |x| x.type == :header }
14
+ lines = text.split("\n")
15
+ lines = lines.map do |line|
16
+ if header_elements.any? { |x| line.include? x.options[:raw_text] }
17
+ # This regex matches the line into 2 groups with the first group being the repeating #
18
+ # characters and the beginning of the string and the second group being the rest of the string
19
+ line_match = line.match(/(#*)(.*)/)
20
+ line = "#{line_match.captures.first} #{line_match.captures.last.strip}"
21
+ else
22
+ line.delete("\r\n")
23
+ end
24
+ end
25
+ lines.join("\r\n")
26
+ end
27
+
28
+ def add_line_break_to_markdown_if_necessary(markdown)
29
+ lines = markdown.split("\n")
30
+ # The regular expression in the if statement looks for a markdown reference to a link like
31
+ # [logo]: https://ieeextreme.org/wp-content/uploads/2019/05/Xtreme_colour-e1557478323964.png
32
+ # If a post starts with that reference in jekyll followed by an image using that reference
33
+ # the line below will be interperted as a paragraph tag instead of an image tag. To fix that
34
+ # we add a line break to the start of the markdown.
35
+ return "\r\n#{markdown}" if lines.first&.match?(/\[(.*)\]: (.*)/)
36
+
37
+ markdown
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../models/page'
4
+
5
+ module Factories
6
+ ##
7
+ # This class is a factory for parsing page text and creating a correseponding page model
8
+ class PageFactory < BaseFactory
9
+ ##
10
+ # This method parses markdown in a page a returns a page model
11
+ #
12
+ # Params:
13
+ # +page_contents+::markdown in a given page
14
+ # +github_ref+::a sha for a ref indicating the head of a branch a page is pushed to on the GitHub server
15
+ # +pull_request_url+::a url to the pull request with the branch the pull request is pushed to on the GitHub server
16
+ def create_page(page_contents, github_ref, pull_request_url)
17
+ create_page_model(page_contents, github_ref, pull_request_url) if !page_contents.nil? && page_contents.is_a?(String)
18
+ end
19
+
20
+ ##
21
+ # This method takes parameters for a given page and formats them
22
+ # as a valid page for a Jekyll website
23
+ #
24
+ # Params:
25
+ # +text+:: the required markdown contents of the post
26
+ # +title+:: the required title of the post
27
+ # +permalink+:: the link to the page on a Jekyll website (e.g /about)
28
+ def create_jekyll_page_text(text, title, permalink)
29
+ header_converted_text = fix_header_syntax(text)
30
+ header_converted_text = add_line_break_to_markdown_if_necessary(header_converted_text)
31
+
32
+ %(---
33
+ layout: page
34
+ title: #{title}
35
+ permalink: #{permalink}
36
+ ---
37
+ #{header_converted_text})
38
+ end
39
+
40
+ private
41
+
42
+ def create_page_model(page_contents, github_ref, pull_request_url)
43
+ result = Page.new
44
+
45
+ result.github_ref = github_ref
46
+ result.pull_request_url = pull_request_url
47
+
48
+ # What this regular expression does is it matches three groups
49
+ # The first group represents the header of the page which appears
50
+ # between the two --- lines. The second group is for helping capture newline characters
51
+ # correctly and the third group is the actual page contents
52
+ match_obj = page_contents.match(/---(.*)---(\r\n|\r|\n)(.*)/m)
53
+ header = match_obj.captures[0]
54
+ parse_page_header(header, result)
55
+ result.contents = match_obj.captures[2]
56
+
57
+ result
58
+ end
59
+
60
+ def parse_page_header(header, page_model)
61
+ # The following regular expressions in this method look for specific properities
62
+ # located in the post header.
63
+ page_model.title = header.match(/title:\s*(.*)(\r\n|\r|\n)/).captures.first
64
+ page_model.permalink = header.match(/permalink:\s*(.*)(\r\n|\r|\n)/).captures.first
65
+ end
66
+ end
67
+ end
@@ -5,7 +5,7 @@ require_relative '../models/post'
5
5
  module Factories
6
6
  ##
7
7
  # This class is a factory for parsing post text and creating a correseponding post model
8
- class PostFactory
8
+ class PostFactory < BaseFactory
9
9
  LEAD = '{: .lead}'
10
10
  BREAK = '<!–-break-–>'
11
11
 
@@ -23,6 +23,50 @@ module Factories
23
23
  create_post_model(post_contents, file_path, ref) if !post_contents.nil? && post_contents.is_a?(String)
24
24
  end
25
25
 
26
+ ##
27
+ # This method takes parameters for a given post and formats them
28
+ # as a valid post for a Jekyll website
29
+ #
30
+ # Params:
31
+ # +text+:: the required markdown contents of the post
32
+ # +author+:: the required author of the post
33
+ # +title+:: the required title of the post
34
+ # +tags+:: optional tags specific to the post, defaults to nil
35
+ # +overlay+:: the optional overlay color of the post, defaults to nil
36
+ # +hero+:: a link to an optional background image for a post, defaults to nil
37
+ # +set_published_property+::an optional flag to set the published: true property for a post, defaults to false
38
+ # +append_lead_break_section+::an optional flag indicating whether to append to lead break section to a post, default to false
39
+ def create_jekyll_post_text(text, author, title, tags = nil, overlay = nil,
40
+ hero = nil, set_published_property = false, append_lead_break_section = false)
41
+ header_converted_text = fix_header_syntax(text)
42
+ header_converted_text = add_line_break_to_markdown_if_necessary(header_converted_text)
43
+
44
+ parsed_tags = nil
45
+ parsed_tags = format_tags(tags) if tags
46
+
47
+ tag_section = %(tags:
48
+ #{parsed_tags})
49
+
50
+ lead_break_section = "{: .lead}\r\n<!–-break-–>"
51
+
52
+ hero_to_use = hero
53
+ hero_to_use = DEFAULT_HERO if hero_to_use&.empty?
54
+ result = %(---
55
+ layout: post
56
+ title: #{title}
57
+ author: #{author}\r\n)
58
+
59
+ result += "#{tag_section}\r\n" unless !parsed_tags || parsed_tags.empty?
60
+ result += "hero: #{hero_to_use}\n" if hero_to_use
61
+ result += "overlay: #{overlay}\n" if overlay
62
+ result += "published: true\n" if set_published_property
63
+ result += "---\n"
64
+ result += "#{lead_break_section}\n" if append_lead_break_section
65
+ result += header_converted_text
66
+
67
+ result
68
+ end
69
+
26
70
  private
27
71
 
28
72
  def parse_tags(header)
@@ -34,6 +78,16 @@ module Factories
34
78
  result.join(', ')
35
79
  end
36
80
 
81
+ def format_tags(tags)
82
+ tag_array = tags.split(',')
83
+ result = ''
84
+ tag_array.each do |tag|
85
+ result += " - #{tag.strip}"
86
+ result += "\r\n" if tag != tag_array.last
87
+ end
88
+ result
89
+ end
90
+
37
91
  def create_post_model(post_contents, file_path, ref)
38
92
  result = Post.new
39
93
 
@@ -4,15 +4,17 @@
4
4
  require 'carrierwave'
5
5
 
6
6
  # Source Files
7
+ require 'factories/base_factory'
7
8
  require 'factories/post_factory'
8
- require 'services/post_services/base_post_service'
9
- require 'services/post_services/post_creation_service'
10
- require 'services/post_services/post_editing_service'
11
- require 'services/post_services/post_pull_request_editing_service'
12
- require 'services/github_service'
9
+ require 'factories/page_factory'
13
10
 
11
+ require 'services/base_editing_service'
12
+ require 'services/github_service'
14
13
  require 'services/kramdown_service'
14
+ require 'services/page_service'
15
+ require 'services/post_service'
15
16
 
17
+ require 'models/page'
16
18
  require 'models/post'
17
19
  require 'models/post_image_manager'
18
20
 
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # An object repsenting a page on a Jekyll website
5
+ class Page
6
+ attr_accessor :title
7
+ attr_accessor :permalink
8
+ attr_accessor :contents
9
+ # The GitHub ref the page's markdown is at. This is used to indicate
10
+ # whether a page is in PR or not
11
+ attr_accessor :github_ref
12
+ attr_accessor :pull_request_url
13
+ end
@@ -2,8 +2,8 @@
2
2
 
3
3
  module Services
4
4
  ##
5
- # The base class for service classes responsible for performing operations on posts
6
- class BasePostService
5
+ # The base class for service classes responsible for performing operations on the Jekyll website
6
+ class BaseEditingService
7
7
  def initialize(repo_name, access_token)
8
8
  @github_service = GithubService.new(repo_name, access_token)
9
9
  @kramdown_service = KramdownService.new
@@ -4,8 +4,6 @@ require 'octokit'
4
4
  require 'base64'
5
5
  require 'date'
6
6
  require 'cgi'
7
- require_relative 'kramdown_service'
8
- require_relative '../factories/post_factory'
9
7
 
10
8
  module Services
11
9
  ##
@@ -13,92 +11,13 @@ module Services
13
11
  class GithubService
14
12
  def initialize(full_repo_name, access_token)
15
13
  @full_repo_name = full_repo_name
16
- @access_token = access_token
17
-
18
- @kramdown_service = Services::KramdownService.new
19
- @post_factory = Factories::PostFactory.new
20
- end
21
-
22
- ##
23
- # This method fetches all the markdown contents of all the posts on a Jekyll website
24
- # that have been written and returns a list of models representing a Post.
25
- def get_all_posts
26
- result = []
27
- client = create_octokit_client
28
- posts = client.contents(@full_repo_name, path: '_posts')
29
- posts.each do |post|
30
- post_api_response = client.contents(@full_repo_name, path: post.path)
31
-
32
- post_model = create_post_from_api_response(post_api_response, nil)
33
- image_paths = @kramdown_service.get_all_image_paths(post_model.contents)
34
-
35
- images = []
36
- image_paths.each do |image_path|
37
- image_content = client.contents(@full_repo_name, path: image_path)
38
- images << create_post_image(image_path, image_content.content)
39
- end
40
-
41
- post_model.images = images
42
-
43
- result << post_model
44
- end
45
- result
46
- end
47
-
48
- ##
49
- # This method fetches all of the posts that have been written but have not been merged into master yet.
50
- def get_all_posts_in_pr(pr_body)
51
- result = []
52
- client = create_octokit_client
53
- pull_requests_for_user = get_open_jekyll_pull_requests(pr_body)
54
-
55
- pull_requests_for_user.each do |pull_request|
56
- pull_request_files = client.pull_request_files(@full_repo_name, pull_request[:number])
57
-
58
- post = nil
59
- images = []
60
- pull_request_files.each do |pull_request_file|
61
- contents_url_params = CGI.parse(pull_request_file[:contents_url])
62
-
63
- # The CGI.parse method returns a hash with the key being the URL and the value being an array of
64
- # URI parameters so in order to get the ref we need to grab the first value in the hash and the first
65
- # URI parameter in the first hash value
66
- ref = contents_url_params.values.first.first
67
- file_contents = client.contents(@full_repo_name, path: pull_request_file[:filename], ref: ref)
68
-
69
- if pull_request_file[:filename].end_with?('.md')
70
- post = create_post_from_api_response(file_contents, ref)
71
- result << post
72
- else
73
- images << create_post_image(pull_request_file[:filename], file_contents.content)
74
- end
75
- end
76
-
77
- post.images = images
78
- end
79
- result
80
- end
81
-
82
- ##
83
- # This method fetches a single post from a Jekyll website given a post title
84
- # and returns a Post model
85
- #
86
- # Params:
87
- # +title+:: A title of a Jekyll website post
88
- # +ref+::a sha for a ref indicating the head of a branch a post is pushed to on the GitHub server
89
- def get_post_by_title(title, ref)
90
- result = nil
91
- result = get_all_posts_in_pr.find { |x| x.title == title } if ref
92
- result = get_all_posts.find { |x| x.title == title } unless ref
93
- result&.images&.each { |x| PostImageManager.instance.add_downloaded_image(x) }
94
- result
14
+ @client = Octokit::Client.new(access_token: access_token)
95
15
  end
96
16
 
97
17
  ##
98
18
  # This method gets the sha of the commit at the head of master in a Jekyll website repo
99
19
  def get_master_head_sha
100
- client = create_octokit_client
101
- client.ref(@full_repo_name, 'heads/master')[:object][:sha]
20
+ @client.ref(@full_repo_name, 'heads/master')[:object][:sha]
102
21
  end
103
22
 
104
23
  ##
@@ -107,8 +26,7 @@ module Services
107
26
  # Params
108
27
  # +head_sha+::the sha of the head of a certain branch
109
28
  def get_base_tree_for_branch(head_sha)
110
- client = create_octokit_client
111
- client.commit(@full_repo_name, head_sha)[:commit][:tree][:sha]
29
+ @client.commit(@full_repo_name, head_sha)[:commit][:tree][:sha]
112
30
  end
113
31
 
114
32
  ##
@@ -117,8 +35,7 @@ module Services
117
35
  # Params
118
36
  # +text+::the text content to create a blob for
119
37
  def create_text_blob(text)
120
- client = create_octokit_client
121
- client.create_blob(@full_repo_name, text)
38
+ @client.create_blob(@full_repo_name, text)
122
39
  end
123
40
 
124
41
  ##
@@ -127,8 +44,7 @@ module Services
127
44
  # Params
128
45
  # +content+::the base 64 encoded content to create a blob for
129
46
  def create_base64_encoded_blob(content)
130
- client = create_octokit_client
131
- client.create_blob(@full_repo_name, content, 'base64')
47
+ @client.create_blob(@full_repo_name, content, 'base64')
132
48
  end
133
49
 
134
50
  ##
@@ -140,7 +56,6 @@ module Services
140
56
  # +file_information+::an array of hashes containing the file path and the blob sha for a file
141
57
  # +sha_base_tree+::the sha of the base tree
142
58
  def create_new_tree_with_blobs(file_information, sha_base_tree)
143
- client = create_octokit_client
144
59
  blob_information = []
145
60
  file_information.each do |file|
146
61
  # This mode property on this hash represents the file mode for a GitHub tree.
@@ -150,24 +65,24 @@ module Services
150
65
  type: 'blob',
151
66
  sha: file[:blob_sha] }
152
67
  end
153
- client.create_tree(@full_repo_name, blob_information, base_tree: sha_base_tree)[:sha]
68
+ @client.create_tree(@full_repo_name, blob_information, base_tree: sha_base_tree)[:sha]
154
69
  end
155
70
 
156
71
  ##
157
- # This method commits and pushes a tree to a Jekyll website repo
72
+ # This method commits and pushes a tree to a Jekyll website repo and returns the sha of the new commit
158
73
  #
159
74
  # Params:
160
75
  # +commit_message+::the message for the new commit
161
76
  # +tree_sha+::the sha of the tree to commit
162
77
  # +head_sha+::the sha of the head to commit from
163
78
  def commit_and_push_to_repo(commit_message, tree_sha, head_sha, ref_name)
164
- client = create_octokit_client
165
- sha_new_commit = client.create_commit(@full_repo_name, commit_message, tree_sha, head_sha)[:sha]
166
- client.update_ref(@full_repo_name, ref_name, sha_new_commit)
79
+ sha_new_commit = @client.create_commit(@full_repo_name, commit_message, tree_sha, head_sha)[:sha]
80
+ @client.update_ref(@full_repo_name, ref_name, sha_new_commit)
81
+ sha_new_commit
167
82
  end
168
83
 
169
84
  ##
170
- # This method creates a pull request for a branch in a Jekyll website repo
85
+ # This method creates a pull request for a branch in a Jekyll website repo and returns the url of the newly created pull request
171
86
  #
172
87
  # Params:
173
88
  # +source_branch+::the source branch for the PR
@@ -176,9 +91,9 @@ module Services
176
91
  # +pr_body+::the body for the PR
177
92
  # +reviewers+::an array of pull request reviewers for the PR
178
93
  def create_pull_request(source_branch, base_branch, pr_title, pr_body, reviewers)
179
- client = create_octokit_client
180
- pull_number = client.create_pull_request(@full_repo_name, base_branch, source_branch, pr_title, pr_body)[:number]
181
- client.request_pull_request_review(@full_repo_name, pull_number, reviewers: reviewers)
94
+ pull_request = @client.create_pull_request(@full_repo_name, base_branch, source_branch, pr_title, pr_body)
95
+ @client.request_pull_request_review(@full_repo_name, pull_request[:number], reviewers: reviewers)
96
+ pull_request[:html_url]
182
97
  end
183
98
 
184
99
  ##
@@ -189,10 +104,9 @@ module Services
189
104
  # +ref_name+:: the name of the branch to create if necessary
190
105
  # +master_head_sha+:: the sha representing the head of master
191
106
  def create_ref_if_necessary(ref_name, master_head_sha)
192
- client = create_octokit_client
193
- client.ref(@full_repo_name, ref_name)
107
+ @client.ref(@full_repo_name, ref_name)
194
108
  rescue Octokit::NotFound
195
- client.create_ref(@full_repo_name, ref_name, master_head_sha)
109
+ @client.create_ref(@full_repo_name, ref_name, master_head_sha)
196
110
  end
197
111
 
198
112
  ##
@@ -200,38 +114,71 @@ module Services
200
114
  # It will also strip off the starting refs portion of the name
201
115
  #
202
116
  # Params:
203
- # +oauth_token+::a user's oauth access token
204
117
  # +ref_sha+:: the sha of the ref to fetch
205
118
  def get_ref_name_by_sha(ref_sha)
206
- client = create_octokit_client
207
- ref_response = client.refs(@full_repo_name).find { |x| x[:object][:sha] == ref_sha }
119
+ ref_response = @client.refs(@full_repo_name).find { |x| x[:object][:sha] == ref_sha }
208
120
  ref_response[:ref].match(%r{refs/(.*)}).captures.first
209
121
  end
210
122
 
211
- private
123
+ ##
124
+ # This method will fetch and decode contents of a given file with text contents on GitHub.
125
+ # By default, it will fetch the file contents from the master branch unless a ref to a branch
126
+ # is supplied
127
+ #
128
+ # Params:
129
+ # +file_path+::the path to a file in a GitHub repo
130
+ # +ref+::an optional ref to a branch to fetch the file from
131
+ def get_text_contents_from_file(file_path, ref = nil)
132
+ api_contents = if ref
133
+ @client.contents(@full_repo_name, path: file_path, ref: ref)
134
+ else
135
+ @client.contents(@full_repo_name, path: file_path)
136
+ end
137
+ Base64.decode64(api_contents.content).dup.force_encoding('UTF-8')
138
+ end
212
139
 
213
- def create_post_from_api_response(post, ref)
214
- # Base64.decode64 will convert our string into a ASCII string
215
- # calling force_encoding('UTF-8') will fix that problem
216
- text_contents = Base64.decode64(post.content).dup.force_encoding('UTF-8')
217
- @post_factory.create_post(text_contents, post.path, ref)
140
+ ##
141
+ # This method will fetch the GitHub contents for a given file on GitHub via the GitHub
142
+ # contents API. The full response from the API will be returned
143
+ #
144
+ # Params:
145
+ # +path+::the path to a file in a GitHub repo
146
+ def get_contents_from_path(path)
147
+ @client.contents(@full_repo_name, path: path)
218
148
  end
219
149
 
220
- def get_open_jekyll_pull_requests(pull_request_body)
221
- client = create_octokit_client
222
- open_pull_requests = client.pull_requests(@full_repo_name, state: 'open')
223
- open_pull_requests.select { |x| x[:body] == pull_request_body }
150
+ ##
151
+ # This method will fetch all open pull requests for the current user matching a specific PR body
152
+ #
153
+ # Params:
154
+ # +pull_request_body+::the body of the PR to look for
155
+ def get_open_pull_requests_with_body(pull_request_body)
156
+ open_pull_requests = @client.pull_requests(@full_repo_name, state: 'open')
157
+ open_pull_requests.select { |x| x[:body] == pull_request_body && x[:user][:login] == @client.user[:login] }
224
158
  end
225
159
 
226
- def create_post_image(filename, contents)
227
- result = PostImage.new
228
- result.filename = filename
229
- result.contents = contents
230
- result
160
+ ##
161
+ # This method will fetch all pull request files for a given pull request
162
+ #
163
+ # Params:
164
+ # +pr_number+::the pull request number for the pull request to get all files for
165
+ def get_pr_files(pr_number)
166
+ @client.pull_request_files(@full_repo_name, pr_number)
231
167
  end
232
168
 
233
- def create_octokit_client
234
- Octokit::Client.new(access_token: @access_token)
169
+ ##
170
+ # Parses the URL for a file's contents to determine the ref of the file
171
+ # The ref is used to determine what branch the file is located on
172
+ #
173
+ # Params:
174
+ # +contents_url+::the contents url for a file in a GitHub repo
175
+ def get_ref_from_contents_url(contents_url)
176
+ contents_url_params = CGI.parse(contents_url)
177
+
178
+ # The CGI.parse method returns a hash with the key being the URL and the value being an array of
179
+ # URI parameters so in order to get the ref we need to grab the first value in the hash and the first
180
+ # URI parameter in the first hash value
181
+ contents_url_params.values.first.first
235
182
  end
236
183
  end
237
184
  end