├── test ├── assets │ ├── reference.rb │ └── hello_world.xml └── test_enterprise.rb ├── bin ├── enterprise_ruby └── enterprise ├── CHANGELOG.rdoc ├── lib ├── enterprise.rb └── enterprise │ ├── file_loader.rb │ ├── sexp_hacks.rb │ └── sexml.rb ├── Manifest.txt ├── Rakefile ├── .autotest └── README.rdoc /test/assets/reference.rb: -------------------------------------------------------------------------------- 1 | class HelloWorld 2 | def innernet 3 | "the innernet is awesome".sub(/nn/, 'bar') 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /bin/enterprise_ruby: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'enterprise' 5 | 6 | Enterprise::FileLoader.load ARGV[0] 7 | -------------------------------------------------------------------------------- /CHANGELOG.rdoc: -------------------------------------------------------------------------------- 1 | === 1.0.0 / 2009-06-17 2 | 3 | * 1 major enhancement 4 | 5 | * Entering in to the enterprise 6 | * Bringing ruby in the back door 7 | 8 | -------------------------------------------------------------------------------- /lib/enterprise.rb: -------------------------------------------------------------------------------- 1 | require 'nokogiri' 2 | require 'ruby_parser' 3 | require 'ruby2ruby' 4 | require 'polyglot' 5 | 6 | require 'enterprise/sexml' 7 | require 'enterprise/file_loader' 8 | require 'enterprise/sexp_hacks' 9 | 10 | module Enterprise 11 | VERSION = '1.0.0' 12 | end 13 | -------------------------------------------------------------------------------- /Manifest.txt: -------------------------------------------------------------------------------- 1 | .autotest 2 | CHANGELOG.rdoc 3 | Manifest.txt 4 | README.rdoc 5 | Rakefile 6 | bin/enterprise 7 | bin/enterprise_ruby 8 | lib/enterprise.rb 9 | lib/enterprise/file_loader.rb 10 | lib/enterprise/sexml.rb 11 | lib/enterprise/sexp_hacks.rb 12 | test/assets/hello_world.xml 13 | test/assets/reference.rb 14 | test/test_enterprise.rb 15 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require 'rubygems' 4 | require 'hoe' 5 | 6 | Hoe.spec 'enterprise' do 7 | developer('Aaron Patterson', 'aaronp@rubyforge.org') 8 | self.readme_file = 'README.rdoc' 9 | self.history_file = 'CHANGELOG.rdoc' 10 | self.extra_rdoc_files = FileList['*.rdoc'] 11 | self.extra_deps = ['ruby2ruby', 'ruby_parser', 'nokogiri', 'polyglot'] 12 | self.rubyforge_name = 'seattlerb' 13 | end 14 | 15 | # vim: syntax=ruby 16 | -------------------------------------------------------------------------------- /lib/enterprise/file_loader.rb: -------------------------------------------------------------------------------- 1 | module Enterprise 2 | module FileLoader 3 | def self.load filename, options = nil, &block 4 | return true if $".include?(filename) # bug in polyglot 5 | 6 | $stderr.puts filename if ENV['ENTERPRISE_DEBUG'] 7 | sexml = Nokogiri::XML(File.read(filename)) { |cmd| cmd.noblanks } 8 | $" << filename 9 | Kernel.eval sexml.to_ruby, TOPLEVEL_BINDING 10 | end 11 | end 12 | end 13 | 14 | Polyglot.register 'xml', Enterprise::FileLoader 15 | -------------------------------------------------------------------------------- /.autotest: -------------------------------------------------------------------------------- 1 | # -*- ruby -*- 2 | 3 | require 'autotest/restart' 4 | 5 | # Autotest.add_hook :initialize do |at| 6 | # at.extra_files << "../some/external/dependency.rb" 7 | # 8 | # at.libs << ":../some/external" 9 | # 10 | # at.add_exception 'vendor' 11 | # 12 | # at.add_mapping(/dependency.rb/) do |f, _| 13 | # at.files_matching(/test_.*rb$/) 14 | # end 15 | # 16 | # %w(TestA TestB).each do |klass| 17 | # at.extra_class_map[klass] = "test/test_misc.rb" 18 | # end 19 | # end 20 | 21 | # Autotest.add_hook :run_command do |at| 22 | # system "rake build" 23 | # end 24 | -------------------------------------------------------------------------------- /bin/enterprise: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require 'rubygems' 4 | require 'enterprise' 5 | require 'find' 6 | 7 | files = [] 8 | 9 | ARGV.each do |path| 10 | if File.directory? path 11 | Find.find path do |file| 12 | next if File.directory? file 13 | next unless File.extname(file) == '.rb' 14 | files << file 15 | end 16 | else 17 | files << path 18 | end 19 | end 20 | 21 | files.each do |path| 22 | $stderr.puts path if ENV['ENTERPRISE_DEBUG'] 23 | sexml = Enterprise::SEXML File.read(path), path 24 | File.open(path.sub(/\.rb/, '.xml'), 'wb') do |f| 25 | sexml.write_to f 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/enterprise/sexp_hacks.rb: -------------------------------------------------------------------------------- 1 | class Sexp 2 | include Nokogiri::XML 3 | 4 | def to_xml doc = Document.new, parent = doc.root = Node.new('s', doc) 5 | each do |node| 6 | case node 7 | when Sexp 8 | new_parent = Node.new('s', parent.document) 9 | parent.add_child new_parent 10 | node.to_xml doc, new_parent 11 | else 12 | name = node.to_s 13 | if node.to_s.empty? || node.to_s !~ /^[A-Za-z]+$/ 14 | name = 'special' 15 | end 16 | 17 | n = Node.new(name, parent.document) 18 | n['type'] = node.class.name 19 | 20 | if Regexp === node 21 | n['value'] = [Marshal.dump(node)].pack('m') 22 | else 23 | n['value'] = node.to_s 24 | end 25 | 26 | parent << n 27 | end 28 | end 29 | doc 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /test/test_enterprise.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit' 2 | require 'rubygems' 3 | require 'enterprise' 4 | 5 | class TestEnterprise < Test::Unit::TestCase 6 | def setup 7 | @filename = File.join(File.dirname(__FILE__), 'assets', 'reference.rb') 8 | @codes = File.read(@filename) 9 | end 10 | 11 | def teardown 12 | Object.send(:remove_const, :HelloWorld) if defined? HelloWorld 13 | end 14 | 15 | def test_sexp_parse 16 | sexml = Enterprise::SEXML @codes, @filename 17 | assert sexml 18 | assert_equal 11, sexml.css('s').length 19 | end 20 | 21 | def test_sexml_can_be_converted_to_sexp 22 | sexml = Enterprise::SEXML @codes, @filename 23 | ruby_codes = sexml.to_sexp 24 | assert_instance_of Sexp, ruby_codes 25 | end 26 | 27 | def test_sexml_can_be_converted_to_ruby 28 | sexml = Enterprise::SEXML @codes, @filename 29 | ruby_codes = sexml.to_ruby 30 | m = Module.new 31 | m.module_eval ruby_codes 32 | assert m::HelloWorld.new.innernet 33 | end 34 | 35 | def test_require_some_xml 36 | require 'assets/hello_world' 37 | assert_equal 'the ibarernet is awesome', ::HelloWorld.new.innernet 38 | end 39 | end 40 | -------------------------------------------------------------------------------- /lib/enterprise/sexml.rb: -------------------------------------------------------------------------------- 1 | require 'nokogiri' 2 | require 'ruby2ruby' 3 | 4 | module Enterprise 5 | def self.SEXML codes, filename = nil 6 | sexp = RubyParser.new.parse codes, filename 7 | sexp ||= s(:nil) 8 | doc = sexp.to_xml 9 | doc.encoding = "UTF-8" 10 | doc 11 | end 12 | 13 | class XMLToSexp 14 | def visit node 15 | if ! node['value'] 16 | return s(*node.children.map { |child| child.accept self }) 17 | else 18 | case node['type'] 19 | when 'Symbol' 20 | node['value'].to_sym 21 | when 'Regexp' 22 | Marshal.load node['value'].unpack('m').first 23 | when 'NilClass' 24 | nil 25 | when 'Fixnum', 'Bignum' 26 | Integer(node['value']) 27 | when 'Float' 28 | Float(node['value']) 29 | else 30 | node['value'] 31 | end 32 | end 33 | end 34 | end 35 | end 36 | 37 | class Nokogiri::XML::Node 38 | def to_sexp 39 | result = accept Enterprise::XMLToSexp.new 40 | $stderr.puts result.inspect if ENV['ENTERPRISE_DEBUG'].to_i > 1 41 | result 42 | end 43 | 44 | def to_ruby 45 | Ruby2Ruby.new.process(to_sexp) 46 | end 47 | end 48 | 49 | class Nokogiri::XML::Document 50 | def to_ruby 51 | Ruby2Ruby.new.process(root.to_sexp) 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /test/assets/hello_world.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /README.rdoc: -------------------------------------------------------------------------------- 1 | = enterprise 2 | 3 | * http://github.com/tenderlove/enterprise/ 4 | 5 | == DESCRIPTION: 6 | 7 | Wish you could write your Ruby in XML? Has the fact that Ruby is not 8 | "enterprise" got you down? Do you feel like your Ruby code could be made to 9 | be more "scalable"? Well look no further my friend. You've found the 10 | enterprise gem. Once you install this gem, you too can make Rails scale, Ruby 11 | faster, your code more attractive, *and* have more XML in your life. 12 | 13 | I'm sure you're asking yourself, "how can the enterprise gem promise so 14 | much?". Well the answer is easy, through the magic of XML! The enterprise 15 | gem allows you to write your Ruby code in XML, therefore making your Ruby and 16 | Rails code scale. Benefits of writing your code in XML include: 17 | 18 | * It's easy to read! 19 | * It scales! 20 | * Cross platform 21 | * TRANSFORM! your code using XSLT! 22 | * Search your AST with XPath *or* CSS! 23 | 24 | The enterprise gem even comes with a handy "enterprise" binary to help you 25 | start converting your existing *legacy* Ruby code in to scaleable, easy to 26 | read XML files. Let's start getting rid of that nasty Ruby code and replacing 27 | it with XML today! 28 | 29 | == FEATURES/PROBLEMS: 30 | 31 | * require files completely written in XML 32 | * convert existing legacy ruby code to XML 33 | 34 | == SYNOPSIS: 35 | 36 | Let's say you have some legacy Ruby code that looks like this: 37 | 38 | class Foo 39 | def hello_world 40 | "bar" 41 | end 42 | end 43 | 44 | puts Foo.new.hello_world 45 | 46 | Let's convert that crappy ruby code to XML: 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | Now, simply save that XML file out to "test.xml". With the enterprise gem, 105 | to execute this xml file, we just do: 106 | 107 | $ enterprise_ruby test.xml 108 | 109 | enterprise lets you do a require on pure xml files too. We can load the 110 | test.xml file like so: 111 | 112 | require 'rubygems' 113 | require 'enterprise' 114 | require 'test' 115 | 116 | The final feature is an enterprise migration assistant. To migrate an entire 117 | project to be enterprise, just do this: 118 | 119 | $ enterprise some_directory 120 | 121 | To make a single file enterprise, just give it the filename: 122 | 123 | $ enterprise some_file.rb 124 | 125 | I'm sure you're asking yourself, "how much does this enterprise solution cost 126 | me?". Well, like any good enterprise system, it is insanely expensive. This 127 | gem will cost you eleventy billion dollars payable to me, now. 128 | 129 | == REQUIREMENTS: 130 | 131 | Like all good enterprise solutions, we do our best to get you stuck in a web 132 | of dependencies. We are working hard to increase the number of dependencies, 133 | but here is the current list 134 | 135 | * ruby2ruby 136 | * ruby_parser 137 | * nokogiri 138 | * polyglot 139 | 140 | == INSTALL: 141 | 142 | * sudo gem install enterprise 143 | 144 | == LICENSE: 145 | 146 | (The MIT License) 147 | 148 | Copyright (c) 2009 Aaron Patterson 149 | 150 | Permission is hereby granted, free of charge, to any person obtaining 151 | a copy of this software and associated documentation files (the 152 | 'Software'), to deal in the Software without restriction, including 153 | without limitation the rights to use, copy, modify, merge, publish, 154 | distribute, sublicense, and/or sell copies of the Software, and to 155 | permit persons to whom the Software is furnished to do so, subject to 156 | the following conditions: 157 | 158 | The above copyright notice and this permission notice shall be 159 | included in all copies or substantial portions of the Software. 160 | 161 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 162 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 163 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 164 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 165 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 166 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 167 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 168 | --------------------------------------------------------------------------------