xnlogic 1.0.0

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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +15 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +31 -0
  6. data/Rakefile +43 -0
  7. data/bin/xnlogic +13 -0
  8. data/lib/xnlogic/cli/application.rb +60 -0
  9. data/lib/xnlogic/cli.rb +73 -0
  10. data/lib/xnlogic/friendly_errors.rb +50 -0
  11. data/lib/xnlogic/man/xnlogic +46 -0
  12. data/lib/xnlogic/man/xnlogic.txt +42 -0
  13. data/lib/xnlogic/templates/application/.rspec.tt +2 -0
  14. data/lib/xnlogic/templates/application/Gemfile.tt +6 -0
  15. data/lib/xnlogic/templates/application/Readme.md.tt +86 -0
  16. data/lib/xnlogic/templates/application/gitignore.tt +9 -0
  17. data/lib/xnlogic/templates/application/lib/fixtures/sample_fixtures.rb.tt +53 -0
  18. data/lib/xnlogic/templates/application/lib/gemname/fixtures.rb.tt +108 -0
  19. data/lib/xnlogic/templates/application/lib/gemname/initializers/inflections.rb.tt +13 -0
  20. data/lib/xnlogic/templates/application/lib/gemname/models.rb.tt +37 -0
  21. data/lib/xnlogic/templates/application/lib/gemname/parts/has_notes.rb.tt +10 -0
  22. data/lib/xnlogic/templates/application/lib/gemname/parts/note.rb.tt +41 -0
  23. data/lib/xnlogic/templates/application/lib/gemname/permissions.rb.tt +136 -0
  24. data/lib/xnlogic/templates/application/lib/gemname/type/url.rb.tt +13 -0
  25. data/lib/xnlogic/templates/application/lib/gemname/type.rb.tt +10 -0
  26. data/lib/xnlogic/templates/application/lib/gemname/version.rb.tt +3 -0
  27. data/lib/xnlogic/templates/application/lib/gemname.rb.tt +116 -0
  28. data/lib/xnlogic/templates/application/spec/gemname/gemname_spec.rb.tt +7 -0
  29. data/lib/xnlogic/templates/application/spec/spec_helper.rb.tt +44 -0
  30. data/lib/xnlogic/ui/shell.rb +96 -0
  31. data/lib/xnlogic/ui/silent.rb +45 -0
  32. data/lib/xnlogic/ui.rb +7 -0
  33. data/lib/xnlogic/version.rb +3 -0
  34. data/lib/xnlogic.rb +33 -0
  35. data/man/xnlogic.ronn +38 -0
  36. data/xnlogic.gemspec +27 -0
  37. metadata +149 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 228227d4a324ef82abaa6dee535286df33108c12
4
+ data.tar.gz: d9a430dbd6b9d08cc251c1a0264ed95fde17d765
5
+ SHA512:
6
+ metadata.gz: 644272798d732f21d5f1be96da46a14b3d70b5036ba2713460c8cb49404041a42a06b0148ef51fe51fa1c69bc5ee15134444e99557f2996566249857c128e56c
7
+ data.tar.gz: 7a87b081194d30a86f416f66fc9f0f7dd128d181600933f2974d9cce809169a4bfd7e18214f406bdf4a6ac1c70a94d600bf85584b4572f8b248ec1cd3a14bcaa
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ /lib/xnlogic/man
11
+ *.bundle
12
+ *.so
13
+ *.o
14
+ *.a
15
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in xnlogic.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Darrick Wiebe
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # Xnlogic
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'xnlogic'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install xnlogic
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/xnlogic/fork )
28
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
29
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
30
+ 4. Push to the branch (`git push origin my-new-feature`)
31
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,43 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require 'xn_gem_release_tasks'
4
+ XNGemReleaseTasks.setup Xnlogic, 'lib/xnlogic/version.rb'
5
+
6
+ begin
7
+ require 'ronn'
8
+
9
+ namespace :man do
10
+ directory "lib/xnlogic/man"
11
+
12
+ Dir["man/*.ronn"].each do |ronn|
13
+ basename = File.basename(ronn, ".ronn")
14
+ roff = "lib/xnlogic/man/#{basename}"
15
+
16
+ file roff => ["lib/xnlogic/man", ronn] do
17
+ sh "#{Gem.ruby} -S ronn --roff --pipe #{ronn} > #{roff}"
18
+ end
19
+
20
+ file "#{roff}.txt" => roff do
21
+ sh "groff -Wall -mtty-char -mandoc -Tascii #{roff} | col -b > #{roff}.txt"
22
+ end
23
+
24
+ task :build_all_pages => "#{roff}.txt"
25
+ end
26
+
27
+ desc "Build the man pages"
28
+ task :build => "man:build_all_pages"
29
+
30
+ desc "Clean up from the built man pages"
31
+ task :clean do
32
+ rm_rf "lib/xnlogic/man"
33
+ end
34
+ end
35
+
36
+ rescue LoadError
37
+ namespace :man do
38
+ task(:build) { warn "Install the ronn gem to be able to release!" }
39
+ task(:clean) { warn "Install the ronn gem to be able to release!" }
40
+ end
41
+ end
42
+
43
+ task :build => ['man:clean', 'man:build']
data/bin/xnlogic ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Exit cleanly from an early interrupt
4
+ Signal.trap("INT") { exit 1 }
5
+
6
+ require 'xnlogic'
7
+
8
+ require 'xnlogic/friendly_errors'
9
+ Xnlogic.with_friendly_errors do
10
+ require 'xnlogic/cli'
11
+ Xnlogic::CLI.start(ARGV, :debug => true)
12
+ end
13
+
@@ -0,0 +1,60 @@
1
+ require 'pathname'
2
+
3
+ module Xnlogic
4
+ class CLI::Application
5
+ attr_reader :options, :app_name, :thor, :name, :target
6
+
7
+ def initialize(options, app_name, thor)
8
+ @options = options
9
+ @app_name = app_name
10
+ @thor = thor
11
+
12
+ @name = app_name.chomp("/").tr('-', '_') # remove trailing slash if present
13
+ @target = Pathname.pwd.join(name)
14
+ end
15
+
16
+ def run
17
+ namespaced_path = name
18
+ constant_name = namespaced_path.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
19
+ git_user_name = `git config user.name`.chomp
20
+ git_user_email = `git config user.email`.chomp
21
+
22
+ opts = {
23
+ :name => name,
24
+ :namespaced_path => namespaced_path,
25
+ :constant_name => constant_name,
26
+ :author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
27
+ :email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
28
+ }
29
+
30
+ templates = {
31
+ "gitignore.tt" => ".gitignore",
32
+ ".rspec.tt" => ".rspec",
33
+ "Gemfile.tt" => "Gemfile",
34
+ "Readme.md.tt" => "Readme.md",
35
+ "lib/gemname.rb.tt" => "lib/#{namespaced_path}.rb",
36
+ "lib/gemname/version.rb.tt" => "lib/#{namespaced_path}/version.rb",
37
+ "lib/gemname/initializers/inflections.rb.tt" => "lib/#{namespaced_path}/initializers/inflections.rb",
38
+ "lib/gemname/parts/has_notes.rb.tt" => "lib/#{namespaced_path}/parts/has_notes.rb",
39
+ "lib/gemname/parts/note.rb.tt" => "lib/#{namespaced_path}/parts/note.rb",
40
+ "lib/gemname/type/url.rb.tt" => "lib/#{namespaced_path}/type/url.rb",
41
+ "lib/gemname/fixtures.rb.tt" => "lib/#{namespaced_path}/fixtures.rb",
42
+ "lib/gemname/models.rb.tt" => "lib/#{namespaced_path}/models.rb",
43
+ "lib/gemname/permissions.rb.tt" => "lib/#{namespaced_path}/permissions.rb",
44
+ "lib/gemname/type.rb.tt" => "lib/#{namespaced_path}/type.rb",
45
+ "lib/fixtures/sample_fixtures.rb.tt" => "lib/fixtures/sample_fixtures.rb",
46
+
47
+ "spec/spec_helper.rb.tt" => "spec/spec_helper.rb",
48
+ "spec/gemname/gemname_spec.rb.tt" => "spec/#{namespaced_path}/#{name}_spec.rb",
49
+ }
50
+
51
+ templates.each do |src, dst|
52
+ thor.template("application/#{src}", target.join(dst), opts)
53
+ end
54
+
55
+ Xnlogic.ui.info "Initializing git repo in #{target}"
56
+ Dir.chdir(target) { `git init`; `git add .` }
57
+ end
58
+ end
59
+ end
60
+
@@ -0,0 +1,73 @@
1
+ require 'thor'
2
+
3
+ module Xnlogic
4
+ class CLI < Thor
5
+ include Thor::Actions
6
+
7
+ def self.start(*)
8
+ super
9
+ rescue Exception => e
10
+ Xnlogic.ui = UI::Shell.new
11
+ raise e
12
+ end
13
+
14
+ def initialize(*args)
15
+ super
16
+ rescue UnknownArgumentError => e
17
+ raise InvalidOption, e.message
18
+ ensure
19
+ self.options ||= {}
20
+ Xnlogic.ui = UI::Shell.new(options)
21
+ Xnlogic.ui.level = "debug" if options["verbose"]
22
+ end
23
+
24
+ check_unknown_options!(:except => [:config, :exec])
25
+
26
+ # Stop parsing of options as soon as an unknown option or a regular argument is encountered. All remaining arguments are passed to the task. This
27
+ # is useful if you have a task that can receive arbitrary additional options, and where those additional options should not be handled by Thor.
28
+ stop_on_unknown_option! :exec
29
+
30
+ class_option "no-color", :type => :boolean, :banner => "Disable colorization in output"
31
+
32
+ class_option "verbose", :type => :boolean, :banner => "Enable verbose output mode", :aliases => "-V"
33
+
34
+ def help(cli = nil)
35
+ case cli
36
+ when nil then command = "xnlogic"
37
+ else command = "xnlogic-#{cli}"
38
+ end
39
+
40
+ manpages = %w(
41
+ xnlogic)
42
+
43
+ if manpages.include?(command)
44
+ root = File.expand_path("../man", __FILE__)
45
+
46
+ if Xnlogic.which("man") && root !~ %r{^file:/.+!/META-INF/jruby.home/.+}
47
+ Kernel.exec "man #{root}/#{command}"
48
+ else
49
+ puts File.read("#{root}/#{command}.txt")
50
+ end
51
+ else
52
+ super
53
+ end
54
+ end
55
+
56
+ def self.handle_no_command_error(command, has_namespace = $thor_runner)
57
+ return super unless command_path = Xnlogic.which("xnlogic-#{command}")
58
+
59
+ Kernel.exec(command_path, *ARGV[1..-1])
60
+ end
61
+
62
+ desc "application NAME [OPTIONS]", "Creates a skeleton for creating an XN Logic application"
63
+ def application(name)
64
+ require 'xnlogic/cli/application'
65
+ Application.new(options, name, self).run
66
+ end
67
+
68
+ def self.source_root
69
+ File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
70
+ end
71
+
72
+ end
73
+ end
@@ -0,0 +1,50 @@
1
+ require "thor"
2
+
3
+ # Create Thor classes if they don't exist already
4
+ class Thor
5
+ class AmbiguousTaskError; end
6
+ class UndefinedTaskError; end
7
+ class Error; end
8
+ end
9
+
10
+ module Xnlogic
11
+ def self.with_friendly_errors
12
+ yield
13
+ rescue Xnlogic::XnlogicError => e
14
+ Xnlogic.ui.error e.message, :wrap => true
15
+ Xnlogic.ui.trace e
16
+ exit e.status_code
17
+ rescue Thor::AmbiguousTaskError => e
18
+ Xnlogic.ui.error e.message
19
+ exit 15
20
+ rescue Thor::UndefinedTaskError => e
21
+ Xnlogic.ui.error e.message
22
+ exit 15
23
+ rescue Thor::Error => e
24
+ Xnlogic.ui.error e.message
25
+ exit 1
26
+ rescue LoadError => e
27
+ raise e unless e.message =~ /cannot load such file -- openssl|openssl.so|libcrypto.so/
28
+ Xnlogic.ui.error "\nCould not load OpenSSL."
29
+ Xnlogic.ui.warn <<-WARN, :wrap => true
30
+ You must recompile Ruby with OpenSSL support or change the sources in your \
31
+ Gemfile from 'https' to 'http'. Instructions for compiling with OpenSSL \
32
+ using RVM are available at http://rvm.io/packages/openssl.
33
+ WARN
34
+ Xnlogic.ui.trace e
35
+ exit 1
36
+ rescue Interrupt => e
37
+ Xnlogic.ui.error "\nQuitting..."
38
+ Xnlogic.ui.trace e
39
+ exit 1
40
+ rescue SystemExit => e
41
+ exit e.status
42
+ rescue Exception => e
43
+ Xnlogic.ui.error <<-ERR, :wrap => true
44
+ Unfortunately, a fatal error has occurred. Please see the XN Logic \
45
+ ZenDesk support pages: https://xnlogic.zendesk.com/hc/en-us
46
+ ERR
47
+ raise e
48
+ end
49
+ end
50
+
@@ -0,0 +1,46 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "XNLOGIC" "1" "November 2014" "" ""
5
+ .
6
+ .SH "NAME"
7
+ \fBxnlogic\fR \- XN Logic Command\-line Tools
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBxnlogic\fR COMMAND [\-\-no\-color] [\-\-verbose] [ARGS]
11
+ .
12
+ .SH "DESCRIPTION"
13
+ XN Logic is a graph database\-backed application framework\.
14
+ .
15
+ .P
16
+ See the XN Logic website \fIhttps://xnlogic\.com\fR for information on getting started, or https://xnlogic\.zendesk\.com/hc/en\-us for support\.
17
+ .
18
+ .SH "OPTIONS"
19
+ .
20
+ .TP
21
+ \fB\-\-no\-color\fR
22
+ Prints all output without color
23
+ .
24
+ .TP
25
+ \fB\-\-verbose\fR
26
+ Prints out additional logging information
27
+ .
28
+ .SH "COMMANDS"
29
+ We divide \fBxnlogic\fR subcommands into primary commands and utilities\.
30
+ .
31
+ .SH "PRIMARY COMMANDS"
32
+ .
33
+ .IP "\(bu" 4
34
+ \&\.\.\.
35
+ .
36
+ .IP "\(bu" 4
37
+ \fBxnlogic help(1)\fR: Displays detailed help for each subcommand
38
+ .
39
+ .IP "" 0
40
+ .
41
+ .SH "UTILITIES"
42
+ .
43
+ .TP
44
+ \fBxnlogic application(1)\fR
45
+ Create a simple application, suitable for development with xnlogic
46
+
@@ -0,0 +1,42 @@
1
+ XNLOGIC(1) XNLOGIC(1)
2
+
3
+
4
+
5
+ NAME
6
+ xnlogic - XN Logic Command-line Tools
7
+
8
+ SYNOPSIS
9
+ xnlogic COMMAND [--no-color] [--verbose] [ARGS]
10
+
11
+ DESCRIPTION
12
+ XN Logic is a graph database-backed application framework.
13
+
14
+ See the XN Logic website https://xnlogic.com for information on getting
15
+ started, or https://xnlogic.zendesk.com/hc/en-us for support.
16
+
17
+ OPTIONS
18
+ --no-color
19
+ Prints all output without color
20
+
21
+ --verbose
22
+ Prints out additional logging information
23
+
24
+ COMMANDS
25
+ We divide xnlogic subcommands into primary commands and utilities.
26
+
27
+ PRIMARY COMMANDS
28
+ o ...
29
+
30
+ o xnlogic help(1): Displays detailed help for each subcommand
31
+
32
+
33
+
34
+ UTILITIES
35
+ xnlogic application(1)
36
+ Create a simple application, suitable for development with
37
+ xnlogic
38
+
39
+
40
+
41
+
42
+ November 2014 XNLOGIC(1)
@@ -0,0 +1,2 @@
1
+ -f d
2
+ -p
@@ -0,0 +1,6 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'pacer'
4
+ gem 'pacer-neo4j'
5
+ gem 'pacer-model'
6
+ gem 'pacer-mcfly'
@@ -0,0 +1,86 @@
1
+ # <%= config[:name] %>
2
+
3
+ This gem provides the domain model and business logic for ...
4
+
5
+ # Getting a New Environment Set Up
6
+
7
+ TODO: Add vagrant setup instructions.
8
+
9
+ # Starting up the Development Console
10
+
11
+ To use this model, simply require the gem and work the graph like you're used to with pacer.
12
+
13
+ To start an IRB console session in the terminal, log into the VM and:
14
+
15
+ ```
16
+ xn console <%= config[:name] %>
17
+ ```
18
+
19
+ The first time you use the application, you must instantiate a client application. To do that from the console:
20
+
21
+ ```ruby
22
+ PM.create_client '<%= config[:name] %>', 'client_app_name'
23
+ ```
24
+
25
+ You can create as many clients for your application as you like. Once you create a client, it will still be available across restarts of the
26
+ application. To get a reference to your client application and the graph that it points to, run:
27
+
28
+ ```ruby
29
+ app = PM['client_app_name']
30
+ graph = app.graph
31
+ ```
32
+
33
+ And that's it! Now just rock your XN skills and Pacer-foo on top of your application model ;)
34
+
35
+ ## Testing the REST API within the Dev Console
36
+
37
+ Start by getting a reference to the application instance (see above). Once you have that, you'll need to get XN to generate the
38
+ console REST endpoints with this command:
39
+
40
+ ```ruby
41
+ include app.console
42
+ ```
43
+
44
+ Now you can execute commands with `xget`, `xpost`, `xpatch`, `xdelete`, `xput`, as follows:
45
+
46
+ ```ruby
47
+ xget '/model/some_model/id/123'
48
+
49
+ # NOTE that hash keys in requests must be strings:
50
+
51
+ xput '/model/some_model', {'name' => 'Record Name'}
52
+ ```
53
+
54
+
55
+ # Fixtures
56
+
57
+ You can create fixture data for your app or for a sample app by creating fixture files in
58
+ `lib/fixtures`. Run `xn sample_fixtures` to see a sample fixtures file.
59
+
60
+ Load:
61
+
62
+ ```ruby
63
+ require 'gemname/fixtures.rb'
64
+ GemName::Fixtures.load_fixtures app
65
+ ```
66
+
67
+ # Export to GraphML
68
+
69
+ (yFiles)[http://www.yworks.com/en/products_yed_about.html] (yfiles will not recognize the file with an incorrect extension):
70
+
71
+ ```ruby
72
+ require 'pacer/utils/y_files'
73
+ exp = Pacer::Util::YFiles.new
74
+ exp.export graph, "/tmp/example.graphml"
75
+ ```
76
+
77
+
78
+ Also, you can load and GraphML back into the graph with:
79
+
80
+ ```ruby
81
+ Pacer::GraphML.import graph, "/tmp/example.graphml"
82
+ ```
83
+
84
+ # Copyright
85
+ Copyright XN Logic Corporation, 2014. All rights reserved.
86
+ Contact us@xnlogic.com for usage restrictions.
@@ -0,0 +1,9 @@
1
+ *.sw?
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ Jarfile.lock
6
+ Jarfile.*.lock
7
+ pkg/*
8
+ bin/*
9
+ tmp/
@@ -0,0 +1,53 @@
1
+ module <%= config[:constant_name] %>
2
+ module Fixtures
3
+
4
+ # TODO: create your own fixtures!
5
+ class UsersFixture < Fixture
6
+ # We define that the UsersFixture depends on the GroupsFixture
7
+ def self.depends_on
8
+ [:GroupsFixture]
9
+ end
10
+
11
+ # This method is optional. Use it to clean up fixture data.
12
+ #
13
+ # NB: This is called each time before load is called.
14
+ def delete
15
+ app.find(<%= config[:constant_name] %>::M::UserAccount, 'david').delete!
16
+ app.find(<%= config[:constant_name] %>::M::UserAccount, 'darrick').delete!
17
+ end
18
+
19
+ def load
20
+ # This fixture method just calls the helper defined below
21
+ create_user 'david', 'David Colebatch', 'dc@xnlogic.com', ['support']
22
+ create_user 'darrick', 'Darrick Wiebe', 'dw@xnlogic.com', ['support']
23
+ end
24
+
25
+ private # HELPERS
26
+
27
+ # This is just a helper method to demonstrate that fixtures are just regular Ruby code.
28
+ def create_user(id, name, email, groups)
29
+ groups = groups.map { |g| app.find(<%= config[:constant_name] %>::M::Group, g) }
30
+ app.create(<%= config[:constant_name] %>::M::UserAccount, id, name: name, email: email) do |user|
31
+ groups.each do |group|
32
+ user.inherit_full_access group
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+
39
+ class GroupsFixture < Fixture
40
+ # This method is optional. Use it to clean up fixture data.
41
+ #
42
+ # NB: This is called each time before load is called.
43
+ def delete
44
+ app.find(<%= config[:constant_name] %>::M::Group, 'support').delete!
45
+ end
46
+
47
+ def load
48
+ # We specify the Group model, an ID and then a list of property values:
49
+ app.create(<%= config[:constant_name] %>::M::Group, 'support', name: 'XN Logic Support')
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,108 @@
1
+ require 'tsort'
2
+
3
+ module <%= config[:constant_name] %>
4
+ module Fixtures
5
+ class Fixture
6
+ class << self
7
+ include TSort
8
+
9
+ def inherited(klass)
10
+ @inherited ||= []
11
+ @inherited = (@inherited + [klass]).sort_by &:name
12
+ end
13
+
14
+ def tsort_each_child(node, &block)
15
+ if node.respond_to? :depends_on
16
+ children = node.depends_on.flat_map do |n|
17
+ @inherited.select do |f|
18
+ f.name.split(/::/).last.to_sym == n
19
+ end
20
+ end
21
+ children.each &block
22
+ end
23
+ end
24
+
25
+ def tsort_each_node(&block)
26
+ @inherited.each &block if @inherited
27
+ end
28
+ end
29
+
30
+ attr_reader :app
31
+
32
+ def initialize(app, commit, rollback)
33
+ @app = app
34
+ @commit = commit
35
+ @rollback = rollback
36
+ end
37
+
38
+ def load
39
+ throw "Fixture #{ self.class.name } does nothing. Define a load method."
40
+ end
41
+
42
+ def delete
43
+ end
44
+
45
+ def commit
46
+ @commit.call
47
+ end
48
+
49
+ def rollback
50
+ @rollback.call
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ module <%= config[:constant_name] %>
57
+ module Fixtures
58
+ class << self
59
+ def load_fixtures(app)
60
+ delete_fixtures(app)
61
+ start_time = Time.now
62
+ app.graph.transaction do |commit, rollback|
63
+ <%= config[:constant_name] %>::Fixtures::Fixture.tsort.each do |fixture|
64
+ puts "Loading fixture: #{ fixture }"
65
+ f = fixture.new(app, commit, rollback)
66
+ f.load
67
+ end
68
+ end
69
+ puts "Loaded fixtures in #{ Time.now - start_time } seconds (#{app.graph.v.count} vertices, #{app.graph.e.count} edges)"
70
+ end
71
+
72
+ def delete_fixtures(app)
73
+ if app.graph.v.count > 300
74
+ raise "Error deleting fixture data. Node count > 300, possible production data."
75
+ end
76
+ reload_fixture_files
77
+ start_time = Time.now
78
+ app.create_indices!(app.graph)
79
+ app.graph.transaction do |commit, rollback|
80
+ <%= config[:constant_name] %>::Fixtures::Fixture.tsort.each do |fixture|
81
+ puts "Deleting fixture data: #{ fixture }"
82
+ fixture.new(app, commit, rollback).delete
83
+ end
84
+ end
85
+ app.generate_metadata!
86
+ puts "Deleted fixtures in #{ Time.now - start_time } seconds (#{app.graph.v.count} vertices, #{app.graph.e.count} edges)"
87
+ end
88
+
89
+ private
90
+
91
+ def fixtures_dir
92
+ <%= config[:constant_name] %>.lib_dir + 'fixtures'
93
+ end
94
+
95
+ def reload_fixture_files
96
+ if Dir[fixtures_dir + '*.rb'].any?
97
+ puts "Loading .rb fixtures from #{fixtures_dir}:"
98
+ Dir[fixtures_dir + '*.rb'].each do |path|
99
+ puts "Loading ruby file: #{path}"
100
+ load path
101
+ end
102
+ else
103
+ puts "Can't reload fixtures without the source code"
104
+ end
105
+ end
106
+ end
107
+ end
108
+ end