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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b34b01d253e7286a465aa34598043b994e5997d5
4
- data.tar.gz: af1030f04a8d51f41d817bd98f309ff6d8bbabfd
3
+ metadata.gz: 26d60357a6871f0590d114c6d082b501425a42b4
4
+ data.tar.gz: 359918fc37af558a46a250e29ac019caeb7fa543
5
5
  SHA512:
6
- metadata.gz: ba1a5cf48693d99d3c337ac45c4610515705360f7a76bffd9b1af49fdd288ea1a515fb584609272c52cdfe0c0e2174d0488b775f895819699fcd7cd9aa23c4bb
7
- data.tar.gz: 614e2160612c5711b11d4c1bf76d4b82fa0460df2fb81b4c5e90d3c22183898bf60c0fb880688922225dddf888457bee85745a0e7cd328b26b3c02d14130ad7f
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 --path="/path/to/your/frontend/code/dir" --verbose
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
- @options = {
8
- path: options[:path] || Dir.pwd,
9
- verbose: options[:verbose]
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
- package_json = get_package_json(@options[:path])
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
- if package_json
17
- package_json_data = parse_package_json(package_json)
18
- @installed_modules = get_installed_modules
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
- if package_json_data && package_json_data.key?('dependencies')
22
- dependencies = package_json_data['dependencies']
23
- check_dependencies(dependencies)
24
- end
42
+ rescue WrongPathError => e
43
+ output("There is no '#{e.message}' directory.")
25
44
 
26
- if package_json_data && package_json_data.key?('devDependencies')
27
- dev_dependencies = package_json_data['devDependencies']
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
- private
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
- def pluralize
35
- ActiveSupport::Inflector.pluralize(self)
63
+ return success
64
+ end
36
65
  end
37
66
 
38
- def get_installed_modules
39
- modules_directory = File.join(@options[:path], 'node_modules')
67
+ private
40
68
 
41
- if Dir.exist?(modules_directory)
42
- modules = {}
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).each do |entry|
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 get_package_json(directory)
63
- file_path = File.join(directory, 'package.json')
64
-
65
- if File.file?(file_path)
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(json)
75
- rescue JSON::ParserError => error
76
- raise error
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 = 'dependencies')
81
- puts "Check #{type}..." if @options[:verbose]
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
- if @installed_modules.key?(dep)
87
- package_json = get_package_json(@installed_modules[dep])
88
- package_json_data = parse_package_json(package_json)
89
- missed_dependencies.push(dep) unless package_json_data && package_json_data['name'] == dep
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
- if missed_dependencies.any?
96
- message = [
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
- option :path
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
@@ -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
@@ -0,0 +1,14 @@
1
+ module Npmdc
2
+ module Formatters
3
+ class ShortFormatter < BaseFormatter
4
+ def dep_output(dep, status, options = {})
5
+ end
6
+
7
+ def check_start_output(type)
8
+ end
9
+
10
+ def check_finish_output
11
+ end
12
+ end
13
+ end
14
+ end
data/lib/npmdc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Npmdc
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
data/npmdc.gemspec CHANGED
@@ -24,4 +24,5 @@ Gem::Specification.new do |spec|
24
24
  spec.add_development_dependency 'bundler', '~> 1.13'
25
25
  spec.add_development_dependency 'rake', '~> 10.0'
26
26
  spec.add_development_dependency 'rspec', '~> 3.0'
27
+ spec.add_development_dependency 'colorize', '~> 0.8.1'
27
28
  end
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.1.2
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-30 00:00:00.000000000 Z
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