daigaku 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -3
- data/README.md +1 -1
- data/daigaku.gemspec +23 -26
- data/lib/daigaku.rb +0 -1
- data/lib/daigaku/chapter.rb +3 -4
- data/lib/daigaku/coloring.rb +13 -13
- data/lib/daigaku/configuration.rb +25 -28
- data/lib/daigaku/congratulator.rb +17 -5
- data/lib/daigaku/course.rb +9 -8
- data/lib/daigaku/exceptions.rb +0 -2
- data/lib/daigaku/generator.rb +13 -13
- data/lib/daigaku/github_client.rb +4 -4
- data/lib/daigaku/loadable.rb +11 -15
- data/lib/daigaku/loading/chapters.rb +0 -2
- data/lib/daigaku/loading/courses.rb +0 -2
- data/lib/daigaku/loading/units.rb +0 -2
- data/lib/daigaku/markdown.rb +1 -0
- data/lib/daigaku/markdown/printer.rb +89 -0
- data/lib/daigaku/markdown/ruby_doc.rb +6 -8
- data/lib/daigaku/solution.rb +18 -15
- data/lib/daigaku/storeable.rb +11 -12
- data/lib/daigaku/task.rb +1 -1
- data/lib/daigaku/terminal.rb +3 -4
- data/lib/daigaku/terminal/cli.rb +6 -8
- data/lib/daigaku/terminal/courses.rb +19 -16
- data/lib/daigaku/terminal/output.rb +0 -2
- data/lib/daigaku/terminal/setup.rb +13 -18
- data/lib/daigaku/terminal/solutions.rb +27 -32
- data/lib/daigaku/terminal/welcome.rb +9 -11
- data/lib/daigaku/test.rb +7 -10
- data/lib/daigaku/test_result.rb +13 -16
- data/lib/daigaku/unit.rb +1 -3
- data/lib/daigaku/version.rb +1 -1
- data/lib/daigaku/views.rb +4 -3
- data/lib/daigaku/views/chapters_menu.rb +16 -20
- data/lib/daigaku/views/courses_menu.rb +12 -15
- data/lib/daigaku/views/main_menu.rb +23 -23
- data/lib/daigaku/views/menu.rb +9 -13
- data/lib/daigaku/views/splash.rb +11 -13
- data/lib/daigaku/views/subscriber.rb +38 -0
- data/lib/daigaku/views/task_view.rb +80 -78
- data/lib/daigaku/views/top_bar.rb +4 -10
- data/lib/daigaku/views/units_menu.rb +16 -21
- data/lib/daigaku/window.rb +12 -70
- data/spec/daigaku/chapter_spec.rb +23 -18
- data/spec/daigaku/coloring_spec.rb +0 -1
- data/spec/daigaku/configuration_spec.rb +54 -50
- data/spec/daigaku/congratulator_spec.rb +11 -8
- data/spec/daigaku/course_spec.rb +70 -51
- data/spec/daigaku/generator_spec.rb +24 -25
- data/spec/daigaku/github_client_spec.rb +17 -18
- data/spec/daigaku/loading/chapters_spec.rb +2 -3
- data/spec/daigaku/loading/courses_spec.rb +2 -3
- data/spec/daigaku/loading/units_spec.rb +4 -5
- data/spec/daigaku/markdown/ruby_doc_spec.rb +3 -6
- data/spec/daigaku/reference_solution_spec.rb +8 -10
- data/spec/daigaku/solution_spec.rb +18 -20
- data/spec/daigaku/storeable_spec.rb +12 -10
- data/spec/daigaku/task_spec.rb +3 -4
- data/spec/daigaku/terminal/cli_spec.rb +29 -21
- data/spec/daigaku/terminal/courses_spec.rb +104 -99
- data/spec/daigaku/terminal/output_spec.rb +44 -39
- data/spec/daigaku/terminal/setup_spec.rb +1 -3
- data/spec/daigaku/terminal/solutions_spec.rb +0 -2
- data/spec/daigaku/terminal/welcome_spec.rb +0 -2
- data/spec/daigaku/terminal_spec.rb +5 -7
- data/spec/daigaku/test_example_spec.rb +16 -14
- data/spec/daigaku/test_result_spec.rb +21 -25
- data/spec/daigaku/test_spec.rb +11 -12
- data/spec/daigaku/unit_spec.rb +24 -27
- data/spec/daigaku/views/chapters_menu_spec.rb +0 -1
- data/spec/daigaku/views/courses_menu_spec.rb +0 -1
- data/spec/daigaku/views/menu_spec.rb +1 -2
- data/spec/daigaku/views/task_view_spec.rb +0 -2
- data/spec/daigaku/views/units_menu_spec.rb +0 -1
- data/spec/daigaku/views_spec.rb +0 -1
- data/spec/daigaku_spec.rb +9 -12
- data/spec/path_helpers_spec.rb +11 -12
- data/spec/resource_helpers_spec.rb +11 -12
- data/spec/spec_helper.rb +3 -4
- data/spec/support/macros/content_helpers.rb +16 -17
- data/spec/support/macros/mock_helpers.rb +6 -6
- data/spec/support/macros/path_helpers.rb +15 -15
- data/spec/support/macros/resource_helpers.rb +34 -35
- metadata +12 -10
data/lib/daigaku/markdown.rb
CHANGED
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'curses'
|
2
|
+
require_relative 'ruby_doc'
|
3
|
+
|
4
|
+
module Daigaku
|
5
|
+
module Markdown
|
6
|
+
class Printer
|
7
|
+
H1 = /\A\#{1}[^#]+/ # '# heading'
|
8
|
+
H2 = /\A\#{2}[^#]+/ # '## sub heading'
|
9
|
+
BOLD = /\*[^*]*\*/ # '*text*'
|
10
|
+
LINE = /\A-{3,}/ # '---' vertical line
|
11
|
+
CODE = /`[^`]*`/ # '`code line`'
|
12
|
+
|
13
|
+
attr_reader :window
|
14
|
+
|
15
|
+
def initialize(window:)
|
16
|
+
@window = window
|
17
|
+
end
|
18
|
+
|
19
|
+
def print(text)
|
20
|
+
text_line = RubyDoc.parse(text)
|
21
|
+
|
22
|
+
case text_line
|
23
|
+
when H1 then print_h1(text_line)
|
24
|
+
when H2 then print_h2(text_line)
|
25
|
+
when /(#{CODE}|#{BOLD})/ then print_code_or_bold(text_line)
|
26
|
+
when BOLD then print_bold(text_line)
|
27
|
+
when LINE then print_line
|
28
|
+
else print_escaped(text_line)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def print_h1(text)
|
33
|
+
window.heading(text.sub(/\A#\s?/, ''))
|
34
|
+
end
|
35
|
+
|
36
|
+
def print_h2(text)
|
37
|
+
text_decoration = Curses::A_UNDERLINE | Curses::A_NORMAL
|
38
|
+
window.emphasize(text.sub(/\A##\s?/, ''), text_decoration)
|
39
|
+
end
|
40
|
+
|
41
|
+
def print_code_or_bold(text)
|
42
|
+
emphasized = false
|
43
|
+
highlighted = false
|
44
|
+
|
45
|
+
text.chars.each_with_index do |char, index|
|
46
|
+
if char == '*' && text[index - 1] != '\\'
|
47
|
+
emphasized = !emphasized
|
48
|
+
next
|
49
|
+
end
|
50
|
+
|
51
|
+
if char == '`'
|
52
|
+
highlighted = !highlighted
|
53
|
+
next
|
54
|
+
end
|
55
|
+
|
56
|
+
character = text[index..(index + 1)] == '\\*' ? '' : char
|
57
|
+
|
58
|
+
if highlighted
|
59
|
+
window.red(character)
|
60
|
+
elsif emphasized
|
61
|
+
window.emphasize(character)
|
62
|
+
else
|
63
|
+
window.write(character)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def print_bold(text)
|
69
|
+
text.chars.each_with_index do |char, index|
|
70
|
+
if char == '*' && text[index - 1] != '\\'
|
71
|
+
emphasized = !emphasized
|
72
|
+
next
|
73
|
+
end
|
74
|
+
|
75
|
+
character = text[index..(index + 1)].to_s == '\\*' ? '' : char
|
76
|
+
emphasized ? window.emphasize(character) : window.write(character)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def print_line
|
81
|
+
window.write('-' * (Curses.cols - 2))
|
82
|
+
end
|
83
|
+
|
84
|
+
def print_escaped(text)
|
85
|
+
window.write(text.gsub(/(\\#)/, '#'))
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -1,15 +1,14 @@
|
|
1
1
|
require 'cgi'
|
2
2
|
|
3
3
|
module Daigaku
|
4
|
-
|
4
|
+
module Markdown
|
5
5
|
class RubyDoc
|
6
|
-
|
7
|
-
RUBY_DOC_URL = "http://ruby-doc.org".freeze
|
6
|
+
RUBY_DOC_URL = 'http://ruby-doc.org'.freeze
|
8
7
|
CORE_BASE_URL = "#{RUBY_DOC_URL}/core-#{RUBY_VERSION}".freeze
|
9
8
|
STDLIB_BASE_URL = "#{RUBY_DOC_URL}/stdlib-#{RUBY_VERSION}".freeze
|
10
9
|
|
11
|
-
CORE_REGEX = /\(ruby-doc core:\s?(.*)\)
|
12
|
-
STDLIB_REGEX = /\(ruby-doc stdlib:\s?(.*)\)
|
10
|
+
CORE_REGEX = /\(ruby-doc core:\s?(.*)\)/
|
11
|
+
STDLIB_REGEX = /\(ruby-doc stdlib:\s?(.*)\)/
|
13
12
|
|
14
13
|
class << self
|
15
14
|
def parse(text)
|
@@ -86,8 +85,8 @@ module Daigaku
|
|
86
85
|
method = text.split(/::|#/).last
|
87
86
|
return '' unless downcased?(method)
|
88
87
|
|
89
|
-
method_type = text
|
90
|
-
method_name = CGI.escape(method.strip).
|
88
|
+
method_type = text =~ /#/ ? 'i' : 'c'
|
89
|
+
method_name = CGI.escape(method.strip).tr('%', '-').gsub(/\A-/, '')
|
91
90
|
"#method-#{method_type}-#{method_name}"
|
92
91
|
end
|
93
92
|
|
@@ -100,7 +99,6 @@ module Daigaku
|
|
100
99
|
def downcased?(text)
|
101
100
|
text == text.downcase
|
102
101
|
end
|
103
|
-
|
104
102
|
end
|
105
103
|
end
|
106
104
|
end
|
data/lib/daigaku/solution.rb
CHANGED
@@ -1,20 +1,19 @@
|
|
1
1
|
module Daigaku
|
2
2
|
class Solution
|
3
|
-
|
4
|
-
FILE_SUFFIX = '_solution.rb'
|
3
|
+
FILE_SUFFIX = '_solution.rb'.freeze
|
5
4
|
|
6
5
|
attr_reader :code, :path, :errors
|
7
6
|
|
8
7
|
def initialize(unit_path)
|
9
8
|
@unit_path = unit_path
|
10
|
-
@path
|
11
|
-
@code
|
12
|
-
@verified
|
9
|
+
@path = solution_path(unit_path)
|
10
|
+
@code = File.read(@path).strip if File.file?(@path)
|
11
|
+
@verified = store_state
|
13
12
|
end
|
14
13
|
|
15
14
|
def verify!
|
16
|
-
result = Daigaku::Test.new(@unit_path).run(
|
17
|
-
|
15
|
+
result = Daigaku::Test.new(@unit_path).run(code)
|
16
|
+
self.store_state = result.passed?
|
18
17
|
result
|
19
18
|
end
|
20
19
|
|
@@ -24,7 +23,7 @@ module Daigaku
|
|
24
23
|
|
25
24
|
def store_key
|
26
25
|
unless @store_key
|
27
|
-
part_path
|
26
|
+
part_path = path.split('/')[-3..-1].join('/').gsub(FILE_SUFFIX, '')
|
28
27
|
@store_key = Storeable.key(part_path, prefix: 'verified')
|
29
28
|
end
|
30
29
|
|
@@ -34,20 +33,24 @@ module Daigaku
|
|
34
33
|
private
|
35
34
|
|
36
35
|
def solution_path(path)
|
37
|
-
local_path
|
38
|
-
|
39
|
-
file
|
36
|
+
local_path = Daigaku.config.solutions_path
|
37
|
+
sub_directory = Storeable.key(directory_from(path))
|
38
|
+
file = Storeable.key(File.basename(path)) + FILE_SUFFIX
|
39
|
+
|
40
|
+
File.join(local_path, sub_directory, file)
|
41
|
+
end
|
40
42
|
|
41
|
-
|
43
|
+
def directory_from(path)
|
44
|
+
path.split('/')[-3..-2].join('/').gsub(FILE_SUFFIX, '')
|
42
45
|
end
|
43
46
|
|
44
|
-
def
|
47
|
+
def store_state=(verified)
|
45
48
|
@verified = verified
|
46
49
|
QuickStore.store.set(store_key, verified?)
|
47
50
|
end
|
48
51
|
|
49
|
-
def
|
52
|
+
def store_state
|
50
53
|
QuickStore.store.get(store_key)
|
51
54
|
end
|
52
55
|
end
|
53
|
-
end
|
56
|
+
end
|
data/lib/daigaku/storeable.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
module Daigaku
|
2
2
|
module Storeable
|
3
|
-
|
4
3
|
LEADING_NUMBERS = /^\d+[\_\-\s]+/
|
5
|
-
PART_JOINTS
|
4
|
+
PART_JOINTS = /[\_\-\s]+/
|
6
5
|
|
7
6
|
class << self
|
8
7
|
def key(text, options = {})
|
9
|
-
separator
|
10
|
-
prefix
|
11
|
-
suffix
|
12
|
-
suffixes
|
8
|
+
separator = QuickStore.config.key_separator
|
9
|
+
prefix = options[:prefix]
|
10
|
+
suffix = clean(options[:suffix])
|
11
|
+
suffixes = options[:suffixes]
|
13
12
|
suffixes_items = suffixes ? suffixes.map { |s| clean(s) }.compact : nil
|
14
13
|
|
15
14
|
[prefix, clean(text), suffix || suffixes_items].compact.join(separator)
|
@@ -18,15 +17,15 @@ module Daigaku
|
|
18
17
|
private
|
19
18
|
|
20
19
|
def clean(text)
|
21
|
-
if text
|
22
|
-
|
23
|
-
|
24
|
-
end
|
20
|
+
return if text.nil?
|
21
|
+
parts(text.to_s).join(QuickStore.config.key_separator)
|
22
|
+
end
|
25
23
|
|
26
|
-
|
24
|
+
def parts(text)
|
25
|
+
text.split(QuickStore.config.key_separator).map do |key|
|
26
|
+
key.gsub(LEADING_NUMBERS, '').gsub(PART_JOINTS, '_').downcase
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
30
|
-
|
31
30
|
end
|
32
31
|
end
|
data/lib/daigaku/task.rb
CHANGED
data/lib/daigaku/terminal.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Daigaku
|
2
2
|
module Terminal
|
3
|
-
|
4
3
|
# text should be of a width of 70 columns or less
|
5
4
|
def self.text(file_name)
|
6
5
|
texts_path = File.expand_path('../terminal/texts', __FILE__)
|
7
|
-
file
|
8
|
-
(File.exist?(file) ? File.read(file).to_s : '')
|
9
|
-
end
|
6
|
+
file = File.join(texts_path, "#{file_name}.txt")
|
10
7
|
|
8
|
+
File.exist?(file) ? File.read(file).to_s : ''
|
9
|
+
end
|
11
10
|
end
|
12
11
|
end
|
data/lib/daigaku/terminal/cli.rb
CHANGED
@@ -1,13 +1,11 @@
|
|
1
1
|
require 'thor'
|
2
|
+
require_relative 'courses'
|
3
|
+
require_relative 'solutions'
|
4
|
+
require_relative 'setup'
|
5
|
+
require_relative 'output'
|
2
6
|
|
3
7
|
module Daigaku
|
4
8
|
module Terminal
|
5
|
-
|
6
|
-
require_relative 'courses'
|
7
|
-
require_relative 'solutions'
|
8
|
-
require_relative 'setup'
|
9
|
-
require_relative 'output'
|
10
|
-
|
11
9
|
class CLI < Thor
|
12
10
|
include Terminal::Output
|
13
11
|
|
@@ -21,7 +19,7 @@ module Daigaku
|
|
21
19
|
subcommand 'setup', Terminal::Setup
|
22
20
|
|
23
21
|
def self.start
|
24
|
-
Daigaku.config.import
|
22
|
+
Daigaku.config.import
|
25
23
|
super
|
26
24
|
end
|
27
25
|
|
@@ -40,7 +38,7 @@ module Daigaku
|
|
40
38
|
generator = Generator.new
|
41
39
|
generator.prepare
|
42
40
|
|
43
|
-
courses_path
|
41
|
+
courses_path = Daigaku.config.courses_path
|
44
42
|
solutions_path = Daigaku.config.solutions_path
|
45
43
|
|
46
44
|
generator.scaffold(courses_path, solutions_path)
|
@@ -1,14 +1,18 @@
|
|
1
|
+
require 'os'
|
2
|
+
require 'open-uri'
|
3
|
+
require 'zip'
|
4
|
+
require_relative 'output'
|
5
|
+
|
1
6
|
module Daigaku
|
2
7
|
module Terminal
|
3
|
-
|
4
|
-
require 'os'
|
5
|
-
require 'open-uri'
|
6
|
-
require 'zip'
|
7
|
-
require_relative 'output'
|
8
|
-
|
9
8
|
class Courses < Thor
|
10
9
|
include Terminal::Output
|
11
10
|
|
11
|
+
GITHUB = /github\.com/
|
12
|
+
MASTER_ZIP_URL = %r{github.com\/(.*)\/archive\/master.zip}
|
13
|
+
URL = /\A#{URI.regexp(%w(http https))}\z/
|
14
|
+
ZIP_FILE = /\.zip/
|
15
|
+
|
12
16
|
desc 'list', 'List your available daigaku courses'
|
13
17
|
def list
|
14
18
|
courses = Loading::Courses.load(Daigaku.config.courses_path)
|
@@ -22,11 +26,11 @@ module Daigaku
|
|
22
26
|
url = GithubClient.master_zip_url(Daigaku.config.initial_course) if use_initial_course
|
23
27
|
url = GithubClient.master_zip_url(options[:github]) if options[:github]
|
24
28
|
|
25
|
-
url_given = (url =~
|
26
|
-
github = use_initial_course || options[:github] || url.match(
|
29
|
+
url_given = (url =~ URL)
|
30
|
+
github = use_initial_course || options[:github] || url.match(GITHUB)
|
27
31
|
|
28
32
|
raise Download::NoUrlError unless url_given
|
29
|
-
raise Download::NoZipFileUrlError unless File.basename(url) =~
|
33
|
+
raise Download::NoZipFileUrlError unless File.basename(url) =~ ZIP_FILE
|
30
34
|
|
31
35
|
courses_path = Daigaku.config.courses_path
|
32
36
|
FileUtils.makedirs(courses_path) unless Dir.exist?(courses_path)
|
@@ -37,7 +41,7 @@ module Daigaku
|
|
37
41
|
course = Course.unzip(file_name, github_repo: github)
|
38
42
|
|
39
43
|
if github
|
40
|
-
user_and_repo = url.match(
|
44
|
+
user_and_repo = url.match(MASTER_ZIP_URL).captures.first
|
41
45
|
store_repo_data(options[:github] || user_and_repo)
|
42
46
|
end
|
43
47
|
|
@@ -46,11 +50,11 @@ module Daigaku
|
|
46
50
|
scaffold_solutions
|
47
51
|
|
48
52
|
say_info "Successfully #{action} the course \"#{course.title}\"!"
|
49
|
-
rescue Download::NoUrlError
|
53
|
+
rescue Download::NoUrlError
|
50
54
|
print_download_warning(url, "\"#{url}\" is not a valid URL!")
|
51
|
-
rescue Download::NoZipFileUrlError
|
55
|
+
rescue Download::NoZipFileUrlError
|
52
56
|
print_download_warning(url, "\"#{url}\" is not a URL of a *.zip file!")
|
53
|
-
rescue
|
57
|
+
rescue StandardError => e
|
54
58
|
print_download_warning(url, e.message)
|
55
59
|
ensure
|
56
60
|
FileUtils.rm(file_name) if File.exist?(file_name.to_s)
|
@@ -124,7 +128,7 @@ module Daigaku
|
|
124
128
|
end
|
125
129
|
|
126
130
|
def store_repo_data(user_and_repo)
|
127
|
-
parts
|
131
|
+
parts = (user_and_repo ||= Daigaku.config.initial_course).split('/')
|
128
132
|
author = parts.first
|
129
133
|
course = parts.second
|
130
134
|
|
@@ -164,7 +168,7 @@ module Daigaku
|
|
164
168
|
def print_course_not_available(course_name)
|
165
169
|
text = [
|
166
170
|
"The course \"#{course_name}\" is not available in",
|
167
|
-
"\"#{Daigaku.config.courses_path}\".\n"
|
171
|
+
"\"#{Daigaku.config.courses_path}\".\n"
|
168
172
|
]
|
169
173
|
|
170
174
|
say_warning text.join("\n")
|
@@ -174,6 +178,5 @@ module Daigaku
|
|
174
178
|
end
|
175
179
|
end
|
176
180
|
end
|
177
|
-
|
178
181
|
end
|
179
182
|
end
|
@@ -1,10 +1,8 @@
|
|
1
1
|
require 'thor'
|
2
|
+
require_relative 'output'
|
2
3
|
|
3
4
|
module Daigaku
|
4
5
|
module Terminal
|
5
|
-
|
6
|
-
require_relative 'output'
|
7
|
-
|
8
6
|
class Setup < Thor
|
9
7
|
include Terminal::Output
|
10
8
|
|
@@ -19,7 +17,7 @@ module Daigaku
|
|
19
17
|
path = get 'path:'
|
20
18
|
|
21
19
|
begin
|
22
|
-
@daigaku_path = File.expand_path(
|
20
|
+
@daigaku_path = File.expand_path(path.to_s, Dir.pwd)
|
23
21
|
rescue
|
24
22
|
say_warning "#{path} is no valid path name. Try another!"
|
25
23
|
next
|
@@ -29,7 +27,7 @@ module Daigaku
|
|
29
27
|
say "\"#{@daigaku_path}\""
|
30
28
|
|
31
29
|
confirmation = get '(yes|no)'
|
32
|
-
break if confirmation.
|
30
|
+
break if confirmation.casecmp('yes').zero?
|
33
31
|
|
34
32
|
empty_line
|
35
33
|
say 'No Problem. Just type another one!'
|
@@ -61,8 +59,8 @@ module Daigaku
|
|
61
59
|
solutions_path = options[:paths] || options[:solutions_path]
|
62
60
|
|
63
61
|
if courses_path.nil? && solutions_path.nil?
|
64
|
-
say_warning
|
65
|
-
say
|
62
|
+
say_warning 'Please specify options when using this command!'
|
63
|
+
say `daigaku setup help set`
|
66
64
|
return
|
67
65
|
end
|
68
66
|
|
@@ -76,11 +74,12 @@ module Daigaku
|
|
76
74
|
private
|
77
75
|
|
78
76
|
def prepare_directories(path)
|
79
|
-
courses_dir
|
77
|
+
courses_dir = Daigaku::Configuration::COURSES_DIR
|
80
78
|
courses_path = File.join(path, courses_dir)
|
79
|
+
|
81
80
|
Daigaku.config.courses_path = courses_path
|
82
81
|
|
83
|
-
solutions_dir
|
82
|
+
solutions_dir = Daigaku::Configuration::SOLUTIONS_DIR
|
84
83
|
solutions_path = File.join(path, solutions_dir)
|
85
84
|
|
86
85
|
if Dir.exist? solutions_path
|
@@ -92,7 +91,7 @@ module Daigaku
|
|
92
91
|
|
93
92
|
text = [
|
94
93
|
"Your Daigaku directory is now set up.\n",
|
95
|
-
|
94
|
+
'Daigaku created/updated following two paths for you:',
|
96
95
|
courses_path,
|
97
96
|
solutions_path
|
98
97
|
]
|
@@ -101,15 +100,11 @@ module Daigaku
|
|
101
100
|
end
|
102
101
|
|
103
102
|
def update_config(attribute, value)
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
say_warning e.message
|
109
|
-
end
|
103
|
+
path = File.expand_path(value, Dir.pwd)
|
104
|
+
Daigaku.config.send("#{attribute}=", path)
|
105
|
+
rescue StandardError => e
|
106
|
+
say_warning e.message
|
110
107
|
end
|
111
|
-
|
112
108
|
end
|
113
|
-
|
114
109
|
end
|
115
110
|
end
|