exegesis 0.0.4 → 0.0.5

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