github-to-canvas 0.1.5 → 0.1.7.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/github-to-canvas +47 -4
- data/lib/github-to-canvas.rb +68 -2
- data/lib/github-to-canvas/canvas_interface.rb +40 -9
- data/lib/github-to-canvas/github_interface.rb +1 -2
- data/lib/github-to-canvas/repository_converter.rb +53 -12
- data/lib/github-to-canvas/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53c9c96308fae1d78f27bc68e80fee55baf2ff23d381866edfd1d114b30601ec
|
4
|
+
data.tar.gz: bf7570a5be4657e102659454295beb72023864ceb20562b51858fa094997b5f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: adbf272b0121b81582d6520bc0c3881980276ede161cb97515d1792563cb29a603c93e7bf35790db1eacc89fb471b68127dccaf24fa43f3205cd758fa53739c2
|
7
|
+
data.tar.gz: 45182fbe2c428468ed967650a5e42ad496af4fa8dca236b61ec52ef9aa0ace3c209ece9a52eadd46849252a7dd6f9fa7c047a5017057bb96ca5143ee3155784a
|
data/bin/github-to-canvas
CHANGED
@@ -108,6 +108,10 @@ OptionParser.new do |opts|
|
|
108
108
|
"Adds additional Flatiron School HTML after markdown conversion") do |f|
|
109
109
|
options[:fis] = true
|
110
110
|
end
|
111
|
+
opts.on("-g", "--git-links",
|
112
|
+
"Adds additional GitHub after markdown conversion") do |f|
|
113
|
+
options[:git_links] = true
|
114
|
+
end
|
111
115
|
opts.on("--aaq",
|
112
116
|
"Adds AAQ flag to HTML header appended with --fis-links") do |aaq|
|
113
117
|
options[:aaq] = aaq
|
@@ -188,6 +192,15 @@ OptionParser.new do |opts|
|
|
188
192
|
"Escapes all HTML included in source markdown by replacing '<' and '>' with HTML charset values") do |html|
|
189
193
|
options[:contains_html] = html
|
190
194
|
end
|
195
|
+
opts.on("--canvas-to-canvas COURSE",
|
196
|
+
"Copies an existing Canvas lesson into another Canvas lesson") do |canvas_to_canvas|
|
197
|
+
options[:canvas_to_canvas] = canvas_to_canvas
|
198
|
+
end
|
199
|
+
opts.on("--build-from-csv CSV",
|
200
|
+
"Build a course usin a CSV of lesson repos, names, modules, and types") do |csv_build|
|
201
|
+
options[:csv_build] = csv_build
|
202
|
+
end
|
203
|
+
|
191
204
|
|
192
205
|
end.parse!
|
193
206
|
|
@@ -202,6 +215,16 @@ if options[:read_from_canvas]
|
|
202
215
|
abort
|
203
216
|
end
|
204
217
|
|
218
|
+
if options[:canvas_to_canvas]
|
219
|
+
GithubToCanvas.new(mode: 'canvas_copy',
|
220
|
+
filepath: options[:canvas_to_canvas],
|
221
|
+
course_id: options[:course_id],
|
222
|
+
type: options[:type],
|
223
|
+
id: options[:id]
|
224
|
+
)
|
225
|
+
abort
|
226
|
+
end
|
227
|
+
|
205
228
|
if options[:read_from_github]
|
206
229
|
GithubToCanvas.new(mode: 'github_read',
|
207
230
|
filepath: options[:read_from_github],
|
@@ -267,13 +290,29 @@ if options[:csv]
|
|
267
290
|
abort
|
268
291
|
end
|
269
292
|
|
293
|
+
if options[:csv_build]
|
294
|
+
GithubToCanvas.new(mode: 'csv_build',
|
295
|
+
file_to_convert: options[:csv_build],
|
296
|
+
course_id: options[:course_id],
|
297
|
+
fis_links: !!options[:fis],
|
298
|
+
remove_header_and_footer: !!options[:remove_header_and_footer],
|
299
|
+
aaq: !!options[:aaq],
|
300
|
+
forkable: !!options[:forkable],
|
301
|
+
branch: options[:branch],
|
302
|
+
contains_html: options[:contains_html],
|
303
|
+
git_links: !!options[:git_links])
|
304
|
+
abort
|
305
|
+
end
|
306
|
+
|
270
307
|
if options[:build_course]
|
271
308
|
GithubToCanvas.new(mode: 'build_course',
|
272
309
|
file_to_convert: options[:build_course],
|
273
310
|
fis_links: !!options[:fis],
|
274
311
|
remove_header_and_footer: !!options[:remove_header_and_footer],
|
275
312
|
aaq: !!options[:aaq],
|
276
|
-
forkable: !!options[:forkable]
|
313
|
+
forkable: !!options[:forkable],
|
314
|
+
contains_html: options[:contains_html],
|
315
|
+
git_links: !!options[:git_links])
|
277
316
|
abort
|
278
317
|
end
|
279
318
|
|
@@ -286,7 +325,8 @@ if options[:add_to_course]
|
|
286
325
|
remove_header_and_footer: !!options[:remove_header_and_footer],
|
287
326
|
forkable: !!options[:forkable],
|
288
327
|
aaq: !!options[:aaq],
|
289
|
-
contains_html: options[:contains_html]
|
328
|
+
contains_html: options[:contains_html],
|
329
|
+
git_links: !!options[:git_links])
|
290
330
|
else
|
291
331
|
puts '--course required'
|
292
332
|
end
|
@@ -300,7 +340,8 @@ if options[:update_course_lessons]
|
|
300
340
|
remove_header_and_footer: !!options[:remove_header_and_footer],
|
301
341
|
forkable: !!options[:forkable],
|
302
342
|
aaq: !!options[:aaq],
|
303
|
-
contains_html: options[:contains_html]
|
343
|
+
contains_html: options[:contains_html],
|
344
|
+
git_links: !!options[:git_links])
|
304
345
|
abort
|
305
346
|
end
|
306
347
|
|
@@ -360,6 +401,7 @@ if options[:create_lesson]
|
|
360
401
|
type: options[:type],
|
361
402
|
save_to_github: !!options[:save_to_github],
|
362
403
|
fis_links: !!options[:fis],
|
404
|
+
git_links: !!options[:git_links],
|
363
405
|
remove_header_and_footer: !!options[:remove_header_and_footer],
|
364
406
|
only_update_content: !!options[:only_content],
|
365
407
|
forkable: !!options[:forkable],
|
@@ -377,7 +419,8 @@ if options[:align]
|
|
377
419
|
name: options[:name],
|
378
420
|
type: options[:type],
|
379
421
|
save_to_github: !!options[:save_to_github],
|
380
|
-
fis_links: !!options[:fis],
|
422
|
+
fis_links: !!options[:fis],
|
423
|
+
git_links: !!options[:git_links],
|
381
424
|
remove_header_and_footer: !!options[:remove_header_and_footer],
|
382
425
|
only_update_content: !!options[:only_content],
|
383
426
|
forkable: !!options[:forkable],
|
data/lib/github-to-canvas.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'byebug'
|
2
|
+
require 'csv'
|
2
3
|
require_relative './github-to-canvas/create_canvas_lesson'
|
3
4
|
require_relative './github-to-canvas/update_canvas_lesson'
|
4
5
|
require_relative './github-to-canvas/canvas_dotfile'
|
@@ -26,6 +27,8 @@ class GithubToCanvas
|
|
26
27
|
CanvasInterface.csv(options[:file_to_convert])
|
27
28
|
when 'canvas_read'
|
28
29
|
puts CanvasInterface.read_lesson(options[:filepath])
|
30
|
+
when 'canvas_copy'
|
31
|
+
CanvasInterface.copy_lesson(options)
|
29
32
|
when 'github_read'
|
30
33
|
html = RepositoryConverter.remote_file_conversion(options)
|
31
34
|
puts RepositoryConverter.adjust_converted_html(options, html)
|
@@ -43,16 +46,25 @@ class GithubToCanvas
|
|
43
46
|
CanvasInterface.update_all_related_lessons(options, name, html)
|
44
47
|
|
45
48
|
when 'github_create'
|
49
|
+
if (!options[:branch])
|
50
|
+
options[:branch] = 'master'
|
51
|
+
end
|
46
52
|
html = RepositoryConverter.remote_file_conversion(options)
|
47
|
-
name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
|
48
|
-
html = RepositoryConverter.adjust_converted_html(options, html)
|
49
53
|
|
54
|
+
html = RepositoryConverter.adjust_converted_html(options, html)
|
55
|
+
name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
|
56
|
+
byebug
|
57
|
+
puts name
|
50
58
|
response = CanvasInterface.create_lesson(options, name, html)
|
51
59
|
|
52
60
|
puts "Canvas lesson created. Lesson available at #{response['html_url']}"
|
53
61
|
when 'github_align'
|
62
|
+
if (!options[:branch])
|
63
|
+
options[:branch] = 'master'
|
64
|
+
end
|
54
65
|
html = RepositoryConverter.remote_file_conversion(options)
|
55
66
|
name = options[:name] ? options[:name] : RepositoryInterface.get_name(options[:filepath], html)
|
67
|
+
|
56
68
|
html = RepositoryConverter.adjust_converted_html(options, html)
|
57
69
|
response = CanvasInterface.update_existing_lesson(options, name, html)
|
58
70
|
puts "Canvas lesson updated. Lesson available at #{response['html_url']}"
|
@@ -152,6 +164,60 @@ class GithubToCanvas
|
|
152
164
|
end
|
153
165
|
}
|
154
166
|
}
|
167
|
+
when 'csv_build'
|
168
|
+
if !options[:course_id]
|
169
|
+
course_info = {
|
170
|
+
name: "CSV Build Test",
|
171
|
+
course_code: "CSV-TEST"
|
172
|
+
}
|
173
|
+
created_course_info = CanvasInterface.create_course(course_info)
|
174
|
+
puts "Course created - #{created_course_info["id"]}"
|
175
|
+
puts "Make sure to add yourself as a teacher to this course before continuing, then press Enter/Return"
|
176
|
+
input = gets
|
177
|
+
options[:course_id] = created_course_info["id"]
|
178
|
+
else
|
179
|
+
puts "Adding to course #{options[:course_id]}"
|
180
|
+
end
|
181
|
+
|
182
|
+
csv_data = CSV.read(options[:file_to_convert])
|
183
|
+
created_module_info = {
|
184
|
+
"id" => "",
|
185
|
+
"name" => ""
|
186
|
+
}
|
187
|
+
|
188
|
+
csv_data.each { |lesson|
|
189
|
+
# lesson[0] == repo
|
190
|
+
# lesson[1] == name
|
191
|
+
# lesson[2] == module
|
192
|
+
# lesson[3] == type
|
193
|
+
# lesson[4] == yes/no contains HTML
|
194
|
+
module_info = {
|
195
|
+
name: lesson[2]
|
196
|
+
}
|
197
|
+
if created_module_info["name"] != module_info[:name]
|
198
|
+
created_module_info = CanvasInterface.create_module(options[:course_id], module_info)
|
199
|
+
puts "New module created - #{created_module_info["id"]} - #{created_module_info["name"]}"
|
200
|
+
end
|
201
|
+
|
202
|
+
options[:filepath] = lesson[0]
|
203
|
+
options[:name] = lesson[1]
|
204
|
+
options[:type] = lesson[3]
|
205
|
+
options[:branch] = "master" if !options[:branch]
|
206
|
+
if !options[:contains_html]
|
207
|
+
options[:contains_html] = (lesson[4] == "yes" || lesson[4] == "Yes") ? true : false
|
208
|
+
end
|
209
|
+
|
210
|
+
|
211
|
+
html = RepositoryConverter.remote_file_conversion(options)
|
212
|
+
html = RepositoryConverter.adjust_converted_html(options, html)
|
213
|
+
created_lesson_info = CanvasInterface.create_lesson(options, lesson[1], html)
|
214
|
+
created_lesson_info["page_url"] = created_lesson_info["url"] if !created_lesson_info["page_url"]
|
215
|
+
created_lesson_info["id"] = created_lesson_info["page_url"] if !created_lesson_info["id"]
|
216
|
+
created_lesson_info["type"] = options[:type]
|
217
|
+
puts "Creating lesson - #{options[:name]}"
|
218
|
+
response = CanvasInterface.add_to_module(options[:course_id], created_module_info, created_lesson_info)
|
219
|
+
|
220
|
+
}
|
155
221
|
else
|
156
222
|
puts VERSION
|
157
223
|
end
|
@@ -51,21 +51,21 @@ class CanvasInterface
|
|
51
51
|
# POST /api/v1/courses/:course_id/modules/:module_id/items
|
52
52
|
url = "#{ENV['CANVAS_API_PATH']}/courses/#{course_id}/modules/#{module_info["id"]}/items"
|
53
53
|
|
54
|
-
if lesson_info["type"] == "Page"
|
54
|
+
if lesson_info["type"] == "Page" || lesson_info["type"] == "page"
|
55
55
|
payload = {
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
56
|
+
'module_item[title]' => lesson_info["title"],
|
57
|
+
'module_item[type]' => lesson_info["type"].capitalize,
|
58
|
+
'module_item[indent]' => 0,
|
59
|
+
'module_item[page_url]' => lesson_info["id"],
|
60
|
+
'module_item[completion_requirement][type]' => 'must_view'
|
61
|
+
}
|
62
62
|
elsif lesson_info["type"] == "Quiz"
|
63
63
|
puts "Quiz needs to be added manually - #{lesson_info['title']} - lesson_info["
|
64
64
|
else
|
65
65
|
|
66
66
|
payload = {
|
67
67
|
'module_item[title]' => lesson_info["title"],
|
68
|
-
'module_item[type]' => lesson_info["type"],
|
68
|
+
'module_item[type]' => lesson_info["type"].capitalize,
|
69
69
|
'module_item[indent]' => 1,
|
70
70
|
'module_item[content_id]' => lesson_info["id"],
|
71
71
|
'module_item[completion_requirement][type]' => 'must_submit'
|
@@ -74,6 +74,8 @@ class CanvasInterface
|
|
74
74
|
begin
|
75
75
|
response = RestClient.post(url, payload, self.headers)
|
76
76
|
rescue
|
77
|
+
byebug
|
78
|
+
|
77
79
|
puts "Something went wrong while adding lesson #{lesson_info["id"]} to module #{module_info["id"]} in course #{course_id}" if lesson_info["type"] == "Assignment"
|
78
80
|
puts "Something went wrong while adding lesson #{lesson_info["page_url"]} to module #{module_info["id"]} in course #{course_id}" if lesson_info["type"] == "Page"
|
79
81
|
abort
|
@@ -340,8 +342,37 @@ class CanvasInterface
|
|
340
342
|
puts course_info.to_yaml
|
341
343
|
end
|
342
344
|
|
343
|
-
|
345
|
+
def self.copy_lesson(options)
|
346
|
+
types = ["page", "assignment", "quiz", "discussion"]
|
347
|
+
url = options[:filepath]
|
348
|
+
type = types.find {|type| url.match(type)}
|
349
|
+
options[:type] = type
|
350
|
+
if !url.include?(ENV['CANVAS_API_PATH'])
|
351
|
+
url = url.sub(/^.*\/\/.*?\//,"#{ENV['CANVAS_API_PATH']}/")
|
352
|
+
end
|
353
|
+
|
354
|
+
response = RestClient.get(url, headers={
|
355
|
+
"Authorization" => "Bearer #{ENV['CANVAS_API_KEY']}"
|
356
|
+
})
|
344
357
|
|
358
|
+
lesson_info = JSON.parse(response)
|
359
|
+
lesson_info = lesson_info.slice("title",
|
360
|
+
"name",
|
361
|
+
"description",
|
362
|
+
"body",
|
363
|
+
"message",
|
364
|
+
"shuffle_answers",
|
365
|
+
"allowed_attempts",
|
366
|
+
"question_count"
|
367
|
+
)
|
368
|
+
if options[:type] == "page"
|
369
|
+
self.update_existing_lesson(options, lesson_info["title"], lesson_info["body"])
|
370
|
+
else
|
371
|
+
self.update_existing_lesson(options, lesson_info["name"], lesson_info["description"])
|
372
|
+
end
|
373
|
+
|
374
|
+
|
375
|
+
end
|
345
376
|
|
346
377
|
def self.build_payload(options, name, html)
|
347
378
|
if options[:only_update_content]
|
@@ -27,9 +27,15 @@ class RepositoryConverter
|
|
27
27
|
markdown = GithubInterface.read_remote(options[:filepath])
|
28
28
|
raw_remote_url = self.set_raw_image_remote_url(options[:filepath])
|
29
29
|
if options[:contains_html]
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
begin
|
31
|
+
markdown = self.escape_existing_html(markdown)
|
32
|
+
rescue
|
33
|
+
puts "Error reading remote markdown"
|
34
|
+
abort
|
35
|
+
end
|
36
|
+
end
|
37
|
+
if (!options[:branch])
|
38
|
+
options[:branch] = 'master'
|
33
39
|
end
|
34
40
|
markdown = self.fix_local_images(options, markdown, raw_remote_url)
|
35
41
|
html = self.convert_to_html(markdown)
|
@@ -37,9 +43,10 @@ class RepositoryConverter
|
|
37
43
|
end
|
38
44
|
|
39
45
|
def self.convert_to_html(markdown)
|
40
|
-
|
46
|
+
renderer = CustomRender.new(escape_html: true, prettify: true, hard_wrap: true)
|
47
|
+
redcarpet = Redcarpet::Markdown.new(CustomRender, options={tables: true, autolink: true, fenced_code_blocks: true, disable_indented_code_blocks: true})
|
41
48
|
html = redcarpet.render(markdown)
|
42
|
-
self.remove_line_breaks(html)
|
49
|
+
# self.remove_line_breaks(html)
|
43
50
|
end
|
44
51
|
|
45
52
|
def self.adjust_converted_html(options, html)
|
@@ -48,7 +55,7 @@ class RepositoryConverter
|
|
48
55
|
html = self.remove_header_and_footer(html)
|
49
56
|
end
|
50
57
|
|
51
|
-
if options[:fis_links]
|
58
|
+
if options[:fis_links] || options[:git_links]
|
52
59
|
html = self.add_fis_links(options, html)
|
53
60
|
end
|
54
61
|
|
@@ -60,8 +67,31 @@ class RepositoryConverter
|
|
60
67
|
end
|
61
68
|
|
62
69
|
def self.fix_escaped_inline_html_code(html)
|
63
|
-
|
70
|
+
|
71
|
+
# stops HTML/JSX code blocks from rendering as HTML in Canvas
|
64
72
|
html = html.gsub("&gt;</code>", "></code>")
|
73
|
+
html = html.gsub("&gt;</code>", "></code>")
|
74
|
+
|
75
|
+
# fixes < and > code snippets
|
76
|
+
html = html.gsub("&lt;", "<")
|
77
|
+
html = html.gsub("&gt;", ">")
|
78
|
+
|
79
|
+
# # fixes blockquotes
|
80
|
+
# html = html.gsub(/\n<p>>\;(.*)\n>\;/) { |bq|
|
81
|
+
# bq.delete_prefix!("\n<p>>")
|
82
|
+
# "\n<blockquote>" + bq
|
83
|
+
# }
|
84
|
+
# html = html.gsub(/\n>\;(.*)\n>\;/) { |bq|
|
85
|
+
# bq.delete_prefix!("\n>")
|
86
|
+
# " " + bq
|
87
|
+
# }
|
88
|
+
# html = html.gsub(/\n>\;(.*)<\/p>/) { |bq|
|
89
|
+
# bq.delete_prefix!("\n>\;")
|
90
|
+
# bq.delete_suffix!("</p>")
|
91
|
+
# " " + bq + "</blockquote>"
|
92
|
+
# }
|
93
|
+
|
94
|
+
html
|
65
95
|
end
|
66
96
|
|
67
97
|
|
@@ -84,6 +114,9 @@ class RepositoryConverter
|
|
84
114
|
|
85
115
|
def self.remove_footer(readme)
|
86
116
|
readme.gsub(/<p class='util--hide'(.+?)<\/p>/,"")
|
117
|
+
readme.gsub(/<p data-visibility='hidden'(.+?)<\/p>/,"")
|
118
|
+
readme.gsub(/<p><\;p data-visibility='\;hidden'(.+?)<\/p>/,"")
|
119
|
+
readme.gsub(/<p><\;p class='util--hide'\;(.+?)<\/p>/,"")
|
87
120
|
end
|
88
121
|
|
89
122
|
def self.remove_html_header(html)
|
@@ -155,7 +188,12 @@ class RepositoryConverter
|
|
155
188
|
image_source = image_source.gsub(/(\'|\")/, "")
|
156
189
|
image_source = image_source.gsub(/src=/, '')
|
157
190
|
image_source = image_source.strip
|
158
|
-
|
191
|
+
|
192
|
+
begin
|
193
|
+
'src="' + raw_remote_url + '/' + branch + '/' + image_source + '"'
|
194
|
+
rescue
|
195
|
+
byebug
|
196
|
+
end
|
159
197
|
else
|
160
198
|
image_source
|
161
199
|
end
|
@@ -185,12 +223,12 @@ class RepositoryConverter
|
|
185
223
|
def self.add_fis_links(options, html)
|
186
224
|
repo_info = self.get_repo_info(options[:filepath])
|
187
225
|
html = html.sub(/<div id="git-data-element.*<header class="fis-header.*<\/header>/,'') # remove existing fis header
|
188
|
-
header = self.create_github_link_header(repo_info[:repo_path], options
|
226
|
+
header = self.create_github_link_header(repo_info[:repo_path], options)
|
189
227
|
data_element = self.create_data_element(repo_info[:repo_org], repo_info[:repo_name], options[:aaq])
|
190
228
|
data_element + header + html
|
191
229
|
end
|
192
230
|
|
193
|
-
def self.create_github_link_header(repo_path,
|
231
|
+
def self.create_github_link_header(repo_path, options)
|
194
232
|
# add link to associated repository
|
195
233
|
github_repo_link = "<a class='fis-git-link' href='#{repo_path}' target='_blank' rel='noopener'><img id='repo-img' title='Open GitHub Repo' alt='GitHub Repo' /></a>"
|
196
234
|
|
@@ -198,9 +236,12 @@ class RepositoryConverter
|
|
198
236
|
github_issue_link = "<a class='fis-git-link' href='#{repo_path}/issues/new' target='_blank' rel='noopener'><img id='issue-img' title='Create New Issue' alt='Create New Issue' /></a>"
|
199
237
|
|
200
238
|
# add link to fork (forking handled by separate Flatiron server, generation of link handled via custom Canvas JS theme file)
|
201
|
-
|
202
|
-
|
239
|
+
|
240
|
+
if (options[:forkable])
|
241
|
+
github_fork_link = "<a class='fis-fork-link' id='fork-link' href='#{repo_path}/fork' target='_blank' rel='noopener'><img id='fork-img' title='Fork This Assignment' alt='Fork This Assignment' /></a>"
|
203
242
|
"<header class='fis-header' style='visibility: hidden;'>#{github_fork_link}#{github_repo_link}#{github_issue_link}</header>"
|
243
|
+
elsif options[:git_links]
|
244
|
+
"<header class='fis-header'>#{github_repo_link}#{github_issue_link}</header>"
|
204
245
|
else
|
205
246
|
"<header class='fis-header' style='visibility: hidden;'>#{github_repo_link}#{github_issue_link}</header>"
|
206
247
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: github-to-canvas
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7.pre
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- maxwellbenton
|
@@ -104,11 +104,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
104
104
|
version: '0'
|
105
105
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
106
|
requirements:
|
107
|
-
- - "
|
107
|
+
- - ">"
|
108
108
|
- !ruby/object:Gem::Version
|
109
|
-
version:
|
109
|
+
version: 1.3.1
|
110
110
|
requirements: []
|
111
|
-
rubygems_version: 3.
|
111
|
+
rubygems_version: 3.2.3
|
112
112
|
signing_key:
|
113
113
|
specification_version: 4
|
114
114
|
summary: github-to-canvas is a tool for migrating and aligning GitHub content with
|