volatility 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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