documented 0.0.0 → 0.1.0

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: 5026a405923100cfe8ea3f484fe324b3588a3481369fd954b7d5645537227672
4
- data.tar.gz: b9d86b71d1a7dfc1018edc79922a54fd2013245d95c17eb9d902d5dd8160f100
3
+ metadata.gz: eed131baa88c812dcc5e2d7539e11a422b40903854ab07f20ee594979537e87b
4
+ data.tar.gz: 4222dd37097a675c37304d4a539bfe3d92c563e3aeb97732ce47246d6bc0f7e3
5
5
  SHA512:
6
- metadata.gz: 55480519881df342fcbff4d0b7ea3b7aef9a6ca96805c3eb18283faf3f43b3e83d8e3df00219310e75293123fd801993848630a7c446626407812b745ae6c896
7
- data.tar.gz: 994c10ccf460e023790c8caaa4198f5bf63f06b41b6ebebefc604b1752af27f1d4610d3f62297f08f0e124f62d7a1786af8ad16e2e9e8e5e31d1bb86db269df4
6
+ metadata.gz: da326d596f66a75475b00be099299b04f997fa88077811f361b3b1e2228b9c0ec79a51f7f7df25f66282fa6cd6d21b466845a29c80c30c86831b1b3a5e4e10aa
7
+ data.tar.gz: 16fe5d6fc344069bf61423b569472332ec4eef9e81374688630887480423321afac84832b3daa6981827b15d177a5eca6a24ef9248b8eaecf165b60d912a1f04
data/bin/documented ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env ruby
2
+ require lib_path = File.expand_path('../lib/documented')
3
+ require '../lib/rewriter'
4
+
5
+ ################################################################################
6
+ # Usage:
7
+ # documented <file_path>
8
+ #
9
+ # Example:
10
+ # documented spec/example_spec.rb
11
+ ################################################################################
12
+
13
+ file_path = File.join(Dir.pwd, ARGV.first)
14
+
15
+ rewriter = Documented::Rewriter.new(file_path)
16
+ rewriter.require_library(lib_path)
17
+ rewriter.replace_comments
18
+ rewriter.write
19
+ rewriter.execute
20
+ rewriter.delete
data/lib/config.rb CHANGED
@@ -2,12 +2,14 @@ module Documented
2
2
  class Config
3
3
  attr_accessor :blocklist
4
4
  attr_accessor :duplicates
5
- attr_accessor :project_path
5
+ attr_accessor :app_path
6
+ attr_accessor :gem_path
6
7
  attr_accessor :output_directory
7
8
 
8
9
  def initialize()
9
10
  @blocklist = [
10
11
  '#<Class:Bundler',
12
+ '#<Class:Documented>',
11
13
  '#<Class:#<Class',
12
14
  '#<Class:0x0000',
13
15
  '#<Class:Cucumber',
@@ -22,6 +24,7 @@ module Documented
22
24
  'Bundler',
23
25
  'Cucumber',
24
26
  'Datadog',
27
+ 'Documented',
25
28
  'Float',
26
29
  'Helpers',
27
30
  'Integer',
@@ -36,10 +39,11 @@ module Documented
36
39
  'URI::Generic',
37
40
  ]
38
41
 
39
- # An absolute path to the project root directory. Defaults to current execution path.
40
- @project_path = Dir.pwd
42
+ @duplicates = false
43
+
44
+ @app_path = Dir.pwd
45
+ @gem_path = File.dirname(File.realpath(__FILE__))
41
46
 
42
- # Name of output directory.
43
47
  @output_directory = "documented"
44
48
  end
45
49
  end
data/lib/documented.rb CHANGED
@@ -1,82 +1,49 @@
1
- require 'set'
2
- require 'erb'
3
-
4
- require_relative 'accessor'
5
- require_relative 'config'
6
- require_relative 'renderer'
1
+ require_relative './config'
2
+ require_relative './tracer'
3
+ require_relative './renderer'
7
4
 
8
5
  module Documented
9
- def documented
10
- events = []
11
- calls = ['Start']
12
-
13
- trace = TracePoint.new(:call, :return) do |tp|
14
- # file = File.open("#{__dir__}/../../doc/diagrams/input.mmd")
15
- # file.write("sequenceDiagram\n")
16
-
17
- # file.close
18
- caller = calls.last.to_s
19
- callee = tp.defined_class.to_s
20
- event = tp.event
21
-
22
- unless blocklist.any? { |e| callee.to_s.start_with? e }
23
- unless calls.last == callee
24
- if event == :return
25
- calls.pop
26
- elsif calls.last != callee
27
- calls << callee
28
- end
29
- end
30
-
31
- unless callee == caller
32
- caller = caller.gsub('::','.')
33
- callee = callee.gsub('::','.')
34
- p "#{caller}->>#{callee}: #{tp.method_id}"
35
- end
36
- end
6
+ class << self
7
+ def setup(file_path)
8
+ @@file_path = file_path
9
+ @@config = Config.new
10
+ @@tracer = Tracer.new(@@config.blocklist)
11
+
12
+ output_path = File.join(@@config.app_path, @@config.output_directory)
13
+ Dir.mkdir(output_path) unless Dir.exist? output_path
14
+ @@renderer = Renderer.new(@@config.gem_path, output_path)
15
+
16
+ @@sequences = []
37
17
  end
38
-
39
- trace.enable
40
-
41
- yield
42
-
43
- trace.disable
44
-
45
- ap events
46
- end
47
18
 
48
- def self.configure
49
- documented_setup_class()
19
+ def enable
20
+ @@tracer.enable
21
+ end
50
22
 
51
- yield(@@documented.config)
52
- end
23
+ def disable
24
+ @@tracer.disable
25
+ @@renderer.render(@@file_path)
26
+ end
53
27
 
54
- def self.included(base)
55
- documented_setup_class()
56
- end
28
+ def sequences
29
+ @@sequences
30
+ end
57
31
 
58
- private
32
+ def add_sequence(sequence)
33
+ @@sequences << sequence
34
+ end
59
35
 
60
- ##
61
- # Setup class.
62
- #
63
- # @paths
64
- # - package_path [String] Absolute path to the library itself.
65
- # - project_path [String] Absolute path to the project root.
66
- # - output_path [String] Absolute path to the documented directory.
67
- ##
68
- def self.documented_setup_class()
69
- @@documented = Accessor.new()
70
- @@documented.config = Config.new()
36
+ def config
37
+ @@config
38
+ end
71
39
 
72
- # Setup paths.
73
- @@documented.package_path = File.dirname(File.realpath(__FILE__))
74
- @@documented.project_path = @@documented.config.project_path
75
- @@documented.output_path = File.join(@@documented.project_path, @@documented.config.output_directory)
76
- unless Dir.exist? @@documented.output_path
77
- Dir.mkdir(@@documented.output_path)
40
+ def tracer
41
+ @@tracer
78
42
  end
79
43
 
80
- @@documented.renderer = Renderer.new(@@documented.package_path, @@documented.output_path)
44
+ # Allow end-user to override config.
45
+ def configure
46
+ yield(@@config)
47
+ end
81
48
  end
82
49
  end
data/lib/renderer.rb CHANGED
@@ -1,26 +1,33 @@
1
1
  module Documented
2
2
  class Renderer
3
- def initialize(package_path, output_path)
4
- @package_path = package_path
3
+ def initialize(gem_path, output_path)
4
+ @gem_path = gem_path
5
5
  @output_path = output_path
6
6
  end
7
7
 
8
- # Place files in output path.
9
- def render()
10
- filenames = [
11
- "README.md",
12
- ]
8
+ def render(file_path)
9
+ # file_names = [
10
+ # "README.md",
11
+ # ]
12
+ # file_names.each do |file_name|
13
+ # file = File.read(File.join(@gem_path, "output", file_name))
14
+ # File.open(File.join(@output_path, file_name), 'w+') do |f|
15
+ # f.write file
16
+ # end
17
+ # end
13
18
 
14
- filenames.each do |filename|
15
- file = File.read(File.join(@package_path, "output", filename))
16
- File.open(File.join(@output_path, filename), 'w+') do |f|
17
- f.write file
18
- end
19
- end
19
+ Documented.sequences.each do |sequence|
20
+ file_name = File.basename(file_path, File.extname(file_path)) + '.md'
21
+ directory = File.join(@output_path, file_name)
22
+
23
+ output = <<~TEXT
24
+ ```mermaid
25
+ sequenceDiagram;
26
+ #{sequence.map { |step| " #{step}" }.join("\n")}
27
+ ````
28
+ TEXT
20
29
 
21
- file = File.read(File.join(@package_path, "output", "gitignore.txt"))
22
- File.open(File.join(@output_path, ".gitignore"), 'w+') do |f|
23
- f.write file
30
+ File.write(directory, output)
24
31
  end
25
32
  end
26
33
  end
data/lib/rewriter.rb ADDED
@@ -0,0 +1,63 @@
1
+ require 'rubocop'
2
+ require_relative './config'
3
+
4
+ module Documented
5
+ class Rewriter
6
+ attr_accessor :file_path
7
+ attr_accessor :source
8
+ attr_accessor :tree
9
+
10
+ def initialize(file_path)
11
+ @file_path = file_path
12
+ @source = RuboCop::ProcessedSource.new(File.read(file_path), 3)
13
+ @tree = Parser::Source::TreeRewriter.new(@source.buffer)
14
+ end
15
+
16
+ def require_library(lib_path)
17
+ setup = <<-RUBY
18
+ \n require "#{lib_path}"
19
+ Documented.setup("#{@file_path}")
20
+ RUBY
21
+ @tree.insert_after(@source.ast.children.first.loc.expression, setup)
22
+ end
23
+
24
+ def replace_comments
25
+ @source.comments.each do |comment|
26
+ range = comment.location.expression
27
+
28
+ if comment.text.start_with?('# documented:enable')
29
+ @tree.replace(range, "Documented.enable")
30
+ elsif comment.text.start_with?('# documented:disable')
31
+ @tree.replace(range, "Documented.disable")
32
+ end
33
+ end
34
+ end
35
+
36
+ def execute
37
+ system("#{command(file_path)} #{temp_file_path}")
38
+ end
39
+
40
+ def write
41
+ File.write(temp_file_path, @tree.process)
42
+ end
43
+
44
+ def delete
45
+ File.delete(temp_file_path)
46
+ end
47
+
48
+ private
49
+
50
+ def temp_file_path
51
+ file_name = 'tmp-' + File.basename(@file_path)
52
+ directory = File.dirname(file_path)
53
+ File.join(directory, file_name)
54
+ end
55
+
56
+ def command(file_path)
57
+ return 'bundle exec rspec' if file_path.end_with?('_spec.rb')
58
+ return 'bundle exec cucumber' if file_path.end_with?('.feature')
59
+
60
+ 'ruby'
61
+ end
62
+ end
63
+ end
data/lib/tracer.rb ADDED
@@ -0,0 +1,54 @@
1
+ require 'set'
2
+ require 'erb'
3
+
4
+ require_relative 'config'
5
+ require_relative 'renderer'
6
+
7
+ module Documented
8
+ class Tracer
9
+ attr_reader :sequence
10
+
11
+ def initialize(blocklist)
12
+ @blocklist = blocklist
13
+ @trace_point = create_trace_point()
14
+ end
15
+
16
+ def enable
17
+ @sequence = []
18
+ @trace_point.enable
19
+ end
20
+
21
+ def disable
22
+ @trace_point.disable
23
+ Documented.add_sequence(@sequence)
24
+ end
25
+
26
+ private
27
+
28
+ def create_trace_point
29
+ calls = ['Start']
30
+
31
+ return TracePoint.new(:call, :return) do |trace_point|
32
+ caller = calls.last.to_s
33
+ callee = trace_point.defined_class.to_s
34
+ event = trace_point.event
35
+
36
+ unless @blocklist.any? { |e| callee.to_s.start_with? e }
37
+ unless calls.last == callee
38
+ if event == :return
39
+ calls.pop
40
+ elsif calls.last != callee
41
+ calls << callee
42
+ end
43
+ end
44
+
45
+ unless callee == caller
46
+ caller = caller.gsub('::','.')
47
+ callee = callee.gsub('::','.')
48
+ @sequence << "#{caller}->>#{callee}: #{trace_point.method_id}"
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: documented
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Maedi Prichard
@@ -11,7 +11,7 @@ cert_chain: []
11
11
  date: 2023-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: parser
14
+ name: rubocop
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - ">="
@@ -26,16 +26,17 @@ dependencies:
26
26
  version: '0'
27
27
  description: Documentation that's completely automated.
28
28
  email: maediprichard@gmail.com
29
- executables: []
29
+ executables:
30
+ - documented
30
31
  extensions: []
31
32
  extra_rdoc_files: []
32
33
  files:
33
- - lib/accessor.rb
34
+ - bin/documented
34
35
  - lib/config.rb
35
36
  - lib/documented.rb
36
- - lib/output/README.md
37
- - lib/output/gitignore.txt
38
37
  - lib/renderer.rb
38
+ - lib/rewriter.rb
39
+ - lib/tracer.rb
39
40
  homepage: https://github.com/greensync/documented
40
41
  licenses:
41
42
  - MPL-2.0
data/lib/accessor.rb DELETED
@@ -1,31 +0,0 @@
1
- ################################################################################
2
- # Access variables via one object to avoid polluting the caller's scope.
3
- #
4
- # @pattern Singleton
5
- ################################################################################
6
-
7
- module Documented
8
- class Accessor
9
- attr_accessor :initialized
10
- attr_accessor :error
11
-
12
- attr_accessor :config
13
- attr_accessor :renderer
14
-
15
- attr_accessor :package_path
16
- attr_accessor :project_path
17
- attr_accessor :output_path
18
-
19
- def initialize()
20
- @initialized = false
21
- @error = nil
22
-
23
- @config = nil
24
- @renderer = nil
25
-
26
- @package_path = nil
27
- @project_path = nil
28
- @output_path = nil
29
- end
30
- end
31
- end
data/lib/output/README.md DELETED
@@ -1,3 +0,0 @@
1
- # Documented
2
-
3
- As you test the application documentation will be added to `/documented`.
@@ -1,2 +0,0 @@
1
- .gitignore
2
- README.md