repo_manager 0.7.1

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 (116) hide show
  1. data/.gemfiles +115 -0
  2. data/.gitattributes +1 -0
  3. data/.gitignore +7 -0
  4. data/.rspec +3 -0
  5. data/.yardopts +11 -0
  6. data/Gemfile +11 -0
  7. data/Gemfile.lock +99 -0
  8. data/Guardfile +63 -0
  9. data/HISTORY.markdown +12 -0
  10. data/LICENSE +20 -0
  11. data/README.markdown +192 -0
  12. data/Rakefile +94 -0
  13. data/TODO.markdown +15 -0
  14. data/VERSION +1 -0
  15. data/bin/repo +151 -0
  16. data/cucumber.yml +28 -0
  17. data/examples/pc_saved_game_backup/.gitignore +2 -0
  18. data/examples/pc_saved_game_backup/INSTALL.markdown +420 -0
  19. data/examples/pc_saved_game_backup/README.markdown +108 -0
  20. data/examples/pc_saved_game_backup/remote/.gitignore +2 -0
  21. data/examples/pc_saved_game_backup/repo_manager/Gemfile +12 -0
  22. data/examples/pc_saved_game_backup/repo_manager/Gemfile.lock +66 -0
  23. data/examples/pc_saved_game_backup/repo_manager/assets/.gitignore +2 -0
  24. data/examples/pc_saved_game_backup/repo_manager/features/support/aruba.rb +15 -0
  25. data/examples/pc_saved_game_backup/repo_manager/features/support/env.rb +11 -0
  26. data/examples/pc_saved_game_backup/repo_manager/features/support/steps.rb +3 -0
  27. data/examples/pc_saved_game_backup/repo_manager/features/tasks/update.feature +144 -0
  28. data/examples/pc_saved_game_backup/repo_manager/global/default/asset.conf +2 -0
  29. data/examples/pc_saved_game_backup/repo_manager/repo.conf +64 -0
  30. data/examples/pc_saved_game_backup/repo_manager/tasks/.gitignore +0 -0
  31. data/examples/pc_saved_game_backup/repo_manager/tasks/remote.rb +57 -0
  32. data/examples/pc_saved_game_backup/repo_manager/tasks/update.rb +65 -0
  33. data/examples/pc_saved_game_backup/saved_games/hearts/save1 +1 -0
  34. data/examples/pc_saved_game_backup/saved_games/hearts/save2 +1 -0
  35. data/examples/pc_saved_game_backup/saved_games/mines/my_profile.ini +1 -0
  36. data/examples/pc_saved_game_backup/saved_games/mines/saves/save1 +1 -0
  37. data/examples/pc_saved_game_backup/saved_games/mines/saves/save2 +1 -0
  38. data/features/actions/git.feature +296 -0
  39. data/features/actions/help.feature +53 -0
  40. data/features/actions/list.feature +624 -0
  41. data/features/actions/path.feature +195 -0
  42. data/features/actions/status.feature +261 -0
  43. data/features/actions/task.feature +127 -0
  44. data/features/assets/configuration.feature +204 -0
  45. data/features/assets/rendering.feature +42 -0
  46. data/features/assets/user_attributes.feature +98 -0
  47. data/features/bin.feature +42 -0
  48. data/features/logger.feature +218 -0
  49. data/features/settings.feature +240 -0
  50. data/features/support/aruba.rb +15 -0
  51. data/features/support/env.rb +11 -0
  52. data/features/support/steps.rb +3 -0
  53. data/features/tasks/add/asset.feature +178 -0
  54. data/features/tasks/generate/init.feature +56 -0
  55. data/lib/repo_manager.rb +36 -0
  56. data/lib/repo_manager/actions.rb +8 -0
  57. data/lib/repo_manager/actions/action_helper.rb +39 -0
  58. data/lib/repo_manager/actions/app_action.rb +30 -0
  59. data/lib/repo_manager/actions/base_action.rb +296 -0
  60. data/lib/repo_manager/actions/git_action.rb +113 -0
  61. data/lib/repo_manager/actions/help_action.rb +52 -0
  62. data/lib/repo_manager/actions/list_action.rb +123 -0
  63. data/lib/repo_manager/actions/path_action.rb +22 -0
  64. data/lib/repo_manager/actions/status_action.rb +192 -0
  65. data/lib/repo_manager/actions/task_action.rb +71 -0
  66. data/lib/repo_manager/app.rb +116 -0
  67. data/lib/repo_manager/assets.rb +3 -0
  68. data/lib/repo_manager/assets/app_asset.rb +15 -0
  69. data/lib/repo_manager/assets/asset_accessors.rb +67 -0
  70. data/lib/repo_manager/assets/asset_configuration.rb +137 -0
  71. data/lib/repo_manager/assets/asset_manager.rb +72 -0
  72. data/lib/repo_manager/assets/base_asset.rb +199 -0
  73. data/lib/repo_manager/assets/repo_asset.rb +30 -0
  74. data/lib/repo_manager/core.rb +2 -0
  75. data/lib/repo_manager/core/array.rb +21 -0
  76. data/lib/repo_manager/core/hash.rb +83 -0
  77. data/lib/repo_manager/errors.rb +10 -0
  78. data/lib/repo_manager/extensions/hash.rb +86 -0
  79. data/lib/repo_manager/git.rb +2 -0
  80. data/lib/repo_manager/git/lib.rb +69 -0
  81. data/lib/repo_manager/git/status.rb +196 -0
  82. data/lib/repo_manager/logger.rb +39 -0
  83. data/lib/repo_manager/settings.rb +98 -0
  84. data/lib/repo_manager/tasks.rb +3 -0
  85. data/lib/repo_manager/tasks/add/asset.rb +213 -0
  86. data/lib/repo_manager/tasks/generate/init.rb +42 -0
  87. data/lib/repo_manager/tasks/generate/templates/config/repo.conf.tt +61 -0
  88. data/lib/repo_manager/tasks/generate/templates/init/assets/.gitignore +0 -0
  89. data/lib/repo_manager/tasks/generate/templates/init/global/default/asset.conf +2 -0
  90. data/lib/repo_manager/tasks/generate/templates/init/tasks/.gitignore +0 -0
  91. data/lib/repo_manager/tasks/task_manager.rb +166 -0
  92. data/lib/repo_manager/tasks/thor_helper.rb +29 -0
  93. data/lib/repo_manager/test/asset_steps.rb +19 -0
  94. data/lib/repo_manager/test/base_steps.rb +152 -0
  95. data/lib/repo_manager/test/repo_api.rb +41 -0
  96. data/lib/repo_manager/test/repo_steps.rb +83 -0
  97. data/lib/repo_manager/test/test_api.rb +88 -0
  98. data/lib/repo_manager/views.rb +2 -0
  99. data/lib/repo_manager/views/app_view.rb +15 -0
  100. data/lib/repo_manager/views/base_view.rb +137 -0
  101. data/lib/repo_manager/views/templates/css/basic.css +26 -0
  102. data/lib/repo_manager/views/templates/default.erb +40 -0
  103. data/lib/repo_manager/views/templates/default.slim +37 -0
  104. data/lib/repo_manager/views/view_helper.rb +55 -0
  105. data/repo_manager.gemspec +75 -0
  106. data/spec/basic_app/actions/action_helper_spec.rb +54 -0
  107. data/spec/basic_app/assets/base_asset_spec.rb +210 -0
  108. data/spec/basic_app/core_spec.rb +78 -0
  109. data/spec/basic_app/settings_spec.rb +64 -0
  110. data/spec/basic_app/views/view_helper_spec.rb +28 -0
  111. data/spec/basic_gem/aruba_helper_spec.rb +33 -0
  112. data/spec/basic_gem/basic_gem_spec.rb +84 -0
  113. data/spec/basic_gem/gemspec_spec.rb +68 -0
  114. data/spec/repo_manager/git_spec.rb +31 -0
  115. data/spec/spec_helper.rb +25 -0
  116. metadata +472 -0
@@ -0,0 +1,41 @@
1
+ require 'git'
2
+
3
+ module RepoManager
4
+ module RepoApi
5
+
6
+ def repo_exists?(folder)
7
+ File.exists?(File.join(current_dir, folder, '.git'))
8
+ end
9
+
10
+ def repo_init(folder)
11
+ create_dir(folder) unless repo_exists?(folder)
12
+ repo_path = fullpath(folder)
13
+ Git.init(repo_path)
14
+ end
15
+
16
+ def repo_add_all(folder)
17
+ repo_path = fullpath(folder)
18
+ repo = Git.init(repo_path)
19
+ in_path(repo_path) do
20
+ repo.add('.').should be_true
21
+ end
22
+ end
23
+
24
+ def repo_add_file(filename, folder)
25
+ repo_path = fullpath(folder)
26
+ repo = Git.init(repo_path)
27
+ repo.add(filename).should be_true
28
+ end
29
+
30
+ def repo_commit_all(folder)
31
+ repo_path = fullpath(folder)
32
+ repo = Git.init(repo_path)
33
+ repo.commit_all("cucumber commit").should be_true
34
+ end
35
+
36
+ def repo_file_exists?(folder, filename)
37
+ File.exists?(File.join(current_dir, folder, filename))
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,83 @@
1
+ require 'fileutils'
2
+ require 'repo_manager/test/repo_api'
3
+
4
+ World(RepoManager::RepoApi)
5
+
6
+ Given /^a repo in folder "([^"]*)"$/ do |folder|
7
+ repo_init(folder)
8
+ end
9
+
10
+ Given /^(?:a|the) repo in folder "([^"]*)" has a remote named "([^"]*)" in folder "([^"]*)"$/ do |repo_folder, remote_name, remote_folder|
11
+ repo_init(repo_folder)
12
+ repo_path = fullpath(repo_folder)
13
+ remote_path = fullpath(remote_folder)
14
+
15
+ Dir.chdir repo_path do
16
+ `git remote add origin #{remote_path}`
17
+ raise "git remote add failed" unless $?.exitstatus == 0
18
+ `git config branch.master.remote origin`
19
+ raise "git config origin failed" unless $?.exitstatus == 0
20
+ `git config branch.master.merge refs/heads/master`
21
+ raise "git config refs failed" unless $?.exitstatus == 0
22
+ `git clone --bare #{repo_path} #{remote_path}`
23
+ raise "git clone failed" unless $?.exitstatus == 0
24
+ end
25
+
26
+ end
27
+
28
+ Given /^a repo in folder "([^"]*)" with the following:$/ do |folder, table|
29
+ repo_init(folder) unless repo_exists?(folder)
30
+
31
+ table.hashes.each do |hash|
32
+ filename = hash[:filename]
33
+ status = hash[:status]
34
+ content = hash[:content]
35
+
36
+ status.split("").each do |st|
37
+ case st
38
+ when "?"
39
+ write_file(File.join(folder, filename), content)
40
+ when "A"
41
+ write_file(File.join(folder, filename), content)
42
+ repo_add_file(filename, folder)
43
+ when "M"
44
+ raise "create file '#{filename}' before modifying it" unless repo_file_exists?(folder, filename)
45
+ append_to_file(File.join(folder, filename), content)
46
+ when "C"
47
+ unless repo_file_exists?(folder, filename)
48
+ write_file(File.join(folder, filename), content)
49
+ end
50
+ repo_add_file(filename, folder)
51
+ repo_commit_all(folder)
52
+ when "D"
53
+ unless repo_file_exists?(folder, filename)
54
+ write_file(File.join(folder, filename), content)
55
+ repo_add_file(filename, folder)
56
+ repo_commit_all(folder)
57
+ end
58
+ FileUtils.rm(File.join(File.join(current_dir, folder), filename))
59
+ end
60
+ end
61
+
62
+ end
63
+ end
64
+
65
+ Given /^I add all to repo in folder "([^"]*)"$/ do |folder|
66
+ repo_add_all(folder)
67
+ end
68
+
69
+ Given /^I add the file "([^"]*)" to repo in folder "([^"]*)"$/ do |filename, folder|
70
+ repo_add_file(filename, folder)
71
+ end
72
+
73
+ Given /^I commit all to repo in folder "([^"]*)"$/ do |folder|
74
+ repo_commit_all(folder)
75
+ end
76
+
77
+ Given /^I delete the file "([^"]*)" in folder "([^"]*)"$/ do |filename, folder|
78
+ FileUtils.rm(File.join(File.join(current_dir, folder), filename))
79
+ end
80
+
81
+ Given /^I delete the file "([^"]*)"$/ do |filename|
82
+ FileUtils.rm(File.join(current_dir, filename))
83
+ end
@@ -0,0 +1,88 @@
1
+ module RepoManager
2
+ module TestApi
3
+
4
+ # cross platform `which` command
5
+ def which(binary)
6
+ separator = RepoManager::WINDOWS ? ';' : ':'
7
+ paths = ENV['PATH'].split(separator)
8
+ paths.each do |path|
9
+ fullpath = File.join(path, binary)
10
+ return fullpath if File.exists?(fullpath)
11
+ end
12
+ return nil
13
+ end
14
+
15
+ # execute a block in a specific working directory (path)
16
+ def in_path(path, &block)
17
+ Dir.chdir(path, &block)
18
+ end
19
+
20
+ # expand tabs to spaces
21
+ def expand_tabs(data, indent=8)
22
+ data.gsub(/([^\t\n]*)\t/) {
23
+ $1 + " " * (indent - ($1.size % indent))
24
+ }
25
+ end
26
+
27
+ # account for differences in line endings and tabs
28
+ def normalize(str)
29
+ # convert/normalize DOS CRLF endings
30
+ str.gsub!(/\r\n/, "\n") if str.match("\r\n")
31
+ if str.match("\t")
32
+ str = expand_tabs(str)
33
+ end
34
+ str
35
+ end
36
+
37
+ def process_and_check_file_content(file, partial_content, expect_match)
38
+ str = process_regex_tokens(Regexp.escape(partial_content))
39
+ content = IO.read(file)
40
+ if expect_match
41
+ content.should =~ Regexp.compile(str)
42
+ else
43
+ content.should_not =~ Regexp.compile(str)
44
+ end
45
+ end
46
+
47
+ # substitute back in each tokenized regexp after all text has been escaped
48
+ def process_regex_tokens(str)
49
+ str = str.gsub(/<%NUMBER[^%]*%>/, '\d+')
50
+ str = str.gsub(/<%PK[^%]*%>/, '\d+')
51
+ str = str.gsub(/<%STRING[^%]*%>/, '.+')
52
+ str
53
+ end
54
+
55
+ def write_fixed_size_file(file_name, file_size)
56
+ _create_fixed_size_file(file_name, file_size, false)
57
+ end
58
+
59
+ def _create_fixed_size_file(file_name, file_size, check_presence)
60
+ in_current_dir do
61
+ raise "expected #{file_name} to be present" if check_presence && !File.file?(file_name)
62
+ _mkdir(File.dirname(file_name))
63
+ File.open(file_name, "wb"){ |f| f.seek(file_size - 1); f.write("\0") }
64
+ end
65
+ end
66
+
67
+ # @return full path to files in the aruba tmp folder
68
+ def fullpath(filename)
69
+ path = File.expand_path(File.join(current_dir, filename))
70
+ #if path.match(/^\/cygdrive/)
71
+ # # match /cygdrive/c/path/to and return c:\\path\\to
72
+ # path = `cygpath -w #{path}`.chomp
73
+ #elsif path.match(/.\:/)
74
+ # # match c:/path/to and return c:\\path\\to
75
+ # path = path.gsub(/\//, '\\')
76
+ #end
77
+ path
78
+ end
79
+
80
+ # @return the contents of "filename" in the aruba tmp folder
81
+ def get_file_contents(filename)
82
+ in_current_dir do
83
+ IO.read(filename)
84
+ end
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,2 @@
1
+ require 'repo_manager/views/base_view'
2
+ require 'repo_manager/views/app_view'
@@ -0,0 +1,15 @@
1
+ ####################################################
2
+ # The file is was originally cloned from "Basic App"
3
+ # More information on "Basic App" can be found in the
4
+ # "Basic App" repository.
5
+ #
6
+ # See http://github.com/robertwahler
7
+ ####################################################
8
+ module RepoManager
9
+
10
+ # An abstract superclass for basic view/reporting functionality specific to
11
+ # an application implementation. Put application specific code here.
12
+ class AppView < BaseView
13
+ end
14
+
15
+ end
@@ -0,0 +1,137 @@
1
+ ####################################################
2
+ # The file is was originally cloned from "Basic App"
3
+ # More information on "Basic App" can be found in the
4
+ # "Basic App" repository.
5
+ #
6
+ # See http://github.com/robertwahler
7
+ ####################################################
8
+
9
+ require 'pathname'
10
+ require 'slim'
11
+ require 'erb'
12
+ require 'chronic'
13
+
14
+ module RepoManager
15
+
16
+ # An abstract superclass for basic view/reporting functionality
17
+ # using templates
18
+ class BaseView
19
+
20
+ def initialize(items, configuration={})
21
+ @configuration = configuration
22
+ @items = items
23
+ @template = File.expand_path('../templates/default.slim', __FILE__)
24
+ end
25
+
26
+ def configuration
27
+ @configuration
28
+ end
29
+
30
+ def items
31
+ @items
32
+ end
33
+
34
+ def template
35
+ return @template if @template.nil? || Pathname.new(@template).absolute?
36
+
37
+ # try relative to PWD
38
+ fullpath = File.expand_path(File.join(FileUtils.pwd, @template))
39
+ return fullpath if File.exists?(fullpath)
40
+
41
+ # try built in template folder
42
+ fullpath = File.expand_path(File.join('../templates', @template), __FILE__)
43
+ end
44
+
45
+ def template=(value)
46
+ @template = value
47
+ end
48
+
49
+ def title
50
+ @title || configuration[:title] || "Default Title"
51
+ end
52
+
53
+ def title=(value)
54
+ @title = value
55
+ end
56
+
57
+ def date
58
+ return @date if @date
59
+
60
+ if configuration[:date]
61
+ @date = Chronic.parse(configuration[:date])
62
+ return @date if @date
63
+ end
64
+ @date = Date.today
65
+ end
66
+
67
+ def date=(value)
68
+ @date = value
69
+ end
70
+
71
+ # ERB binding
72
+ def get_binding
73
+ binding
74
+ end
75
+
76
+ # render a partial
77
+ #
78
+ # filename: unless absolute, it will be relative to the main template
79
+ #
80
+ # @example slim escapes HTML, use '=='
81
+ #
82
+ # head
83
+ # == render 'mystyle.css'
84
+ #
85
+ # @return [String] of non-escaped textual content
86
+ def partial(filename)
87
+ filename = partial_path(filename)
88
+ raise "unable to find partial file: #{filename}" unless File.exists?(filename)
89
+ contents = File.open(filename, "rb") {|f| f.read}
90
+ # TODO: detect template EOL and match it to the partial's EOL
91
+ # force unix eol
92
+ contents.gsub!(/\r\n/, "\n") if contents.match("\r\n")
93
+ contents
94
+ end
95
+
96
+ # TODO: render based on file ext
97
+ def render
98
+ raise "unable to find template file: #{template}" unless File.exists?(template)
99
+
100
+ extension = File.extname(template)
101
+ extension = extension.downcase if extension
102
+
103
+ case extension
104
+ when '.erb'
105
+ contents = File.open(template, "r") {|f| f.read}
106
+ ERB.new(contents, nil, '-').result(self.get_binding)
107
+ when '.slim'
108
+ Slim::Template.new(template, {:pretty => true}).render(self)
109
+ else
110
+ raise "unsupported template type based on file extension #{extension}"
111
+ end
112
+ end
113
+
114
+ private
115
+
116
+ # full expanded path to the given partial
117
+ #
118
+ def partial_path(filename)
119
+ return filename if filename.nil? || Pathname.new(filename).absolute?
120
+
121
+ # try relative to template
122
+ if template
123
+ base_folder = File.dirname(template)
124
+ filename = File.expand_path(File.join(base_folder, filename))
125
+ return filename if File.exists?(filename)
126
+ end
127
+
128
+ # try relative to PWD
129
+ filename = File.expand_path(File.join(FileUtils.pwd, filename))
130
+ return filename if File.exists?(filename)
131
+
132
+ # try built in template folder
133
+ filename = File.expand_path(File.join('../templates', filename), __FILE__)
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,26 @@
1
+ html, body {
2
+ background-color: #eee;
3
+ }
4
+ .container {
5
+ width: 820px;
6
+ }
7
+ .container > footer p {
8
+ text-align: center;
9
+ }
10
+ .page-header {
11
+ background-color: #f5f5f5;
12
+ padding: 20px 20px 10px;
13
+ margin: -20px -20px 20px;
14
+ }
15
+ /* The white background content wrapper */
16
+ .content {
17
+ background-color: #fff;
18
+ padding: 20px;
19
+ margin: 0 -20px; /* negative indent the amount of the padding to maintain the grid system */
20
+ -webkit-border-radius: 0 0 6px 6px;
21
+ -moz-border-radius: 0 0 6px 6px;
22
+ border-radius: 0 0 6px 6px;
23
+ -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.15);
24
+ -moz-box-shadow: 0 1px 2px rgba(0,0,0,.15);
25
+ box-shadow: 0 1px 2px rgba(0,0,0,.15);
26
+ }
@@ -0,0 +1,40 @@
1
+ <!DOCTYPE html> <html lang="en"> <head> <title>Default View</title>
2
+ <meta charset="utf-8" />
3
+ <meta content="repo" name="keywords" />
4
+ <meta content="RepoManager default template" name="description" />
5
+ <meta content="Robert Wahler" name="author" />
6
+ <link href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css" rel="stylesheet" />
7
+ <style type="text/css"><%= partial 'css/basic.css' %></style>
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <div class="content">
12
+ <div class="page-header">
13
+ <h1>Assets Report</h1>
14
+ </div>
15
+ <% unless items.empty? -%>
16
+ <h2>Assets</h2>
17
+ <table class="condensed-table bordered-table zebra-striped">
18
+ <thead>
19
+ <tr>
20
+ <th>Name</th>
21
+ </tr>
22
+ </thead>
23
+ <tbody>
24
+ <% for item in items do -%>
25
+ <%= "<tr>" %>
26
+ <%= "<td>#{item.name}</td>" %>
27
+ <%= "</tr>" %>
28
+ <% end -%>
29
+ </tbody>
30
+ </table>
31
+ <% else -%>
32
+ <p>No Assets found.</p>
33
+ <% end -%>
34
+ </div>
35
+ <footer>
36
+ <p>Copyright &copy; 2011 GearheadForHire, LLC</p>
37
+ </footer>
38
+ </div>
39
+ </body>
40
+ </html>
@@ -0,0 +1,37 @@
1
+ doctype html
2
+ html lang="en"
3
+ head
4
+ title Default View
5
+
6
+ meta charset="utf-8"
7
+ meta name="keywords" content="repo"
8
+ meta name="description" content="RepoManager default template"
9
+ meta name="author" content="Robert Wahler"
10
+
11
+ link rel="stylesheet" href="http://twitter.github.com/bootstrap/1.4.0/bootstrap.min.css"
12
+
13
+ style type="text/css"
14
+ == partial 'css/basic.css'
15
+
16
+ body
17
+ div class="container"
18
+ div class="content"
19
+ div class="page-header"
20
+ h1 Assets Report
21
+ - unless items.empty?
22
+ h2 Assets
23
+ table class="condensed-table bordered-table zebra-striped"
24
+ thead
25
+ tr
26
+ th = "Name"
27
+ tbody
28
+ - for item in items do
29
+ tr
30
+ td = item.name
31
+ - else
32
+ p
33
+ | No assets found.
34
+
35
+ footer
36
+ p
37
+ | Copyright &copy; 2011 GearheadForHire, LLC