mudguard 0.1.4 → 0.1.5

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
  SHA256:
3
- metadata.gz: e84d450c1adfd300b6be1e11244dd8eec43bc4ef2dffdd090974290591bce06f
4
- data.tar.gz: c36b94a49c130dc29b6ce80befc227121348c53b977a88451337bc6987b5a0fa
3
+ metadata.gz: c6b60554fbef1a22d26bcc61a3b7362f9351d3a86464e1e1e3c29f44d6f8d44f
4
+ data.tar.gz: 2a3617b3c12dc0ce2ecafdf09b6b0d9eb1464b3f51e7f93360c875fc5d63a3ff
5
5
  SHA512:
6
- metadata.gz: 4db49720f6381c3c67a7e2e669235e070d8ed2cb650f48f41752dd95a243da43dc1bbc7bec7947828fd40c7abf3c7dc786c366cd04efb026d2c732cc5908d8d2
7
- data.tar.gz: 84291c975dce9b7b893ae831dcfc54cafe16313d17b86f590d27a529b231fe4e1c2a4683455746c7a5143bbf880fe39f17ffb7be16954a63647eb98bda5a22ad
6
+ metadata.gz: 647203da7407adc474020ab9b559847ba0cdcbf308a031ca980f02d63c45222abc52c144c03f7bbc497f24f23a37541cb37f45fd555079b44f5d95bbe6c2fcba
7
+ data.tar.gz: 576533ce4ca809ea053bb8c3ea36f6ed20b51b989f071bbfb10204b91ecf1196d82e9af4132a92b431621618b6c5e8da09d1c8d6c9c1181664a4c67111a4277d
data/.gitignore CHANGED
@@ -13,3 +13,6 @@
13
13
  # Ignore RSpec Working Dir
14
14
  /.rspec
15
15
  .rspec_status
16
+
17
+ # Ignore pkg (gem dir)
18
+ /pkg
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mudguard (0.1.4)
4
+ mudguard (0.1.5)
5
5
  parser (~> 2.7)
6
6
 
7
7
  GEM
data/Guardfile CHANGED
@@ -12,5 +12,5 @@ guard "rspec", rspec_options do
12
12
  watch(%r{^lib/mudguard/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
13
13
  watch(%r{^lib/mudguard/(.+)\.rb$}) { |m| Dir.glob("spec/lib/#{m[1]}_*.rb") }
14
14
  watch("spec/spec_helper.rb") { "spec" }
15
- watch(%r{^exe\/mudguard$}) { |_| "spec/bin/mudguard_spec.rb" }
15
+ watch(%r{^exe\/mudguard$}) { |_| "spec/exe/mudguard_spec.rb" }
16
16
  end
data/exe/mudguard CHANGED
@@ -1,20 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- require "mudguard"
5
- require "optparse"
4
+ require "mudguard/infrastructure/cli/view"
5
+ require "mudguard/infrastructure/cli/controller"
6
6
 
7
7
  # Checks the dependencies of a ruby project
8
8
  module Mudguard
9
- parser = OptionParser.new do |opts|
10
- opts.banner = "Usage: mudguard [options] [directory]"
11
- opts.on("-h", "--help", "Prints this help") do
12
- puts opts
13
- exit
14
- end
15
- end
16
-
17
- directories = parser.parse!
18
- ok = directories.all?(&Mudguard.method(:check))
9
+ view = Mudguard::Infrastructure::Cli::View.new
10
+ parser = Mudguard::Infrastructure::Cli::Controller.new(view: view)
11
+ ok = parser.parse!(ARGV)
19
12
  exit(ok ? 0 : 1)
20
13
  end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../infrastructure/persistence/policy_file"
4
+ require_relative "../infrastructure/persistence/ruby_files"
5
+
6
+ # Contains methods to check if your project is a bit muddy
7
+ module Mudguard
8
+ # API to mudguard
9
+ module Application
10
+ class << self
11
+ def check(project_path, notification)
12
+ policy_file_path = File.expand_path("MudguardFile", project_path)
13
+ policies = Infrastructure::Persistence::PolicyFile.read(policy_file_path)
14
+
15
+ policies.check(Infrastructure::Persistence::RubyFiles.all(project_path), notification)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mudguard
4
+ module Domain
5
+ # A Dependency between Modules
6
+ class Dependency
7
+ def initialize(location: nil, dependency:)
8
+ @location = location
9
+ @dependency = dependency
10
+ end
11
+
12
+ def inspect
13
+ "{#{@location}, #{@dependency}}"
14
+ end
15
+
16
+ def to_s
17
+ "#{@location} #{@dependency}"
18
+ end
19
+
20
+ def match(policy)
21
+ @dependency.match(policy)
22
+ end
23
+
24
+ def ==(other)
25
+ @location == other.instance_eval { @location } &&
26
+ @dependency == other.instance_eval { @dependency }
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mudguard
4
- class Error < StandardError
4
+ module Domain
5
+ class Error < StandardError
6
+ end
5
7
  end
6
8
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mudguard
4
+ module Domain
5
+ # Contains the policies to be enforced
6
+ class Policies
7
+ def initialize(policies: [])
8
+ @policies = policies.map { |l| l.gsub(/\s/, "") }.map { |p| /^#{p}/ }
9
+ end
10
+
11
+ def check(sources, notification)
12
+ result = check_sources(sources, notification)
13
+
14
+ count = result[:count]
15
+ violations = result[:violations]
16
+
17
+ files = pluralize("file", count)
18
+ problems = pluralize("problem", violations)
19
+ notification.add("#{count} #{files} inspected, #{violations} #{problems} detected")
20
+ violations.zero?
21
+ end
22
+
23
+ private
24
+
25
+ def pluralize(word, count)
26
+ count == 1 ? word : "#{word}s"
27
+ end
28
+
29
+ def check_sources(sources, notification)
30
+ sources.each_with_object(count: 0, violations: 0) do |source, result|
31
+ result[:count] += 1
32
+ dependencies = source.find_mod_dependencies
33
+ result[:violations] += check_dependencies(dependencies, notification)
34
+ end
35
+ end
36
+
37
+ def check_dependencies(dependencies, notification)
38
+ dependencies.reject { |d| check_dependency(d, notification) }.count
39
+ end
40
+
41
+ def check_dependency(dependency, notification)
42
+ is_allowed = @policies.any? { |p| dependency.match(p) }
43
+ notification.add("#{dependency} not allowed") unless is_allowed
44
+ is_allowed
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,14 +1,28 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "parser/current"
4
+ require "mudguard/domain/dependency"
4
5
 
5
6
  module Mudguard
6
- # Analyses Ruby-Source and returns extracted information
7
- class RubyAnalyser
8
- class << self
9
- def find_mod_dependencies(source)
7
+ module Domain
8
+ # Represents a Ruby source file
9
+ class Source
10
+ def initialize(location: nil, code:)
11
+ @code = code
12
+ @location = location
13
+ end
14
+
15
+ def ==(other)
16
+ @code == other.instance_eval { @code } && @location == other.instance_eval { @location }
17
+ end
18
+
19
+ def inspect
20
+ @location
21
+ end
22
+
23
+ def find_mod_dependencies
10
24
  begin
11
- root = Parser::CurrentRuby.parse(source)
25
+ root = Parser::CurrentRuby.parse(@code)
12
26
  rescue Parser::SyntaxError
13
27
  return []
14
28
  end
@@ -26,12 +40,18 @@ module Mudguard
26
40
  when type?(:class)
27
41
  process_class(node.children, module_name)
28
42
  when type?(:const)
29
- ["#{module_name}->#{find_const_name(node.children)}"]
43
+ [create_dependency(module_name, node)]
30
44
  else
31
45
  ignore_and_continue(node, module_name)
32
46
  end
33
47
  end
34
48
 
49
+ def create_dependency(module_name, node)
50
+ dependency = "#{module_name}->#{find_const_name(node.children)}"
51
+ location = "#{@location}:#{node.location.line}"
52
+ Dependency.new(location: location, dependency: dependency)
53
+ end
54
+
35
55
  def ignore_and_continue(node, module_name)
36
56
  case node
37
57
  when children?
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require "mudguard/application/application"
5
+ require_relative "notification_adapter"
6
+
7
+ module Mudguard
8
+ module Infrastructure
9
+ module Cli
10
+ # Parses the cli arguments
11
+ class Controller
12
+ def initialize(view:)
13
+ @view = view
14
+ @done = false
15
+ @parser = ::OptionParser.new do |opts|
16
+ opts.banner = "Usage: mudguard [options] [directory]"
17
+ opts.on("-h", "--help", "Prints this help") do
18
+ view.print(opts.to_s)
19
+ @done = true
20
+ end
21
+ end
22
+ end
23
+
24
+ def parse!(argv)
25
+ directories = @parser.parse!(argv)
26
+
27
+ return true if @done
28
+
29
+ notification = NotificationAdapter.new(view: @view)
30
+ directories = [Dir.pwd] if directories.empty?
31
+ directories.all? { |d| Mudguard::Application.check(d, notification) }
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mudguard
4
+ module Infrastructure
5
+ module Cli
6
+ # Forwards Notification to the view for printing
7
+ class NotificationAdapter
8
+ def initialize(view:)
9
+ @view = view
10
+ end
11
+
12
+ def add(text)
13
+ @view.print(text)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mudguard
4
+ module Infrastructure
5
+ module Cli
6
+ # Handles user input
7
+ class View
8
+ def print(text)
9
+ puts text
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../../domain/policies"
4
+ require_relative "../../domain/error"
5
+
6
+ module Mudguard
7
+ module Infrastructure
8
+ module Persistence
9
+ # A file containing the Mudguard-Policies
10
+ class PolicyFile
11
+ def self.read(policy_file)
12
+ policy_exists = File.exist?(policy_file)
13
+
14
+ unless policy_exists
15
+ raise Mudguard::Domain::Error, "expected policy file #{policy_file} doesn't exists"
16
+ end
17
+
18
+ Mudguard::Domain::Policies.new(policies: File.readlines(policy_file))
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "mudguard/domain/source"
4
+
5
+ module Mudguard
6
+ module Infrastructure
7
+ module Persistence
8
+ # Provides access to all ruby-files of a project
9
+ class RubyFiles
10
+ class << self
11
+ def all(project_path)
12
+ project_exists = Dir.exist?(project_path)
13
+
14
+ unless project_exists
15
+ raise Mudguard::Domain::Error, "expected project #{project_path} doesn't exists"
16
+ end
17
+
18
+ enumerate_files(project_path)
19
+ end
20
+
21
+ private
22
+
23
+ def enumerate_files(project_path)
24
+ project_path_name = Pathname.new(project_path)
25
+ ruby_files = File.join(project_path, "**", "*.rb")
26
+ Dir.glob(ruby_files).map do |f|
27
+ file_path_name = Pathname.new(f)
28
+ diff_path = file_path_name.relative_path_from(project_path_name).to_s
29
+ Mudguard::Domain::Source.new(location: File.join("./", diff_path), code: File.read(f))
30
+ end.lazy
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mudguard
4
- VERSION = "0.1.4"
4
+ VERSION = "0.1.5"
5
5
  end
data/lib/mudguard.rb CHANGED
@@ -1,19 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "mudguard/version"
4
- require_relative "mudguard/policy_file"
5
- require_relative "mudguard/ruby_files"
6
-
7
- # Contains methods to check if your project is a bit muddy
8
- module Mudguard
9
- class << self
10
- def check(project_path)
11
- policy_file_path = File.expand_path("MudguardFile", project_path)
12
- policies = PolicyFile.read(policy_file_path)
13
-
14
- files = RubyFiles.all(project_path).map { |f| File.read(f) }
15
-
16
- policies.check(files)
17
- end
18
- end
19
- end
3
+ require_relative "./mudguard/version"
4
+ require_relative "./mudguard/application/application"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mudguard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jorg Jenni
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-20 00:00:00.000000000 Z
11
+ date: 2020-03-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -171,13 +171,17 @@ files:
171
171
  - Rakefile
172
172
  - exe/mudguard
173
173
  - lib/mudguard.rb
174
- - lib/mudguard/error.rb
175
- - lib/mudguard/policies.rb
176
- - lib/mudguard/policy_file.rb
177
- - lib/mudguard/ruby_analyser.rb
178
- - lib/mudguard/ruby_files.rb
174
+ - lib/mudguard/application/application.rb
175
+ - lib/mudguard/domain/dependency.rb
176
+ - lib/mudguard/domain/error.rb
177
+ - lib/mudguard/domain/policies.rb
178
+ - lib/mudguard/domain/source.rb
179
+ - lib/mudguard/infrastructure/cli/controller.rb
180
+ - lib/mudguard/infrastructure/cli/notification_adapter.rb
181
+ - lib/mudguard/infrastructure/cli/view.rb
182
+ - lib/mudguard/infrastructure/persistence/policy_file.rb
183
+ - lib/mudguard/infrastructure/persistence/ruby_files.rb
179
184
  - lib/mudguard/version.rb
180
- - lib/tasks/gem.rake
181
185
  - lib/tasks/rubocop.rake
182
186
  - lib/tasks/test.rake
183
187
  - mudguard.gemspec
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "ruby_analyser"
4
-
5
- module Mudguard
6
- # Contains the policies to be enforced
7
- class Policies
8
- def initialize(policies: [])
9
- @policies = policies.map { |l| l.gsub(/\s/, "") }.map { |p| /^#{p}/ }
10
- end
11
-
12
- def check(sources)
13
- sources.all? do |source|
14
- dependencies = RubyAnalyser.find_mod_dependencies(source)
15
- dependencies.all? do |d|
16
- @policies.any? do |p|
17
- d.match?(p)
18
- end
19
- end
20
- end
21
- end
22
- end
23
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "policies"
4
- require_relative "error"
5
-
6
- module Mudguard
7
- # A file containing the Mudguard-Policies
8
- class PolicyFile
9
- def self.read(policy_file)
10
- policy_exists = File.exist?(policy_file)
11
-
12
- raise Error, "expected policy file #{policy_file} doesn't exists" unless policy_exists
13
-
14
- Policies.new(policies: File.readlines(policy_file))
15
- end
16
- end
17
- end
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Mudguard
4
- # Provides access to all ruby-files of a project
5
- class RubyFiles
6
- class << self
7
- def all(project_path)
8
- project_exists = Dir.exist?(project_path)
9
-
10
- raise Error, "expected project #{project_path} doesn't exists" unless project_exists
11
-
12
- ruby_files = File.join(project_path, "**", "*.rb")
13
- Dir.glob(ruby_files).lazy
14
- end
15
- end
16
- end
17
- end
data/lib/tasks/gem.rake DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rspec/core/rake_task"
4
- require "mudguard/version"
5
-
6
- namespace :gem do
7
- desc "Publishes the gem on rubygems.org"
8
- task publish: "gem:build" do
9
- exec("gem push mudguard-#{Mudguard::VERSION}.gem")
10
- end
11
- desc "Builds the gem"
12
- task :build do
13
- exec("gem build mudguard.gemspec")
14
- end
15
- end