grsync 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +33 -0
- data/bin/grsync +62 -19
- data/grsync.gemspec +1 -1
- data/lib/grsync.rb +9 -4
- data/lib/grsync/version.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 777a138f95c8f7fc7510a0736a5c6ad1573b8e2a
|
4
|
+
data.tar.gz: 050b44659cd12abe1710f595df19298c5051022f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8287076f642834a5e0c35acef50f7b0137184c6ad09103f7b81e08f4c2d6f11ff148b64d0816d83969d31568edfe972a52ecdff73c5e6295681edcad4cd9ae89
|
7
|
+
data.tar.gz: b0d88b97cb46368a8b472849e8b00d8863e5a65734e15b79ca2d63332c69dda5312cc6304e2a12242f1f2a4fe1117248ff9b63a514bdf5ba31a0b8479947304e
|
data/README.md
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# grsync
|
2
|
+
|
3
|
+
A tool to synchronize local and remote git repositories' code.
|
4
|
+
|
5
|
+
# why
|
6
|
+
|
7
|
+
Imagine you are developing a project which requires complicated dependencies like databases, third party plugins and other systems' API. All of them make your project hard to develop and test since you are unlikely to run it on your local machine.
|
8
|
+
|
9
|
+
One feasible way is to develop and test on your server with all issues resolved. Of course you can mount remote server's disks onto your local machine, write some code and run your tests right on the server but the performance of those mounted disks probably would drive you crazy.
|
10
|
+
|
11
|
+
So the approach grsync takes is try to apply all changes you've make on the local git repository to the remote one. Although these two repositories are (and have to be) same project and on the same branch, they may have different code changed. So all grsync do is to sync remote repository to your local one making all your local changes easily available on the remote side.
|
12
|
+
|
13
|
+
# how grsync works
|
14
|
+
|
15
|
+
Simple. Diff the local git repository and apply all changes on the remote git repository (and a hard reset is done before apply to avoid weird state).
|
16
|
+
|
17
|
+
# usage
|
18
|
+
|
19
|
+
Options:
|
20
|
+
```
|
21
|
+
-l, --local=<s> local source git repository(e.g. /path/to/repo)
|
22
|
+
-r, --remote=<s> remote destination git repository(e.g.
|
23
|
+
username@host:/path/to/repo)
|
24
|
+
-p, --passwd=<s> password for ssh login
|
25
|
+
-o, --port=<i> port for ssh login (default: 22)
|
26
|
+
-s, --save save this synchronization link(not implemented yet)
|
27
|
+
-h, --help Show this message
|
28
|
+
```
|
29
|
+
|
30
|
+
Example:
|
31
|
+
`grsync --local /home/tom/myproj --remote allen@remotehost:/projects/myproj --passwd hellowld`
|
32
|
+
|
33
|
+
The command above synchronizes remote `allen@remotehost:/projects/myproj` to local `/home/tom/myproj`.
|
data/bin/grsync
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'bundler/setup'
|
4
4
|
require 'net/ssh'
|
5
5
|
require 'trollop'
|
6
|
+
require 'json'
|
6
7
|
|
7
8
|
require 'grsync'
|
8
9
|
require 'grsync/logger'
|
@@ -14,6 +15,10 @@ require 'grsync/logger'
|
|
14
15
|
# --passwd barabara
|
15
16
|
# --port 2222
|
16
17
|
|
18
|
+
module GRSync
|
19
|
+
RecordFilePath = '~/.grsync'
|
20
|
+
end
|
21
|
+
|
17
22
|
# parse arguments
|
18
23
|
opts = Trollop::options do
|
19
24
|
opt :local, 'local source git repository(e.g. /path/to/repo)', :type => :string
|
@@ -23,13 +28,64 @@ opts = Trollop::options do
|
|
23
28
|
opt :save, 'save this synchronization link'
|
24
29
|
end
|
25
30
|
|
26
|
-
local
|
27
|
-
|
31
|
+
# if neither local repo or remote repo are given
|
32
|
+
# read arguments from the record file
|
33
|
+
if opts[:local].nil? and opts[:remote].nil?
|
34
|
+
record_file_path = File.expand_path(GRSync::RecordFilePath)
|
35
|
+
unless File.exist? record_file_path
|
36
|
+
$Log.info 'Run without --local and --remote arguments. ' <<
|
37
|
+
"Tried to read the record file #{record_file_path} but it's not found."
|
38
|
+
Trollop::die :local, 'must be specified when record file is unavailable'
|
39
|
+
end
|
40
|
+
|
41
|
+
# read meta data from record file
|
42
|
+
record = JSON.parse(File.read(record_file_path))
|
43
|
+
local = record['local']
|
44
|
+
user_name = record['user_name']
|
45
|
+
host = record['host']
|
46
|
+
remote = record['remote']
|
47
|
+
passwd = record['passwd']
|
48
|
+
port = record['port']
|
49
|
+
|
50
|
+
# read arguments from command line
|
51
|
+
else
|
52
|
+
local = opts[:local]
|
53
|
+
remote_full = opts[:remote] # location with username, host and path
|
54
|
+
|
55
|
+
Trollop::die :local, 'must be specified' if local.nil?
|
56
|
+
Trollop::die :remote, 'must be specified' if remote_full.nil?
|
57
|
+
|
58
|
+
# extract remote, user_name and host from dest_full
|
59
|
+
login_str, remote = remote_full.split ':'
|
60
|
+
if login_str.split('@').size == 2
|
61
|
+
user_name, host = login_str.split('@')
|
62
|
+
else
|
63
|
+
user_name = nil
|
64
|
+
host = login_str
|
65
|
+
end
|
28
66
|
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
67
|
+
# optional options for login
|
68
|
+
passwd = opts[:passwd] || ''
|
69
|
+
port = opts[:port]
|
70
|
+
|
71
|
+
# save sync meta data into record file if -save flag specified
|
72
|
+
if opts[:save]
|
73
|
+
# collect meta data
|
74
|
+
meta = {
|
75
|
+
:local => local,
|
76
|
+
:user_name => user_name,
|
77
|
+
:host => host,
|
78
|
+
:remote => remote,
|
79
|
+
:passwd => passwd,
|
80
|
+
:port => port
|
81
|
+
}
|
82
|
+
|
83
|
+
# write meta into record file
|
84
|
+
File.open(File.expand_path(GRSync::RecordFilePath), mode='w') do |file|
|
85
|
+
file.write JSON.dump(meta)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
33
89
|
|
34
90
|
# local dir must exist
|
35
91
|
# always check existence asap
|
@@ -38,19 +94,6 @@ unless Dir.exist?(File.expand_path(local))
|
|
38
94
|
abort
|
39
95
|
end
|
40
96
|
|
41
|
-
# extract remote, user_name and host from dest_full
|
42
|
-
login_str, remote = remote_full.split ':'
|
43
|
-
if login_str.split('@').size == 2
|
44
|
-
user_name, host = login_str.split('@')
|
45
|
-
else
|
46
|
-
host = login_str
|
47
|
-
user_name = nil
|
48
|
-
end
|
49
|
-
|
50
|
-
# optional options for login
|
51
|
-
passwd = opts[:passwd] || ''
|
52
|
-
port = opts[:port]
|
53
|
-
|
54
97
|
# ssh login
|
55
98
|
begin
|
56
99
|
Net::SSH.start(host, user_name, :password => passwd, :port => port) do |ssh|
|
data/grsync.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ['luminocean']
|
10
10
|
spec.email = ['luminocean@foxmail.com']
|
11
11
|
|
12
|
-
spec.summary = '
|
12
|
+
spec.summary = 'A tool to synchronize local and remote git repositories\' code'
|
13
13
|
spec.files = `git ls-files`.split("\n")
|
14
14
|
spec.bindir = 'bin'
|
15
15
|
spec.executables = ['grsync']
|
data/lib/grsync.rb
CHANGED
@@ -33,19 +33,24 @@ module GRSync
|
|
33
33
|
def reset_remote_repo
|
34
34
|
@ssh.exec! "cd #{@remote_path} && git reset --hard" do |ch, stream, data|
|
35
35
|
if stream == :stderr and data.to_s != '' # check for nil or ''
|
36
|
-
raise GitResetException, "
|
36
|
+
raise GitResetException, "Reset failed: #{data}"
|
37
37
|
end
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
41
|
def apply_diff_to_remote(diff_text)
|
42
|
+
# remove trailing spaces from diff text
|
43
|
+
# very important because trailing spaces would cause git apply failure
|
44
|
+
no_trailing_diff_text = []
|
45
|
+
diff_text.split("\n").each{|line| no_trailing_diff_text << line.rstrip }
|
46
|
+
|
42
47
|
# be careful, string in ruby may not be used safely in shell directly
|
43
48
|
# so here's a conversion
|
44
|
-
echoable_text = Shellwords.escape
|
49
|
+
echoable_text = Shellwords.escape no_trailing_diff_text.join("\n")
|
45
50
|
|
46
|
-
result = @ssh.exec! "cd #{@remote_path} && echo #{echoable_text} | git apply -"
|
51
|
+
result = @ssh.exec! "cd #{@remote_path} && (echo #{echoable_text} | git apply -)"
|
47
52
|
# diff fails if something other than empty string returns
|
48
|
-
raise GitDiffApplyException, "
|
53
|
+
raise GitDiffApplyException, "Apply failed: #{result}" if result != ''
|
49
54
|
end
|
50
55
|
|
51
56
|
# diff the local git repository and returns the diff text for later use
|
data/lib/grsync/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grsync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- luminocean
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: trollop
|
@@ -76,6 +76,7 @@ extra_rdoc_files: []
|
|
76
76
|
files:
|
77
77
|
- ".gitignore"
|
78
78
|
- Gemfile
|
79
|
+
- README.md
|
79
80
|
- bin/grsync
|
80
81
|
- grsync.gemspec
|
81
82
|
- lib/grsync.rb
|
@@ -104,5 +105,5 @@ rubyforge_project:
|
|
104
105
|
rubygems_version: 2.4.5.1
|
105
106
|
signing_key:
|
106
107
|
specification_version: 4
|
107
|
-
summary:
|
108
|
+
summary: A tool to synchronize local and remote git repositories' code
|
108
109
|
test_files: []
|