hastie 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.autotest +9 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +10 -0
  5. data/LICENSE +21 -0
  6. data/README.textile +136 -0
  7. data/Rakefile +1 -0
  8. data/bin/hastie +64 -0
  9. data/hastie.gemspec +31 -0
  10. data/lib/hastie/config_file.rb +42 -0
  11. data/lib/hastie/config_generator.rb +37 -0
  12. data/lib/hastie/constants.rb +25 -0
  13. data/lib/hastie/report_generator.rb +118 -0
  14. data/lib/hastie/report_publisher.rb +162 -0
  15. data/lib/hastie/report_updater.rb +40 -0
  16. data/lib/hastie/report_watcher.rb +65 -0
  17. data/lib/hastie/server_generator.rb +47 -0
  18. data/lib/hastie/server_reader.rb +81 -0
  19. data/lib/hastie/templates/hastie_config.tt +6 -0
  20. data/lib/hastie/templates/report.markdown.tt +19 -0
  21. data/lib/hastie/templates/report.textile.tt +19 -0
  22. data/lib/hastie/templates/report_index.html.tt +8 -0
  23. data/lib/hastie/templates/server/.gitignore +1 -0
  24. data/lib/hastie/templates/server/_config.yml +25 -0
  25. data/lib/hastie/templates/server/_includes/.gitignore +0 -0
  26. data/lib/hastie/templates/server/_layouts/.gitignore +0 -0
  27. data/lib/hastie/templates/server/_plugins/.gitignore +0 -0
  28. data/lib/hastie/templates/server/_posts/.gitignore +0 -0
  29. data/lib/hastie/templates/server/_reports.yml +0 -0
  30. data/lib/hastie/templates/server/_server_config.yml +15 -0
  31. data/lib/hastie/templates/server/css/.gitignore +0 -0
  32. data/lib/hastie/templates/server/data/.gitignore +0 -0
  33. data/lib/hastie/templates/server/imgs/.gitignore +0 -0
  34. data/lib/hastie/templates/server/index.html +0 -0
  35. data/lib/hastie/templates/server/js/.gitignore +0 -0
  36. data/lib/hastie/version.rb +3 -0
  37. data/lib/hastie.rb +15 -0
  38. data/spec/config_generator_spec.rb +124 -0
  39. data/spec/fakefs_helper.rb +67 -0
  40. data/spec/fixtures/config.ru +29 -0
  41. data/spec/fixtures/hastie_config +2 -0
  42. data/spec/fixtures/report/2110-12-16-report.textile +19 -0
  43. data/spec/fixtures/report/_config.yml +9 -0
  44. data/spec/fixtures/report/data/report/.gitignore +0 -0
  45. data/spec/fixtures/report/imgs/report/.gitignore +0 -0
  46. data/spec/fixtures/report/js/.gitignore +0 -0
  47. data/spec/fixtures/report/report.yml +23 -0
  48. data/spec/fixtures/server/_config.yml +10 -0
  49. data/spec/fixtures/server/_posts/2011-11-11-jfv_mak_snp_analysis.textile +0 -0
  50. data/spec/fixtures/server/_reports.yml +1 -0
  51. data/spec/fixtures/server/css/style.css +126 -0
  52. data/spec/fixtures/server/data/jfv_mak_snp_analysis/.gitignore +0 -0
  53. data/spec/fixtures/server/imgs/favicon.ico +0 -0
  54. data/spec/fixtures/server/imgs/subset_images/.gitignore +0 -0
  55. data/spec/fixtures/server/js/.gitignore +0 -0
  56. data/spec/report_generator_spec.rb +168 -0
  57. data/spec/report_publisher_spec.rb +148 -0
  58. data/spec/report_updater_spec.rb +54 -0
  59. data/spec/report_watcher_spec.rb +99 -0
  60. data/spec/server_generator_spec.rb +68 -0
  61. data/spec/server_reader_spec.rb +120 -0
  62. data/spec/spec_helper.rb +52 -0
  63. metadata +234 -0
data/.autotest ADDED
@@ -0,0 +1,9 @@
1
+ Autotest.add_hook :initialize do |at|
2
+ at.clear_mappings
3
+ at.add_exception(/\.git/)
4
+ at.add_exception(/coverage/)
5
+ at.add_exception(/spec\/sandbox/)
6
+ at.add_mapping(%r{^spec/.*_spec}) {|filename,_| at.files_matching %r{#{filename}}}
7
+ at.add_mapping(%r{}) {|_,_| at.files_matching %r{spec/.*_spec}}
8
+ end
9
+
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ Gemfile.lock
2
+ demo/*
3
+ coverage/*
4
+ spec/sandbox/*
5
+ spec/reports/*
6
+ .DS_Store
7
+ .config
8
+ .bundle
9
+ doc/*
10
+ pkg/*
11
+
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format=documentation
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem "jekyll", :git => "git://github.com/vlandham/jekyll.git"
6
+
7
+ group :test do
8
+ gem 'fakefs', require: "fakefs/safe"
9
+ end
10
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2011 Jim Vallandingham
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
data/README.textile ADDED
@@ -0,0 +1,136 @@
1
+ h1. Hastie
2
+
3
+ A tool to extend Jekyll for use in report creation.
4
+
5
+ h2. Using Hastie
6
+
7
+ Assuming you have hastie installed, what are the steps to start using it? These steps also assume you have a compatible jekyll installed as well as a jekyll blog framework, such as bioreports. See below for more info on jekyll and bioreports.
8
+
9
+ h3. hastie config
10
+
11
+ First, setup your @.hastie@ config file to point to your bioreports path
12
+
13
+ <pre>
14
+ hastie config /path/to/bioreports/source -a jfv -t textile
15
+ </pre>
16
+
17
+ This creates a @.hastie@ file in your home directory. The @-a@ flag indicates the analyst (your username) to set. The @-t@ flag tells hastie to generate textile documents for your reports.
18
+
19
+ h3. hastie create
20
+
21
+ Now you are ready to generate a new report. Navigate to the directory that you would like the report to be created in, and create it with @hastie create@:
22
+
23
+ <pre>
24
+ cd /path/to/report/base
25
+ hastie create analysis_of_sample_x -r ada -p hym
26
+ </pre>
27
+
28
+ This will create a new directory called @report@ with your new report inside. The flags set meta data about the report. @-r@ for the researcher this report is for and @-p@ for the PI or lead researcher of the researcher specified by @-r@. These flags are optional. This data can be easily added later to your report if you forget.
29
+
30
+ Inside your report directory will be a number of files and sub-directories to get your report started. Many of these files are copied directly from the server you supplied in your config file.
31
+
32
+ h3. hastie watch
33
+
34
+ Now start editing your report. It will be inside your @report@ directory, and be named @date_report_name.textile@. Watch changes to your report as you modify this file using @hastie watch@:
35
+
36
+ <pre>
37
+ cd report
38
+ vim 2011-02-04_analysis_of_sample_x.textile
39
+ hastie watch
40
+ </pre>
41
+
42
+ Hastie watch really just starts jekyll and builds your report locally. But this helps so that you don't have to remember any new commands.
43
+
44
+ h3. hastie publish
45
+
46
+ Now you have some info in your report, and you would like to publish it to the main server. That's where @hastie publish@ comes in:
47
+
48
+ <pre>
49
+ # ctrl-c to kill hastie watch
50
+ hastie publish
51
+ </pre>
52
+
53
+ This will copy your important files to the server in your @.hastie@ file and then run jekyll there. It will also check in this change to your server's git repository.
54
+
55
+ And that's all there is to creating a new report! @create@, @watch@, and @publish@.
56
+
57
+ h3. NOTE
58
+
59
+ Users may get an error in @read_yaml@ about an *invalid byte sequence*. To fix this, modify your @.bashrc@ to include:
60
+
61
+ <pre>
62
+ export LC_ALL=en_US.UTF-8
63
+ export LANG=en_US.UTF-8
64
+ </pre>
65
+
66
+ This is "documented in a jekyll issue":https://github.com/mojombo/jekyll/issues/188
67
+
68
+ h2. What is Hastie?
69
+
70
+ Hastie works with "Jekyll":https://github.com/metalhelix/jekyll to create a powerful and flexible system by which reports can be created by different individuals and uploaded to a central 'server'.
71
+
72
+ h2. Why Hastie?
73
+
74
+ Say you work in an office that generates data, and reports about that data, for clients (so, for example, a core Bioinformatics facility providing results to various research labs).
75
+
76
+ The reports you generate typically come as a mix of Word documents, Excel spreadsheets, and external data files. Everyone in your office creates these reports differently. They are stored in various locations, in various folders on networked drives. They have different levels of information, and generally are a hassle to create and update.
77
+
78
+ Consumers of these reports (i.e. the researchers you generated them for) have to navigate confusing and disparate network paths to find these reports. They have to have Word, Excel, and whatever other programs you have (and the right versions of these programs) installed on the computer they are using, and have to have them all open at the same time to see their report and data.
79
+
80
+ In short, there is a high cost for both encoding and decoding this information. Its a lose lose situation.
81
+
82
+ Hastie is a component of a small suite of tools to facilitate faster encoding and decoding of this data. Attempting to lower the requirements of producing and consuming reports - so producers (analysts) can generate bigger, better, reports faster and more consistent with their co-workers, and consumers (researchers) can get to their data with less hand-holding and fewer hoops to jump through.
83
+
84
+
85
+ h2. What part does Hastie play?
86
+
87
+ Hastie serves as a simple interface between the creators of the reports and the report system itself. It takes care of all the back-end silliness, and lets you create and publish reports quickly and easily.
88
+
89
+ Hastie is a command-line tool that communicates with the report server (really just a jekyll source directory). It creates a framework for building up a report, allows you to develop this report locally, with whatever tools you are most comfortable with, and then easily publish this report so that it can be shared with others.
90
+
91
+ h2. Hastie's associates
92
+
93
+ Hastie is one piece of the puzzle for better, faster, more consistent reports. You also need:
94
+ * "Jekyll":https://github.com/metalhelix/jekyll - a static site generator that has lots of power behind it to allow customization galore. Jekyll is built for blogs - but with Hastie's help, it makes a mighty fine report system as well.
95
+ ** Hastie requires a custom build of Jekyll that includes some missing features to be fully functional.
96
+ ** Hopefully in the future, these features will be integrated back into Jekyll proper.
97
+ * A Jekyll site framework. Jekyll allows for plugins and layouts and other components. Hastie also expects some additional files present in its 'Jekyll Sever' to work.
98
+ ** Check out "bioreports":https://github.com/metalhexlix/bioreports for an example of such a site framework.
99
+
100
+
101
+ h2. Hastie features
102
+
103
+ <pre>
104
+ Usage: hastie [COMMAND] <OPTIONS>
105
+
106
+ Hastie Commands:
107
+ version - Print version number and exit
108
+ help - Print this help and exit
109
+ create - Create new report directory framework with given name
110
+ watch - Monitor current directory for changes.
111
+ Updates local copy of report
112
+ publish - Send report to server. Update published reports
113
+ update - Update local report directory with changes from report server
114
+ config - Create new hastie config file for communicating with server
115
+ create_server - Create new server directory framework with given name
116
+
117
+ create options:
118
+ Use 'hastie create -h' for more information on start options
119
+
120
+ publish options:
121
+ Use 'hastie publish -h' for more information on publish options
122
+
123
+ update options:
124
+ Use 'hastie update -h' for more information on publish options
125
+
126
+ config options:
127
+ Use 'hastie config -h' for more information on publish options
128
+
129
+ create_server options:
130
+ Use 'hastie create_server -h' for more information on publish options
131
+ </pre>
132
+
133
+
134
+ h2. Whats in a name?
135
+
136
+ In Strange Case of Dr. Jekyll and Mr. Hyde, "Dr. Hastie Lanyon":http://en.wikipedia.org/wiki/Strange_Case_of_Dr_Jekyll_and_Mr_Hyde#Dr_Hastie_Lanyon finds Jekyll's ideas *too fanciful*.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/hastie ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env ruby
2
+ # -*- mode: ruby -*-
3
+
4
+ require 'hastie'
5
+
6
+ module Hastie
7
+ module Executable
8
+ HELP = <<-HELP
9
+ Usage: hastie [COMMAND] <OPTIONS>
10
+
11
+ Hastie Commands:
12
+ version - Print version number and exit
13
+ help - Print this help and exit
14
+ create - Create new report directory framework with given name
15
+ watch - Monitor current directory for changes.
16
+ Updates local copy of report
17
+ publish - Send report to server. Update published reports
18
+ update - Update local report directory with changes from report server
19
+ config - Create new hastie config file for communicating with server
20
+ create_server - Create new server directory framework with given name
21
+
22
+ create options:
23
+ Use 'hastie create -h' for more information on start options
24
+
25
+ publish options:
26
+ Use 'hastie publish -h' for more information on publish options
27
+
28
+ update options:
29
+ Use 'hastie update -h' for more information on publish options
30
+
31
+ config options:
32
+ Use 'hastie config -h' for more information on publish options
33
+
34
+ create_server options:
35
+ Use 'hastie create_server -h' for more information on publish options
36
+
37
+ HELP
38
+
39
+ def self.execute(command, args)
40
+ case command
41
+ when "version"
42
+ require 'hastie/version'
43
+ puts Hastie::VERSION
44
+ when "create", "start"
45
+ Hastie::ReportGenerator.start ARGV
46
+ when "watch", "monitor"
47
+ Hastie::ReportWatcher.start ARGV
48
+ when "publish"
49
+ Hastie::ReportPublisher.start ARGV
50
+ when "update"
51
+ Hastie::ReportUpdater.start ARGV
52
+ when "config"
53
+ Hastie::ConfigGenerator.start ARGV
54
+ when "create_server","server_start"
55
+ Hastie::ServerGenerator.start ARGV
56
+ else
57
+ puts Hastie::Executable::HELP
58
+ end
59
+ end
60
+ end
61
+ end
62
+
63
+ command = ARGV.shift
64
+ Hastie::Executable.execute command, ARGV
data/hastie.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/hastie/version', __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.add_dependency "thor", "~> 0.14.6"
6
+ s.add_dependency "grit", "~> 2.4.1"
7
+ s.add_dependency "sinatra", "~> 1.3.2"
8
+ s.add_dependency "thin", "~> 1.3.1"
9
+ s.add_development_dependency "bundler", "~> 1.0"
10
+ s.add_development_dependency "rdoc", "~> 3.9"
11
+ s.add_development_dependency "rspec", "~> 2.3"
12
+ s.add_development_dependency "simplecov", "~> 0.4"
13
+ s.add_development_dependency "ZenTest", "~> 4.5.0"
14
+ # s.add_development_dependency "autotest-fsevent", "~> 0.2.5"
15
+ # s.add_development_dependency "autotest-growl", "~> 0.2.9"
16
+ s.authors = ['Jim Vallandingham']
17
+ s.description = %q{}
18
+ s.email = 'none@none.com'
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{|f| File.basename(f)}
20
+ s.extra_rdoc_files = ['LICENSE', 'README.textile']
21
+ s.files = `git ls-files`.split("\n")
22
+ s.homepage = 'http://github.com/vlandham/hastie'
23
+ s.name = 'hastie'
24
+ s.rdoc_options = ['--charset=UTF-8']
25
+ s.require_paths = ['lib']
26
+ s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6')
27
+ s.summary = s.description
28
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
29
+ s.version = Hastie::VERSION.dup
30
+ end
31
+
@@ -0,0 +1,42 @@
1
+ require 'yaml'
2
+ require 'thor/core_ext/hash_with_indifferent_access'
3
+
4
+ module Hastie
5
+ class ConfigFile
6
+
7
+ # takes yaml filename
8
+ # outputs thor's hash with indifferent access of content
9
+ # if input file cannot be read, empty thor hash is returned
10
+ def self.load filename, root = nil
11
+ if !File.exists? filename
12
+ return
13
+ end
14
+ output = Thor::CoreExt::HashWithIndifferentAccess.new()
15
+ config = YAML.load(File.read(filename))
16
+ if config
17
+ if root
18
+ config = {root => config}
19
+ end
20
+ output = Thor::CoreExt::HashWithIndifferentAccess.new(config)
21
+ end
22
+ output
23
+ end
24
+
25
+ def self.write filename, data
26
+ output_data = data.to_hash.to_yaml
27
+ File.open(filename, 'w') {|file| file.puts output_data}
28
+ end
29
+
30
+ # very lazy. very limited
31
+ # only use for _reports.yml
32
+ def self.append filename, data
33
+ if !File.exists? filename
34
+ puts "ERROR: #{filename} not found"
35
+ return
36
+ end
37
+ File.open(filename, 'a') do |file|
38
+ file.puts "- #{data}"
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ require 'fileutils'
2
+ require 'thor/group'
3
+ require 'hastie/constants'
4
+ module Hastie
5
+ class ConfigGenerator < Thor::Group
6
+ include Thor::Actions
7
+
8
+ def self.banner
9
+ "hastie config [SERVER_ROOT] <OPTIONS>"
10
+ end
11
+
12
+ argument :server_root, :type => :string, :desc => "Root path of server location"
13
+ class_option :path, :aliases => "-p", :desc => "Root directory of where the config file will be written to", :default => File.expand_path("~")
14
+ class_option :name, :aliases => "-n", :desc => "Name of the config file", :default => ".hastie"
15
+ class_option :analyst, :aliases => "-a", :desc => "Analyst for reports generated with this config file"
16
+ class_option :type, :aliases => "-t", :desc => "Default format of reports to generate", :default => "textile"
17
+
18
+ def self.source_root
19
+ File.dirname(__FILE__)
20
+ end
21
+
22
+
23
+ def check_server_root
24
+ if !File.directory? server_root
25
+ say_status "error", "#{server_root} is not a directory", :red
26
+ say_status "error", "Please use full path to server directory", :red
27
+ exit(1)
28
+ end
29
+ end
30
+
31
+ def create_config_file
32
+ output_file = File.join(options[:path], options[:name])
33
+ template "templates/hastie_config.tt", output_file
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,25 @@
1
+ module Hastie
2
+ CONFIG_FILE = File.expand_path(File.join("~", ".hastie"))
3
+ SERVER_REPORTS_FILE = "_reports.yml"
4
+ SERVER_CONFIG_FILE = "_config.yml"
5
+ SERVER_PUBLISH_CONFIG_FILE = "_server_config.yml"
6
+
7
+ DATA_ROOT = "data"
8
+ REPORT_CONFIG_FILE = "report.yml"
9
+
10
+ def self.config_file
11
+ CONFIG_FILE
12
+ end
13
+
14
+ def self.report_config_name
15
+ REPORT_CONFIG_FILE
16
+ end
17
+
18
+ def self.watch_config_file
19
+ SERVER_CONFIG_FILE
20
+ end
21
+
22
+ def self.publish_config_file
23
+ SERVER_PUBLISH_CONFIG_FILE
24
+ end
25
+ end
@@ -0,0 +1,118 @@
1
+ require 'fileutils'
2
+ require 'hastie/config_file'
3
+ require 'hastie/constants'
4
+ require 'hastie/server_reader'
5
+
6
+ module Hastie
7
+ class ReportGenerator < ServerReader
8
+ def self.banner
9
+ "hastie create [NAME] <OPTIONS>"
10
+ end
11
+
12
+ attr_accessor :report_id, :title, :analyst, :researcher, :pi
13
+
14
+ desc "Creates framework for new report"
15
+ argument :name, :type => :string, :desc => "The name of the new report. no spaces"
16
+ class_option :type, :aliases => "-t", :desc => "Type of report to generate"
17
+ class_option :analyst, :aliases => "-a", :desc => "Analyst generating the report"
18
+ class_option :researcher, :aliases => "-r", :desc => "Researcher the report is for"
19
+ class_option :pi, :aliases => "-p", :desc => "PI the researcher is under"
20
+ class_option :date, :aliases => "-d", :desc => "Date to use in report filename. Ex: 2011-11-29", :default => "#{Time.now.strftime('%Y-%m-%d')}"
21
+ class_option :output, :aliases => "-o", :desc => "Output Directory for report", :default => File.join(".", "report")
22
+
23
+ def setup_variables
24
+ options[:type] ||= "textile"
25
+ options[:date] ||= "#{Time.now.strftime('%Y-%m-%d')}"
26
+ options[:name] = File.basename(name)
27
+ self.title = options[:name].gsub("_", " ").capitalize
28
+ options[:title] = self.title
29
+ # report_id will be used internally in case the name turns
30
+ # out to be too loose to use
31
+ self.report_id = File.basename(name)
32
+ options[:report_id] = self.report_id
33
+ self.destination_root = options[:output]
34
+ say_status "note", "root: #{self.destination_root}"
35
+
36
+ options[:analyst] ||= "unknown"
37
+ self.analyst = options[:analyst] || "unknown"
38
+ options[:researcher] ||= "unknown"
39
+ options[:pi] ||= "unknown"
40
+ options[:data_dir] ||= data_dir
41
+ end
42
+
43
+ def check_name_availible
44
+ if options[:published_reports] and options[:published_reports].include? report_id
45
+ say_status "error", "Sorry, the #{report_id} is already a published report", :red
46
+ say_status "error", "Please run again with a different name", :red
47
+ exit(1)
48
+ end
49
+ end
50
+
51
+ def check_destination
52
+ if File.exists? self.destination_root
53
+ say_status "error", "#{self.destination_root} already exists.", :red
54
+ say_status "error", "please choose different output directory", :red
55
+ exit(1)
56
+ end
57
+ end
58
+
59
+ def create_report_file
60
+ say_status "create", "report: #{options[:report_id]}"
61
+ extension = determine_extension(options[:type])
62
+ options[:extension] = extension
63
+ template_file = "templates/report.#{extension}.tt"
64
+ report_filename = "#{options[:date]}-#{report_id}.#{extension}"
65
+ say_status "note", "report file: #{report_filename}"
66
+ template template_file, report_filename
67
+ options[:report_file] = report_filename
68
+ options[:report_file_generated] = File.basename(report_filename, File.extname(report_filename)) + ".html"
69
+ end
70
+
71
+ def create_index_file
72
+ template_file = "templates/report_index.html.tt"
73
+ template template_file, "index.html"
74
+ end
75
+
76
+ def create_data_dir
77
+ create_file File.join(data_dir, ".gitignore"), :verbose => true
78
+ end
79
+
80
+ def fetch_static_files
81
+ options[:server]["static"] ||= []
82
+ options[:server]["static"].each do |static_file|
83
+ static_path = File.join(options[:server_root], static_file)
84
+ if File.exists? static_path
85
+ say_status "copy", "#{static_path} to #{File.basename(destination_root)}"
86
+ FileUtils.cp_r static_path, self.destination_root
87
+ end
88
+ end
89
+ end
90
+
91
+ def write_config_file
92
+ output_config_file = File.join(self.destination_root, Hastie.report_config_name)
93
+ say_status "write", "#{File.basename(output_config_file)}"
94
+ ConfigFile.write(output_config_file, options)
95
+ end
96
+
97
+ no_tasks do
98
+ def determine_extension report_type
99
+ extension = case report_type.to_sym
100
+ when :markdown,:md
101
+ "markdown"
102
+ when :textile
103
+ "textile"
104
+ when :html,:htm
105
+ "html"
106
+ else
107
+ say "WARNING: #{report_type} not a valid type. Defaulting to textile"
108
+ "textile"
109
+ end
110
+ extension
111
+ end
112
+
113
+ def data_dir
114
+ File.join(DATA_ROOT, options[:report_id])
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,162 @@
1
+ require 'fileutils'
2
+ require 'hastie/config_file'
3
+ require 'hastie/constants'
4
+ require 'hastie/server_reader'
5
+
6
+ module Hastie
7
+ class ReportPublisher < ServerReader
8
+ def self.banner
9
+ "hastie publish <REPORT_DIR> <OPTIONS>"
10
+ end
11
+
12
+ attr_accessor :report_dir
13
+ desc "Publishes report to server"
14
+ argument :name, :type => :string, :default => ".", :desc => "The name report directory"
15
+
16
+ def read_report_file
17
+ self.report_dir = File.expand_path(name)
18
+ report_config_file = File.join(report_dir, Hastie.report_config_name)
19
+ if !File.exists? report_config_file
20
+ say "Cannot locate #{Hastie.report_config_name}."
21
+ say "Current directory is not a report."
22
+ exit(1)
23
+ end
24
+ # we get the report filename from this config file
25
+ local_config = ConfigFile.load(report_config_file, :local)
26
+ self.options = local_config.merge(self.options)
27
+ end
28
+
29
+ def check_options
30
+ all_valid = true
31
+ required_server_options = ["reports_dir"]
32
+ required_server_options.each do |option|
33
+ if !options[:server] or !options[:server][option]
34
+ say_status "error", "Missing #{option} option from server config", :red
35
+ all_valid = false
36
+ end
37
+ end
38
+
39
+ required_local_options = ["report_file", "report_id"]
40
+ required_local_options.each do |option|
41
+ if !options[:local] or !options[:local][option]
42
+ say_status "error", "Missing #{option} option from local config", :red
43
+ all_valid = false
44
+ end
45
+ end
46
+
47
+ if !all_valid
48
+ exit(1)
49
+ end
50
+ end
51
+
52
+ def set_destination_directory
53
+ self.destination_root = File.join(options[:server_root])
54
+ say_status "note", "root: #{self.destination_root}"
55
+ end
56
+
57
+ def copy_report_file
58
+ report_filename = options[:local]["report_file"]
59
+ local_report = File.join(report_dir, report_filename)
60
+ destination_report = File.join(options[:server_root], options[:server]["reports_dir"], report_filename)
61
+
62
+ if File.exists? destination_report
63
+ say_status "removing", destination_report, :yellow
64
+ command = "rm -f #{destination_report}"
65
+ pid = Process.fork do
66
+ exec(command)
67
+ end
68
+ Process.waitpid(pid)
69
+ end
70
+
71
+ if File.exists? local_report
72
+ say_status "publishing", report_filename
73
+ # command = "cp #{local_report} #{destination_report}"
74
+ # pid = Process.fork do
75
+ # exec(command)
76
+ # end
77
+ # Process.waitpid(pid)
78
+ FileUtils.cp local_report, destination_report
79
+ else
80
+ say_status "error", "Report file not found: #{report_filename}", :red
81
+ exit(1)
82
+ end
83
+ end
84
+
85
+ def copy_data_directory
86
+ data_dir = File.join(report_dir, DATA_ROOT, options[:local]["report_id"])
87
+ destination_dir = File.join(options[:server_root], DATA_ROOT)
88
+
89
+ existing_destination_dir = File.join(destination_dir, options[:local]["report_id"])
90
+
91
+ if File.exists? existing_destination_dir
92
+ say_status "removing", existing_destination_dir, :yellow
93
+ command = "rm -rf #{existing_destination_dir}"
94
+ pid = Process.fork do
95
+ exec(command)
96
+ end
97
+ Process.waitpid(pid)
98
+ end
99
+
100
+ if File.exists? data_dir
101
+ say_status "publishing", data_dir
102
+ # command = "cp -r #{data_dir} #{destination_dir}"
103
+ # pid = Process.fork do
104
+ # exec(command)
105
+ # end
106
+ # Process.waitpid(pid)
107
+ FileUtils.cp_r data_dir, destination_dir
108
+ else
109
+ say_status "warning", "report data directory not found #{data_dir}", :yellow
110
+ end
111
+ end
112
+
113
+ def add_to_reports_file
114
+ in_root do
115
+ say_status "note", "modifying #{SERVER_REPORTS_FILE}"
116
+ say_status "note", " to include #{options[:local]["report_id"]}"
117
+ server_report_file = SERVER_REPORTS_FILE
118
+ if !File.exists? server_report_file
119
+ say_status "error", "Cannot find #{SERVER_REPORTS_FILE} file in server directory:", :red
120
+ end
121
+ ConfigFile.append(server_report_file, options[:local]["report_id"])
122
+ end
123
+ end
124
+
125
+ def update_git_repo
126
+ in_root do
127
+ say_status "note", "updating git repository"
128
+ Grit::Git.git_timeout = 25
129
+ repo = Grit::Repo.new(".")
130
+ # ensure we are on the server branch
131
+ repo.git.native :checkout, {}, 'server'
132
+ repo = Grit::Repo.new(".")
133
+ if repo.head.name != "server"
134
+ say_status "error", "Remote git not on server branch", :red
135
+ say_status "error", "Please git checkout server", :red
136
+ say_status "error", "Current branch: #{repo.head.name}", :red
137
+ exit(1)
138
+ end
139
+ all_files = Dir.glob("./**")
140
+ repo.add(all_files)
141
+ repo.commit_all("update with report: #{options[:local]["report_id"]}")
142
+ end
143
+ end
144
+
145
+ def publish_with_jekyll
146
+ in_root do
147
+ say_status "publishing", "updating server reports", :yellow
148
+ config_file = File.expand_path(File.join(FileUtils.getwd, Hastie.watch_config_file))
149
+ server_config_file = File.expand_path(File.join(FileUtils.getwd, Hastie.publish_config_file))
150
+ if File.exists?(server_config_file)
151
+ config_file = server_config_file
152
+ end
153
+ say_status "config", config_file, :yellow
154
+ command = "jekyll --config #{config_file}"
155
+ pid = Process.fork do
156
+ exec(command)
157
+ end
158
+ Process.waitpid(pid)
159
+ end
160
+ end
161
+ end
162
+ end