klee 0.1.0 → 0.1.1
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 +4 -4
- data/CHANGELOG.md +27 -1
- data/README.md +49 -0
- data/lib/klee/concepts.rb +4 -4
- data/lib/klee/gestalt.rb +3 -4
- data/lib/klee/patterns.rb +2 -2
- data/lib/klee/version.rb +1 -1
- data/lib/klee.rb +20 -2
- metadata +19 -8
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b40d9febee207cdff655e91d94f0f719188454fa98592a5cb9fa7b54521ed0c7
|
|
4
|
+
data.tar.gz: 701294ca8f65152b881f6492caa4e51979e4de81dec22735989829ae87b8a015
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 57dc53e9ff93189272b0a5ad5d203e9921f21376c1142db3f37d5b1074808dd92f57b4b2bc2181e43f4ca0df64a9c75e467f40efaf61b0b0bc380e4aa1830a7a
|
|
7
|
+
data.tar.gz: 07a3b7c9588044077452430f1ebb9dba9a5f23443d141fcb7bb6b6b2ec4f32182cd1cd024178f9b87850aacdabe1d778ec9dc9f18d8ddd972ccaafa40993365f
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
|
6
|
+
and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
7
|
+
|
|
8
|
+
## [0.1.1] - 2026-01-29
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Switch to supporting ruby 3.4 and up. (84fdd9c)
|
|
13
|
+
- Require ruby 3.4 and above (067ec87)
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Reissue for version and release support. (885fe28)
|
|
18
|
+
- SimpleCov for coverage reporting (889d169)
|
|
19
|
+
- Coverage comment from PRs (067ec87)
|
|
20
|
+
- Klee.scan() method for codebase-wide analysis with glob patterns (3e509a1)
|
|
21
|
+
- ConceptIndex for aggregating domain concepts across files (3e509a1)
|
|
22
|
+
- CollaboratorIndex for pairwise co-occurrence and clustering (3e509a1)
|
|
23
|
+
- FileAnalyzer using Prism AST to extract classes, methods, and collaborators (3e509a1)
|
|
24
|
+
- Configurable threshold and ignore list for filtering noise (3e509a1)
|
|
25
|
+
- Method-level scope option for tighter coupling analysis (3e509a1)
|
|
2
26
|
|
|
3
27
|
## [0.1.0] - 2022-05-01
|
|
4
28
|
|
|
29
|
+
### Added
|
|
30
|
+
|
|
5
31
|
- Initial release
|
data/README.md
CHANGED
|
@@ -52,6 +52,55 @@ filtered = Klee.object_concepts(Something, modifiers: %i[fill_in_ hover_over_ _m
|
|
|
52
52
|
filtered[4] #=> Set of concepts excluding any common modifiers
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
### Scan a codebase for domain concepts
|
|
56
|
+
|
|
57
|
+
Discover hidden vocabulary across your entire codebase by analyzing class and method names.
|
|
58
|
+
|
|
59
|
+
```ruby
|
|
60
|
+
codebase = Klee.scan("app/**/*.rb", "lib/**/*.rb")
|
|
61
|
+
|
|
62
|
+
# See all concepts ranked by frequency
|
|
63
|
+
codebase.concepts.rank
|
|
64
|
+
# => {
|
|
65
|
+
# "user" => { classes: Set["User", "UserSession"], methods: Set["current_user", "find_user"] },
|
|
66
|
+
# "account" => { classes: Set["Account", "AccountManager"], methods: Set["account_balance"] },
|
|
67
|
+
# ...
|
|
68
|
+
# }
|
|
69
|
+
|
|
70
|
+
# Drill into a specific concept
|
|
71
|
+
codebase.concepts[:account]
|
|
72
|
+
# => { classes: Set["Account", "AccountManager"], methods: Set["account_balance", "close_account"] }
|
|
73
|
+
|
|
74
|
+
# Filter noise with ignore list and threshold
|
|
75
|
+
codebase = Klee.scan("app/**/*.rb",
|
|
76
|
+
ignore: %i[new create get set find all],
|
|
77
|
+
threshold: 3)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
### Find collaborator clusters
|
|
81
|
+
|
|
82
|
+
Discover which objects frequently work together across your codebase.
|
|
83
|
+
|
|
84
|
+
```ruby
|
|
85
|
+
codebase = Klee.scan("app/**/*.rb", threshold: 3)
|
|
86
|
+
|
|
87
|
+
# Pairwise co-occurrence (which objects appear together in files)
|
|
88
|
+
codebase.collaborators.pairs
|
|
89
|
+
# => { ["account", "user"] => 15, ["session", "user"] => 12, ... }
|
|
90
|
+
|
|
91
|
+
# Method-level co-occurrence (tighter coupling)
|
|
92
|
+
codebase.collaborators.pairs(scope: :method)
|
|
93
|
+
# => { ["account", "user"] => 8, ... }
|
|
94
|
+
|
|
95
|
+
# What collaborates with a specific object
|
|
96
|
+
codebase.collaborators.for(:user)
|
|
97
|
+
# => { "account" => 15, "session" => 12, "order" => 5 }
|
|
98
|
+
|
|
99
|
+
# Derived clusters (connected components)
|
|
100
|
+
codebase.collaborators.clusters
|
|
101
|
+
# => [Set["user", "account", "session"], Set["order", "payment", "invoice"]]
|
|
102
|
+
```
|
|
103
|
+
|
|
55
104
|
## Development
|
|
56
105
|
|
|
57
106
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/lib/klee/concepts.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Klee
|
|
|
26
26
|
|
|
27
27
|
def clear
|
|
28
28
|
clearable = instance_variables - %i[@method_names @modifiers]
|
|
29
|
-
clearable.each { send(:remove_instance_variable,
|
|
29
|
+
clearable.each { send(:remove_instance_variable, it) }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def each(&block)
|
|
@@ -34,7 +34,7 @@ module Klee
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def samples
|
|
37
|
-
@samples ||= method_names.flat_map{ words(
|
|
37
|
+
@samples ||= method_names.flat_map { words(it) }.tally
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def max
|
|
@@ -52,7 +52,7 @@ module Klee
|
|
|
52
52
|
private
|
|
53
53
|
|
|
54
54
|
def modifier_matcher
|
|
55
|
-
@modifier_matcher ||= Regexp.new modifiers.map{ Regexp.quote(
|
|
55
|
+
@modifier_matcher ||= Regexp.new modifiers.map { Regexp.quote(it) }.join("|")
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def words(method_name)
|
|
@@ -66,7 +66,7 @@ module Klee
|
|
|
66
66
|
end
|
|
67
67
|
.gsub(/\s/, "")
|
|
68
68
|
.split("_")
|
|
69
|
-
.delete_if {
|
|
69
|
+
.delete_if { it.empty? }
|
|
70
70
|
end
|
|
71
71
|
end
|
|
72
72
|
end
|
data/lib/klee/gestalt.rb
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
require "set"
|
|
2
1
|
module Klee
|
|
3
2
|
class Gestalt
|
|
4
3
|
def initialize(object, patterns:, ignored:)
|
|
@@ -49,15 +48,15 @@ module Klee
|
|
|
49
48
|
end
|
|
50
49
|
|
|
51
50
|
def prefixes
|
|
52
|
-
plot.
|
|
51
|
+
plot.slice(*patterns.prefixes)
|
|
53
52
|
end
|
|
54
53
|
|
|
55
54
|
def infixes
|
|
56
|
-
plot.
|
|
55
|
+
plot.slice(*patterns.infixes)
|
|
57
56
|
end
|
|
58
57
|
|
|
59
58
|
def suffixes
|
|
60
|
-
plot.
|
|
59
|
+
plot.slice(*patterns.suffixes)
|
|
61
60
|
end
|
|
62
61
|
|
|
63
62
|
def unusual?(*items)
|
data/lib/klee/patterns.rb
CHANGED
|
@@ -9,7 +9,7 @@ module Klee
|
|
|
9
9
|
|
|
10
10
|
def prefix(which)
|
|
11
11
|
@patterns[__callee__].add which
|
|
12
|
-
send("to_#{__callee__}", which).tap { match(
|
|
12
|
+
send("to_#{__callee__}", which).tap { match(it) }
|
|
13
13
|
end
|
|
14
14
|
alias_method :suffix, :prefix
|
|
15
15
|
alias_method :infix, :prefix
|
|
@@ -40,7 +40,7 @@ module Klee
|
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def key_for(pattern)
|
|
43
|
-
keys.find { pattern =~
|
|
43
|
+
keys.find { pattern =~ it }
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
private
|
data/lib/klee/version.rb
CHANGED
data/lib/klee.rb
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
# require "classifier-reborn"
|
|
3
4
|
require_relative "klee/version"
|
|
4
5
|
require_relative "klee/patterns"
|
|
5
6
|
require_relative "klee/gestalt"
|
|
6
7
|
require_relative "klee/concepts"
|
|
8
|
+
require_relative "klee/collaborators"
|
|
9
|
+
require_relative "klee/file_analyzer"
|
|
10
|
+
require_relative "klee/concept_index"
|
|
11
|
+
require_relative "klee/collaborator_index"
|
|
12
|
+
require_relative "klee/codebase"
|
|
7
13
|
|
|
8
14
|
module Klee
|
|
9
15
|
class Error < StandardError; end
|
|
@@ -20,10 +26,14 @@ module Klee
|
|
|
20
26
|
Patterns.new(&block)
|
|
21
27
|
end
|
|
22
28
|
|
|
23
|
-
def self.concepts(*
|
|
24
|
-
Concepts.new(*
|
|
29
|
+
def self.concepts(*method_names, modifiers: [])
|
|
30
|
+
Concepts.new(*method_names, modifiers: [])
|
|
25
31
|
end
|
|
26
32
|
|
|
33
|
+
# def self.classifier
|
|
34
|
+
# @classifier ||= ClassifierReborn::Bayes.new "Interesting", "Uninteresting"
|
|
35
|
+
# end
|
|
36
|
+
|
|
27
37
|
def self.object_concepts(object, modifiers: [])
|
|
28
38
|
names = if object.respond_to?(:public_instance_methods)
|
|
29
39
|
object.public_instance_methods(false)
|
|
@@ -38,4 +48,12 @@ module Klee
|
|
|
38
48
|
ignored: Class.instance_methods)
|
|
39
49
|
Gestalt.new(object, patterns: patterns, ignored: ignored).trace(threshold: threshold)
|
|
40
50
|
end
|
|
51
|
+
|
|
52
|
+
def self.collaborators(const)
|
|
53
|
+
Klee::Collaborators.new(const)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def self.scan(*patterns, ignore: [], threshold: 2)
|
|
57
|
+
Codebase.new(*patterns, ignore: ignore, threshold: threshold)
|
|
58
|
+
end
|
|
41
59
|
end
|
metadata
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: klee
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jim Gay
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
-
dependencies:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: prism
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '0'
|
|
13
26
|
description: Evaluate the similarities and differences in your objects. Art does not
|
|
14
27
|
reflect what is seen, rather it makes the hidden visible.
|
|
15
28
|
email:
|
|
@@ -38,7 +51,6 @@ metadata:
|
|
|
38
51
|
homepage_uri: https://github.com/saturnflyer/klee
|
|
39
52
|
source_code_uri: https://github.com/saturnflyer/klee
|
|
40
53
|
changelog_uri: https://github.com/saturnflyer/klee/blob/main/CHANGELOG.md
|
|
41
|
-
post_install_message:
|
|
42
54
|
rdoc_options: []
|
|
43
55
|
require_paths:
|
|
44
56
|
- lib
|
|
@@ -46,15 +58,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
46
58
|
requirements:
|
|
47
59
|
- - ">="
|
|
48
60
|
- !ruby/object:Gem::Version
|
|
49
|
-
version:
|
|
61
|
+
version: 3.4.0
|
|
50
62
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
51
63
|
requirements:
|
|
52
64
|
- - ">="
|
|
53
65
|
- !ruby/object:Gem::Version
|
|
54
66
|
version: '0'
|
|
55
67
|
requirements: []
|
|
56
|
-
rubygems_version:
|
|
57
|
-
signing_key:
|
|
68
|
+
rubygems_version: 4.0.5
|
|
58
69
|
specification_version: 4
|
|
59
70
|
summary: Evaluate the similarities and differences in your objects
|
|
60
71
|
test_files: []
|