nodepile 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rspec +2 -0
- data/.rubocop.yml +1 -1
- data/BACKLOG.md +34 -0
- data/Rakefile +92 -2
- data/lib/nodepile/base_structs.rb +62 -0
- data/lib/nodepile/colspecs.rb +562 -0
- data/lib/nodepile/gross_actions.rb +38 -0
- data/lib/nodepile/gviz.rb +108 -0
- data/lib/nodepile/keyed_array.rb +386 -0
- data/lib/nodepile/pile_organizer.rb +258 -0
- data/lib/nodepile/pragmas.rb +97 -0
- data/lib/nodepile/rec_source.rb +329 -0
- data/lib/nodepile/rule_eval.rb +155 -0
- data/lib/nodepile/version.rb +1 -1
- data/nodepile.gemspec +53 -0
- data/tmp/.gitignore +1 -0
- metadata +136 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0f5e500d69380f252e066be80ecc79f173f9546ebb5c428071fb33c889898b80
|
4
|
+
data.tar.gz: e0e9714d8f0d552a0e0cc24ba5806894cafe9fefbdcbd9e33cf0d51b3a9db916
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e39d3f127385ed3562ccc4ba8a940665075b70cbff267837be44c304baa3a697b5f7a875285ac65a89ec5849494464d45c6401eef6a71bb499a6e04a9b7352f
|
7
|
+
data.tar.gz: 8cc2401dca81d3e3f24e3234e7e4fc89a911c0c0d89cdbdc28e560d790f72eb2150d7f0504246bf36ed065d1cf960cfaba25d30b2ba153fad98f39a4ce8fba52
|
data/.rspec
CHANGED
data/.rubocop.yml
CHANGED
data/BACKLOG.md
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# Development Backlog
|
2
|
+
|
3
|
+
## Primary Backlog
|
4
|
+
* Implement one or two test cases in spec/pragmas_spec.rb
|
5
|
+
* Add a command line program that can take an input file and generate an image file as output in a pretty painless way like "nodepile srcfile.csv outputfile.png"
|
6
|
+
* Create a baby simple rack-compatible app to render diagrams and be able to output the flattened data.
|
7
|
+
* Add an _emphasis column as a shorthand for certain stylistic modifications: strong, weak, hidden, clear, big, faint, tiny
|
8
|
+
* Add a _url column
|
9
|
+
* Add a _tooltip column
|
10
|
+
* Add a _next column (or something named similar) to allow nested substates. Note that nested substates may also have a visibility implication. In particular, that the nested substates can only be seen when viewed from their same nesting level (with blank nesting level being the top level)
|
11
|
+
* Add a rakefile command to build/make (see note with 2023-07-15)
|
12
|
+
|
13
|
+
## Maybe Someday Backlog
|
14
|
+
* NECESSARY? - Add a #yield_flat() to the organizer that will iterate through the summaries
|
15
|
+
|
16
|
+
## Supporting Notes
|
17
|
+
### Rakefile Commands to Add 2023-07-15
|
18
|
+
* Build the gem
|
19
|
+
* List the current version number
|
20
|
+
* Increment the current version number
|
21
|
+
* Example below was taking almost verbatim from a tutorial
|
22
|
+
```ruby
|
23
|
+
GEM_NAME = "nodepile"
|
24
|
+
GEM_VERSION = "0.0.0"
|
25
|
+
|
26
|
+
|
27
|
+
task :publish => :build do
|
28
|
+
system 'gem push ' + GEM_NAME + "-" + GEM_VERSION + ".gem"
|
29
|
+
end
|
30
|
+
|
31
|
+
task :clean do
|
32
|
+
system "rm *.gem"
|
33
|
+
end
|
34
|
+
```
|
data/Rakefile
CHANGED
@@ -1,12 +1,102 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'rake'
|
4
|
+
require 'yard'
|
3
5
|
require "bundler/gem_tasks"
|
4
|
-
require
|
6
|
+
require 'rspec/core/rake_task'
|
5
7
|
|
6
8
|
RSpec::Core::RakeTask.new(:spec)
|
7
9
|
|
10
|
+
begin
|
11
|
+
require 'bundler/setup'
|
12
|
+
Bundler::GemHelper.install_tasks
|
13
|
+
rescue LoadError
|
14
|
+
puts 'although not required, bundler is recommended for running the tests'
|
15
|
+
end
|
16
|
+
|
8
17
|
require "rubocop/rake_task"
|
9
18
|
|
10
|
-
RuboCop::RakeTask.new
|
19
|
+
RuboCop::RakeTask.new do |task|
|
20
|
+
task.requires << 'rubocop-performance'
|
21
|
+
task.requires << 'rubocop-rspec'
|
22
|
+
end
|
23
|
+
|
11
24
|
|
12
25
|
task default: %i[spec rubocop]
|
26
|
+
|
27
|
+
# Dave's Dev trinkets below
|
28
|
+
LINE_LEVEL_SWEEP_TESTS = [
|
29
|
+
Proc.new {|line| line.match(/^[^#]*binding\.pry/) && "found uncommented binding.pry"},
|
30
|
+
Proc.new {|line| line.match(/^[^#]*binding\.irb/) && "found uncommented binding.irb"},
|
31
|
+
Proc.new {|line| line.match(/^[^#]*debugger/) && "found uncommented debugger invocation"},
|
32
|
+
Proc.new {|line| line.match(/^.*#\s*DEBUG/) && "found debug line"},
|
33
|
+
Proc.new {|line| line.match(/^[^#]*require[^#]+['"]pry/) && "uncommented require of 'pry' code"},
|
34
|
+
Proc.new {|line| line.match(/^[^#]*TDOUT\.puts ([^\s]+)\.inspect/) && "verbose obj going to stdout"},
|
35
|
+
Proc.new {|line| line.match(/^[^#]*debug_mode\s+:console/) && "sentry set with debug_mode :console"},
|
36
|
+
]
|
37
|
+
|
38
|
+
|
39
|
+
# rake yard #to generate documentation
|
40
|
+
YARD::Rake::YardocTask.new do |t|
|
41
|
+
t.files = ['lib/**/*.rb', 'README','LICENSE'] # optional
|
42
|
+
#t.options = ['--any', '--extra', '--opts'] # optional
|
43
|
+
t.stats_options = ['--list-undoc'] # optional
|
44
|
+
end
|
45
|
+
|
46
|
+
def simplify_dir(target_path)
|
47
|
+
this_root = Pathname.new(File.dirname(__FILE__))
|
48
|
+
target = Pathname.new(target_path)
|
49
|
+
target.relative_path_from(this_root)
|
50
|
+
end
|
51
|
+
|
52
|
+
desc "Serve yard docs on port 8080 with automatic reload"
|
53
|
+
task :yardserv do
|
54
|
+
puts "You probably want to run this directly from the command line with:"
|
55
|
+
puts "yard server --reload -p 8080"
|
56
|
+
end
|
57
|
+
|
58
|
+
|
59
|
+
desc "Build the gem and deploy to rubygems"
|
60
|
+
task :publish => :build do
|
61
|
+
File.open(File.join(__dir__,'lib','nodepile','version.rb')){|f|
|
62
|
+
f.each{|line|
|
63
|
+
if /\s*VERSION\s*=\s*"([^"]+)"/ =~ line
|
64
|
+
system 'gem push ' + 'pkg/nodepile' + "-" + $1 + ".gem"
|
65
|
+
break
|
66
|
+
end
|
67
|
+
}
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Pre-release sweep of code"
|
72
|
+
task :sweep do
|
73
|
+
|
74
|
+
a = Dir["#{File.dirname(__FILE__)}/**/*.rb"]
|
75
|
+
alert_was_triggered = nil
|
76
|
+
a.each{|fname|
|
77
|
+
num = 0
|
78
|
+
File.open(fname,"r") do |f|
|
79
|
+
next if fname.match(/\/tests\//)
|
80
|
+
f.each_line do |line|
|
81
|
+
num+= 1
|
82
|
+
LINE_LEVEL_SWEEP_TESTS.each{|proc|
|
83
|
+
err_msg = proc.call(line)
|
84
|
+
if err_msg
|
85
|
+
if !alert_was_triggered
|
86
|
+
puts "\nSweep found problems in source code..."
|
87
|
+
alert_was_triggered = true
|
88
|
+
end
|
89
|
+
puts "{#{simplify_dir(fname)} : #{num}} - #{err_msg}"
|
90
|
+
end
|
91
|
+
}
|
92
|
+
end # loop over lines in file
|
93
|
+
end # loop over files
|
94
|
+
|
95
|
+
} # end loop over sourcecode
|
96
|
+
puts "Hurray! No active debug code found in the project." unless alert_was_triggered
|
97
|
+
|
98
|
+
# Clean up code elements that may linger
|
99
|
+
FileUtils.rm(Dir["#{File.dirname(__FILE__)}/test/tmp/*"])
|
100
|
+
end # sweep task
|
101
|
+
|
102
|
+
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
# Define a few basic "interchange" classes tha
|
3
|
+
|
4
|
+
module Nodepile
|
5
|
+
|
6
|
+
# Caches the result of named calculations and their parameters and provides
|
7
|
+
# a crude flushing
|
8
|
+
class CrudeCalculationCache
|
9
|
+
|
10
|
+
# Used to disable use of cache by all instances of this class. Note that this
|
11
|
+
# is extremely useful during testing.
|
12
|
+
def self.global_disable_cache(flag) = @@universally_disable_cache = flag
|
13
|
+
|
14
|
+
# @param disable_cache [Boolean] if truthy, then caching is never triggered
|
15
|
+
# for this object
|
16
|
+
def initialize(disable_cache: false)
|
17
|
+
@h = Hash.new
|
18
|
+
@disable_cache = disable_cache
|
19
|
+
end
|
20
|
+
|
21
|
+
# Empties the entire cache forcing recalculation of some or all entries
|
22
|
+
# @param name [String,Symbol,nil] Name of the calculation or nil if all calculations
|
23
|
+
# are to be flushed
|
24
|
+
# @param params [] If empty, all cached values for the given name will be flushed
|
25
|
+
def flush_cache(name = nil, *params)
|
26
|
+
if key.nil?
|
27
|
+
@h.clear
|
28
|
+
elsif params.empty?
|
29
|
+
@h.delete(name) # delete simple keys
|
30
|
+
@h.delete{|(cname,*cparams)| cname == name }
|
31
|
+
else
|
32
|
+
@h.delete([key,*params])
|
33
|
+
end
|
34
|
+
return nil
|
35
|
+
end
|
36
|
+
|
37
|
+
def form_cache_key(sym,*parms) = parms.empty? ? sym : [sym,*parms]
|
38
|
+
def stuff_cache(val,sym,*parms) = @h[form_cache_key(sym,*parms)] = val
|
39
|
+
def has_cache?(sym,*parms) = @h.include?(form_cache_key(sym,*parms))
|
40
|
+
|
41
|
+
def fetch_cache(sym,*parms)
|
42
|
+
key = form_cache_key(sym,*parms)
|
43
|
+
raise "This item is not in the cache #{key.inspect}" unless @h.include?(key)
|
44
|
+
return @h[key]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Will either retrieve the value matching these parameters from the cache
|
48
|
+
# or will do the calculation, cache the value, and return the result
|
49
|
+
def cache(sym,*parms)
|
50
|
+
raise "Calculation block expected" unless block_given?
|
51
|
+
key = form_cache_key(sym,*parms)
|
52
|
+
if @h.include?(key) && !@disable_cache && !@@global_disable_cache
|
53
|
+
return @h[key]
|
54
|
+
else
|
55
|
+
return @h[sym] = yield(*parms)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
@@global_disable_cache = false
|
60
|
+
end
|
61
|
+
|
62
|
+
end #module Nodepile
|