npmdc 0.1.2 → 0.2.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/CHANGELOG.md +12 -0
- data/README.md +14 -1
- data/lib/npmdc/checker.rb +75 -74
- data/lib/npmdc/cli.rb +4 -2
- data/lib/npmdc/errors.rb +9 -0
- data/lib/npmdc/formatter.rb +21 -0
- data/lib/npmdc/formatters/base_formatter.rb +45 -0
- data/lib/npmdc/formatters/documentation_formatter.rb +14 -0
- data/lib/npmdc/formatters/progress_formatter.rb +18 -0
- data/lib/npmdc/formatters/short_formatter.rb +14 -0
- data/lib/npmdc/version.rb +1 -1
- data/npmdc.gemspec +1 -0
- metadata +22 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26d60357a6871f0590d114c6d082b501425a42b4
|
4
|
+
data.tar.gz: 359918fc37af558a46a250e29ac019caeb7fa543
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bcd8679aef9341352d09f4799deb2aa0aeb471409168eb74a3280bbf6f17ab35baea9b4dc0f42b030a1612d3a72602b3a5b2cb69bdcbded267ee04c9ae288e8f
|
7
|
+
data.tar.gz: afd9ef02c3fe2f49d2499d00703ddcfcb521dd87c9923512f9443ded6b5af4e766c29b40558c13ebc23210311a82332ec8e733d7d322638453142c8a7f726fa7
|
data/CHANGELOG.md
CHANGED
@@ -21,3 +21,15 @@ Initial implementation of Npmdc gem with following features:
|
|
21
21
|
* Better JSON parser errors - now with more details
|
22
22
|
|
23
23
|
* Fixed deprecated methods
|
24
|
+
|
25
|
+
### 0.2.0
|
26
|
+
|
27
|
+
Thanks to @aderyabin !
|
28
|
+
|
29
|
+
* Output formatters
|
30
|
+
|
31
|
+
* Colorized output
|
32
|
+
|
33
|
+
* Added specs
|
34
|
+
|
35
|
+
* Refactored and optimized
|
data/README.md
CHANGED
@@ -37,6 +37,8 @@ YourApp::Application.configure do
|
|
37
37
|
config.npmdc = {
|
38
38
|
:path => "/path/to/your/frontend/code/dir" # `Rails.root` by default,
|
39
39
|
:verbose => true # `false` by default
|
40
|
+
:'no-color' => true # `false` by default
|
41
|
+
:format => "doc" # `short`, `doc`, `progress`. `short` by default
|
40
42
|
}
|
41
43
|
end
|
42
44
|
```
|
@@ -44,10 +46,21 @@ end
|
|
44
46
|
### CLI tool:
|
45
47
|
|
46
48
|
```bash
|
47
|
-
$ bundle exec npmdc
|
49
|
+
$ bundle exec npmdc [options]
|
48
50
|
|
49
51
|
```
|
50
52
|
|
53
|
+
_Options:_
|
54
|
+
|
55
|
+
* --path PATH - Path to frontend code
|
56
|
+
|
57
|
+
* -V, --verbose - Set the verbose level of output
|
58
|
+
|
59
|
+
* --no-color - Disable color formatting of output
|
60
|
+
|
61
|
+
* --format FORMAT - Set format of output
|
62
|
+
|
63
|
+
|
51
64
|
## Development
|
52
65
|
|
53
66
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/npmdc/checker.rb
CHANGED
@@ -1,109 +1,110 @@
|
|
1
|
+
require 'colorize'
|
1
2
|
require 'json'
|
2
3
|
require 'active_support/inflector'
|
4
|
+
require 'npmdc/formatter'
|
5
|
+
require 'npmdc/errors'
|
6
|
+
require 'forwardable'
|
3
7
|
|
4
8
|
module Npmdc
|
5
9
|
class Checker
|
10
|
+
extend Forwardable
|
11
|
+
include Npmdc::Errors
|
12
|
+
|
13
|
+
attr_accessor :path, :formatter
|
14
|
+
|
15
|
+
DEPENDENCIES = %w(dependencies devDependencies).freeze
|
16
|
+
|
6
17
|
def initialize(options)
|
7
|
-
@
|
8
|
-
|
9
|
-
|
10
|
-
|
18
|
+
@path = options['path'] || Dir.pwd
|
19
|
+
@formatter = Npmdc::Formatter.(options)
|
20
|
+
@dependencies_count = 0
|
21
|
+
@missed_dependencies = []
|
11
22
|
end
|
12
23
|
|
24
|
+
delegate [:output, :dep_output, :check_start_output, :check_finish_output] => :formatter
|
25
|
+
|
13
26
|
def call
|
14
|
-
|
27
|
+
begin
|
28
|
+
success = false
|
29
|
+
package_json_data = package_json(@path)
|
30
|
+
DEPENDENCIES.each do |dep|
|
31
|
+
if package_json_data[dep]
|
32
|
+
begin
|
33
|
+
check_dependencies(package_json_data[dep], dep)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
15
37
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
end
|
38
|
+
rescue NoNodeModulesError => e
|
39
|
+
output("Failed! Can't find `node_modules` folder inside '#{e.message}' directory!")
|
40
|
+
output("\nRun `npm install` to install missing packages.", :warn)
|
20
41
|
|
21
|
-
|
22
|
-
|
23
|
-
check_dependencies(dependencies)
|
24
|
-
end
|
42
|
+
rescue WrongPathError => e
|
43
|
+
output("There is no '#{e.message}' directory.")
|
25
44
|
|
26
|
-
|
27
|
-
|
28
|
-
check_dependencies(dev_dependencies, 'devDependencies')
|
29
|
-
end
|
30
|
-
end
|
45
|
+
rescue MissedPackageError => e
|
46
|
+
output("There is no `package.json` file inside '#{e.message}' directory.")
|
31
47
|
|
32
|
-
|
48
|
+
rescue JsonParseError => e
|
49
|
+
output("Can't parse JSON file #{e.message}")
|
50
|
+
else
|
51
|
+
success = true unless !@missed_dependencies.empty?
|
52
|
+
ensure
|
53
|
+
if !@missed_dependencies.empty?
|
54
|
+
output("Following dependencies required by your package.json file are missing or not installed properly:")
|
55
|
+
@missed_dependencies.uniq.each do |dep|
|
56
|
+
output(" * #{dep}")
|
57
|
+
end
|
58
|
+
output("\nRun `npm install` to install #{@missed_dependencies.uniq.count} missed packages.", :warn)
|
59
|
+
elsif success
|
60
|
+
output("#{@dependencies_count} #{"package".pluralize(@dependencies_count)} checked. Everything is ok.", :success)
|
61
|
+
end
|
33
62
|
|
34
|
-
|
35
|
-
|
63
|
+
return success
|
64
|
+
end
|
36
65
|
end
|
37
66
|
|
38
|
-
|
39
|
-
modules_directory = File.join(@options[:path], 'node_modules')
|
67
|
+
private
|
40
68
|
|
41
|
-
|
42
|
-
|
69
|
+
def installed_modules
|
70
|
+
@installed_modules ||= begin
|
71
|
+
modules_directory = File.join(@path, 'node_modules')
|
72
|
+
raise NoNodeModulesError, @path unless Dir.exist?(modules_directory)
|
43
73
|
|
44
|
-
Dir.entries(modules_directory).
|
74
|
+
Dir.entries(modules_directory).each_with_object({}) do |entry, modules|
|
45
75
|
if entry != '.' && entry != '..' and File.directory? File.join(modules_directory, entry)
|
46
|
-
modules[entry] = File.join(modules_directory, entry)
|
76
|
+
modules[entry] = package_json(File.join(modules_directory, entry))
|
47
77
|
end
|
48
78
|
end
|
49
|
-
|
50
|
-
modules
|
51
|
-
else
|
52
|
-
message = [
|
53
|
-
"Failed! Can't find `node_modules` folder inside '#{@options[:path]}' directory!",
|
54
|
-
'Try running `npm install` first.'
|
55
|
-
].join("\n")
|
56
|
-
|
57
|
-
puts message
|
58
|
-
exit
|
59
79
|
end
|
60
80
|
end
|
61
81
|
|
62
|
-
def
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
File.read(file_path)
|
67
|
-
else
|
68
|
-
puts "There is no `package.json` file inside '#{directory}' directory." if @options[:verbose]
|
69
|
-
end
|
70
|
-
end
|
82
|
+
def package_json(directory, filename = 'package.json')
|
83
|
+
raise WrongPathError, directory unless Dir.exist?(directory)
|
84
|
+
file_path = File.join(directory, filename)
|
85
|
+
raise MissedPackageError, directory unless File.file?(file_path)
|
71
86
|
|
72
|
-
def parse_package_json(json)
|
73
87
|
begin
|
74
|
-
JSON.parse(
|
75
|
-
rescue JSON::ParserError
|
76
|
-
raise
|
88
|
+
JSON.parse(File.read(file_path))
|
89
|
+
rescue JSON::ParserError
|
90
|
+
raise JsonParseError, file_path
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
80
|
-
def check_dependencies(deps = {}, type
|
81
|
-
|
82
|
-
|
83
|
-
missed_dependencies = []
|
84
|
-
|
94
|
+
def check_dependencies(deps = {}, type)
|
95
|
+
installed_modules
|
96
|
+
check_start_output(type)
|
85
97
|
deps.keys.each do |dep|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
else
|
91
|
-
missed_dependencies.push(dep)
|
92
|
-
end
|
98
|
+
@dependencies_count += 1
|
99
|
+
status = valid_dependency?(dep) ? :success : :failure
|
100
|
+
@missed_dependencies.push("#{dep}@#{deps[dep]}") unless valid_dependency?(dep)
|
101
|
+
dep_output(dep, status)
|
93
102
|
end
|
103
|
+
check_finish_output
|
104
|
+
end
|
94
105
|
|
95
|
-
|
96
|
-
|
97
|
-
"Failed! Following #{type} required by your package.json file are missing or not installed properly:\n",
|
98
|
-
missed_dependencies.map { |dep| "* #{dep}@#{deps[dep]}" },
|
99
|
-
"\nRun `npm install` to install #{missed_dependencies.length} missing #{'package'.pluralize(missed_dependencies.length)}.",
|
100
|
-
].join("\n")
|
101
|
-
|
102
|
-
puts message
|
103
|
-
exit
|
104
|
-
else
|
105
|
-
puts "OK! #{deps.length} #{'dependency'.pluralize(deps.length)} checked." if @options[:verbose]
|
106
|
-
end
|
106
|
+
def valid_dependency?(dep)
|
107
|
+
!!installed_modules[dep]
|
107
108
|
end
|
108
109
|
end
|
109
110
|
end
|
data/lib/npmdc/cli.rb
CHANGED
@@ -3,11 +3,13 @@ require 'npmdc'
|
|
3
3
|
|
4
4
|
module Npmdc
|
5
5
|
class Cli < Thor
|
6
|
-
class_option 'verbose', type: :boolean, desc: 'Enable verbose output mode', aliases: '-V'
|
7
6
|
default_task :check
|
8
7
|
|
9
8
|
desc 'check', 'Run check'
|
10
|
-
|
9
|
+
method_option :path, desc: 'Path to package.json config'
|
10
|
+
method_option :'no-color', desc: 'Disable color', type: :boolean
|
11
|
+
method_option :format, desc: "Output format, possible values: #{Npmdc::Formatter::FORMATTERS.keys.join(", ")}"
|
12
|
+
|
11
13
|
def check
|
12
14
|
Npmdc::Checker.new(options).call
|
13
15
|
end
|
data/lib/npmdc/errors.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
module Npmdc
|
2
|
+
module Errors
|
3
|
+
class NoNodeModulesError < StandardError; end
|
4
|
+
class MissedPackageError < StandardError; end
|
5
|
+
class JsonParseError < StandardError; end
|
6
|
+
class MissedDepsError < StandardError; end
|
7
|
+
class WrongPathError < StandardError; end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Dir["#{File.dirname(__FILE__)}/formatters/*.rb"].each { |file| require file }
|
2
|
+
|
3
|
+
module Npmdc
|
4
|
+
module Formatter
|
5
|
+
|
6
|
+
FORMATTERS = {
|
7
|
+
progress: Npmdc::Formatters::ProgressFormatter,
|
8
|
+
doc: Npmdc::Formatters::DocumentationFormatter,
|
9
|
+
short: Npmdc::Formatters::ShortFormatter,
|
10
|
+
}.freeze
|
11
|
+
|
12
|
+
DEFAULT_FORMAT = :short
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def call(options)
|
16
|
+
fmt = options['format'] || options[:format] || DEFAULT_FORMAT
|
17
|
+
FORMATTERS[fmt.to_sym].new(options)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'colorized_string'
|
2
|
+
|
3
|
+
module Npmdc
|
4
|
+
module Formatters
|
5
|
+
class BaseFormatter
|
6
|
+
|
7
|
+
COLORS = {
|
8
|
+
success: :green,
|
9
|
+
failure: :red,
|
10
|
+
warn: :yellow,
|
11
|
+
info: :white
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
def initialize(options, output = $stdout)
|
15
|
+
@options = options
|
16
|
+
@output = output
|
17
|
+
@disable_colorization = !!(@options['no-color'] || @options['no_color'])
|
18
|
+
end
|
19
|
+
|
20
|
+
def output(message, status = nil)
|
21
|
+
@output.puts color_message(message, status)
|
22
|
+
end
|
23
|
+
|
24
|
+
def check_finish_output
|
25
|
+
@output.puts "\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
def check_start_output(type)
|
29
|
+
@output.puts "Checking #{type}:"
|
30
|
+
end
|
31
|
+
|
32
|
+
def color_message(message, status = nil)
|
33
|
+
if @disable_colorization || !status
|
34
|
+
message
|
35
|
+
else
|
36
|
+
ColorizedString[message].colorize(color(status))
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def color(status)
|
41
|
+
COLORS[status]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Npmdc
|
2
|
+
module Formatters
|
3
|
+
class DocumentationFormatter < BaseFormatter
|
4
|
+
def dep_output(dep, status, options = {})
|
5
|
+
case status
|
6
|
+
when :success
|
7
|
+
@output.puts color_message(" ✓ #{dep}", status)
|
8
|
+
when :failure
|
9
|
+
@output.puts color_message(" ✗ #{dep}", status)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Npmdc
|
2
|
+
module Formatters
|
3
|
+
class ProgressFormatter < BaseFormatter
|
4
|
+
def dep_output(dep, status, options = {})
|
5
|
+
case status
|
6
|
+
when :success
|
7
|
+
@output.print color_message(".", status)
|
8
|
+
when :failure
|
9
|
+
@output.print color_message("F", status)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def check_finish_output
|
14
|
+
2.times { @output.puts "\n" }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/npmdc/version.rb
CHANGED
data/npmdc.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: npmdc
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emil Kashkevich
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -86,6 +86,20 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '3.0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: colorize
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: 0.8.1
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.8.1
|
89
103
|
description: Check for missed dependencies of NPM packages based on dependency list
|
90
104
|
specified in package.json file.
|
91
105
|
email:
|
@@ -112,6 +126,12 @@ files:
|
|
112
126
|
- lib/npmdc.rb
|
113
127
|
- lib/npmdc/checker.rb
|
114
128
|
- lib/npmdc/cli.rb
|
129
|
+
- lib/npmdc/errors.rb
|
130
|
+
- lib/npmdc/formatter.rb
|
131
|
+
- lib/npmdc/formatters/base_formatter.rb
|
132
|
+
- lib/npmdc/formatters/documentation_formatter.rb
|
133
|
+
- lib/npmdc/formatters/progress_formatter.rb
|
134
|
+
- lib/npmdc/formatters/short_formatter.rb
|
115
135
|
- lib/npmdc/railtie.rb
|
116
136
|
- lib/npmdc/version.rb
|
117
137
|
- npmdc.gemspec
|