exegesis 0.0.4 → 0.0.5

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.
data/CHANGELOG CHANGED
@@ -1,4 +1,14 @@
1
- = 0.0.3 - 0.0.4
1
+ * 0.0.5
2
+ * Split up the project into three projects
3
+ - Exegesis remains as the FileSystem API
4
+ - Katuv is a new tool for defining and dealing with internal DSLs
5
+ - Eisegesis is the build tool proper, which uses Katuv and Exegesis to
6
+ provide build related functionality.
7
+ * Prepare for splitting out Drosophila, which contains the flyweight
8
+ implementation (mostly so I never have to write another Flyweight again)
9
+ * Update some docs to reflect the changes
10
+
11
+ * 0.0.3 - 0.0.4
2
12
  * Make sure Forwardable gem dependency gets loaded at the appropriate
3
13
  load-level
4
14
  * Skirt a very rare crash during tests (happens _literally_ only to my one
@@ -12,5 +22,4 @@
12
22
  everything stays synced.
13
23
 
14
24
  * 0.0.1
15
-
16
25
  Initial Release
data/NOTES.md CHANGED
@@ -1,3 +1,10 @@
1
+ # Nota Bene
2
+
3
+ Much of this is out of date, now that things are split up. It remains as an
4
+ interesting relic of a time long since forgotten. Some day it will be
5
+ unceremoniously killed.
6
+
7
+
1
8
  # Basic structure
2
9
 
3
10
  ## Implementation
@@ -212,3 +219,20 @@ the various subdirs.
212
219
  - set up hooks (run tests, etc)
213
220
  - Set up standard docs (README, AUTHORS, LICENSE, etc)
214
221
 
222
+ # Notes on how projects should work
223
+
224
+ * Project is the thing that interfaces with rake.
225
+ - creating a project creates a series of directory tasks, provides the
226
+ exegesis DSL for specifying package deps/whatever in whatever language
227
+ - it should automatically generate `clean`, `distclean`, and `scaffold`
228
+ tasks, the last of which is just a task that depends on all the directory
229
+ tasks
230
+ - it should use the environment for configuration.
231
+
232
+ * The Project should also automatically generate a default task which builds all
233
+ the binaries, tasks which build each binary individually, and a `install` task
234
+ which copies it to the appropriate place on the PATH
235
+
236
+ * The Project should, in particular, support multi-threaded compilation.
237
+
238
+
@@ -1,3 +1,4 @@
1
+ module Exegesis; end
1
2
 
2
3
  ################################################################################
3
4
  #load order matters here. These are sorted into load-levels Level-0 files must
@@ -30,20 +31,3 @@ require 'exegesis/base_directory'
30
31
  #-------------------------------------------------------------------------------
31
32
  #load whenever
32
33
  require 'exegesis/version'
33
-
34
- ################################################################################
35
-
36
-
37
- # Exegesis is a tool for automating many parts of the development of C projects.
38
- # Following a convention-over-configuration model.
39
- #
40
- # It provides tools to:
41
- #
42
- # * Create skeleton projects
43
- # * Build
44
- # * Testing
45
- # * Packaging
46
- #
47
- # Though C is presently the only supported language, it is the aim of Exegesis to
48
- # support tooling for other compiled languages.
49
- module Exegesis; end
@@ -13,17 +13,19 @@
13
13
  # Collaborators:
14
14
  # [Directory]
15
15
  # [SourceFile]
16
- class BaseDirectory < Directory
17
- # @param root [String] the root path of the project
18
- # @param searcher [FileSearcher] an object used to search for files in a given
19
- # directory
20
- def initialize(root, searcher = FileSearcher)
21
- super(nil, root, searcher)
22
- end
16
+ module Exegesis
17
+ class BaseDirectory < Directory
18
+ # @param root [String] the root path of the project
19
+ # @param searcher [FileSearcher] an object used to search for files in a given
20
+ # directory
21
+ def initialize(root, searcher = FileSearcher)
22
+ super(nil, root, searcher)
23
+ end
23
24
 
24
- # The path to the root of the project
25
- def path
26
- name
25
+ # The path to the root of the project
26
+ def path
27
+ name
28
+ end
29
+ alias root path
27
30
  end
28
- alias root path
29
31
  end
@@ -11,23 +11,33 @@
11
11
  # Collaborators:
12
12
  # SourceFile
13
13
  # Directory
14
- class Directory
15
- include FileSystemEntity
14
+ module Exegesis
15
+ class Directory
16
+ include FileSystemEntity
16
17
 
17
- delegate [:directories, :files] => :searcher
18
- alias children directories
18
+ delegate [:directories, :files] => :searcher
19
+ alias children directories
19
20
 
20
- private
21
+ def find_directory(dirname)
22
+ directories.select { |d| d.name == dirname || d.name + '/' == dirname }.first
23
+ end
21
24
 
22
- attr_reader :searcher
25
+ def find_file(filename)
26
+ files.select { |f| f.name == filename }.first
27
+ end
23
28
 
24
- # @param parent [Directory] the root directory or project of the project
25
- # @param name [String] the name of the directory
26
- # @param searcher [FileSearcher] an object used to search for files in a given
27
- # directory
28
- def initialize(parent, name, searcher = FileSearcher)
29
- @parent = parent
30
- @name = name
31
- @searcher = searcher.new(self)
29
+ private
30
+
31
+ attr_reader :searcher
32
+
33
+ # @param parent [Directory] the root directory or project of the project
34
+ # @param name [String] the name of the directory
35
+ # @param searcher [FileSearcher] an object used to search for files in a given
36
+ # directory
37
+ def initialize(parent, name, searcher = FileSearcher)
38
+ @parent = parent
39
+ @name = name
40
+ @searcher = searcher.new(self)
41
+ end
32
42
  end
33
43
  end
@@ -15,39 +15,41 @@
15
15
  # Project, Directory
16
16
  # Uses:
17
17
  # Some system-level class like Dir, FileList, or Find
18
- class FileSearcher
19
- # Create a new FileSearcher on the given path
20
- #
21
- # @param parent [Directory] the parent directory to search downward from
22
- def initialize(parent, fs_interface = File)
23
- @fs_interface = fs_interface
24
- @parent = parent
25
- end
18
+ module Exegesis
19
+ class FileSearcher
20
+ # Create a new FileSearcher on the given path
21
+ #
22
+ # @param parent [Directory] the parent directory to search downward from
23
+ def initialize(parent, fs_interface = File)
24
+ @fs_interface = fs_interface
25
+ @parent = parent
26
+ end
26
27
 
27
- #All of the directories in the given path
28
- def directories
29
- content.
30
- select { |s| fs_interface.directory?(s) }.
31
- map { |s| Directory.create(parent, fs_interface.basename(s)) }
32
- end
28
+ #All of the directories in the given path
29
+ def directories
30
+ content.
31
+ select { |s| fs_interface.directory?(s) }.
32
+ map { |s| Directory.create(parent, fs_interface.basename(s)) }
33
+ end
33
34
 
34
- #All of the files in the given path
35
- def files
36
- content.
37
- select { |s| fs_interface.file?(s) }.
38
- map { |s| SourceFile.create(parent, fs_interface.basename(s)) }
39
- end
35
+ #All of the files in the given path
36
+ def files
37
+ content.
38
+ select { |s| fs_interface.file?(s) }.
39
+ map { |s| SourceFile.create(parent, fs_interface.basename(s)) }
40
+ end
40
41
 
41
- #All of the content from the given path
42
- def content
43
- Dir[File.join(parent.path, '*')]
44
- end
42
+ #All of the content from the given path
43
+ def content
44
+ Dir[File.join(parent.path, '*')]
45
+ end
45
46
 
46
- def inspect
47
- "FileSearcher(#{parent.path.inspect})"
48
- end
47
+ def inspect
48
+ "FileSearcher(#{parent.path.inspect})"
49
+ end
49
50
 
50
- private
51
+ private
51
52
 
52
- attr_reader :parent, :fs_interface
53
+ attr_reader :parent, :fs_interface
54
+ end
53
55
  end
@@ -1,52 +1,52 @@
1
1
  # A collection of shared methods for Directories and SourceFiles
2
- module FileSystemEntity
3
- def self.included(base)
4
- base.send(:include , Registerable)
5
- base.send(:extend , Forwardable)
6
- base.send(:include , Methods)
7
- end
8
-
9
- module Methods
10
- def path
11
- File.join(parent.path, name)
2
+ module Exegesis
3
+ module FileSystemEntity
4
+ def self.included(base)
5
+ base.send(:include , Registerable)
6
+ base.send(:extend , Forwardable)
7
+ base.send(:include , Methods)
12
8
  end
13
9
 
14
- def inspect
15
- "#{self.class.inspect}(#{path.inspect})"
16
- end
10
+ module Methods
11
+ def path
12
+ File.join(parent.path, name)
13
+ end
17
14
 
18
- attr_reader :parent, :name
19
- alias container parent
15
+ def inspect
16
+ "#{self.class.inspect}(#{path.inspect})"
17
+ end
20
18
 
21
- def basename
22
- File.basename(name, ext)
23
- end
19
+ attr_reader :parent, :name
20
+ alias container parent
24
21
 
25
- def ext
26
- @ext || ""
27
- end
28
- alias extension ext
22
+ def basename
23
+ File.basename(name, ext)
24
+ end
29
25
 
26
+ def ext
27
+ @ext || ""
28
+ end
29
+ alias extension ext
30
30
 
31
- def visit(visitor)
32
- visitor.on_enter if visitor.respond_to? :on_enter
31
+ def visit(visitor)
32
+ visitor.on_enter if visitor.respond_to? :on_enter
33
33
 
34
- visitor.call(self.class, self)
34
+ visitor.call(self.class, self)
35
35
 
36
- if respond_to?(:directories)
37
- directories.each do |dir|
38
- dir.visit(visitor)
36
+ if respond_to?(:directories)
37
+ directories.each do |dir|
38
+ dir.visit(visitor)
39
+ end
39
40
  end
40
- end
41
41
 
42
- if respond_to?(:files)
43
- files.each do |file|
44
- file.visit(visitor)
42
+ if respond_to?(:files)
43
+ files.each do |file|
44
+ file.visit(visitor)
45
+ end
45
46
  end
46
- end
47
47
 
48
- visitor.on_exit if visitor.respond_to? :on_exit
48
+ visitor.on_exit if visitor.respond_to? :on_exit
49
+ end
49
50
  end
50
51
  end
51
52
  end
52
-
@@ -10,121 +10,122 @@
10
10
  # SourceFile
11
11
  # Directory
12
12
  # Project
13
- class Flyweight
14
- extend Forwardable
15
-
16
- # Create an empty Flyweight with the given key-processing proc.
17
- #
18
- # @param key_processor [Proc] a proc which turns an instance into it's key.
19
- def initialize(&key_processor)
20
- clear!
21
-
22
- if block_given?
23
- @key_processor = key_processor
24
- else
25
- @key_processor = proc { |id| id }
13
+ module Exegesis
14
+ class Flyweight
15
+ extend Forwardable
16
+
17
+ # Create an empty Flyweight with the given key-processing proc.
18
+ #
19
+ # @param key_processor [Proc] a proc which turns an instance into it's key.
20
+ def initialize(&key_processor)
21
+ clear!
22
+
23
+ if block_given?
24
+ @key_processor = key_processor
25
+ else
26
+ @key_processor = proc { |id| id }
27
+ end
28
+
29
+ self
26
30
  end
27
31
 
28
- self
29
- end
30
-
31
- # Register an instance in the flyweight. Throw an error if the key is already
32
- # used.
33
- #
34
- # @param instance [Object] the instance to register in the flyweight
35
- # @return [Object] the instance given
36
- # @raise [AlreadyRegisteredError] when trying to register the same key twice
37
- def register!(instance)
38
- raise AlreadyRegisteredError if has_key?(instance)
39
- register(instance)
40
- end
32
+ # Register an instance in the flyweight. Throw an error if the key is already
33
+ # used.
34
+ #
35
+ # @param instance [Object] the instance to register in the flyweight
36
+ # @return [Object] the instance given
37
+ # @raise [AlreadyRegisteredError] when trying to register the same key twice
38
+ def register!(instance)
39
+ raise AlreadyRegisteredError if has_key?(instance)
40
+ register(instance)
41
+ end
41
42
 
42
- # Register an instance in the flyweight.
43
- #
44
- # @param instance [Object] the instance to register in the flyweight
45
- # @return [Object] the instance given
46
- def register(instance)
47
- key = build_key(instance)
48
- key_registry[key] = instance
49
- end
43
+ # Register an instance in the flyweight.
44
+ #
45
+ # @param instance [Object] the instance to register in the flyweight
46
+ # @return [Object] the instance given
47
+ def register(instance)
48
+ key = build_key(instance)
49
+ key_registry[key] = instance
50
+ end
50
51
 
51
- # Remove an instance (by key or instance proper) from the flyweight. Throw an
52
- # error if no such instance exists
53
- #
54
- # @param key_or_instance [Object] Either the key under which an instance is
55
- # registered, or the instance itself.
56
- # @return [Object] the instance deleted from the flyweight
57
- # @raise [NoFlyweightEntryError] when trying to delete a key that isn't
58
- # present in the flyweight
59
- def unregister!(key_or_instance)
60
- raise NoEntryError unless has_key?(key_or_instance)
61
- unregister(key_or_instance)
62
- end
52
+ # Remove an instance (by key or instance proper) from the flyweight. Throw an
53
+ # error if no such instance exists
54
+ #
55
+ # @param key_or_instance [Object] Either the key under which an instance is
56
+ # registered, or the instance itself.
57
+ # @return [Object] the instance deleted from the flyweight
58
+ # @raise [NoFlyweightEntryError] when trying to delete a key that isn't
59
+ # present in the flyweight
60
+ def unregister!(key_or_instance)
61
+ raise NoEntryError unless has_key?(key_or_instance)
62
+ unregister(key_or_instance)
63
+ end
63
64
 
64
- # Remove an instance from the flyweight
65
- #
66
- # @param key_or_instance [Object] Either the key under which an instance is
67
- # registered, or the instance itself.
68
- # @return [Object] the instance deleted from the flyweight
69
- def unregister(key_or_instance)
70
- proxy_across_keytypes(:delete, key_or_instance)
71
- end
65
+ # Remove an instance from the flyweight
66
+ #
67
+ # @param key_or_instance [Object] Either the key under which an instance is
68
+ # registered, or the instance itself.
69
+ # @return [Object] the instance deleted from the flyweight
70
+ def unregister(key_or_instance)
71
+ proxy_across_keytypes(:delete, key_or_instance)
72
+ end
72
73
 
73
- # Whether the flyweight has the given key or instance registered
74
- #
75
- # @param key_or_instance [Object] Either the key under which an instance is
76
- # registered, or the instance itself.
77
- # @return [Boolean] True if the Flyweight has the key or instance, false
78
- # otherwise
79
- def has_key?(key_or_instance)
80
- proxy_across_keytypes(:has_key?, key_or_instance)
81
- end
74
+ # Whether the flyweight has the given key or instance registered
75
+ #
76
+ # @param key_or_instance [Object] Either the key under which an instance is
77
+ # registered, or the instance itself.
78
+ # @return [Boolean] True if the Flyweight has the key or instance, false
79
+ # otherwise
80
+ def has_key?(key_or_instance)
81
+ proxy_across_keytypes(:has_key?, key_or_instance)
82
+ end
82
83
 
83
- # Access the entry under the given key or instance
84
- #
85
- # NB. If, given an instance that would generate a matching key to an already
86
- # registered instance, but perhaps with different data, you'll get back a
87
- # reference to the _registered_ instance.
88
- #
89
- # @param key_or_instance [Object] The key or instance to access.
90
- # @return [Object, NilClass] the instance desired, or nil if it doesn't exist
91
- def [](key_or_instance)
92
- proxy_across_keytypes(:[], key_or_instance)
93
- end
84
+ # Access the entry under the given key or instance
85
+ #
86
+ # NB. If, given an instance that would generate a matching key to an already
87
+ # registered instance, but perhaps with different data, you'll get back a
88
+ # reference to the _registered_ instance.
89
+ #
90
+ # @param key_or_instance [Object] The key or instance to access.
91
+ # @return [Object, NilClass] the instance desired, or nil if it doesn't exist
92
+ def [](key_or_instance)
93
+ proxy_across_keytypes(:[], key_or_instance)
94
+ end
94
95
 
95
- # Clear the Flyweight of all entries.
96
- def clear!
97
- @key_registry = {}
98
- self
99
- end
100
- alias reset! clear!
96
+ # Clear the Flyweight of all entries.
97
+ def clear!
98
+ @key_registry = {}
99
+ self
100
+ end
101
+ alias reset! clear!
101
102
 
102
- def inspect
103
- "Flyweight<#{object_id}, items=#{@key_registry.keys.count}>"
104
- end
103
+ def inspect
104
+ "Flyweight<#{object_id}, items=#{@key_registry.keys.count}>"
105
+ end
105
106
 
106
- private
107
+ private
107
108
 
108
- # Build a key from an instance via the key_processor
109
- def build_key(instance)
110
- @key_processor.call(instance)
111
- end
109
+ # Build a key from an instance via the key_processor
110
+ def build_key(instance)
111
+ @key_processor.call(instance)
112
+ end
112
113
 
113
- # Proxy a method, aim to use the raw key first, but if that doesn't work, use
114
- # the build_key helper and assume you were given an instance.
115
- #
116
- # NB. This is a bit dirty, but since we don't know what types we're given, we
117
- # can't distinguish between key's and instance's without forcing the user to
118
- # specifically tell us.
119
- def proxy_across_keytypes(method, key)
120
- key_registry.send(method, key) || key_registry.send(method, build_key(key))
121
- end
114
+ # Proxy a method, aim to use the raw key first, but if that doesn't work, use
115
+ # the build_key helper and assume you were given an instance.
116
+ #
117
+ # NB. This is a bit dirty, but since we don't know what types we're given, we
118
+ # can't distinguish between key's and instance's without forcing the user to
119
+ # specifically tell us.
120
+ def proxy_across_keytypes(method, key)
121
+ key_registry.send(method, key) || key_registry.send(method, build_key(key))
122
+ end
122
123
 
123
- attr_accessor :key_registry
124
+ attr_accessor :key_registry
124
125
 
125
- # An error raised when trying to use an already used key
126
- class AlreadyRegisteredError < ArgumentError ; end
127
- # An error raised when trying to remove an unused key
128
- class NoEntryError < ArgumentError ; end
126
+ # An error raised when trying to use an already used key
127
+ class AlreadyRegisteredError < ArgumentError ; end
128
+ # An error raised when trying to remove an unused key
129
+ class NoEntryError < ArgumentError ; end
130
+ end
129
131
  end
130
-