confgit 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,28 @@
1
+ /VERSION
2
+ *.gem
3
+ *.rbc
4
+ .bundle
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
19
+
20
+ # editor noise
21
+ *~
22
+
23
+ # old skool
24
+ .svn
25
+
26
+ # osx noise
27
+ .DS_Store
28
+ Icon
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in confgit.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 gnue
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,192 @@
1
+ # Confgit
2
+
3
+ 分散している設定ファイルを git を使ってバージョン管理するためのツール
4
+
5
+ ## Features
6
+
7
+ * 分散している設定ファイルを一括管理
8
+ * バージョン管理できる
9
+ * 一度ファイルを登録すると以後は backup/restore サブコマンドで簡単管理
10
+ * 慣れ親しんだ(?)git のサブコマンドがそのまま使える
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+
16
+ gem 'confgit'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install confgit
25
+
26
+ ## 必要なソフトウェア
27
+
28
+ * 必須
29
+ * ruby 1.9以上(1.9.3 でのみ動作確認)
30
+ * git
31
+ * オプション
32
+ * tree
33
+ * tig
34
+
35
+ ## Usage
36
+
37
+ 固有のサブコマンドとgitのサブコマンドが使用できます
38
+
39
+ ### 固有のサブコマンド一覧
40
+
41
+ $ confgit repo # リポジトリ一覧の表示
42
+ $ confgit repo リポジトリ名 # カレントリポジトリの変更
43
+ $ confgit root # ルートの表示
44
+ $ confgit root ディレクトリ名 # ルートの変更
45
+ $ confgit root -d # ルートの設定を削除する(デフォルト値 / になる)
46
+ $ confgit add ファイル名 # ファイルを追加
47
+ $ confgit rm ファイル名 # ファイルを削除
48
+ $ confgit rm -rf ディレクトリ名 # ディレクトリを削除
49
+ $ confgit backup # バックアップ(更新されたもののみ)
50
+ $ confgit backup -f # 強制バックアップ
51
+ $ confgit restore # リストア(更新されたもののみ)
52
+ $ confgit restore -f # 強制リストア
53
+ $ confgit tree # ツリー表示(要treeコマンド)
54
+ $ confgit tig # tigで表示(要tigコマンド)
55
+ $ confgit path # リポジトリのパスを表示
56
+ $ confgit list # 一覧表示
57
+
58
+ ### gitのサブコマンド
59
+
60
+ $ confgit commit -m 'ログ'
61
+ $ confgit status
62
+ $ confgit log
63
+ $ confgit reset --hard
64
+ $ confgit branch ブランチ名
65
+ $ confgit tag タグ名
66
+
67
+ * その他 git のサブコマンドがそのまま使えます
68
+
69
+ ### 使用例
70
+
71
+ #### システム環境の管理
72
+
73
+ 管理するファイルを追加してコミット
74
+
75
+ $ confgit add /etc/apache2/httpd.conf
76
+ $ confgit add /etc/postfix/aliases
77
+ $ confgit commit -m '設定を追加'
78
+
79
+ 変更されたファイルをバックアップする
80
+
81
+ $ confgit backup
82
+ --> etc/apache2/httpd.conf [yN]: y
83
+ $ confgit commit -m '設定を変更'
84
+
85
+ 変更されたファイルを復元する
86
+
87
+ $ sudo confgit restore
88
+ <-- etc/apache2/httpd.conf [yN]: y
89
+
90
+ * そのたままだと書込み権限がないので sudo で実行する
91
+
92
+ #### ユーザ環境の管理
93
+
94
+ リポジトリを変更してルートをホームディレクトリにする
95
+
96
+ $ confgit repo myconfig
97
+ $ confgit root ~
98
+
99
+ * ルートの変更は初回のみ行うようにする(ファイルを追加したあとに変更すると整合性がとれなくなってしまうので注意)
100
+ * ルートを変更することによりホームディレクトリからのパスで記録される(treeサブコマンドで確認すると違いが一目瞭然)
101
+ * リポジトリはいくつでも作成できるので、管理対象に合わせてルートを変更して使い分けてもよい
102
+
103
+ 管理するファイルを追加してコミット
104
+
105
+ $ confgit add ~/.bash_profile
106
+ $ confgit add ~/.bashrc
107
+ $ confgit commit -m '設定を追加'
108
+
109
+ 変更されたファイルをバックアップする
110
+
111
+ $ emacs ~/.bash_profile
112
+ $ confgit backup
113
+ --> .bash_profile [yN]: y
114
+ $ confgit commit -m '設定を変更'
115
+
116
+ 変更されたファイルを復元する
117
+
118
+ $ confgit restore
119
+ <-- .bash_profile [yN]: y
120
+
121
+ #### Tips
122
+
123
+ 俯瞰する
124
+
125
+ $ confgit tree -a
126
+ .
127
+ ├── Users
128
+ | └── foo
129
+ | ├── .bash_profile
130
+ | └── .bashrc
131
+ └── etc
132
+ ├── apache2
133
+ │ └── httpd.conf
134
+ └── postfix
135
+ └── aliases
136
+
137
+ * ドットファイルは -a を付けて表示する
138
+
139
+ リポジトリに cd して直接ファイルを編集や git の操作をしたいとき
140
+
141
+ $ pushd `confgit path`
142
+ (作業)
143
+ $ popd
144
+
145
+ bash で補完機能を使う
146
+
147
+ $ curl -O https://raw.github.com/gnue/confgit/master/etc/bash_completion.d/confgit
148
+ $ cp confgit $BASH_COMPLETION_DIR
149
+ (再ログイン)
150
+
151
+ * bash-completion がインストールされて使用可能な状態になっている必要がある
152
+ * 使える補完
153
+ * 固有サブコマンド
154
+ * `confgit repo` でリポジトリを補完
155
+
156
+ ## Directory
157
+
158
+ ~/.etc/confgit
159
+ ├── confgit.conf -- 設定ファイル
160
+ └── repos
161
+ ├── current -- カレントリポジトリへのシンボリックリンク
162
+ └── `hostname` -- リポジトリ(デフォルト)
163
+
164
+ ## FAQ
165
+
166
+ * [Q] ~/.etc って何?
167
+
168
+ [A] ホームディレクトリにドットファイルが叛乱しているUNIX文化の悪しき伝統への提案。
169
+ いいかげん、ホームディレクトリ直下にドットファイルをつくるのを減らしましょう。
170
+ 各ソフトの設定ファイルがひとつに場所(~/.etc)にまとまってるほうがわかりやすいし管理しやすいでしょ。
171
+
172
+ * [Q] confgit.conf って特に使われてないみたいなんですけど?
173
+
174
+ [A] 最初の頃にカレントリポジトリを覚えておくのとかに使ってましたが、カレントリポジトリはシンボリックリンク
175
+ に変更したりとかしてしまって現在は空の状態になってしまいました。
176
+ 将来的には表示色の変更とかカスタマイズに使えるようになるかもしれません。
177
+
178
+ ## TODO
179
+
180
+ * README の英語化
181
+ * `confgit サブコマンド -h` のローカライズ
182
+ * リストアで書込み権限がない場合は sudo でファイルコピーを行えるようにする
183
+ * user/group の情報を保存
184
+ * user/group の情報を復元
185
+
186
+ ## Contributing
187
+
188
+ 1. Fork it
189
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
190
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
191
+ 4. Push to the branch (`git push origin my-new-feature`)
192
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require File.expand_path('../etc/tools/update_version', __FILE__)
2
+ require "bundler/gem_tasks"
3
+
4
+ # Spec
5
+ require 'rake/testtask'
6
+ Rake::TestTask.new(:spec) do |spec|
7
+ spec.libs << "spec"
8
+ spec.test_files = Dir['spec/**/*_spec.rb']
9
+ spec.verbose = true
10
+ end
11
+
12
+
13
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.3
data/bin/confgit ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'confgit'
7
+
8
+ Confgit.run
data/confgit.gemspec ADDED
@@ -0,0 +1,41 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'confgit/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "confgit"
8
+ gem.version = Confgit::VERSION
9
+ gem.authors = ["gnue"]
10
+ gem.email = ["gnue@so-kukan.com"]
11
+ gem.description = %q{Config files management tool with git}
12
+ gem.summary = %q{Config files management tool with git}
13
+ gem.homepage = "https://github.com/gnue/confgit"
14
+
15
+ gem.files = `git ls-files`.split($/) + %w(VERSION)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.required_ruby_version = '>= 1.9.0'
21
+
22
+ # dependency
23
+ gem.add_dependency('i18n')
24
+ gem.add_dependency('json')
25
+
26
+ # for development
27
+ gem.add_development_dependency('minitest')
28
+ gem.add_development_dependency('turn')
29
+
30
+ gem.post_install_message = %Q{
31
+ ==================
32
+ This software requires 'git'.
33
+ Also optional softwares 'tree' and 'tig'.
34
+
35
+ If you are using the bash-completion
36
+
37
+ $ cp `gem env gemdir`/gems/confgit-#{gem.version}/etc/bash_completion.d/confgit $BASH_COMPLETION_DIR
38
+
39
+ ==================
40
+ }
41
+ end
@@ -0,0 +1,39 @@
1
+ # bash completion for confgit
2
+
3
+ _confgit()
4
+ {
5
+ local cur
6
+
7
+ COMPREPLY=()
8
+ _get_comp_words_by_ref cur
9
+
10
+ if [[ $COMP_CWORD == 1 ]]; then
11
+ COMPREPLY=(repo root add rm backup restore tree tig path list)
12
+ COMPREPLY=($(compgen -W "${COMPREPLY[*]}" "$cur"))
13
+ return 0
14
+ fi
15
+
16
+ case ${COMP_WORDS[1]} in
17
+ repo)
18
+ [[ 2 < $COMP_CWORD ]] && return 0
19
+
20
+ COMPREPLY=$(ls ~/.etc/confgit/repos/ | fgrep -v current)
21
+ COMPREPLY=("${COMPREPLY[@]}" `readlink ~/.etc/confgit/repos/current`)
22
+ COMPREPLY=($(compgen -W "${COMPREPLY[*]}" "$cur"))
23
+ ;;
24
+ *)
25
+ _filedir
26
+ ;;
27
+ esac
28
+
29
+ return 0
30
+ } &&
31
+ complete -F _confgit confgit
32
+
33
+ # Local variables:
34
+ # mode: shell-script
35
+ # sh-basic-offset: 4
36
+ # sh-indent-comment: t
37
+ # indent-tabs-mode: nil
38
+ # End:
39
+ # ex: ts=4 sw=4 et filetype=sh
@@ -0,0 +1,14 @@
1
+ def update_version(path)
2
+ version = `git describe --tags --dirty`.chomp
3
+ version.gsub!(/-([a-z0-9]+(-dirty)?)$/) { |m| "(#{$1})" }
4
+
5
+ begin
6
+ return if version == open(path).read.chomp
7
+ return if version.empty?
8
+ rescue
9
+ end
10
+
11
+ open(path, 'w') { |f| f.puts version }
12
+ end
13
+
14
+ update_version 'VERSION'
@@ -0,0 +1,143 @@
1
+ # coding: UTF-8
2
+
3
+
4
+ require 'optparse'
5
+ require 'rubygems'
6
+ require 'i18n'
7
+
8
+
9
+ module Confgit
10
+
11
+ class CLI
12
+
13
+ def self.run(argv = ARGV, options = {})
14
+ CLI.new.run(argv, options)
15
+ end
16
+
17
+ def run(argv = ARGV, options = {})
18
+ i18n_init
19
+
20
+ trap ('SIGINT') { abort '' }
21
+
22
+ # コマンド引数の解析
23
+ command = nil
24
+
25
+ OptionParser.new { |opts|
26
+ begin
27
+ opts.version = LONG_VERSION || VERSION
28
+ opts.banner = "Usage: #{opts.program_name} <command> [<args>]"
29
+
30
+ opts.on('-h', '--help', t(:help)) { abort opts.help }
31
+ opts.separator ''
32
+ opts.separator t(:commands)
33
+
34
+ opts.order!(argv)
35
+ command = argv.shift
36
+ abort opts.help unless command
37
+ rescue => e
38
+ abort e.to_s
39
+ end
40
+ }
41
+
42
+ action(command, argv, options)
43
+ end
44
+
45
+ # I18n を初期化する
46
+ def i18n_init
47
+ I18n.load_path = Dir[File.expand_path('../locales/*.yml', __FILE__)]
48
+ I18n.backend.load_translations
49
+
50
+ locale = ENV['LANG'][0, 2].to_sym if ENV['LANG']
51
+ I18n.locale = locale if I18n.available_locales.include?(locale)
52
+ end
53
+
54
+ # I18n で翻訳する
55
+ def t(code, options = {})
56
+ options[:scope] ||= [:usage]
57
+ I18n.t(code, options)
58
+ end
59
+
60
+ # アクションの実行
61
+ def action(command, argv, options = {})
62
+ command = command.gsub(/-/, '_')
63
+
64
+ # オプション解析
65
+ options_method = "options_#{command}"
66
+ options.merge!(send(options_method, argv)) if respond_to?(options_method)
67
+
68
+ confgit = Repo.new
69
+ confgit.send("confgit_#{command}", options, *argv)
70
+ end
71
+
72
+ # サブコマンド・オプションのバナー作成
73
+ def banner(opts, method, *args)
74
+ subcmd = method.to_s.gsub(/^.+_/, '')
75
+ ["Usage: #{opts.program_name} #{subcmd}", *args].join(' ')
76
+ end
77
+
78
+ # オプション解析を定義する
79
+ def self.define_options(command, *banner, &block)
80
+ define_method "options_#{command}" do |argv|
81
+ options = {}
82
+
83
+ OptionParser.new { |opts|
84
+ begin
85
+ opts.banner = banner(opts, command, *banner)
86
+ block.call(opts, argv, options)
87
+ rescue => e
88
+ abort e.to_s
89
+ end
90
+ }
91
+
92
+ options
93
+ end
94
+ end
95
+
96
+ # オプション解析
97
+
98
+ # カレントリポジトリの表示・変更
99
+ define_options(:repo, '[options] [<repo>]') { |opts, argv, options|
100
+ opts.on('-d', 'remove repo') { options[:remove] = true }
101
+ opts.on('-D', 'remove repo (even if current repository)') {
102
+ options[:remove] = true
103
+ options[:force] = true
104
+ }
105
+ opts.parse!(argv)
106
+ }
107
+
108
+ # ルートの表示・変更
109
+ define_options(:root, '[PATH]') { |opts, argv, options|
110
+ opts.on('-d', 'default root') { options[:remove] = true }
111
+ opts.parse!(argv)
112
+ }
113
+
114
+ # ファイルを管理対象に追加
115
+ define_options(:add, '<file>…') { |opts, argv, options|
116
+ opts.parse!(argv)
117
+ abort opts.help if argv.empty?
118
+ }
119
+
120
+ # バックアップする
121
+ define_options(:backup, '[options] [<file>…]') { |opts, argv, options|
122
+ opts.on('-n', '--dry-run', 'dry run') { options[:yes] = false }
123
+ opts.on('-y', '--yes', 'yes') { options[:yes] = true }
124
+ opts.on('-f', 'force') { options[:force] = true }
125
+ opts.parse!(argv)
126
+ }
127
+
128
+ # リストアする
129
+ define_options(:restore, '[options] [<file>…]') { |opts, argv, options|
130
+ opts.on('-n', '--dry-run', 'dry run') { options[:yes] = false }
131
+ opts.on('-y', '--yes', 'yes') { options[:yes] = true }
132
+ opts.on('-f', 'force') { options[:force] = true }
133
+ opts.parse!(argv)
134
+ }
135
+
136
+ # 一覧表示する
137
+ define_options(:list, '[options] [<file>…]') { |opts, argv, options|
138
+ opts.on('-8', 'mode display octal') { options[:octal] = true }
139
+ opts.parse!(argv)
140
+ }
141
+ end
142
+
143
+ end
@@ -0,0 +1,18 @@
1
+ en:
2
+ usage:
3
+ help: Show this message
4
+ commands: |
5
+ commands:
6
+ repo Show repositories
7
+ repo REPO Change repository
8
+ root Show root
9
+ root PATH Change root
10
+ add FILE… Add files
11
+ rm FILE… Remove files
12
+ rm -rf DIRECTORY Remove directories
13
+ backup Backup
14
+ restore Restore
15
+ tree Show tree(require tree)
16
+ tig Show by tig(require tig)
17
+ path Show repository path
18
+ list Show file list
@@ -0,0 +1,18 @@
1
+ ja:
2
+ usage:
3
+ help: このメッセージを表示
4
+ commands: |
5
+ commands:
6
+ repo リポジトリ一覧の表示
7
+ repo REPO カレントリポジトリの変更
8
+ root ルートの表示
9
+ root PATH ルートの変更
10
+ add FILE… ファイルを追加
11
+ rm FILE… ファイルを削除
12
+ rm -rf DIRECTORY ディレクトリを削除
13
+ backup 更新されたファイルをバックアップ
14
+ restore 更新されたファイルを復元
15
+ tree ツリー表示(要treeコマンド)
16
+ tig tigで表示(要tigコマンド)
17
+ path リポジトリのパスを表示
18
+ list 一覧表示