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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: de99ffe827d1c73cbf2cecb80105944f169372f8
4
- data.tar.gz: d9b4eabba343b0cf73b1153a1f8b3c001ffeb373
3
+ metadata.gz: 777a138f95c8f7fc7510a0736a5c6ad1573b8e2a
4
+ data.tar.gz: 050b44659cd12abe1710f595df19298c5051022f
5
5
  SHA512:
6
- metadata.gz: da04bdd002f65a2ddd4814b76c36a08bcb40d7d793dd9a1d14501de0c2f1f2d295db36a051e93789389e8198e91f43a03178673e1db45c5d3c8416eb84aa977c
7
- data.tar.gz: 8e5d2ff12d81960f4711f5bd3d179d0d88987703fd1179d7968910396db005f504a5b9dd97d933243ea51fe9ead68d82ffe1d84a25163feac47cfac3a5fc909d
6
+ metadata.gz: 8287076f642834a5e0c35acef50f7b0137184c6ad09103f7b81e08f4c2d6f11ff148b64d0816d83969d31568edfe972a52ecdff73c5e6295681edcad4cd9ae89
7
+ data.tar.gz: b0d88b97cb46368a8b472849e8b00d8863e5a65734e15b79ca2d63332c69dda5312cc6304e2a12242f1f2a4fe1117248ff9b63a514bdf5ba31a0b8479947304e
@@ -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 = opts[:local]
27
- remote_full = opts[:remote] # location with username, host and path
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
- # since save feature is unimplemented
30
- # both local and remote option have to be specified for an explicit synchronization
31
- Trollop::die :local, 'must be specified' if local.nil?
32
- Trollop::die :remote, 'must be specified' if remote_full.nil?
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|
@@ -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 = 'development code synchronization tool'
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']
@@ -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, "reset failed: #{data}"
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 diff_text
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, "apply failed: #{result}" if result != ''
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
@@ -1,3 +1,3 @@
1
1
  module GRSync
2
- VERSION = '0.0.2'
2
+ VERSION = '0.1.0'
3
3
  end
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.2
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-21 00:00:00.000000000 Z
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: development code synchronization tool
108
+ summary: A tool to synchronize local and remote git repositories' code
108
109
  test_files: []