trout 0.2 → 0.3

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.
@@ -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