cir 0.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.
- checksums.yaml +7 -0
- data/LICENSE.txt +202 -0
- data/Rakefile +25 -0
- data/bin/cir +19 -0
- data/lib/cir.rb +32 -0
- data/lib/cir/cli/command.rb +41 -0
- data/lib/cir/cli/command_with_repository.rb +33 -0
- data/lib/cir/cli/deregister_command.rb +35 -0
- data/lib/cir/cli/init_command.rb +31 -0
- data/lib/cir/cli/main.rb +95 -0
- data/lib/cir/cli/register_command.rb +35 -0
- data/lib/cir/cli/restore_command.rb +34 -0
- data/lib/cir/cli/status_command.rb +43 -0
- data/lib/cir/cli/update_command.rb +35 -0
- data/lib/cir/diff_manager.rb +52 -0
- data/lib/cir/exception/exceptions.rb +28 -0
- data/lib/cir/git_repository.rb +96 -0
- data/lib/cir/repository.rb +209 -0
- data/lib/cir/stored_file.rb +41 -0
- data/lib/cir/version.rb +17 -0
- data/test/cir_test_case.rb +81 -0
- data/test/test_diff_manager.rb +32 -0
- data/test/test_git_repository.rb +88 -0
- data/test/test_repository.rb +163 -0
- data/test/test_stored_file.rb +23 -0
- metadata +138 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
|
14
|
+
module Cir
|
15
|
+
##
|
16
|
+
# Represents metadata about stored file.
|
17
|
+
class StoredFile
|
18
|
+
|
19
|
+
##
|
20
|
+
# Full file path of the original file location
|
21
|
+
attr :file_path
|
22
|
+
|
23
|
+
##
|
24
|
+
# Location in the repository with stored and versioned copy of the file
|
25
|
+
attr :repository_location
|
26
|
+
|
27
|
+
##
|
28
|
+
# Constructor that will optionally populate attributes
|
29
|
+
def initialize(attrs = {})
|
30
|
+
attrs.each do |attr, value|
|
31
|
+
instance_variable_set "@#{attr}", value
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
##
|
36
|
+
# Generate diff using DiffManager
|
37
|
+
def diff
|
38
|
+
Cir::DiffManager.create(repository_location, file_path)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/cir/version.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
module Cir
|
14
|
+
##
|
15
|
+
# Version of Cir
|
16
|
+
VERSION = "0.1"
|
17
|
+
end # module Cir
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
require 'cir'
|
14
|
+
require 'tmpdir'
|
15
|
+
require 'test/unit'
|
16
|
+
require 'fileutils'
|
17
|
+
|
18
|
+
##
|
19
|
+
# Parent test case that will contain shared functionality that we need
|
20
|
+
# across various test cases.
|
21
|
+
class CirTestCase < Test::Unit::TestCase
|
22
|
+
|
23
|
+
##
|
24
|
+
# Prepare each test, currently:
|
25
|
+
# * Forward stderr and stdout to /dev/null
|
26
|
+
# * Prepare working directory (in tmp space)
|
27
|
+
def setup
|
28
|
+
# Create working directory
|
29
|
+
@workDir = Dir.mktmpdir(["cir_test_", "_#{self.class.name}"])
|
30
|
+
@repoDir = "#{@workDir}/repo"
|
31
|
+
|
32
|
+
# Forward stderr/stdout to /dev/null to not mess with test output
|
33
|
+
@original_stderr = $stderr
|
34
|
+
@original_stdout = $stdout
|
35
|
+
$stderr = File.open(File::NULL, "w")
|
36
|
+
$stdout = File.open(File::NULL, "w")
|
37
|
+
end
|
38
|
+
|
39
|
+
##
|
40
|
+
# Undo all the changes we did in #setup
|
41
|
+
def teardown
|
42
|
+
# Remove forwarding of stderr/stdout to /dev/null
|
43
|
+
$stderr = @original_stderr
|
44
|
+
$stdout = @original_stdout
|
45
|
+
|
46
|
+
# Cleaning up working directory
|
47
|
+
FileUtils.rm_rf(@workDir, secure: true)
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Create new file with given file name inside the work directory
|
52
|
+
# and return absolute path to the created file.
|
53
|
+
def create_file(fileName, content)
|
54
|
+
full_path = "#{@workDir}/#{fileName}"
|
55
|
+
File.open(full_path, 'w') { |f| f.write(content) }
|
56
|
+
File.expand_path(full_path)
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Initialize Cir::Repository inside @repoDir and persist that inside
|
61
|
+
# @repo variable (e.g. we have max 1 repo per test instance).
|
62
|
+
def init_repo
|
63
|
+
Cir::Repository.create(@repoDir)
|
64
|
+
@repo = Cir::Repository.new(@repoDir)
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Initialize only git repository (no metadata) and persist that inside
|
69
|
+
# @repo variable.
|
70
|
+
def init_git_repo
|
71
|
+
@repo = Cir::GitRepository.create(@repoDir)
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Asserts if given file have been correctly updated in the git working
|
76
|
+
# directory.
|
77
|
+
def assert_file_in_repo(file)
|
78
|
+
diff = Cir::DiffManager.create(file, "#{@repDir}/#{file}")
|
79
|
+
assert_false diff.changed?
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
require 'cir_test_case'
|
14
|
+
|
15
|
+
class DiffManagerTest < CirTestCase
|
16
|
+
|
17
|
+
def test_create
|
18
|
+
# Test files
|
19
|
+
file_a = create_file("a.file", "A")
|
20
|
+
file_b = create_file("b.file", "A")
|
21
|
+
file_c = create_file("c.file", "B")
|
22
|
+
|
23
|
+
# Same content
|
24
|
+
diff = Cir::DiffManager.create(file_a, file_b)
|
25
|
+
assert_false diff.changed?
|
26
|
+
|
27
|
+
# Different content
|
28
|
+
diff = Cir::DiffManager.create(file_a, file_c)
|
29
|
+
assert diff.changed?
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
require 'tmpdir'
|
14
|
+
require 'cir_test_case'
|
15
|
+
|
16
|
+
class GitRepositoryTest < CirTestCase
|
17
|
+
|
18
|
+
def test_create_already_exists
|
19
|
+
assert_raise Cir::Exception::RepositoryExists do
|
20
|
+
Cir::GitRepository.create(@workDir)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_create
|
25
|
+
Cir::GitRepository.create(@repoDir)
|
26
|
+
assert Dir.exists? "#{@repoDir}/.git"
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_add_file_and_commit
|
30
|
+
init_git_repo
|
31
|
+
|
32
|
+
create_file("repo/a.file", "Content")
|
33
|
+
create_file("repo/b.file", "Content")
|
34
|
+
|
35
|
+
@repo.add_file "a.file"
|
36
|
+
@repo.add_file "b.file"
|
37
|
+
@repo.commit
|
38
|
+
|
39
|
+
ruggedRepo = Rugged::Repository.new(@repoDir)
|
40
|
+
master = ruggedRepo.branches.first
|
41
|
+
assert_equal "master", master.name
|
42
|
+
assert_not_nil master.target
|
43
|
+
|
44
|
+
assert_match "a.file", master.target.message
|
45
|
+
assert_match "b.file", master.target.message
|
46
|
+
|
47
|
+
tree = master.target.tree
|
48
|
+
assert_not_nil tree
|
49
|
+
assert_equal 2, tree.count
|
50
|
+
assert_not_nil tree['a.file']
|
51
|
+
assert_not_nil tree['b.file']
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_remove_file_and_commit
|
55
|
+
init_git_repo
|
56
|
+
|
57
|
+
ruggedRepo = Rugged::Repository.new(@repoDir)
|
58
|
+
|
59
|
+
create_file("repo/a.file", "Content")
|
60
|
+
@repo.add_file "a.file"
|
61
|
+
@repo.commit
|
62
|
+
assert_equal 1, ruggedRepo.branches.first.target.tree.count
|
63
|
+
|
64
|
+
@repo.remove_file("a.file")
|
65
|
+
@repo.commit
|
66
|
+
assert_equal 0, ruggedRepo.branches.first.target.tree.count
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_commit_message
|
70
|
+
init_git_repo
|
71
|
+
|
72
|
+
ruggedRepo = Rugged::Repository.new(@repoDir)
|
73
|
+
|
74
|
+
# Default commit message starts with "Affected files"
|
75
|
+
create_file("repo/a.file", "Content")
|
76
|
+
@repo.add_file "a.file"
|
77
|
+
@repo.commit
|
78
|
+
assert_match "Affected files", ruggedRepo.branches.first.target.message
|
79
|
+
|
80
|
+
# Which can be overridden to arbitrary text
|
81
|
+
@repo.remove_file "a.file"
|
82
|
+
@repo.commit("My message")
|
83
|
+
assert_match "My message", ruggedRepo.branches.first.target.message
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
end
|
88
|
+
|
@@ -0,0 +1,163 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
require 'tmpdir'
|
14
|
+
require 'cir_test_case'
|
15
|
+
|
16
|
+
class RepositoryTest < CirTestCase
|
17
|
+
|
18
|
+
def test_create_already_exists
|
19
|
+
assert_raise Cir::Exception::RepositoryExists do
|
20
|
+
Cir::Repository.create(@workDir)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_create
|
25
|
+
init_repo
|
26
|
+
|
27
|
+
fileList = "#{@repoDir}/cir.file_list.yml"
|
28
|
+
|
29
|
+
assert File.exists? fileList
|
30
|
+
yaml = YAML::Store.new(fileList)
|
31
|
+
|
32
|
+
assert_equal(1, yaml.transaction { yaml[:version] })
|
33
|
+
assert_equal({}, yaml.transaction { yaml[:files] })
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def test_register
|
38
|
+
init_repo
|
39
|
+
|
40
|
+
# Prepare test file
|
41
|
+
test_file = create_file("A", "Input data")
|
42
|
+
|
43
|
+
# Register in repository - we'll use not a final path to make sure that repository will correctly resolve it
|
44
|
+
@repo.register ["#{File.dirname(test_file)}/./#{File.basename(test_file)}"]
|
45
|
+
|
46
|
+
# Which should create entity in the repository
|
47
|
+
yaml = YAML::Store.new(@repoDir + '/cir.file_list.yml')
|
48
|
+
result = yaml.transaction { yaml[:files][test_file] }
|
49
|
+
assert_not_nil result
|
50
|
+
assert_equal({}, result)
|
51
|
+
|
52
|
+
# And the file should also exists in the working directory
|
53
|
+
assert File.exists?("#{@repoDir}/#{test_file}")
|
54
|
+
|
55
|
+
# Registering again should fail
|
56
|
+
assert_raise Cir::Exception::AlreadyRegistered do
|
57
|
+
@repo.register [test_file]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_registered
|
62
|
+
init_repo
|
63
|
+
|
64
|
+
test_file = create_file("A", "Input data")
|
65
|
+
|
66
|
+
@repo.register [test_file]
|
67
|
+
|
68
|
+
assert @repo.registered?(test_file)
|
69
|
+
assert_false @repo.registered?("/blah")
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_deregister
|
73
|
+
init_repo
|
74
|
+
|
75
|
+
# Prepare test file
|
76
|
+
test_file = create_file("A", "Input data")
|
77
|
+
|
78
|
+
# Register in repository
|
79
|
+
@repo.register [test_file]
|
80
|
+
assert @repo.registered? test_file
|
81
|
+
|
82
|
+
# Deregister the file now
|
83
|
+
@repo.deregister [test_file]
|
84
|
+
|
85
|
+
assert_false @repo.registered? test_file
|
86
|
+
assert_false File.exists?("#{@repoDir}/#{test_file}")
|
87
|
+
|
88
|
+
# Deregister of not registered file should raise an exception
|
89
|
+
assert_raise(Cir::Exception::NotRegistered) { @repo.deregister ["X"]}
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_status
|
93
|
+
init_repo
|
94
|
+
|
95
|
+
test_file_a = create_file("A", "data")
|
96
|
+
test_file_b = create_file("B", "data")
|
97
|
+
@repo.register [test_file_a, test_file_b]
|
98
|
+
|
99
|
+
# Everything
|
100
|
+
status = @repo.status
|
101
|
+
assert_not_nil status
|
102
|
+
assert_equal status.size, 2
|
103
|
+
|
104
|
+
# Not registered file
|
105
|
+
assert_raise(Cir::Exception::NotRegistered) { @repo.status ["X"] }
|
106
|
+
|
107
|
+
# One specific file
|
108
|
+
status = @repo.status [test_file_a]
|
109
|
+
assert_not_nil status
|
110
|
+
assert_equal status.size, 1
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_update
|
114
|
+
init_repo
|
115
|
+
|
116
|
+
test_file = create_file("A", "data")
|
117
|
+
@repo.register [test_file]
|
118
|
+
|
119
|
+
# Update non existing file
|
120
|
+
assert_raise(Cir::Exception::NotRegistered) { @repo.update ["X"] }
|
121
|
+
|
122
|
+
# Updating via "all"
|
123
|
+
create_file("A", "New data")
|
124
|
+
@repo.update
|
125
|
+
assert_file_in_repo test_file
|
126
|
+
|
127
|
+
# Updating via "given file"
|
128
|
+
create_file("A", "Newer data")
|
129
|
+
@repo.update
|
130
|
+
assert_file_in_repo test_file
|
131
|
+
end
|
132
|
+
|
133
|
+
def test_restore
|
134
|
+
init_repo
|
135
|
+
|
136
|
+
test_file = create_file("A", "data")
|
137
|
+
@repo.register [test_file]
|
138
|
+
|
139
|
+
# Restore non existing file
|
140
|
+
assert_raise(Cir::Exception::NotRegistered) { @repo.restore ["X"] }
|
141
|
+
|
142
|
+
# Restoring non-existing file via "all"
|
143
|
+
FileUtils.rm test_file
|
144
|
+
@repo.restore
|
145
|
+
assert_file_in_repo test_file
|
146
|
+
|
147
|
+
# Restore non-existing file specifically by file name
|
148
|
+
FileUtils.rm test_file
|
149
|
+
@repo.restore([test_file])
|
150
|
+
assert_file_in_repo test_file
|
151
|
+
|
152
|
+
# Restoring via "all"
|
153
|
+
create_file("A", "New data")
|
154
|
+
@repo.restore(nil, true)
|
155
|
+
assert_file_in_repo test_file
|
156
|
+
|
157
|
+
# Restore given file
|
158
|
+
create_file("A", "Newer data")
|
159
|
+
@repo.restore([test_file])
|
160
|
+
assert_file_in_repo test_file
|
161
|
+
end
|
162
|
+
|
163
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
2
|
+
# you may not use this file except in compliance with the License.
|
3
|
+
# You may obtain a copy of the License at
|
4
|
+
#
|
5
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
6
|
+
#
|
7
|
+
# Unless required by applicable law or agreed to in writing, software
|
8
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
9
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
10
|
+
# See the License for the specific language governing permissions and
|
11
|
+
# limitations under the License.
|
12
|
+
#
|
13
|
+
require 'cir_test_case'
|
14
|
+
|
15
|
+
class StoredFileTest < CirTestCase
|
16
|
+
|
17
|
+
def test_initialize
|
18
|
+
file = Cir::StoredFile.new file_path: "/home/jarcec/", repository_location: "location"
|
19
|
+
assert_equal file.file_path, "/home/jarcec/"
|
20
|
+
assert_equal file.repository_location, "location"
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|