trout 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,43 @@
1
+ Feature: sync a file nested within a directory the source repo
2
+
3
+ Scenario: sync a nested file
4
+ Given a directory named "upstream_repo"
5
+ And a directory named "child_repo"
6
+ And a file named "upstream_repo/sub/dir/file" with:
7
+ """
8
+ contents
9
+ """
10
+ When I cd to "upstream_repo"
11
+ And I run "git init"
12
+ And I run "git add sub"
13
+ And I run "git commit -m 'Added file'"
14
+ And I cd to "../child_repo"
15
+ And I run "trout checkout --source-root sub/dir file ../upstream_repo"
16
+ Then the output should contain:
17
+ """
18
+ Checked out file from ../upstream_repo.
19
+ """
20
+ And I run "cat file"
21
+ Then the output should contain:
22
+ """
23
+ contents
24
+ """
25
+ When I cd to "../upstream_repo"
26
+ And I write to "sub/dir/file" with:
27
+ """
28
+ new contents
29
+ """
30
+ When I run "git add sub"
31
+ And I run "git commit -m 'updated file'"
32
+ And I cd to "../child_repo"
33
+ When I run "trout update file"
34
+ Then the output should contain:
35
+ """
36
+ Merged changes to file.
37
+ """
38
+ When I run "cat file"
39
+ Then the output should contain:
40
+ """
41
+ new contents
42
+ """
43
+
@@ -1,5 +1,6 @@
1
1
  require 'optparse'
2
2
  require 'trout/managed_file'
3
+ require 'trout/version_list'
3
4
 
4
5
  module Trout
5
6
  class CLI
@@ -7,24 +8,29 @@ module Trout
7
8
  new(arguments).run
8
9
  end
9
10
 
10
- attr_accessor :command, :option_parser, :arguments, :file
11
+ attr_accessor :command, :option_parser, :arguments, :managed_files, :file_attributes
11
12
 
12
13
  def initialize(arguments)
13
- self.arguments = arguments
14
- self.option_parser = parse_options
14
+ self.arguments = arguments
15
+ self.file_attributes = {}
16
+ self.option_parser = parse_options
17
+ self.managed_files = VersionList.new('.trout')
15
18
  end
16
19
 
17
20
  def run
18
21
  case command
19
22
  when 'checkout'
20
- build_file
21
- git_url = next_argument
23
+ file_attributes[:filename] = next_argument
24
+ file_attributes[:git_url] = next_argument
25
+ file = ManagedFile.new(file_attributes)
22
26
  end_arguments
23
- file.copy_from(git_url)
27
+ file.checkout
28
+ managed_files << file
24
29
  when 'update'
25
- build_file
30
+ file = managed_files[next_argument]
26
31
  end_arguments
27
32
  file.update
33
+ managed_files << file
28
34
  when 'help', nil
29
35
  puts option_parser
30
36
  if arguments_left?
@@ -48,6 +54,9 @@ module Trout
48
54
  parser.separator "Options:"
49
55
  parser.separator ""
50
56
 
57
+ parser.on("-s", "--source-root PATH", "Path to the file in the source repository") do |path|
58
+ file_attributes[:source_root] = path
59
+ end
51
60
  parser.on("-h", "--help", "View this help document")
52
61
 
53
62
  parser.separator ""
@@ -87,10 +96,6 @@ module Trout
87
96
  invalid_arguments if arguments_left?
88
97
  end
89
98
 
90
- def build_file
91
- self.file = ManagedFile.new(next_argument)
92
- end
93
-
94
99
  def usage_for(command)
95
100
  case command
96
101
  when 'checkout'
@@ -1,45 +1,53 @@
1
1
  require 'fileutils'
2
- require 'trout/version_list'
3
2
 
4
3
  module Trout
5
4
  class ManagedFile
6
- attr_reader :filename, :checked_out_url
5
+ attr_accessor :filename, :git_url, :version, :latest_version, :source_root
7
6
 
8
- def initialize(filename)
9
- @filename = filename
7
+ def initialize(attributes)
8
+ self.filename = attributes[:filename]
9
+ self.git_url = attributes[:git_url]
10
+ self.version = attributes[:version]
11
+ self.source_root = attributes[:source_root] || '/'
10
12
  end
11
13
 
12
- def copy_from(git_url)
13
- checkout(git_url)
14
+ def checkout
15
+ clone_repository
14
16
  copy_to_destination
15
- write_url_and_version
16
17
  puts "Checked out #{filename} from #{git_url}."
17
18
  ensure
18
19
  cleanup
19
20
  end
20
21
 
21
22
  def update
22
- checkout(previous_git_url)
23
+ clone_repository
23
24
  if up_to_date?
24
25
  puts "#{filename} already up to date."
25
26
  else
26
27
  merge_to_destination
27
- write_url_and_version
28
28
  puts "Merged changes to #{filename}."
29
29
  end
30
30
  ensure
31
31
  cleanup
32
32
  end
33
33
 
34
+ def to_hash
35
+ { :filename => filename,
36
+ :git_url => git_url,
37
+ :version => version,
38
+ :source_root => source_root }
39
+ end
40
+
34
41
  private
35
42
 
36
- def checkout(git_url)
43
+ def clone_repository
37
44
  run_or_fail("git clone #{git_url} #{working('git')}")
38
- @checked_out_url = git_url
45
+ self.latest_version = checked_out_version
39
46
  end
40
47
 
41
48
  def copy_to_destination
42
- FileUtils.cp(working('git', filename), filename)
49
+ FileUtils.cp(working('git', source_path), filename)
50
+ self.version = checked_out_version
43
51
  end
44
52
 
45
53
  def merge_to_destination
@@ -47,17 +55,19 @@ module Trout
47
55
  at_last_update = working('at_last_update')
48
56
  merge = working('merge')
49
57
 
50
- FileUtils.cp(working('git', filename), upstream)
58
+ FileUtils.cp(working('git', source_path), upstream)
51
59
 
52
60
  checkout_last_version
53
- FileUtils.cp(working('git', filename), at_last_update)
61
+ FileUtils.cp(working('git', source_path), at_last_update)
54
62
 
55
63
  enforce_newline(upstream)
56
64
  enforce_newline(at_last_update)
57
65
  enforce_newline(filename)
58
66
 
59
- run("diff3 -mX #{filename} #{at_last_update} #{upstream} > #{merge}")
67
+ run("diff3 -mE #{filename} #{at_last_update} #{upstream} > #{merge}")
60
68
  FileUtils.mv(merge, filename)
69
+
70
+ self.version = latest_version
61
71
  ensure
62
72
  FileUtils.rm_rf(upstream)
63
73
  FileUtils.rm_rf(at_last_update)
@@ -65,45 +75,26 @@ module Trout
65
75
 
66
76
  def cleanup
67
77
  FileUtils.rm_rf(working('git'))
68
- @checked_out_url = nil
69
78
  end
70
79
 
71
80
  def prepare_working_directory
72
81
  FileUtils.mkdir(working_root)
73
82
  end
74
83
 
75
- def write_url_and_version
76
- version_list.update(filename,
77
- 'git_url' => checked_out_url,
78
- 'version' => checked_out_version)
79
- end
80
-
81
84
  def checked_out_version
82
85
  git_command("rev-parse master")
83
86
  end
84
87
 
85
88
  def checkout_last_version
86
- git_command("checkout #{previous_git_version}")
89
+ git_command("checkout #{version}")
87
90
  end
88
91
 
89
92
  def git_command(command)
90
93
  run_or_fail("git --git-dir=#{working('git/.git')} --work-tree=#{working('git')} #{command}").strip
91
94
  end
92
95
 
93
- def previous_git_url
94
- version_list.git_url_for(filename)
95
- end
96
-
97
- def previous_git_version
98
- version_list.version_for(filename)
99
- end
100
-
101
96
  def up_to_date?
102
- previous_git_version == checked_out_version
103
- end
104
-
105
- def version_list
106
- @version_list ||= VersionList.new('.trout')
97
+ version == latest_version
107
98
  end
108
99
 
109
100
  def working(*paths)
@@ -127,5 +118,9 @@ module Trout
127
118
  end
128
119
  output
129
120
  end
121
+
122
+ def source_path
123
+ File.join(source_root, filename)
124
+ end
130
125
  end
131
126
  end
@@ -1,43 +1,47 @@
1
1
  require 'yaml'
2
+ require 'trout/managed_file'
2
3
 
3
4
  module Trout
4
5
  class VersionList
5
- attr_reader :path, :entries
6
+ FILE_VERSION = '1.0'
7
+
8
+ attr_accessor :path, :data, :files
6
9
 
7
10
  def initialize(path)
8
11
  @path = path
9
12
  end
10
13
 
11
- def git_url_for(filename)
14
+ def [](filename)
12
15
  read
13
- entries[filename]['git_url']
16
+ attributes = files[filename] || { :filename => filename }
17
+ ManagedFile.new(attributes)
14
18
  end
15
19
 
16
- def version_for(filename)
20
+ def []=(filename, managed_file)
17
21
  read
18
- entries[filename]['version']
22
+ files[filename] = managed_file.to_hash
23
+ write
19
24
  end
20
25
 
21
- def update(filename, info)
22
- read
23
- entries[filename] ||= {}
24
- entries[filename].update(info)
25
- write
26
+ def <<(managed_file)
27
+ self[managed_file.filename] = managed_file
26
28
  end
27
29
 
28
30
  private
29
31
 
30
32
  def read
31
33
  if File.exist?(path)
32
- @entries = YAML.load(IO.read(path))
34
+ self.data = YAML.load(IO.read(path))
33
35
  else
34
- @entries = {}
36
+ self.data = { :files => {},
37
+ :version => FILE_VERSION }
35
38
  end
39
+ self.files = data[:files]
36
40
  end
37
41
 
38
42
  def write
39
43
  File.open(path, 'w') do |file|
40
- file.write(YAML.dump(entries))
44
+ file.write(YAML.dump(data))
41
45
  end
42
46
  end
43
47
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: trout
3
3
  version: !ruby/object:Gem::Version
4
- hash: 15
4
+ hash: 13
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
- - 2
9
- version: "0.2"
8
+ - 3
9
+ version: "0.3"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Joe Ferris
@@ -14,11 +14,13 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-09-21 00:00:00 -04:00
17
+ date: 2010-09-28 00:00:00 -04:00
18
18
  default_executable: trout
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
- version_requirements: &id001 !ruby/object:Gem::Requirement
21
+ name: cucumber
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
22
24
  none: false
23
25
  requirements:
24
26
  - - ">="
@@ -27,12 +29,12 @@ dependencies:
27
29
  segments:
28
30
  - 0
29
31
  version: "0"
30
- requirement: *id001
31
32
  type: :development
32
- name: cucumber
33
- prerelease: false
33
+ version_requirements: *id001
34
34
  - !ruby/object:Gem::Dependency
35
- version_requirements: &id002 !ruby/object:Gem::Requirement
35
+ name: aruba
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
36
38
  none: false
37
39
  requirements:
38
40
  - - ">="
@@ -41,10 +43,8 @@ dependencies:
41
43
  segments:
42
44
  - 0
43
45
  version: "0"
44
- requirement: *id002
45
46
  type: :development
46
- name: aruba
47
- prerelease: false
47
+ version_requirements: *id002
48
48
  description: |-
49
49
  Trout allows you to maintain a base version of special
50
50
  files (like Gemfile) in one repository, and then syncronize just that
@@ -72,6 +72,7 @@ files:
72
72
  - features/help.feature
73
73
  - features/support/env.rb
74
74
  - features/sync_gemfile.feature
75
+ - features/sync_nested_file.feature
75
76
  - bin/trout
76
77
  has_rdoc: true
77
78
  homepage: http://github.com/jferris/trout
@@ -111,3 +112,4 @@ test_files:
111
112
  - features/help.feature
112
113
  - features/support/env.rb
113
114
  - features/sync_gemfile.feature
115
+ - features/sync_nested_file.feature