volatility 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ae778023e10f6f3df5d0bde8b2224190d8d38fd9894f37f3e42991aeff42d16d
4
+ data.tar.gz: 06ec9bedb53b835950d6594f478e87cb9d7e195a3648cd7b15bb4b5edce17119
5
+ SHA512:
6
+ metadata.gz: f1c375ed4b9331daf1f991221dfc4871646761e14d557f0883b2cdab2e3d605c6e369607e1092024dd86dc14f4d1b3a523c939454a2ad063ded6d1f89de07123
7
+ data.tar.gz: 01c649c4038d089d1bf0ca9a3765486c27a9ff7a3e74777730523f4fe83c0be4cefa836ac693026e8b961b96b68431e7a77195024a29c8e9d9a1eec0c5f7f92c
@@ -0,0 +1,9 @@
1
+ errors:
2
+ - yegor256@gmail.com
3
+ # alerts:
4
+ # github:
5
+ # - yegor256
6
+
7
+ tags:
8
+ - pdd
9
+ - bug
@@ -0,0 +1,8 @@
1
+ # Check out all text files in UNIX format, with LF as end of line
2
+ # Don't change this file. If you have any ideas about it, please
3
+ # submit a separate issue about it and we'll discuss.
4
+
5
+ * text=auto eol=lf
6
+ *.java ident
7
+ *.xml ident
8
+ *.pdf binary
@@ -0,0 +1,11 @@
1
+ coverage/
2
+ Gemfile.lock
3
+ .idea/
4
+ *.gem
5
+ .bundle/
6
+ .DS_Store
7
+ rdoc/
8
+ *.log
9
+ *.aux
10
+ *.fdb_latexmk
11
+ *.fls
@@ -0,0 +1,2 @@
1
+ $latex = 'latex %O --shell-escape %S';
2
+ $pdflatex = 'pdflatex %O --shell-escape %S';
data/.pdd ADDED
@@ -0,0 +1,7 @@
1
+ --source=.
2
+ --verbose
3
+ --exclude target/**/*
4
+ --exclude coverage/**/*
5
+ --rule min-words:20
6
+ --rule min-estimate:15
7
+ --rule max-estimate:90
@@ -0,0 +1,19 @@
1
+ AllCops:
2
+ Exclude:
3
+ - 'assets/**/*'
4
+ DisplayCopNames: true
5
+ TargetRubyVersion: 2.3
6
+
7
+ Style/GlobalVars:
8
+ Enabled: false
9
+ Metrics/LineLength:
10
+ Max: 100
11
+ Layout/EndOfLine:
12
+ EnforcedStyle: lf
13
+ Metrics/BlockLength:
14
+ Max: 30
15
+ Layout/AlignParameters:
16
+ Enabled: false
17
+ Layout/EmptyLineAfterGuardClause:
18
+ Enabled: false
19
+
@@ -0,0 +1,24 @@
1
+ assets:
2
+ rubygems.yml: yegor256/home#assets/rubygems.yml
3
+ install: |
4
+ sudo bundle install --no-color "--gemfile=$(pwd)/Gemfile"
5
+ release:
6
+ script: |-
7
+ bundle exec rake
8
+ rm -rf *.gem
9
+ sed -i "s/0\.0\.0/${tag}/g" bin/volatility
10
+ sed -i "s/0\.0\.0/${tag}/g" volatility.gemspec
11
+ git add bin/volatility
12
+ git add volatility.gemspec
13
+ git commit -m "version set to ${tag}"
14
+ gem build volatility.gemspec
15
+ chmod 0600 ../rubygems.yml
16
+ gem push *.gem --config-file ../rubygems.yml
17
+ merge:
18
+ script: |-
19
+ bundle exec rake
20
+ pdd -f /dev/null
21
+ deploy:
22
+ script: |-
23
+ echo "There is nothing to deploy"
24
+ exit -1
@@ -0,0 +1,38 @@
1
+ # Copyright (c) 2019-2020 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+
21
+ if Gem.win_platform? then
22
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[
23
+ SimpleCov::Formatter::HTMLFormatter
24
+ ]
25
+ SimpleCov.start do
26
+ add_filter "/test/"
27
+ add_filter "/features/"
28
+ end
29
+ else
30
+ SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
31
+ [SimpleCov::Formatter::HTMLFormatter]
32
+ )
33
+ SimpleCov.start do
34
+ add_filter "/test/"
35
+ add_filter "/features/"
36
+ minimum_coverage 60
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.6.0
4
+ cache: bundler
5
+ branches:
6
+ only:
7
+ - master
8
+ install:
9
+ - gem install pdd -v 0.20.5
10
+ - travis_retry bundle update
11
+ script:
12
+ - pdd -f /dev/null
13
+ - bundle exec rake
14
+ after_success:
15
+ - "bash <(curl -s https://codecov.io/bash)"
data/Gemfile ADDED
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2012-2020 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ source 'https://rubygems.org'
24
+ ruby '~>2.3'
25
+ gemspec
@@ -0,0 +1,21 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2012-2016 Yegor Bugayenko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the 'Software'), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,45 @@
1
+ [![EO principles respected here](https://www.elegantobjects.org/badge.svg)](https://www.elegantobjects.org)
2
+ [![Managed by Zerocracy](https://www.0crat.com/badge/C3RFVLU72.svg)](https://www.0crat.com/p/C3RFVLU72)
3
+ [![DevOps By Rultor.com](http://www.rultor.com/b/yegor256/volatility)](http://www.rultor.com/p/yegor256/volatility)
4
+ [![We recommend RubyMine](https://www.elegantobjects.org/rubymine.svg)](https://www.jetbrains.com/ruby/)
5
+
6
+ [![Build Status](https://travis-ci.org/yegor256/volatility.svg)](https://travis-ci.org/yegor256/volatility)
7
+ [![Build status](https://ci.appveyor.com/api/projects/status/tbeaa0d4dk38xdb5?svg=true)](https://ci.appveyor.com/project/yegor256/volatility)
8
+ [![PDD status](http://www.0pdd.com/svg?name=yegor256/volatility)](http://www.0pdd.com/p?name=yegor256/volatility)
9
+ [![Gem Version](https://badge.fury.io/rb/volatility.svg)](http://badge.fury.io/rb/volatility)
10
+ [![Maintainability](https://api.codeclimate.com/v1/badges/74c909f06d4afa0d8001/maintainability)](https://codeclimate.com/github/yegor256/volatility/maintainability)
11
+
12
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/yegor256/takes/volatility/master/LICENSE.txt)
13
+ [![Test Coverage](https://img.shields.io/codecov/c/github/yegor256/volatility.svg)](https://codecov.io/github/yegor256/volatility?branch=master)
14
+ [![Hits-of-Code](https://hitsofcode.com/github/yegor256/volatility)](https://hitsofcode.com/view/github/yegor256/volatility)
15
+
16
+ It's an experimental way to calculate how "volatile" is a project
17
+ source code repository, by comparing the amount of dead code (rarely touched)
18
+ with the amount of actively modified one. More or less detailed theoretical summary
19
+ is in [theory.pdf](https://github.com/yegor256/volatility/raw/master/theory.pdf).
20
+
21
+ You need to have Ruby 2.6+ installed. Then you install this tool:
22
+
23
+ ```bash
24
+ $ gem install volatility
25
+ ```
26
+
27
+ Then, you run it:
28
+
29
+ ```bash
30
+ $ volatility --help
31
+ ```
32
+
33
+ ## How to contribute
34
+
35
+ Read [these guidelines](https://www.yegor256.com/2014/04/15/github-guidelines.html).
36
+ Make sure your build is green before you contribute
37
+ your pull request. You will need to have [Ruby](https://www.ruby-lang.org/en/) 2.3+ and
38
+ [Bundler](https://bundler.io/) installed. Then:
39
+
40
+ ```
41
+ $ bundle update
42
+ $ bundle exec rake
43
+ ```
44
+
45
+ If it's clean and you don't see any error messages, submit your pull request.
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-2020 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'rubygems'
24
+ require 'rake'
25
+ require 'rdoc'
26
+ require 'rake/clean'
27
+
28
+ def name
29
+ @name ||= File.basename(Dir['*.gemspec'].first, '.*')
30
+ end
31
+
32
+ def version
33
+ Gem::Specification.load(Dir['*.gemspec'].first).version
34
+ end
35
+
36
+ task default: %i[clean test features rubocop copyright]
37
+
38
+ require 'rake/testtask'
39
+ Rake::TestTask.new(:test) do |test|
40
+ ENV['skip_live'] = 'yes'
41
+ Rake::Cleaner.cleanup_files(['coverage'])
42
+ test.libs << 'lib' << 'test'
43
+ test.pattern = 'test/**/test_*.rb'
44
+ test.verbose = false
45
+ end
46
+
47
+ require 'rdoc/task'
48
+ Rake::RDocTask.new do |rdoc|
49
+ rdoc.rdoc_dir = 'rdoc'
50
+ rdoc.title = "#{name} #{version}"
51
+ rdoc.rdoc_files.include('README*')
52
+ rdoc.rdoc_files.include('lib/**/*.rb')
53
+ end
54
+
55
+ require 'rubocop/rake_task'
56
+ RuboCop::RakeTask.new(:rubocop) do |task|
57
+ task.fail_on_error = true
58
+ task.requires << 'rubocop-rspec'
59
+ end
60
+
61
+ require 'cucumber/rake/task'
62
+ Cucumber::Rake::Task.new(:features) do
63
+ Rake::Cleaner.cleanup_files(['coverage'])
64
+ end
65
+ Cucumber::Rake::Task.new(:'features:html') do |t|
66
+ t.profile = 'html_report'
67
+ end
68
+
69
+ task :copyright do
70
+ sh "grep -q -r '2019-#{Date.today.strftime('%Y')}' \
71
+ --include '*.rb' \
72
+ --include '*.txt' \
73
+ --include 'Rakefile' \
74
+ ."
75
+ end
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Copyright (c) 2019-2020 Yegor Bugayenko
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the 'Software'), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in all
14
+ # copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
+ # SOFTWARE.
23
+
24
+ STDOUT.sync = true
25
+
26
+ VERSION = '0.1.0'
27
+
28
+ require 'slop'
29
+ require 'backtrace'
30
+
31
+ $verbose = false
32
+
33
+ def put(msg)
34
+ puts msg if $verbose
35
+ end
36
+
37
+ begin
38
+ begin
39
+ opts = Slop.parse(ARGV, strict: true, help: true) do |o|
40
+ o.banner = "Usage (#{VERSION}): volatility [options]
41
+ Options are:"
42
+ o.bool '--verbose', 'Print all details' do
43
+ $verbose = true
44
+ end
45
+ o.string '--home',
46
+ 'The path to the repository (current dir by default)',
47
+ default: '.'
48
+ o.bool '--help', 'Read this: https://github.com/yegor256/volatility' do
49
+ puts o
50
+ exit
51
+ end
52
+ end
53
+ rescue Slop::Error => ex
54
+ raise ex.message
55
+ end
56
+ files = {}
57
+ home = File.expand_path(opts[:home])
58
+ puts "Home: #{home}"
59
+ `git --git-dir=#{home}/.git log --numstat`.split("\n").each do |t|
60
+ add, del, file = t.split("\t", 3)
61
+ next if file.nil?
62
+ files[file] = 0 if files[file].nil?
63
+ files[file] += add.to_i
64
+ files[file] += del.to_i
65
+ end
66
+ raise "No Git history found in #{home}" if files.empty?
67
+ put "N = #{files.count}"
68
+ values = files.select { |f, _| File.exist?(File.join(home, f)) }.map { |_, v| v }
69
+ put "M = #{values.count}"
70
+ min = values.min
71
+ put "Min = #{min}"
72
+ max = values.max
73
+ put "Max = #{max}"
74
+ values = values.map { |v| (v - min).to_f / (max - min) }
75
+ mu = values.inject(&:+) / values.count
76
+ put "µ = #{mu}"
77
+ var = values.map { |v| (v - mu)**2 }.inject(&:+).to_f / values.count
78
+ put "Var(X) = #{var}"
79
+ puts var
80
+ rescue StandardError => ex
81
+ puts Backtrace.new(ex).to_s
82
+ exit(255)
83
+ end
@@ -0,0 +1,3 @@
1
+ default: --format pretty
2
+ travis: --format progress
3
+ html_report: --format progress --format html --out=features_report.html
@@ -0,0 +1,22 @@
1
+ Feature: Command Line Processing
2
+ As a Git developer I want to calculate volatility of my repo
3
+
4
+ Scenario: Help can be printed
5
+ When I run bin/volatility with "--help"
6
+ Then Exit code is zero
7
+ And Stdout contains "--help"
8
+
9
+ Scenario: Volatility can be calculated
10
+ When I run bash with:
11
+ """
12
+ git config --global user.name "NoName"
13
+ git config --global user.email "noname@example.com"
14
+ mkdir tmp
15
+ cd tmp
16
+ git init .
17
+ touch test.txt
18
+ git add test.txt
19
+ git commit -am 'test'
20
+ """
21
+ Then I run bin/volatility with "--verbose --home=./tmp"
22
+ Then Exit code is zero
@@ -0,0 +1,24 @@
1
+ Feature: Gem Package
2
+ As a source code writer I want to be able to
3
+ package the Gem into .gem file
4
+
5
+ Scenario: Gem can be packaged
6
+ Given It is Unix
7
+ Given I have a "execs.rb" file with content:
8
+ """
9
+ #!/usr/bin/env ruby
10
+ require 'rubygems'
11
+ spec = Gem::Specification::load('./spec.rb')
12
+ if spec.executables.empty?
13
+ fail 'no executables: ' + File.read('./spec.rb')
14
+ end
15
+ """
16
+ When I run bash with:
17
+ """
18
+ cd volatility
19
+ gem build volatility.gemspec
20
+ gem specification --ruby volatility-*.gem > ../spec.rb
21
+ cd ..
22
+ ruby execs.rb
23
+ """
24
+ Then Exit code is zero
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-2020 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'nokogiri'
24
+ require 'tmpdir'
25
+ require 'slop'
26
+ require 'English'
27
+
28
+ Before do
29
+ @cwd = Dir.pwd
30
+ @dir = Dir.mktmpdir('test')
31
+ FileUtils.mkdir_p(@dir) unless File.exist?(@dir)
32
+ Dir.chdir(@dir)
33
+ @opts = Slop.parse ['-v', '-s', @dir] do |o|
34
+ o.bool '-v', '--verbose'
35
+ o.string '-s', '--source'
36
+ end
37
+ end
38
+
39
+ After do
40
+ Dir.chdir(@cwd)
41
+ FileUtils.rm_rf(@dir) if File.exist?(@dir)
42
+ end
43
+
44
+ Given(/^I have a "([^"]*)" file with content:$/) do |file, text|
45
+ FileUtils.mkdir_p(File.dirname(file)) unless File.exist?(file)
46
+ File.open(file, 'w') do |f|
47
+ f.write(text.gsub(/\\xFF/, 0xFF.chr))
48
+ end
49
+ end
50
+
51
+ When(%r{^I run bin/volatility with "([^"]*)"$}) do |arg|
52
+ home = File.join(File.dirname(__FILE__), '../..')
53
+ @stdout = `ruby -I#{home}/lib #{home}/bin/volatility #{arg}`
54
+ @exitstatus = $CHILD_STATUS.exitstatus
55
+ end
56
+
57
+ Then(/^Stdout contains "([^"]*)"$/) do |txt|
58
+ raise "STDOUT doesn't contain '#{txt}':\n#{@stdout}" unless @stdout.include?(txt)
59
+ end
60
+
61
+ Then(/^Stdout is empty$/) do
62
+ raise "STDOUT is not empty:\n#{@stdout}" unless @stdout == ''
63
+ end
64
+
65
+ Then(/^Exit code is zero$/) do
66
+ raise "Non-zero exit #{@exitstatus}:\n#{@stdout}" unless @exitstatus.zero?
67
+ end
68
+
69
+ Then(/^Exit code is not zero$/) do
70
+ raise 'Zero exit code' if @exitstatus.zero?
71
+ end
72
+
73
+ When(/^I run bash with "([^"]*)"$/) do |text|
74
+ FileUtils.copy_entry(@cwd, File.join(@dir, 'volatility'))
75
+ @stdout = `#{text}`
76
+ @exitstatus = $CHILD_STATUS.exitstatus
77
+ end
78
+
79
+ When(/^I run bash with:$/) do |text|
80
+ FileUtils.copy_entry(@cwd, File.join(@dir, 'volatility'))
81
+ @stdout = `#{text}`
82
+ @exitstatus = $CHILD_STATUS.exitstatus
83
+ end
84
+
85
+ Given(/^It is Unix$/) do
86
+ pending if Gem.win_platform?
87
+ end
88
+
89
+ Given(/^It is Windows$/) do
90
+ pending unless Gem.win_platform?
91
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2019-2020 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'simplecov'
24
+ # require 'aruba/cucumber'
Binary file
@@ -0,0 +1,77 @@
1
+ % Copyright (c) 2012-2020, Yegor Bugayenko
2
+ % All rights reserved.
3
+ %
4
+ % Redistribution and use in source and binary forms, with or without
5
+ % modification, are permitted provided that the following conditions
6
+ % are met: 1) Redistributions of source code must retain the above
7
+ % copyright notice, this list of conditions and the following
8
+ % disclaimer. 2) Redistributions in binary form must reproduce the above
9
+ % copyright notice, this list of conditions and the following
10
+ % disclaimer in the documentation and/or other materials provided
11
+ % with the distribution. 3) Neither the name of Yegor Bugayenko nor
12
+ % the names of other contributors may be used to endorse or promote
13
+ % products derived from this software without specific prior written
14
+ % permission.
15
+ %
16
+ % THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
+ % "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
18
+ % NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
19
+ % FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20
+ % THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
21
+ % INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ % (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23
+ % SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24
+ % HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25
+ % STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
+ % ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27
+ % OF THE POSSIBILITY OF SUCH DAMAGE.
28
+ %
29
+ \documentclass[12pt]{article}
30
+ \usepackage{amsmath}
31
+ \begin{document}
32
+ \title{Source Code Volatility (SCV)\\to Spot Dead Code}
33
+ \author{Yegor Bugayenko}
34
+ \maketitle
35
+
36
+ \section{Introduction}
37
+
38
+ Volatility of source code is an experimental metric that
39
+ shows how big is the difference between actively and rarely changed (possibly dead)
40
+ code. It is assumed that a big percentage of dead code is
41
+ an indicator of maintainability problems in the project.
42
+
43
+ \section{Details}
44
+
45
+ First, by looking at Git history,
46
+ it is observed how many times every source code file $i$ out of $N$ was touched
47
+ during the lifetime of the repository:
48
+
49
+ \begin{eqnarray}
50
+ T = [t_1, t_2, \dots, t_N]
51
+ \end{eqnarray}
52
+
53
+ Then, $t$ that relate to the files already absent in the
54
+ repository are deleted and the array $T$ is ``normalized''
55
+ to keep all values within the $[0,1]$ range:
56
+
57
+ \begin{eqnarray}
58
+ X = [x_1, x_2, \dots, x_M],\quad \text{where}\ x_i = \frac{t_i - \hat{T}}{\check{T} - \hat{T}}
59
+ \end{eqnarray}
60
+
61
+ Then, the mean $\mu$ is calculated as:
62
+
63
+ \begin{eqnarray}
64
+ \mu = \frac{1}{M}\sum{x_i}
65
+ \end{eqnarray}
66
+
67
+ Finally, the variance is calculated as:
68
+
69
+ \begin{eqnarray}
70
+ Var(x) = \frac{1}{M}\sum{|x_i - \mu|^2}
71
+ \end{eqnarray}
72
+
73
+ The variance $Var(x)$ is the volatility of the source code. The smaller
74
+ the volatility the more cohesive is the repository and the smaller
75
+ the amount of the dead code inside it.
76
+
77
+ \end{document}
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (c) 2012-2020 Yegor Bugayenko
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the 'Software'), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ require 'English'
24
+
25
+ lib = File.expand_path('lib', __dir__)
26
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
27
+ Gem::Specification.new do |s|
28
+ s.specification_version = 2 if s.respond_to? :specification_version=
29
+ if s.respond_to? :required_rubygems_version=
30
+ s.required_rubygems_version = Gem::Requirement.new('>= 0')
31
+ end
32
+ s.rubygems_version = '2.2'
33
+ s.required_ruby_version = '>= 2.3'
34
+ s.name = 'volatility'
35
+ s.version = '0.1.0'
36
+ s.license = 'MIT'
37
+ s.summary = 'Source Code Volatility'
38
+ s.description = 'The command line tool calculates the SCV metric for a Git repo'
39
+ s.authors = ['Yegor Bugayenko']
40
+ s.email = 'yegor256@gmail.com'
41
+ s.homepage = 'http://github.com/yegor256/volatility'
42
+ s.files = `git ls-files`.split($RS)
43
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
44
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
45
+ s.rdoc_options = ['--charset=UTF-8']
46
+ s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
47
+ s.add_runtime_dependency 'backtrace', '~> 0.3'
48
+ s.add_runtime_dependency 'slop', '~> 4.6'
49
+ s.add_development_dependency 'codecov', '0.1.10'
50
+ s.add_development_dependency 'cucumber', '~> 1.3.17'
51
+ s.add_development_dependency 'minitest', '5.5.0'
52
+ s.add_development_dependency 'rake', '12.0.0'
53
+ s.add_development_dependency 'rspec-rails', '3.1.0'
54
+ s.add_development_dependency 'rubocop', '0.61.0'
55
+ s.add_development_dependency 'rubocop-rspec', '1.31.0'
56
+ end
metadata ADDED
@@ -0,0 +1,198 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: volatility
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yegor Bugayenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-04-14 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: backtrace
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: slop
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.6'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.6'
41
+ - !ruby/object:Gem::Dependency
42
+ name: codecov
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.1.10
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.1.10
55
+ - !ruby/object:Gem::Dependency
56
+ name: cucumber
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 1.3.17
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 1.3.17
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '='
74
+ - !ruby/object:Gem::Version
75
+ version: 5.5.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '='
81
+ - !ruby/object:Gem::Version
82
+ version: 5.5.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '='
88
+ - !ruby/object:Gem::Version
89
+ version: 12.0.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '='
95
+ - !ruby/object:Gem::Version
96
+ version: 12.0.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: rspec-rails
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '='
102
+ - !ruby/object:Gem::Version
103
+ version: 3.1.0
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '='
109
+ - !ruby/object:Gem::Version
110
+ version: 3.1.0
111
+ - !ruby/object:Gem::Dependency
112
+ name: rubocop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '='
116
+ - !ruby/object:Gem::Version
117
+ version: 0.61.0
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '='
123
+ - !ruby/object:Gem::Version
124
+ version: 0.61.0
125
+ - !ruby/object:Gem::Dependency
126
+ name: rubocop-rspec
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 1.31.0
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 1.31.0
139
+ description: The command line tool calculates the SCV metric for a Git repo
140
+ email: yegor256@gmail.com
141
+ executables:
142
+ - volatility
143
+ extensions: []
144
+ extra_rdoc_files:
145
+ - README.md
146
+ - LICENSE.txt
147
+ files:
148
+ - ".0pdd.yml"
149
+ - ".gitattributes"
150
+ - ".gitignore"
151
+ - ".latexmkrc"
152
+ - ".pdd"
153
+ - ".rubocop.yml"
154
+ - ".rultor.yml"
155
+ - ".simplecov"
156
+ - ".travis.yml"
157
+ - Gemfile
158
+ - LICENSE.txt
159
+ - README.md
160
+ - Rakefile
161
+ - bin/volatility
162
+ - cucumber.yml
163
+ - features/cli.feature
164
+ - features/gem_package.feature
165
+ - features/step_definitions/steps.rb
166
+ - features/support/env.rb
167
+ - theory.pdf
168
+ - theory.tex
169
+ - volatility.gemspec
170
+ homepage: http://github.com/yegor256/volatility
171
+ licenses:
172
+ - MIT
173
+ metadata: {}
174
+ post_install_message:
175
+ rdoc_options:
176
+ - "--charset=UTF-8"
177
+ require_paths:
178
+ - lib
179
+ required_ruby_version: !ruby/object:Gem::Requirement
180
+ requirements:
181
+ - - ">="
182
+ - !ruby/object:Gem::Version
183
+ version: '2.3'
184
+ required_rubygems_version: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ requirements: []
190
+ rubygems_version: 3.0.1
191
+ signing_key:
192
+ specification_version: 2
193
+ summary: Source Code Volatility
194
+ test_files:
195
+ - features/cli.feature
196
+ - features/gem_package.feature
197
+ - features/step_definitions/steps.rb
198
+ - features/support/env.rb