learn-tool 0.0.16 → 0.0.20

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: 2d759f8eb4d52c7c0a73d3eb067320d66341085777d1e22cef08c026fc0d02e0
4
- data.tar.gz: 339ede530dbd6f1a4e1aa62a816a91f6bf40b697250582ce549c58cb82dae4d5
3
+ metadata.gz: 71fe36246ba3b898eff013d99569d72091bd0e575ee5efa2d52135e4425bed67
4
+ data.tar.gz: ac8b171728f7ff943d58d6bbe334d406b02e87a6236c781aa96ffac0954c693a
5
5
  SHA512:
6
- metadata.gz: 1c31b985672fa05ea1ed8350103fd00fd536715c2336686ac490aee10cfb33425a9490d4927453182256518f47ea856505825a54309cdb96c128c61bad8cd8df
7
- data.tar.gz: ab74b388effd6db8844f8c6ba89596e4e2fcea0cdafecf468ac98c9952079522d06114d693c8f29fcca7b7573120eadb1cdb214b7f3272c5ad37af9d75eb1c2a
6
+ metadata.gz: 07af1813e35c0678cc0eee5645f79cd68a160b313e537c259e9e090767bf7e6619416df40e91841352d4d64ebc5e7e57d5d4c6960914b7233b07227404b6d7d6
7
+ data.tar.gz: c3b7f30f1e39ec94cad66695614d58de030a8895ccad61d9569a7905a268f71085db9add823aae700dd17d3c7399ff422d0aa553623335e0eb9335f17b5e193e
data/bin/learn-tool CHANGED
@@ -12,9 +12,10 @@ OptionParser.new do |opts|
12
12
  A tool for creating, cloning and repairing repositories. This tool has
13
13
  three basic commands
14
14
 
15
- learn-tool create
16
- learn-tool duplicate
17
- learn-tool repair
15
+ learn-tool --create
16
+ learn-tool --duplicate
17
+ learn-tool --lint <optional: filepath>
18
+ learn-tool --repair <optional: filepath>
18
19
 
19
20
  When creating, you will need to provide a name of the repository you are
20
21
  creating and choose from an existing template.
@@ -25,23 +26,43 @@ OptionParser.new do |opts|
25
26
 
26
27
  EOBANNER
27
28
 
28
- opts.on("--create", "-c", "Create new repository"){ |v| options[:create] = true }
29
- opts.on("--duplicate", "-d", "Clone from existing repository"){ |v| options[:duplicate] = true }
30
- opts.on("--repair", "-r", "Fix current repository"){ |v| options[:repair] = true }
29
+ opts.on("-c", "--create",
30
+ "Create new repository") do |v|
31
+ options[:create] = true
32
+ end
33
+ opts.on("-d", "--duplicate",
34
+ "Clone from existing repository") do |v|
35
+ options[:duplicate] = true
36
+ end
37
+ opts.on("-l", "--lint [ABSOLUTE_FILEPATH]",
38
+ "Lint a directory given its absolute path. If blank, lints current directory") do |filepath|
39
+ filepath ? options[:lint] = filepath : options[:lint] = Dir.pwd
40
+ end
41
+ opts.on("-r", "--repair [ABSOLUTE_FILEPATH]",
42
+ "Add correct files to a directory given its absolute path. If blank, edits current directory") do |filepath|
43
+ filepath ? options[:repair] = filepath : options[:repair] = Dir.pwd
44
+ end
45
+
31
46
  end.parse!
32
47
 
33
48
  puts options
34
49
 
35
50
  if options[:create]
36
- LearnTool.new("create")
51
+ LearnTool.new(mode: "create", filepath: Dir.pwd)
37
52
  end
38
53
 
39
54
  if options[:duplicate]
40
- LearnTool.new("duplicate")
55
+ LearnTool.new(mode: "duplicate", filepath: Dir.pwd)
41
56
  end
42
57
 
43
- if options[:repair]
44
- LearnTool.new("repair")
58
+ if options[:lint]
59
+ LearnTool.new(mode: "lint", filepath: options[:lint])
45
60
  end
46
61
 
62
+ if options[:repair]
63
+ LearnTool.new(mode: "repair", filepath: options[:repair])
64
+ end
47
65
 
66
+ if options == {}
67
+ LearnTool.new(mode: "lint", filepath: Dir.pwd)
68
+ end
data/lib/learn-tool.rb CHANGED
@@ -1,238 +1,50 @@
1
1
  require 'faraday'
2
2
  require 'uri'
3
3
  require 'open3'
4
+ require_relative './learn-tool/learn-base'
5
+ require_relative './learn-tool/learn-repair'
6
+ require_relative './learn-tool/learn-create'
7
+ require_relative './learn-tool/learn-duplicate'
8
+ require_relative './learn-tool/learn-lint'
9
+ require_relative './learn-tool/learn-error'
10
+ require_relative './learn-tool/license-linter'
11
+ require_relative './learn-tool/readme-linter'
12
+ require_relative './learn-tool/yaml-linter'
13
+ require_relative './learn-tool/contributing-linter'
4
14
 
5
15
  class LearnTool
6
- GITHUB_ORG = 'https://api.github.com/repos/learn-co-curriculum/'
7
- README_TEMPLATE = 'readme-template'
8
- RUBY_LAB_TEMPLATE = 'ruby-lab-template'
9
- JAVASCRIPT_LAB_TEMPLATE = 'js-lab-template'
10
- REACT_LAB_TEMPLATE = 'react-lab-template'
16
+
11
17
 
12
- def initialize(mode)
13
- @ssh_configured = check_ssh_config
14
- puts mode
18
+ def initialize(mode:, filepath:Dir.pwd)
19
+ puts filepath
15
20
  if mode == 'create'
16
- create
21
+ LearnCreate.new(filepath)
17
22
  end
18
23
 
19
24
  if mode == 'duplicate'
20
- duplicate
25
+ LearnDuplicate.new(filepath)
21
26
  end
22
27
 
23
28
  if mode == 'repair'
24
- repair
25
- end
26
- end
27
-
28
- def create
29
- puts 'Note: You must have write access to the learn-co-curriculum org on GitHub to use this tool'
30
- until name_new_repo do
31
- puts 'Careful - rate limiting can occur'
29
+ LearnRepair.new(filepath)
32
30
  end
33
31
 
34
- choose_repo_template
35
- create_new_repo
36
- end_message
37
- end
38
-
39
- def choose_repo_template
40
- puts 'Is the lesson you are creating a Readme? (Y/n)'
41
- readme_input = gets.chomp.downcase
42
- if readme_input == "n" || readme_input == "no" || readme_input == "N" || readme_input == "No"
43
- language = choose_language
44
- case language
45
- when /^ru/
46
- @old_repo_name = RUBY_LAB_TEMPLATE
47
- when /^j/
48
- @old_repo_name = JAVASCRIPT_LAB_TEMPLATE
49
- when /^re/
50
- @old_repo_name = REACT_LAB_TEMPLATE
51
- else
52
- @old_repo_name = README_TEMPLATE
53
- end
54
- else
55
- @old_repo_name = README_TEMPLATE
32
+ if mode == 'lint'
33
+ LearnLinter.new(filepath).lint_directory
56
34
  end
57
- @old_repo_name
58
35
  end
59
36
 
60
- def choose_language
61
- language = ''
62
- loop do
63
- puts 'What lab template would you like to use? (Ruby/JavaScript/React)'
64
- language = gets.chomp.downcase
65
- break if language =~ /^(ru|j|re)/
66
- puts 'Please enter Ruby, JavaScript or React, or at minimum, the first two letters:'
67
- puts ''
68
- end
69
- language
70
- end
71
-
72
- def duplicate
73
- puts 'Note: You must have write access to the learn-co-curriculum org on GitHub to use this tool'
74
- loop do
75
- puts 'What is the name of the repository you would like to copy? Paste exactly as is shown in the URL (i.e. advanced-hashes-hashketball)'
76
- old_repo_name_input = gets.strip
77
- if repo_exists(old_repo_name_input)
78
- @old_repo_name = old_repo_name_input
79
- puts ''
80
- puts 'Old repository: ' + @old_repo_name
81
- until name_new_repo do
82
- puts 'Careful - rate limiting can occur'
83
- end
84
-
85
-
86
- create_new_repo
87
- end_message
88
- break
89
- else
90
- puts 'Provided repository name is not a valid learn-co-curriculum repository. Please try again. Careful - rate limiting can be triggered'
91
- end
92
- end
93
- end
37
+
94
38
 
95
- def name_new_repo
96
- puts 'What is the name of the repository you would like to create?'
97
- new_name = gets.strip.gsub(/\s+/, '-').downcase
98
-
99
- if name_length_is_good(new_name)
100
- if !repo_exists(new_name)
101
- @new_repo_name = new_name
102
- else
103
- puts 'A repository with that name already exists. Please try again.'
104
- return false
105
- end
106
- else
107
- puts 'Repository names must be shorter than 100 characters'
108
- return false
109
- end
110
- @new_repo_name
111
- end
112
-
113
- def create_new_repo
114
- # 'cd' doesn't work the way it would in the shell, must be used before every command
115
- puts 'Cloning old repository'
116
- git_clone
117
- # puts "Renaming old directory with new name: #{@new_repo_name}"
118
- # rename_repo
119
- puts ''
120
- puts 'Creating new remote learn-co-curriculum repository'
121
- git_create_and_set_new_origin
122
- puts ''
123
- puts 'Setting new git remote based on SSH settings'
124
- git_set_remote
125
- puts ''
126
- puts 'Pushing all old-remote branches to new remote'
127
- git_push
128
- end
129
-
130
- def end_message
131
- puts ''
132
- puts 'To access local folder, change directory into ' + @new_repo_name + '/'
133
- puts "Repository available at #{GITHUB_ORG}" + @new_repo_name
134
- end
135
-
136
- private
137
-
138
- def git_clone
139
- cmd = "git clone https://github.com/learn-co-curriculum/#{@old_repo_name} #{@new_repo_name}"
140
- puts cmd
141
- `#{cmd}`
142
- end
143
-
144
- def git_create_and_set_new_origin
145
- # Creates repo **and** assigns new remote to 'origin' shortname
146
- cmd = cd_into_and("hub create learn-co-curriculum/#{@new_repo_name}")
147
- puts cmd
148
- `#{cmd}`
149
- end
150
-
151
- def git_set_remote
152
- remote = check_ssh_config ? "git@github.com:learn-co-curriculum/#{@new_repo_name}.git" : "https://github.com/learn-co-curriculum/#{@new_repo_name}"
153
- cmd = cd_into_and("git remote set-url origin #{remote}")
154
- puts cmd
155
- `#{cmd}`
156
- end
157
-
158
- def git_push
159
- # Copy `master`, attempt to copy `solution`, but if it's not there, no complaints
160
- cmds = [
161
- %q|git push origin 'refs/remotes/origin/master:refs/heads/master' > /dev/null 2>&1|,
162
- %q|git push origin 'refs/remotes/origin/solution:refs/heads/solution' > /dev/null 2>&1|
163
- ]
164
- cmds.each { |cmd| `#{cd_into_and(cmd)}` }
165
- end
166
-
167
- def repo_exists(repo_name)
168
- url = GITHUB_ORG + repo_name
169
- encoded_url = URI.encode(url).slice(0, url.length)
170
- check_existing = Faraday.get URI.parse(encoded_url)
171
- !check_existing.body.include? '"Not Found"'
172
- end
173
-
174
- def cd_into_and(command)
175
- "cd #{@new_repo_name} && #{command}"
176
- end
177
-
178
- def create_support_file(name_of_file)
179
- # copies a template folder from the learn_create gem to a subfolder of the current directory
180
- gem_template_location = File.dirname(__FILE__)
181
- template_path = File.expand_path(gem_template_location) + "/support_files/#{name_of_file.upcase}"
182
- cmd = "cp #{template_path} #{Dir.pwd}"
183
- `#{cmd}`
184
- end
185
-
186
- def create_dot_learn_file
187
- `
188
- cat > .learn <<EOL
189
- languages:
190
- - none
191
- `
192
- end
193
39
 
194
- # def create_dot_gitignore_file
195
- # `
196
- # cat > .gitignore <<EOL
197
- # .DS_Store
198
- # logs
199
- # *.log
200
- # npm-debug.log*
201
- # pids
202
- # *.pid
203
- # *.seed
204
- # lib-cov
205
- # build/Release
206
- # node_modules
207
- # jspm_packages
208
- # .npm
209
- # .node_repl_history
210
- # .results.json
211
- # /.bundle
212
- # /db/*.sqlite3
213
- # /db/*.sqlite3-journal
214
- # /log/*
215
- # !/log/.keep
216
- # /tmp
217
- # `
218
- # end
219
40
 
220
41
 
221
42
 
222
- def repair
223
- create_dot_learn_file
224
- create_support_file("LICENSE.md")
225
- create_support_file("CONTRIBUTING.md")
226
- end
43
+
227
44
 
228
- def name_length_is_good(name)
229
- name.length < 100
230
- end
45
+
231
46
 
232
- def check_ssh_config
233
- result = Open3.capture2e('ssh -T git@github.com').first
234
- result.include?("You've successfully authenticated")
235
- end
47
+
236
48
 
237
49
 
238
50
  end
@@ -0,0 +1,23 @@
1
+ class ContributingLinter
2
+
3
+ VALID_FILE = File.open(File.expand_path(File.dirname(__FILE__)) + '/support_files/CONTRIBUTING.md')
4
+
5
+ def self.parse_file(file, learn_error)
6
+ directory_file = sanitize_whitespace(File.open(file).read)
7
+ valid_file_array = sanitize_whitespace(VALID_FILE.read)
8
+ diff = directory_file - valid_file_array
9
+
10
+ if diff.empty?
11
+ learn_error.contributing_error[:valid_contributing] = true
12
+ learn_error.valid_contributing = {message: "valid CONTRIBUTING.md", color: :green}
13
+ else
14
+ learn_error.contributing_error[:valid_contributing] = false
15
+ learn_error.valid_contributing = {message: "invalid CONTRIBUTING.md - Errors: #{diff}", color: :red}
16
+ end
17
+ end
18
+
19
+ def self.sanitize_whitespace(file)
20
+ file.split.delete_if {|char| char.empty? || char == "\n"}
21
+ end
22
+
23
+ end
@@ -0,0 +1,112 @@
1
+ require 'pry'
2
+ class LearnBase
3
+
4
+ GITHUB_ORG = 'https://api.github.com/repos/learn-co-curriculum/'
5
+ README_TEMPLATE = 'readme-template'
6
+ RUBY_LAB_TEMPLATE = 'ruby-lab-template'
7
+ JAVASCRIPT_LAB_TEMPLATE = 'js-lab-template'
8
+ REACT_LAB_TEMPLATE = 'react-lab-template'
9
+
10
+ def initialize(filepath)
11
+ @filepath = filepath
12
+ @old_repo_name = ''
13
+ @new_repo_name = ''
14
+ end
15
+
16
+ def repo_is_available(repo_name)
17
+ url = GITHUB_ORG + repo_name
18
+ encoded_url = URI.encode(url).slice(0, url.length)
19
+ check_existing = Faraday.get URI.parse(encoded_url)
20
+ check_existing.body.include? '"Not Found"'
21
+ end
22
+
23
+ def cd_into_and(filepath, command)
24
+ puts filepath, command
25
+ cmd = "cd #{filepath} && #{command}"
26
+ `#{cmd}`
27
+ end
28
+
29
+ def name_new_repo
30
+ puts 'What is the name of the repository you would like to create?'
31
+ new_name = gets.strip.gsub(/\s+/, '-').downcase
32
+
33
+ if name_length_is_good(new_name)
34
+ if repo_is_available(new_name)
35
+ @new_repo_name = new_name
36
+ else
37
+ puts 'A repository with that name already exists. Please try again.'
38
+ return false
39
+ end
40
+ else
41
+ puts 'Repository names must be shorter than 100 characters'
42
+ return false
43
+ end
44
+ @new_repo_name
45
+ end
46
+
47
+ def get_new_name
48
+ puts 'Note: You must have write access to the learn-co-curriculum org on GitHub to use this tool'
49
+ until name_new_repo do
50
+ puts 'Careful - rate limiting can occur'
51
+ end
52
+ end
53
+
54
+ def create_new_repo
55
+ # 'cd' doesn't work the way it would in the shell, must be used before every command
56
+ puts 'Cloning old repository'
57
+ git_clone
58
+ # puts "Renaming old directory with new name: #{new_repo_name}"
59
+ # rename_repo
60
+ puts ''
61
+ puts 'Creating new remote learn-co-curriculum repository'
62
+ git_create_and_set_new_origin
63
+ puts ''
64
+ puts 'Setting new git remote based on SSH settings'
65
+ git_set_remote
66
+ puts ''
67
+ puts 'Pushing all old-remote branches to new remote'
68
+ git_push
69
+ end
70
+
71
+ def end_message
72
+ puts ''
73
+ puts 'To access local folder, change directory into ' + @new_repo_name + '/'
74
+ puts "Repository available at #{GITHUB_ORG}" + @new_repo_name
75
+ end
76
+
77
+ private
78
+
79
+ def git_clone
80
+ cmd = "git clone https://github.com/learn-co-curriculum/#{@old_repo_name} #{@new_repo_name}"
81
+ puts cmd
82
+ `#{cmd}`
83
+ end
84
+
85
+ def git_create_and_set_new_origin
86
+ # Creates repo **and** assigns new remote to 'origin' shortname
87
+ cd_into_and(@filepath + "/#{@new_repo_name}", "hub create learn-co-curriculum/#{@new_repo_name}")
88
+ end
89
+
90
+ def git_set_remote
91
+ remote = check_ssh_config ? "git@github.com:learn-co-curriculum/#{@new_repo_name}.git" : "https://github.com/learn-co-curriculum/#{new_repo_name}"
92
+ cd_into_and(@filepath + "/#{@new_repo_name}", "git remote set-url origin #{remote}")
93
+ end
94
+
95
+ def git_push
96
+ # Copy `master`, attempt to copy `solution`, but if it's not there, no complaints
97
+ cmds = [
98
+ %q|git push origin 'refs/remotes/origin/master:refs/heads/master' > /dev/null 2>&1|,
99
+ %q|git push origin 'refs/remotes/origin/solution:refs/heads/solution' > /dev/null 2>&1|
100
+ ]
101
+ cmds.each { |cmd| cd_into_and(@filepath + "/#{@new_repo_name}", cmd) }
102
+ end
103
+
104
+ def name_length_is_good(name)
105
+ name.length < 100
106
+ end
107
+
108
+ def check_ssh_config
109
+ result = Open3.capture2e('ssh -T git@github.com').first
110
+ result.include?("You've successfully authenticated")
111
+ end
112
+ end
@@ -0,0 +1,44 @@
1
+ class LearnCreate < LearnBase
2
+
3
+ def initialize(filepath)
4
+ super(filepath)
5
+ get_new_name
6
+ choose_repo_template
7
+ create_new_repo
8
+ end_message
9
+ end
10
+
11
+ def choose_repo_template
12
+ puts 'Is the lesson you are creating a Readme? (Y/n)'
13
+ readme_input = gets.chomp.downcase
14
+ if readme_input == "n" || readme_input == "no" || readme_input == "N" || readme_input == "No"
15
+ language = choose_language
16
+ case language
17
+ when /^ru/
18
+ @old_repo_name = RUBY_LAB_TEMPLATE
19
+ when /^j/
20
+ @old_repo_name = JAVASCRIPT_LAB_TEMPLATE
21
+ when /^re/
22
+ @old_repo_name = REACT_LAB_TEMPLATE
23
+ else
24
+ @old_repo_name = README_TEMPLATE
25
+ end
26
+ else
27
+ @old_repo_name = README_TEMPLATE
28
+ end
29
+ @old_repo_name
30
+ end
31
+
32
+ def choose_language
33
+ language = ''
34
+ loop do
35
+ puts 'What lab template would you like to use? (Ruby/JavaScript/React)'
36
+ language = gets.chomp.downcase
37
+ break if language =~ /^(ru|j|re)/
38
+ puts 'Please enter Ruby, JavaScript or React, or at minimum, the first two letters:'
39
+ puts ''
40
+ end
41
+ language
42
+ end
43
+
44
+ end
@@ -0,0 +1,31 @@
1
+ class LearnDuplicate < LearnBase
2
+
3
+ def initialize(filepath)
4
+ super(filepath)
5
+ puts 'Note: You must have write access to the learn-co-curriculum org on GitHub to use this tool'
6
+ get_old_repo
7
+ end
8
+
9
+ def get_old_repo
10
+ loop do
11
+ puts 'What is the name of the repository you would like to copy? Paste exactly as is shown in the URL (i.e. advanced-hashes-hashketball)'
12
+ old_repo_name_input = gets.strip
13
+ if !repo_is_available(old_repo_name_input)
14
+ @old_repo_name = old_repo_name_input
15
+ puts ''
16
+ puts 'Old repository: ' + @old_repo_name
17
+ until name_new_repo do
18
+ puts 'Careful - rate limiting can occur'
19
+ end
20
+
21
+
22
+ create_new_repo
23
+ end_message
24
+ break
25
+ else
26
+ puts 'Provided repository name is not a valid learn-co-curriculum repository. Please try again. Careful - rate limiting can be triggered'
27
+ end
28
+ end
29
+ end
30
+
31
+ end
@@ -0,0 +1,69 @@
1
+ class LearnError < StandardError
2
+ attr_accessor :filepath, :valid_yaml, :valid_license,
3
+ :present_learn, :present_license, :present_readme, :yaml_error,
4
+ :readme_error, :license_error, :valid_readme, :correct_yaml_content,
5
+ :valid_contributing, :present_contributing, :contributing_error
6
+
7
+ ESCAPES = { :green => "\033[32m",
8
+ :yellow => "\033[33m",
9
+ :red => "\033[31m",
10
+ :reset => "\033[0m" }
11
+
12
+
13
+ def initialize
14
+ @yaml_error = {present_dotlearn: false, valid_yaml: false, valid_whitespace: false, attributes: false}
15
+ @readme_error = {present_readme: false, valid_readme: false}
16
+ @license_error = {present_license: false, valid_license: false}
17
+ @contributing_error = {present_contributing: false, valid_contributing: false}
18
+
19
+ @correct_yaml_content = {message: ".learn file must have 'languages' key", color: :red}
20
+
21
+ @valid_yaml = {message: "invalid yaml", color: :red}
22
+ @valid_license = {message: "invalid or missing license content", color: :yellow}
23
+ @valid_readme = {message: [], color: :red}
24
+ @valid_contributing = {message: "invalid or missing contributing content", color: :yellow}
25
+
26
+ @present_learn = {message: "missing .learn file", color: :red}
27
+ @present_license = {message: "missing LICENSE.md", color: :red}
28
+ @present_readme = {message: "missing README.md", color: :red}
29
+ @present_contributing = {message: "missing CONTRIBUTING.md", color: :red}
30
+
31
+ end
32
+
33
+ def emit(opts={})
34
+ color = opts[:color]
35
+ message = opts[:message]
36
+ print ESCAPES[color]
37
+ print message
38
+ print ESCAPES[:reset]
39
+ print "\n"
40
+ end
41
+
42
+ def total_errors
43
+ {
44
+ dot_learn: yaml_error,
45
+ license: license_error,
46
+ readme: readme_error,
47
+ contributing: contributing_error
48
+ }
49
+
50
+ end
51
+
52
+ def result_message
53
+ [present_learn, valid_yaml, correct_yaml_content, present_license, valid_license, present_readme, valid_readme, present_contributing, valid_contributing ]
54
+ end
55
+
56
+
57
+ def result_output
58
+ result_message.each do |result|
59
+ if result[:message].is_a?(Array)
60
+ result[:message].each do |result_message|
61
+ emit({message: result_message, color: result[:color]})
62
+ end
63
+ else
64
+ emit(result)
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,55 @@
1
+ class LearnLinter
2
+ def initialize(filepath)
3
+ @learn_error = LearnError.new
4
+ @filepath = filepath
5
+ end
6
+
7
+ def result_message
8
+ @learn_error.result_message
9
+ end
10
+
11
+ def has_file?(file)
12
+ Dir.entries(@filepath).include?(file) || Dir.entries(@filepath).include?(file.upcase) || Dir.entries(@filepath).include?(file.downcase)
13
+ end
14
+
15
+ def lint_directory
16
+ self.yaml_lint
17
+ self.license_lint
18
+ self.readme_lint
19
+ self.contributing_lint
20
+ @learn_error.result_output
21
+ @learn_error.total_errors
22
+ end
23
+
24
+ def yaml_lint
25
+ if self.has_file?(".learn")
26
+ @learn_error.yaml_error[:present_dotlearn] = true
27
+ @learn_error.present_learn = {message: "present .learn file", color: :green}
28
+ YamlLint.parse_file("#{@filepath}/.learn", @learn_error)
29
+ end
30
+ end
31
+
32
+ def license_lint
33
+ if self.has_file?("LICENSE.md")
34
+ @learn_error.license_error[:present_license] = true
35
+ @learn_error.present_license = {message: "present LICENSE.md", color: :green}
36
+ LicenseLinter.parse_file("#{@filepath}/LICENSE.md", @learn_error)
37
+ end
38
+ end
39
+
40
+ def readme_lint
41
+ if self.has_file?("README.md")
42
+ @learn_error.readme_error[:present_readme] = true
43
+ @learn_error.present_readme = {message: "present README.md", color: :green}
44
+ ReadmeLinter.parse_file("#{@filepath}/README.md", @learn_error)
45
+ end
46
+ end
47
+
48
+ def contributing_lint
49
+ if self.has_file?("CONTRIBUTING.md")
50
+ @learn_error.contributing_error[:present_contributing] = true
51
+ @learn_error.present_contributing = {message: "present CONTRIBUTING.md", color: :green}
52
+ ContributingLinter.parse_file("#{@filepath}/CONTRIBUTING.md", @learn_error)
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,25 @@
1
+ class LearnRepair < LearnBase
2
+
3
+ def initialize(filepath)
4
+ super(filepath)
5
+ cd_into_and(filepath, create_dot_learn_file)
6
+ cd_into_and(filepath, create_support_file("LICENSE.md"))
7
+ cd_into_and(filepath, create_support_file("CONTRIBUTING.md"))
8
+ end
9
+
10
+ def create_dot_learn_file
11
+ `
12
+ cat > .learn <<- EOL
13
+ languages:
14
+ - none
15
+ `
16
+ end
17
+
18
+ def create_support_file(name_of_file)
19
+ # copies a template folder from the learn_create gem to a subfolder of the current directory
20
+ gem_template_location = File.dirname(__FILE__)
21
+ template_path = File.expand_path(gem_template_location) + "/support_files/#{name_of_file}"
22
+ "cp #{template_path} #{@filepath}"
23
+ end
24
+
25
+ end
@@ -0,0 +1,27 @@
1
+ class LicenseLinter
2
+
3
+ VALID_FILE = File.open(File.expand_path(File.dirname(__FILE__)) + '/support_files/LICENSE.md')
4
+ VALID_YEARS = ["2015","2016","2017","2018","2019","2020","2021","2022","2023","2024","2025"]
5
+
6
+ def self.parse_file(file, learn_error)
7
+ directory_file_array = sanitize_whitespace(File.open(file).read)
8
+ valid_file_array = sanitize_whitespace(VALID_FILE.read)
9
+ diff = directory_file_array - valid_file_array
10
+
11
+ VALID_YEARS.each do |year|
12
+ diff.delete(year)
13
+ end
14
+
15
+ if diff.empty?
16
+ learn_error.license_error[:valid_license] = true
17
+ learn_error.valid_license = {message: "valid LICENSE.md", color: :green}
18
+ else
19
+ learn_error.license_error[:valid_license] = false
20
+ learn_error.valid_license = {message: "invalid LICENSE.md - Errors: #{diff}", color: :red}
21
+ end
22
+ end
23
+
24
+ def self.sanitize_whitespace(file)
25
+ file.split.delete_if {|char| char.empty? || char == "\n"}
26
+ end
27
+ end
@@ -0,0 +1,55 @@
1
+ class ReadmeLinter
2
+
3
+ def self.parse_file(file, learn_error)
4
+ if has_code_snippets?(file)
5
+ lines = collect_lines(file)
6
+ validate_snippets(lines, learn_error)
7
+ else
8
+ green_light(learn_error)
9
+ end
10
+ end
11
+
12
+ def self.green_light(learn_error)
13
+ learn_error.readme_error[:valid_readme] = true
14
+ learn_error.valid_readme = {message: "valid readme", color: :green}
15
+ end
16
+
17
+ def self.has_code_snippets?(file)
18
+ file_content = File.open(file).read
19
+ file_content.match(/``/)
20
+ end
21
+
22
+ def self.collect_lines(file)
23
+ lines = {}
24
+ File.foreach(file) do |line_content|
25
+ lines["#{$.}"] = line_content
26
+ end
27
+ lines
28
+ end
29
+
30
+ def self.validate_snippets(lines, learn_error)
31
+ lint_lines(lines, learn_error)
32
+ total_errors?(learn_error)
33
+ end
34
+
35
+ def self.lint_lines(lines, learn_error)
36
+ lines.each do |line_num, line_content|
37
+ if line_content.match(/``/)
38
+ if !(line_content.match(/^```(ruby|rb|bash|sh|swift|html|erb|js|javascript|objc|java|sql|css|text|python)?$/))
39
+ learn_error.valid_readme[:message] << "INVALID CODE SNIPPET - line #{line_num}: #{line_content}"
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ def self.total_errors?(learn_error)
46
+ if error_free?(learn_error)
47
+ green_light(learn_error)
48
+ end
49
+ end
50
+
51
+ def self.error_free?(learn_error)
52
+ learn_error.valid_readme[:message].empty?
53
+ end
54
+ end
55
+
@@ -0,0 +1,44 @@
1
+ require 'yaml'
2
+
3
+ class YamlLint
4
+
5
+
6
+ def self.parse_file(file, learn_error)
7
+ begin
8
+ YAML.load_file(file)
9
+ rescue Exception => err
10
+ learn_error.valid_yaml = {message: "#{err}", color: :red}
11
+ else
12
+ learn_error.yaml_error[:valid_yaml] = true
13
+ if check_attributes(file)
14
+ learn_error.yaml_error[:attributes] = true
15
+ learn_error.correct_yaml_content = {message: "valid attribute key names", color: :green}
16
+ end
17
+ if self.validate_whitespace_for_learn(file)
18
+ learn_error.yaml_error[:valid_whitespace] = true
19
+ learn_error.valid_yaml = {message: "valid yaml and valid whitespace.", color: :green}
20
+ else
21
+ learn_error.valid_yaml = {message: "valid yaml but invalid whitespace", color: :red}
22
+ end
23
+ end
24
+ end
25
+
26
+ def self.validate_whitespace_for_learn(file)
27
+ lines = file_lines(file).split("\n")
28
+ attributes = lines.select { |line| line.include?("-") }
29
+ attributes.each do |attribute|
30
+ return false unless attribute[0..3] == " - "
31
+ end
32
+ true
33
+ end
34
+
35
+ def self.check_attributes(file)
36
+ file_string = file_lines(file)
37
+ file_string.match(/languages/)
38
+ end
39
+
40
+ def self.file_lines(file)
41
+ f = File.read(file)
42
+ end
43
+
44
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: learn-tool
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.16
4
+ version: 0.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - flatironschool
@@ -38,8 +38,18 @@ files:
38
38
  - Rakefile
39
39
  - bin/learn-tool
40
40
  - lib/learn-tool.rb
41
- - lib/support_files/CONTRIBUTING.md
42
- - lib/support_files/LICENSE.md
41
+ - lib/learn-tool/contributing-linter.rb
42
+ - lib/learn-tool/learn-base.rb
43
+ - lib/learn-tool/learn-create.rb
44
+ - lib/learn-tool/learn-duplicate.rb
45
+ - lib/learn-tool/learn-error.rb
46
+ - lib/learn-tool/learn-lint.rb
47
+ - lib/learn-tool/learn-repair.rb
48
+ - lib/learn-tool/license-linter.rb
49
+ - lib/learn-tool/readme-linter.rb
50
+ - lib/learn-tool/support_files/CONTRIBUTING.md
51
+ - lib/learn-tool/support_files/LICENSE.md
52
+ - lib/learn-tool/yaml-linter.rb
43
53
  homepage: https://github.com/learn-co-curriculum/learn-tool
44
54
  licenses:
45
55
  - MIT