learn_linter 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/learn-lint +20 -0
- data/lib/learn_linter/learn_error.rb +52 -0
- data/lib/learn_linter/license_linter.rb +17 -0
- data/lib/learn_linter/readme_linter.rb +33 -0
- data/lib/learn_linter/valid_license.md +7 -0
- data/lib/learn_linter/version.rb +3 -0
- data/lib/learn_linter/yaml_linter.rb +44 -0
- data/lib/learn_linter.rb +58 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ff6709294423453b712f1860fb87d32547883ef4
|
4
|
+
data.tar.gz: 8aad25a7d9c986e6025828c8781e6a4e3c4cd2c0
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bab10c9091c47939a7f5ab3404b7c5b913fe240da5b99bc5817f17b56da64661150abc08505cefd17e14efc9dec2087b20bce3b3d5e868507fbb6dc8411c26d3
|
7
|
+
data.tar.gz: 665585a7d296bfc2b55f4e011f48f7051eae194484c936562d124be21019d9cfe96d94381cdd4c4f9a2bc29b411f4d2a747e6492a828ff0a798435cad7ef251c
|
data/bin/learn-lint
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'yaml'
|
3
|
+
require 'optparse'
|
4
|
+
require_relative '../lib/learn_linter.rb'
|
5
|
+
|
6
|
+
if ARGV.length == 0
|
7
|
+
dir = File.expand_path(File.dirname(File.dirname(__FILE__)))
|
8
|
+
lint = LearnLinter.new(dir).lint_directory
|
9
|
+
elsif ARGV.length == 1 && ARGV[0] == "quiet"
|
10
|
+
dir = File.expand_path(File.dirname(File.dirname(__FILE__)))
|
11
|
+
lint = LearnLinter.new(dir, "quiet")
|
12
|
+
elsif ARGV.length > 1 && ARGV[1] == "quiet"
|
13
|
+
lint = LearnLinter.new(ARGV[0], "quiet").lint_directory
|
14
|
+
elsif ARGV.length > 1 && ARG[1] != "quiet"
|
15
|
+
puts "please use 'learn-lint directory_name quiet' or 'learn-lint directory_name"
|
16
|
+
elsif ARGV.length == 1
|
17
|
+
lint = LearnLinter.new(ARGV[0]).lint_directory
|
18
|
+
end
|
19
|
+
|
20
|
+
|
@@ -0,0 +1,52 @@
|
|
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
|
+
|
6
|
+
ESCAPES = { :green => "\033[32m",
|
7
|
+
:yellow => "\033[33m",
|
8
|
+
:red => "\033[31m",
|
9
|
+
:reset => "\033[0m" }
|
10
|
+
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@yaml_error = {present_dotlearn: false, valid_yaml: false, valid_whitespace: false, attributes: false}
|
14
|
+
@readme_error = {present_readme: false, valid_readme: false}
|
15
|
+
@license_error = {present_license: false, valid_license: false}
|
16
|
+
@correct_yaml_content = {message: ".learn file must have 'tags', 'resources' and 'languages' keys", color: :yellow}
|
17
|
+
@valid_yaml = {message: "invalid yaml", color: :red}
|
18
|
+
@valid_license = {message: "invalid or missing license content", color: :yellow}
|
19
|
+
@valid_readme = {message: "invalid code snippet. Must have three backticks to open and close all code snippets", color: :red}
|
20
|
+
@present_learn = {message: "missing .learn file", color: :red}
|
21
|
+
@present_license = {message: "missing LICENSE.md", color: :red}
|
22
|
+
@present_readme = {message: "missing README.md", color: :yellow}
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
def emit(opts={})
|
27
|
+
color = opts[:color]
|
28
|
+
message = opts[:message]
|
29
|
+
print ESCAPES[color]
|
30
|
+
print message
|
31
|
+
print ESCAPES[:reset]
|
32
|
+
print "\n"
|
33
|
+
end
|
34
|
+
|
35
|
+
def total_errors
|
36
|
+
{
|
37
|
+
dot_learn: yaml_error,
|
38
|
+
license: license_error,
|
39
|
+
readme: readme_error
|
40
|
+
}
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
def result_output
|
46
|
+
all_results = [present_learn, valid_yaml, correct_yaml_content, present_license, valid_license, present_readme, valid_readme]
|
47
|
+
all_results.each do |result|
|
48
|
+
emit(result)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class LicenseLinter
|
2
|
+
|
3
|
+
VALID_FILE = File.open(File.expand_path(File.dirname(__FILE__)) + '/valid_license.md')
|
4
|
+
|
5
|
+
def self.parse_file(file, learn_error)
|
6
|
+
directory_file = File.open(file).read
|
7
|
+
valid_file = VALID_FILE.read
|
8
|
+
if sanitize_whitespace(directory_file) == sanitize_whitespace(valid_file)
|
9
|
+
learn_error.license_error[:valid_license] = true
|
10
|
+
learn_error.valid_license = {message: "valid license", color: :green}
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.sanitize_whitespace(file)
|
15
|
+
file.split("\n").delete_if { |l| l.empty? }
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class ReadmeLinter
|
2
|
+
|
3
|
+
def self.parse_file(file, learn_error)
|
4
|
+
file_string = File.open(file).read
|
5
|
+
if has_code_snippets?(file_string)
|
6
|
+
validate_snippets(file_string, 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.match(/``/)
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.validate_snippets(file, learn_error)
|
22
|
+
file.split(" ").each do |chars|
|
23
|
+
if chars.match(/``/)
|
24
|
+
if !(chars.match(/```ruby/) || chars.match(/```bash/) || chars.match(/```objc/) || chars.match(/```javascript/) || chars.match(/``` /))
|
25
|
+
break
|
26
|
+
else
|
27
|
+
green_light(learn_error)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
#Learn.co Educational Content License
|
2
|
+
|
3
|
+
Copyright (c) 2015 Flatiron School, Inc
|
4
|
+
|
5
|
+
The Flatiron School, Inc. owns this Educational Content. However, the Flatiron School supports the development and availability of educational materials in the public domain. Therefore, the Flatiron School grants Users of the Flatiron Educational Content set forth in this repository certain rights to reuse, build upon and share such Educational Content subject to the terms of the Educational Content License set forth [here](http://learn.co/content-license) (http://learn.co/content-license). You must read carefully the terms and conditions contained in the Educational Content License as such terms govern access to and use of the Educational Content.
|
6
|
+
|
7
|
+
Flatiron School is willing to allow you access to and use of the Educational Content only on the condition that you accept all of the terms and conditions contained in the Educational Content License set forth [here](http://learn.co/content-license) (http://learn.co/content-license). By accessing and/or using the Educational Content, you are agreeing to all of the terms and conditions contained in the Educational Content License. If you do not agree to any or all of the terms of the Educational Content License, you are prohibited from accessing, reviewing or using in any way the Educational Content.
|
@@ -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(/tags/) && file_string.match(/resources/) && file_string.match(/languages/)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.file_lines(file)
|
41
|
+
f = File.read(file)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
data/lib/learn_linter.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative './learn_linter/version'
|
2
|
+
require_relative './learn_linter/learn_error'
|
3
|
+
require_relative './learn_linter/license_linter'
|
4
|
+
require_relative './learn_linter/readme_linter'
|
5
|
+
require_relative './learn_linter/yaml_linter'
|
6
|
+
|
7
|
+
class LearnLinter
|
8
|
+
|
9
|
+
attr_accessor :filepath, :quiet
|
10
|
+
|
11
|
+
|
12
|
+
def initialize(filepath, quiet=nil)
|
13
|
+
@filepath = filepath
|
14
|
+
@learn_error = LearnError.new
|
15
|
+
@quiet = quiet
|
16
|
+
end
|
17
|
+
|
18
|
+
def lint_directory
|
19
|
+
self.yaml_lint
|
20
|
+
self.license_lint
|
21
|
+
self.readme_lint
|
22
|
+
unless quiet
|
23
|
+
@learn_error.result_output
|
24
|
+
end
|
25
|
+
@learn_error.total_errors
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
def has_file?(file)
|
31
|
+
Dir.entries(filepath).include?(file)
|
32
|
+
end
|
33
|
+
|
34
|
+
def yaml_lint
|
35
|
+
if self.has_file?(".learn")
|
36
|
+
@learn_error.yaml_error[:present_dotlearn] = true
|
37
|
+
@learn_error.present_learn = {message: "present .learn file", color: :green}
|
38
|
+
YamlLint.parse_file("#{filepath}/.learn", @learn_error)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def license_lint
|
43
|
+
if self.has_file?("LICENSE.md")
|
44
|
+
@learn_error.license_error[:present_license] = true
|
45
|
+
@learn_error.present_license = {message: "present LICENSE.md", color: :green}
|
46
|
+
LicenseLinter.parse_file("#{filepath}/LICENSE.md", @learn_error)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def readme_lint
|
51
|
+
if self.has_file?("README.md")
|
52
|
+
@learn_error.readme_error[:present_readme] = true
|
53
|
+
@learn_error.present_readme = {message: "present README.md", color: :green}
|
54
|
+
ReadmeLinter.parse_file("#{filepath}/README.md", @learn_error)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: learn_linter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sophie DeBenedetto
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.10'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- sophie.debenedetto@gmail.com
|
58
|
+
executables:
|
59
|
+
- learn-lint
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- bin/learn-lint
|
64
|
+
- lib/learn_linter.rb
|
65
|
+
- lib/learn_linter/learn_error.rb
|
66
|
+
- lib/learn_linter/license_linter.rb
|
67
|
+
- lib/learn_linter/readme_linter.rb
|
68
|
+
- lib/learn_linter/valid_license.md
|
69
|
+
- lib/learn_linter/version.rb
|
70
|
+
- lib/learn_linter/yaml_linter.rb
|
71
|
+
homepage: ''
|
72
|
+
licenses:
|
73
|
+
- MIT
|
74
|
+
metadata:
|
75
|
+
allowed_push_host: https://rubygems.org
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.4.6
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: can lint a directory for valid .learn, license files
|
96
|
+
test_files: []
|