junk 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
6
+ .junk
7
+ .rvmrc
8
+ test
9
+ test2
10
+ test3
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in junk.gemspec
4
+ gemspec
data/LICENSE.md ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 by David Albert, http://dave.is/
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,81 @@
1
+ # Junk
2
+
3
+ ## About
4
+
5
+ Junk is a simple wrapper around git that tracks all the files you're not supposed to commit. This might include your .rvmrc files, sqlite development databases, and any other local project settings files. It's good for keeping your local configs synced across your development machines.
6
+
7
+ Behind the scenes, junk moves your tracked files into a git repository stored in ~/.junkd and symlinks to them from their original location. If it finds a .gitignore file, junk will make sure git ignores the symlink. Many junk commands just run the analogous git command in ~/.junkd.
8
+
9
+ ## Install
10
+
11
+ $ gem install junk
12
+
13
+ ## Requirements
14
+
15
+ Junk requires a version of git. It will probably work with most versions, but I developed it with 1.7.6.
16
+
17
+ ## How it works
18
+
19
+ $ cd myproject
20
+ $ junk init
21
+ Alright, /path/to/myproject now has a junk drawer.
22
+
23
+ $ junk track .rvmrc
24
+ Now tracking .rvmrc in your junk drawer
25
+
26
+ # Edit .rvmrc
27
+
28
+ $ junk status
29
+ # runs git status in your junk drawer
30
+
31
+ $ junk add .rvmrc
32
+ $ junk commit -m "tracking my .rvmrc file in junk"
33
+
34
+ $ junk remote add origin YOUR_GIT_REMOTE
35
+ $ junk push -u origin master
36
+
37
+ # on your other development machine
38
+ $ cd myproject
39
+
40
+ # for first time setup
41
+ $ junk clone JUNK_REPO
42
+
43
+ # or if you have already cloned the repo
44
+ $ junk pull
45
+
46
+ $ junk link
47
+ Linking in myproject's junk drawer.
48
+
49
+ ## Other commands
50
+
51
+ $ junk --home
52
+ ~/.junkd
53
+
54
+ # to do any custom git stuff like changing your junk remote, just cd to the junk home and go from there.
55
+ $ cd `junk --home`
56
+ # run your git commands here!
57
+
58
+ $ cd myproject
59
+ $ junk --drawer
60
+ ~/.junkd/myproject
61
+
62
+ ## Hub support!
63
+
64
+ Junk supports [hub](https://github.com/defunkt/hub) out of the box. If you have hub installed in your path, junk will see it. This means you can do this:
65
+
66
+ $ junk remote add -p origin YOUR_GITHUB_USERNAME/myjunk
67
+ $ junk remote -v
68
+ origin git@github.com:YOUR_GITHUB_USERNAME/myjunk.git (fetch) # look, hub added expanded your private remote url!
69
+ origin git@github.com:YOUR_GITHUB_USERNAME/myjunk.git (push)
70
+
71
+ ## License
72
+
73
+ Junk is licensed under the MIT License. See LICENSE.md for more information.
74
+
75
+ ## Who are you?
76
+
77
+ I'm [Dave](http://dave.is/).
78
+
79
+ ## That's it?
80
+
81
+ Well for now! I'm just getting started. Cut me some slack.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/bin/junk ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $:.unshift File.join(File.dirname(__FILE__), "..", "lib")
4
+
5
+ require 'junk'
6
+
7
+ Junk::Command.run(*ARGV)
data/junk.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "junk/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "junk"
7
+ s.version = Junk::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["David Albert"]
10
+ s.email = ["davidbalbert@gmail.com"]
11
+ s.homepage = "http://github.com/davidbalbert/junk"
12
+ s.summary = %q{A place to keep all the stuff you're not supposed to commit.}
13
+ s.description = %q{Junk is a simple wrapper around git that tracks all the files you're not supposed to commit.}
14
+
15
+ s.rubyforge_project = "junk"
16
+
17
+ s.add_dependency "trollop", "~> 1.16.2"
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ end
@@ -0,0 +1,341 @@
1
+ require 'fileutils'
2
+ require 'find'
3
+ require 'pathname'
4
+ require 'trollop'
5
+
6
+ module Junk
7
+ class Command
8
+
9
+ PROXY_COMMANDS = %w(add commit diff remote push pull log)
10
+ SUB_COMMANDS = %w(init clone track link unlink help status) + PROXY_COMMANDS
11
+
12
+ HELP_STRING = <<-EOS
13
+ usage: junk [-v|--version] [--home] [--drawer] [-h|--help] COMMAND [ARGS]
14
+
15
+ Commands:
16
+ init Initialize a new junk drawer for the current directory
17
+ clone Clones a git repo into ~/.junkd
18
+ track Moves a file to the junk drawer and symlinks it from it's old location
19
+ link Links in the junk drawer with the same name as the current directory
20
+ unlink Removes any symlinks pointing to the current junk drawer
21
+ help Displays information about a command
22
+
23
+ Proxy Commands (passed to git):
24
+ status
25
+ #{PROXY_COMMANDS.inject("") { |str, c| str << " #{c}\n" }}
26
+ EOS
27
+
28
+ CMD_HELP_STRINGS = {
29
+ "init" => "usage: junk init\n\nInitialize a new junk drawer for the current directory",
30
+ "clone" => "usage: junk clone REMOTE\n\nClone REMOTE into ~/.junkd",
31
+ "track" => "usage: junk track FILE\n\nMoves FILE to the junk drawer and symlinks it from it's old location",
32
+ "link" => "usage: junk link\n\nCreates symlinks to to all the files in the junk drawer with the same name as the current directory",
33
+ "unlink" => "usage: junk unlink\n\nRemoves any symlinks pointing to the current junk drawer",
34
+ "status" => "usage: junk status\n\nRuns `git status` in the current junk drawer",
35
+ "help" => "usage: junk help COMMAND\n\nShows usage information for COMMAND"
36
+ }
37
+
38
+ PROXY_COMMANDS.each do |c|
39
+ CMD_HELP_STRINGS[c] = "usage: junk #{c} ARGUMENTS\n\nRuns `git #{c} ARGUMENTS` in the current junk drawer"
40
+ end
41
+
42
+ attr_reader :args
43
+ def initialize(*args)
44
+ @args = args
45
+ end
46
+
47
+ def self.run(*args)
48
+ new(*args).run
49
+ end
50
+
51
+ def run
52
+ parser = Trollop::Parser.new do
53
+ version "Junk #{Junk::VERSION}"
54
+ banner "#{HELP_STRING}\nOptions:"
55
+ opt :home, "Prints junk's home directory", :short => :none
56
+ opt :drawer, "Prints the junk drawer for the current directory", :short => :none
57
+ stop_on SUB_COMMANDS
58
+ end
59
+
60
+ @global_opts = Trollop::with_standard_exception_handling parser do
61
+ o = parser.parse @args
62
+ raise Trollop::HelpNeeded if ARGV.empty?
63
+ o
64
+ end
65
+
66
+ if @global_opts[:home]
67
+ puts junk_home
68
+ exit(0)
69
+ end
70
+
71
+ if @global_opts[:drawer]
72
+ puts junk_repo!
73
+ exit(0)
74
+ end
75
+
76
+ check_for_git!
77
+
78
+ cmd = @args.shift
79
+ @cmd_opts = case cmd
80
+ when *SUB_COMMANDS
81
+ else
82
+ error "unknown command '#{cmd}'."
83
+ exit(1)
84
+ end
85
+
86
+ if PROXY_COMMANDS.include? cmd
87
+ proxy_command(cmd)
88
+ else
89
+ self.send(cmd)
90
+ end
91
+ end
92
+
93
+ def init
94
+ setup unless prefix_is_setup?
95
+
96
+ drawer_name = get_drawer_name(Dir.pwd)
97
+
98
+ Dir.chdir(junk_home) do
99
+ if File.exists?(File.join(junk_home, drawer_name))
100
+ error "There is already a junk drawer called #{drawer_name}."
101
+ exit(1)
102
+ end
103
+
104
+ Dir.mkdir drawer_name
105
+ end
106
+
107
+ File.symlink(File.join(junk_home, drawer_name), File.join(Dir.pwd, ".junk"))
108
+
109
+ add_to_git_ignore(".junk")
110
+
111
+ say "Alright, #{Dir.pwd} now has a junk drawer."
112
+ end
113
+
114
+ def track
115
+ file = @args.shift
116
+
117
+ Dir.chdir(parent_with_junk_drawer!) do
118
+ unless File.exists? file
119
+ error "#{file} doesn't seem to exist."
120
+ exit(1)
121
+ end
122
+
123
+ if file[0] == '/'
124
+ pwd = Pathname.new(Dir.pwd)
125
+ file_path = Pathname.new(file)
126
+ relative_path = file_path.relative_path_from(pwd).to_s
127
+ else
128
+ relative_path = file
129
+ end
130
+
131
+ if File.directory? relative_path
132
+ error "junk doesn't support adding directories, only single files :(."
133
+ exit(1)
134
+ end
135
+
136
+ dir, filename = File.split(relative_path)
137
+ new_path = File.join(junk_drawer_for_directory(Dir.pwd), dir)
138
+ unless File.exists? new_path
139
+ FileUtils.mkpath(new_path)
140
+ end
141
+
142
+ new_path = File.join(junk_drawer_for_directory(Dir.pwd), relative_path)
143
+ if File.exists? new_path
144
+ error "it looks like you've already added #{file}"
145
+ exit(1)
146
+ end
147
+
148
+ FileUtils.mv(relative_path, new_path)
149
+ File.symlink(new_path, relative_path)
150
+
151
+ add_to_git_ignore(relative_path)
152
+ end
153
+ end
154
+
155
+ def link
156
+ junk_drawer = junk_drawer_for_directory(Dir.pwd)
157
+
158
+ unless File.directory? junk_drawer
159
+ if File.exists? junk_home
160
+ error "#{junk_drawer} doesn't exist. Are you in the root directory of your project?"
161
+ else
162
+ error "#{junk_drawer} doesn't exist. Have you cloned your junk repo yet?"
163
+ end
164
+
165
+ exit(1)
166
+ end
167
+
168
+ say "found junk drawer #{junk_drawer}"
169
+ unless File.exists? ".junk"
170
+ say "linking #{junk_drawer} => .junk"
171
+ File.symlink(junk_drawer, ".junk")
172
+ end
173
+
174
+ junk_drawer_path = Pathname.new(junk_drawer)
175
+ Find.find(junk_drawer) do |path|
176
+ unless File.directory? path
177
+ rel_path = Pathname.new(path).relative_path_from(junk_drawer_path).to_s
178
+ unless File.exists? rel_path
179
+ say "linking #{path} => #{rel_path}"
180
+ File.symlink(path, rel_path)
181
+ end
182
+ end
183
+ end
184
+ end
185
+
186
+ def unlink
187
+ junk_repo = junk_repo! # junk_repo! uses Dir.chdir without a block. Will fix this later maybe
188
+ Dir.chdir(parent_with_junk_drawer!) do |dir|
189
+ Find.find(Dir.pwd) do |path|
190
+ if File.directory? path
191
+ if File.basename(path)[0] == ?.
192
+ Find.prune
193
+ end
194
+ elsif File.symlink? path
195
+ if File.readlink(path).start_with? junk_repo
196
+ puts "unlinking #{path}"
197
+ File.unlink(path)
198
+ end
199
+ end
200
+ end
201
+
202
+ if File.exists? ".junk"
203
+ puts "unlinking #{dir}/.junk"
204
+ File.unlink(".junk")
205
+ end
206
+ end
207
+ end
208
+
209
+ def clone
210
+ Dir.chdir(ENV["HOME"]) do
211
+ exec_git_or_hub("clone #{@args.join(" ")} .junkd")
212
+ end
213
+ end
214
+
215
+ def status
216
+ Dir.chdir(junk_repo!) do
217
+ exec_git_or_hub("status .")
218
+ end
219
+ end
220
+
221
+ def proxy_command(cmd)
222
+ Dir.chdir(junk_repo!) do
223
+ exec_git_or_hub("#{cmd} #{@args.join(" ")}")
224
+ end
225
+ end
226
+
227
+ def help
228
+ if @args.empty?
229
+ puts HELP_STRING
230
+ return
231
+ end
232
+
233
+ cmd = @args.shift
234
+
235
+ if CMD_HELP_STRINGS[cmd]
236
+ puts CMD_HELP_STRINGS[cmd]
237
+ else
238
+ error "unknown command '#{cmd}'."
239
+ end
240
+ end
241
+
242
+ private
243
+ def check_for_git!
244
+ if `which git` == ""
245
+ error "You need git installed in your path to use junk."
246
+ exit(1)
247
+ end
248
+ end
249
+
250
+ def prefix_is_setup?
251
+ if File.directory? junk_home
252
+ `git status`
253
+ if $? == 0
254
+ return true
255
+ end
256
+ end
257
+
258
+ false
259
+ end
260
+
261
+ def setup
262
+ say "Setting up your junk home in #{junk_home}..."
263
+ Dir.mkdir junk_home unless File.exists? junk_home
264
+
265
+ Dir.chdir(junk_home) do
266
+ print ">>> "
267
+ system("git init")
268
+ end
269
+
270
+ say ""
271
+ end
272
+
273
+ def parent_with_junk_drawer!
274
+ old_pwd = Dir.pwd
275
+
276
+ loop do
277
+ if Dir.pwd == "/"
278
+ Dir.chdir old_pwd
279
+ error "it looks like this folder doesn't have a junk drawer"
280
+ exit(1)
281
+ elsif Dir.exists? ".junk"
282
+ junk_dir = Dir.pwd
283
+ Dir.chdir old_pwd
284
+ return junk_dir
285
+ end
286
+ Dir.chdir ".."
287
+ end
288
+ end
289
+
290
+ def add_to_git_ignore(path)
291
+ if File.exists? ".gitignore"
292
+ File.open(".gitignore", "r+") do |f|
293
+ f.each do |l|
294
+ return if l.chomp == path
295
+ end
296
+ f.puts(path)
297
+ end
298
+ end
299
+ end
300
+
301
+ def exec_git_or_hub(cmd)
302
+ if has_hub?
303
+ exec("hub #{cmd}")
304
+ else
305
+ exec("git #{cmd}")
306
+ end
307
+ end
308
+
309
+ def has_hub?
310
+ @has_hub ||= (`which hub` != "")
311
+ end
312
+
313
+ def junk_home
314
+ @junk_home ||= File.join(ENV["HOME"], ".junkd")
315
+ end
316
+
317
+ def get_drawer_name(dir)
318
+ File.basename(dir)
319
+ end
320
+
321
+ def junk_repo!
322
+ junk_drawer_for_directory(parent_with_junk_drawer!)
323
+ end
324
+
325
+ def junk_drawer_for_directory(dir)
326
+ File.join(junk_home, File.basename(dir))
327
+ end
328
+
329
+ def error(str)
330
+ $stderr.puts "Error: #{str}"
331
+ end
332
+
333
+ def debug(str)
334
+ say "debug: #{str}" if @debug
335
+ end
336
+
337
+ def say(str)
338
+ puts str
339
+ end
340
+ end
341
+ end
@@ -0,0 +1,3 @@
1
+ module Junk
2
+ VERSION = "0.1.1"
3
+ end
data/lib/junk.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'junk/version'
2
+ require 'junk/command'
3
+
4
+ module Junk
5
+ # Your code goes here...
6
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: junk
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - David Albert
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-08-02 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: trollop
16
+ requirement: &70338571771620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.16.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70338571771620
25
+ description: Junk is a simple wrapper around git that tracks all the files you're
26
+ not supposed to commit.
27
+ email:
28
+ - davidbalbert@gmail.com
29
+ executables:
30
+ - junk
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - .gitignore
35
+ - Gemfile
36
+ - LICENSE.md
37
+ - README.md
38
+ - Rakefile
39
+ - bin/junk
40
+ - junk.gemspec
41
+ - lib/junk.rb
42
+ - lib/junk/command.rb
43
+ - lib/junk/version.rb
44
+ homepage: http://github.com/davidbalbert/junk
45
+ licenses: []
46
+ post_install_message:
47
+ rdoc_options: []
48
+ require_paths:
49
+ - lib
50
+ required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ required_rubygems_version: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ requirements: []
63
+ rubyforge_project: junk
64
+ rubygems_version: 1.8.6
65
+ signing_key:
66
+ specification_version: 3
67
+ summary: A place to keep all the stuff you're not supposed to commit.
68
+ test_files: []