mudguard 0.1.4 → 0.1.5

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: 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