lessons_indexer 0.0.2.2 → 0.1.0
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/.rspec +1 -1
- data/.travis.yml +1 -1
- data/README.md +6 -5
- data/lessons_indexer.gemspec +3 -4
- data/lib/lessons_indexer.rb +14 -5
- data/lib/lessons_indexer/addons/file_manager.rb +26 -21
- data/lib/lessons_indexer/addons/git_manager.rb +25 -23
- data/lib/lessons_indexer/collections/base.rb +17 -0
- data/lib/lessons_indexer/collections/headings_list.rb +11 -0
- data/lib/lessons_indexer/collections/lessons_list.rb +6 -0
- data/lib/lessons_indexer/course.rb +37 -19
- data/lib/lessons_indexer/indexer.rb +24 -70
- data/lib/lessons_indexer/models/base.rb +25 -0
- data/lib/lessons_indexer/models/heading.rb +6 -0
- data/lib/lessons_indexer/models/lesson.rb +17 -0
- data/lib/lessons_indexer/options.rb +4 -4
- data/lib/lessons_indexer/starter.rb +3 -16
- data/lib/lessons_indexer/version.rb +1 -1
- data/spec/addons/file_manager_spec.rb +21 -23
- data/spec/addons/git_manager_spec.rb +23 -0
- data/spec/addons/utils_spec.rb +49 -51
- data/spec/collections/headings_list_spec.rb +28 -0
- data/spec/collections/lessons_list_spec.rb +16 -0
- data/spec/course_spec.rb +89 -0
- data/spec/indexer_spec.rb +83 -0
- data/spec/models/heading_spec.rb +28 -0
- data/spec/models/lesson_spec.rb +36 -0
- data/spec/options_spec.rb +21 -25
- data/spec/spec_helper.rb +2 -0
- data/spec/starter_spec.rb +9 -0
- data/spec/support/spec_files_setup.rb +19 -0
- data/spec/support/spec_samples.rb +38 -0
- data/spec/support/spec_utils.rb +11 -0
- metadata +41 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a7243e7160db8957d476986d9f39a7798a37f2b2
|
4
|
+
data.tar.gz: 99309f57fe10c2a1553d70f44d61a35626fd4a7d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e903f04e4067dd895c6d0883d0b8494b5c6e195f63f1bb71b82231a93b5f2a57145e8b23443ce81577d3ad3a71c14ef85445e5cfb805ecc0edf44c62483e777
|
7
|
+
data.tar.gz: aaeeed24149cc80a1382a2817bdadf12b07e97600512423a9f183dfd4be39b2fbd61f8f8eeba86ff41c4179724f083ea0d5910c5529dd71121837f59f73a86d8
|
data/.rspec
CHANGED
@@ -1 +1 @@
|
|
1
|
-
--color --format doc --order rand
|
1
|
+
--color --format doc --order rand --require spec_helper
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
|
-
[](http://badge.fury.io/rb/lessons_indexer)
|
2
|
+
[](https://travis-ci.org/bodrovis/lessons_indexer)
|
3
|
+
[](https://codeclimate.com/github/bodrovis/lessons_indexer)
|
4
|
+
[](https://codeclimate.com/github/bodrovis/lessons_indexer/coverage)
|
5
|
+
[](https://gemnasium.com/bodrovis/lessons_indexer)
|
5
6
|
# Lessons Indexer for Learnable
|
6
7
|
|
7
8
|
Builds an index in Markdown format for the lesson files in the provided directory, adds heading images to the files,
|
@@ -49,7 +50,7 @@ is not set.
|
|
49
50
|
* `-i` (`--headings`) - if present, heading images will be added to the beginning of each lesson file. If the file already
|
50
51
|
has a heading in the beginning, it will be skipped.
|
51
52
|
* `-d` (`--headings_dir`) - relative path to the directory with heading images.
|
52
|
-
Defaults to `
|
53
|
+
Defaults to `headings`, has no effect if the `-i` flag is not set.
|
53
54
|
|
54
55
|
## Some Assumptions
|
55
56
|
|
data/lessons_indexer.gemspec
CHANGED
@@ -19,8 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.add_dependency "facets", "~> 3.0"
|
20
20
|
spec.add_dependency "colorize", "~> 0.7.7"
|
21
21
|
|
22
|
-
spec.add_development_dependency "rake"
|
23
|
-
spec.add_development_dependency "rspec"
|
24
|
-
spec.add_development_dependency "
|
25
|
-
spec.add_development_dependency "codeclimate-test-reporter"
|
22
|
+
spec.add_development_dependency "rake", "~> 10.4"
|
23
|
+
spec.add_development_dependency "rspec", "~> 3.2"
|
24
|
+
spec.add_development_dependency "codeclimate-test-reporter", "~> 0.4"
|
26
25
|
end
|
data/lib/lessons_indexer.rb
CHANGED
@@ -2,14 +2,23 @@ require 'facets/string/titlecase'
|
|
2
2
|
require 'slop'
|
3
3
|
require 'colorize'
|
4
4
|
|
5
|
-
require 'lessons_indexer/version'
|
6
|
-
require 'lessons_indexer/starter'
|
7
|
-
require 'lessons_indexer/indexer'
|
8
|
-
require 'lessons_indexer/options'
|
9
|
-
require 'lessons_indexer/course'
|
10
5
|
require 'lessons_indexer/addons/file_manager'
|
11
6
|
require 'lessons_indexer/addons/git_manager'
|
12
7
|
require 'lessons_indexer/addons/utils'
|
13
8
|
|
9
|
+
require 'lessons_indexer/models/base'
|
10
|
+
require 'lessons_indexer/models/heading'
|
11
|
+
require 'lessons_indexer/models/lesson'
|
12
|
+
|
13
|
+
require 'lessons_indexer/collections/base'
|
14
|
+
require 'lessons_indexer/collections/headings_list'
|
15
|
+
require 'lessons_indexer/collections/lessons_list'
|
16
|
+
|
17
|
+
require 'lessons_indexer/version'
|
18
|
+
require 'lessons_indexer/options'
|
19
|
+
require 'lessons_indexer/course'
|
20
|
+
require 'lessons_indexer/indexer'
|
21
|
+
require 'lessons_indexer/starter'
|
22
|
+
|
14
23
|
module LessonsIndexer
|
15
24
|
end
|
@@ -1,28 +1,33 @@
|
|
1
1
|
module LessonsIndexer
|
2
|
-
|
3
|
-
|
2
|
+
module Addons
|
3
|
+
module FileManager
|
4
|
+
class Writer
|
5
|
+
attr_reader :name
|
4
6
|
|
5
|
-
|
6
|
-
|
7
|
-
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
end
|
8
10
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
def prepend_data(data)
|
12
|
+
begin
|
13
|
+
old_data = File.read(name)
|
14
|
+
rescue StandardError => e
|
15
|
+
warning `ls`
|
16
|
+
warning e.message
|
17
|
+
end
|
18
|
+
unless old_data.start_with?(data)
|
19
|
+
new_data = old_data.prepend(data)
|
20
|
+
self << new_data
|
21
|
+
end
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def <<(*args)
|
25
|
+
begin
|
26
|
+
File.open(name, 'w+') { |f| f.write(args.join) }
|
27
|
+
rescue StandardError => e
|
28
|
+
warning e.message
|
29
|
+
end
|
30
|
+
end
|
26
31
|
end
|
27
32
|
end
|
28
33
|
end
|
@@ -1,34 +1,36 @@
|
|
1
1
|
module LessonsIndexer
|
2
|
-
module
|
3
|
-
|
4
|
-
|
2
|
+
module Addons
|
3
|
+
module GitManager
|
4
|
+
class Pusher
|
5
|
+
attr_reader :message
|
5
6
|
|
6
|
-
|
7
|
-
|
8
|
-
|
7
|
+
def initialize(message)
|
8
|
+
@message = message
|
9
|
+
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
def push!
|
12
|
+
%x{git add .}
|
13
|
+
%x{git commit -am "#{message}"}
|
14
|
+
%x{git push origin HEAD}
|
15
|
+
end
|
14
16
|
end
|
15
|
-
end
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
class Brancher
|
19
|
+
attr_reader :ignore_master
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
def initialize(ignore_master = true)
|
22
|
+
@ignore_master = ignore_master
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
def get_branches
|
26
|
+
branches = %x{git branch}.split("\n").map {|br| br.strip.gsub(/\A\*\s*/, '') }
|
27
|
+
ignore_master ? branches.reject {|el| el == 'master'} : branches
|
28
|
+
end
|
28
29
|
|
29
|
-
|
30
|
-
|
31
|
-
|
30
|
+
def within_branch(branch)
|
31
|
+
%x{git checkout #{branch} --force}
|
32
|
+
yield if block_given?
|
33
|
+
end
|
32
34
|
end
|
33
35
|
end
|
34
36
|
end
|
@@ -1,32 +1,50 @@
|
|
1
1
|
module LessonsIndexer
|
2
2
|
class Course
|
3
|
-
|
3
|
+
include Models
|
4
|
+
include Collections
|
4
5
|
|
5
|
-
attr_reader :dir, :title, :lessons
|
6
|
+
attr_reader :dir, :headings_dir, :title, :lessons, :headings
|
6
7
|
|
7
|
-
def initialize(course_dir)
|
8
|
+
def initialize(course_dir, headings_dir)
|
8
9
|
@dir = course_dir
|
10
|
+
@headings_dir = headings_dir
|
9
11
|
@title = dir.gsub(/_handouts\z/i, '').titlecase
|
10
|
-
@
|
12
|
+
@headings = []
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
14
|
-
#
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
warning "Found the #{lesson} file which does not have proper naming. File name should contain lesson and step, for example: 'lesson3.2.md'. Skipping this file."
|
27
|
-
end
|
15
|
+
def generate_index
|
16
|
+
lessons.list.sort.inject("# Index for the " + title + " course\n\n") do |memo, lesson|
|
17
|
+
memo + lesson.link(dir)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate_headings
|
22
|
+
lessons.each do |lesson|
|
23
|
+
lesson_heading = headings.for(lesson)
|
24
|
+
if lesson_heading
|
25
|
+
yield "\n\n", lesson.path
|
26
|
+
else
|
27
|
+
warning "I was not able to find heading image for the #{lesson.name}"
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
31
|
+
|
32
|
+
def load_headings!
|
33
|
+
within(dir + '/' + headings_dir, true) do
|
34
|
+
@headings = HeadingsList.new(all_with_pattern(Heading::VERSION_PATTERN).map {|heading| Heading.new(heading)})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def load_lessons!
|
39
|
+
within(dir, true) do
|
40
|
+
@lessons = LessonsList.new(all_with_pattern(Lesson::NAME_PATTERN).map {|lesson| Lesson.new(lesson)})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def all_with_pattern(pattern)
|
47
|
+
Dir.entries('.').keep_if {|f| f =~ pattern }
|
48
|
+
end
|
31
49
|
end
|
32
50
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module LessonsIndexer
|
2
2
|
class Indexer
|
3
|
-
|
3
|
+
include Addons::FileManager
|
4
|
+
include Addons::GitManager
|
4
5
|
|
5
6
|
attr_reader :options
|
6
7
|
|
@@ -8,88 +9,36 @@ module LessonsIndexer
|
|
8
9
|
@options = options
|
9
10
|
end
|
10
11
|
|
11
|
-
def
|
12
|
-
course = Course.new(
|
13
|
-
with_messages("Starting to build index...", "Index for the #{course.title} course is generated!") do
|
14
|
-
generate_index_for course
|
15
|
-
end
|
16
|
-
end
|
12
|
+
def do_work!
|
13
|
+
course = Course.new(get_course_dir, options.headings_dir)
|
17
14
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
within(course.dir, true) do
|
22
|
-
generate_headings_for course
|
23
|
-
end
|
24
|
-
end
|
15
|
+
build_index(course) unless options.skip_index
|
16
|
+
add_headings(course) if options.headings
|
17
|
+
git_push! if options.git
|
25
18
|
end
|
26
19
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
course.lessons.each do |lesson_file|
|
33
|
-
step_lesson = lesson_file.match(STEP_LESSON_PATTERN)
|
34
|
-
begin
|
35
|
-
lesson_image = images.detect do |image|
|
36
|
-
step_image = image.match(STEP_LESSON_PATTERN)
|
37
|
-
step_lesson[1] == step_image[1] && step_lesson[2] == step_image[2]
|
38
|
-
end
|
39
|
-
if lesson_image
|
40
|
-
prepend!("\n\n", lesson_file)
|
41
|
-
else
|
42
|
-
warning "I was not able to find heading image for the lesson #{step_lesson[0]}"
|
43
|
-
end
|
44
|
-
rescue NoMethodError
|
45
|
-
warning "Found the #{lesson_file} file which does not have proper naming. File name should contain lesson and step, for example: 'lesson3.2.md'. Skipping this file."
|
46
|
-
end
|
20
|
+
def build_index(course)
|
21
|
+
course.load_lessons!
|
22
|
+
with_messages("Starting to build index...", "Index for the #{course.title} course is generated!") do
|
23
|
+
write! course.generate_index, options.output
|
47
24
|
end
|
48
25
|
end
|
49
26
|
|
50
|
-
def
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
)
|
56
|
-
end
|
57
|
-
|
58
|
-
def display_lesson_link(lesson, dir)
|
59
|
-
step = lesson.match(STEP_LESSON_PATTERN)
|
60
|
-
begin
|
61
|
-
"* [Lesson #{step[1]}.#{step[2]}](#{dir}/#{lesson})\n"
|
62
|
-
rescue NoMethodError
|
63
|
-
warning "Found the #{lesson} file which does not have proper naming. File name should contain lesson and step, for example: 'lesson3.2.md'. Skipping this file."
|
64
|
-
return ''
|
27
|
+
def add_headings(course)
|
28
|
+
course.load_lessons!
|
29
|
+
course.load_headings!
|
30
|
+
with_messages("Starting to add headings...", "Headings for the lesson files of #{course.title} course were added!") do
|
31
|
+
course.generate_headings { |heading_line, lesson_file| prepend!(heading_line, lesson_file) }
|
65
32
|
end
|
66
33
|
end
|
67
34
|
|
68
|
-
def
|
69
|
-
dir =
|
35
|
+
def get_course_dir
|
36
|
+
dir = Dir.entries('.').detect {|el| el =~ /_handouts\z/i}
|
70
37
|
exit_msg("Lesson files were not found inside the provided directory. Aborting...") if dir.nil?
|
71
38
|
dir
|
72
39
|
end
|
73
40
|
|
74
|
-
|
75
|
-
Dir.entries('.').delete_if {|f| f == '.' || f == '..' || f == '.git' || f == '.gitignore' }
|
76
|
-
end
|
77
|
-
|
78
|
-
def get_lessons
|
79
|
-
Dir.entries('.').keep_if {|f| f =~ /\.md\z/i }.sort do |a, b|
|
80
|
-
begin
|
81
|
-
step_a, step_b = a.match(STEP_LESSON_PATTERN), b.match(STEP_LESSON_PATTERN)
|
82
|
-
major_a, minor_a, major_b, minor_b = step_a[1].to_i, step_a[2].to_i, step_b[1].to_i, step_b[2].to_i
|
83
|
-
if major_a == major_b
|
84
|
-
minor_a <=> minor_b
|
85
|
-
else
|
86
|
-
major_a <=> major_b
|
87
|
-
end
|
88
|
-
rescue NoMethodError
|
89
|
-
warning "Found the #{lesson} file which does not have proper naming. File name should contain lesson and step, for example: 'lesson3.2.md'. Skipping this file."
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|
41
|
+
private
|
93
42
|
|
94
43
|
def write!(contents, file)
|
95
44
|
writer = Writer.new(file)
|
@@ -100,5 +49,10 @@ module LessonsIndexer
|
|
100
49
|
writer = Writer.new(file)
|
101
50
|
writer.prepend_data(contents)
|
102
51
|
end
|
52
|
+
|
53
|
+
def git_push!
|
54
|
+
pusher = Pusher.new(options.message)
|
55
|
+
pusher.push!
|
56
|
+
end
|
103
57
|
end
|
104
58
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module LessonsIndexer
|
2
|
+
module Models
|
3
|
+
class Base
|
4
|
+
include Comparable
|
5
|
+
|
6
|
+
VERSION_PATTERN = /(?<minor_major>(?<major>(\d+))(?:\.|-)(?<minor>(\d+)))/i
|
7
|
+
attr_reader :file_name, :major, :minor, :path
|
8
|
+
|
9
|
+
def initialize(file_name)
|
10
|
+
@file_name = file_name
|
11
|
+
@path = File.expand_path(file_name)
|
12
|
+
@major = file_name.match(VERSION_PATTERN)[:major].to_i
|
13
|
+
@minor = file_name.match(VERSION_PATTERN)[:minor].to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
def <=>(other)
|
17
|
+
if self.major == other.major
|
18
|
+
self.minor <=> other.minor
|
19
|
+
else
|
20
|
+
self.major <=> other.major
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|