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.
- data/features/sync_nested_file.feature +43 -0
- data/lib/trout/cli.rb +16 -11
- data/lib/trout/managed_file.rb +31 -36
- data/lib/trout/version_list.rb +17 -13
- metadata +14 -12
@@ -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
|
+
|
data/lib/trout/cli.rb
CHANGED
@@ -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, :
|
11
|
+
attr_accessor :command, :option_parser, :arguments, :managed_files, :file_attributes
|
11
12
|
|
12
13
|
def initialize(arguments)
|
13
|
-
self.arguments
|
14
|
-
self.
|
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
|
-
|
21
|
-
git_url
|
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.
|
27
|
+
file.checkout
|
28
|
+
managed_files << file
|
24
29
|
when 'update'
|
25
|
-
|
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'
|
data/lib/trout/managed_file.rb
CHANGED
@@ -1,45 +1,53 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
require 'trout/version_list'
|
3
2
|
|
4
3
|
module Trout
|
5
4
|
class ManagedFile
|
6
|
-
|
5
|
+
attr_accessor :filename, :git_url, :version, :latest_version, :source_root
|
7
6
|
|
8
|
-
def initialize(
|
9
|
-
|
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
|
13
|
-
|
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
|
-
|
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
|
43
|
+
def clone_repository
|
37
44
|
run_or_fail("git clone #{git_url} #{working('git')}")
|
38
|
-
|
45
|
+
self.latest_version = checked_out_version
|
39
46
|
end
|
40
47
|
|
41
48
|
def copy_to_destination
|
42
|
-
FileUtils.cp(working('git',
|
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',
|
58
|
+
FileUtils.cp(working('git', source_path), upstream)
|
51
59
|
|
52
60
|
checkout_last_version
|
53
|
-
FileUtils.cp(working('git',
|
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 -
|
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 #{
|
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
|
-
|
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
|
data/lib/trout/version_list.rb
CHANGED
@@ -1,43 +1,47 @@
|
|
1
1
|
require 'yaml'
|
2
|
+
require 'trout/managed_file'
|
2
3
|
|
3
4
|
module Trout
|
4
5
|
class VersionList
|
5
|
-
|
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
|
14
|
+
def [](filename)
|
12
15
|
read
|
13
|
-
|
16
|
+
attributes = files[filename] || { :filename => filename }
|
17
|
+
ManagedFile.new(attributes)
|
14
18
|
end
|
15
19
|
|
16
|
-
def
|
20
|
+
def []=(filename, managed_file)
|
17
21
|
read
|
18
|
-
|
22
|
+
files[filename] = managed_file.to_hash
|
23
|
+
write
|
19
24
|
end
|
20
25
|
|
21
|
-
def
|
22
|
-
|
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
|
-
|
34
|
+
self.data = YAML.load(IO.read(path))
|
33
35
|
else
|
34
|
-
|
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(
|
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:
|
4
|
+
hash: 13
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: "0.
|
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-
|
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
|
-
|
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
|
-
|
33
|
-
prerelease: false
|
33
|
+
version_requirements: *id001
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
|
-
|
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
|
-
|
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
|