sheldon 0.2.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: bc997c5b4f37ad9017e95676da13f93ccda540c2
4
+ data.tar.gz: 3597991837046118327d7a54d29bac5c648755c5
5
+ SHA512:
6
+ metadata.gz: fdf2d411262be96f41d48f8c09d49e89214d5cc66adcbacdf6f4501e84e709d45145df515a687d43096857a619c774b5b776ad16024757129875d5aa8374ab43
7
+ data.tar.gz: 9b20b0a6110eb0f7210314f00c80d26c2302d70c411bd2ceea67a994ce3c9bf250d1dc9aa2df2489eae49b4cf53431a10bd488ff032e967fdcc64f2d721ad95b
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 David V Jones
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # Sheldon
2
+ [![Build Status](https://travis-ci.org/dvjones89/sheldon.svg?branch=master)](https://travis-ci.org/dvjones89/sheldon)
3
+
4
+ Designed with the obsessive developer in mind, Sheldon makes it easy for you to manage your .dotfiles and configs across all your OS X / linux devices.
5
+
6
+ ### How It Works
7
+ #### Add files/folders to Sheldon (sheldon learn)
8
+ Teach Sheldon about new files or directories using the `learn` command:
9
+ ```shell
10
+ sheldon learn ~/.gitconfig
11
+ Recall Cue For File/Folder: git
12
+ ```
13
+
14
+ Sheldon will move the original file/directory into his data directory (defaults to `~/sheldon`) and symlink back to it's original location.
15
+ ```shell
16
+ ls -al ~ | grep .gitconfig
17
+ .gitconfig -> /Users/dave/sheldon/git/.gitconfig
18
+ ```
19
+ Keep Sheldon's data directory synchronised across all your devices using your tool of choice, Dropbox, Google Drive, BTSync.
20
+
21
+ #### Recall your files on other machines (sheldon recall)
22
+ Sheldon's `recall` command will symlink the file from the data directory to it's correct location on any filesystem (even under different home directories):
23
+
24
+ ```shell
25
+ sheldon recall git
26
+
27
+ ls -al ~ | grep .gitconfig
28
+ .gitconfig -> /Users/john/sheldon/git/.gitconfig
29
+ ```
30
+
31
+ Pass the `-i` flag to Sheldon's `recall` command for interactive mode:
32
+ ```shell
33
+ sheldon recall -i
34
+ Recall git_config (Y/N): y
35
+ Recall .zshrc (Y/N): y
36
+ ```
37
+
38
+ #### Build Bespoke Configs For Your Host (sheldon build)
39
+ Sometimes copying an entire config file between all your machine is overkill. What if you only want a subset of your configuration? Sheldon can help.
40
+
41
+ Split your ssh config into `config_work` and `config_personal`
42
+
43
+ Use Sheldon `learn` and `recall` to make the appropriate `_config` files available on the appropriate hosts.
44
+
45
+ Once the files are in the right place, use Sheldon `build` to create a single `config` file that can be easily sourced.
46
+
47
+ ```shell
48
+ cd ~/.ssh
49
+
50
+ ls -l
51
+ config_dev -> /Users/dave/sheldon/ssh_config_dev/config_dev
52
+ config_personal -> /Users/dave/sheldon/ssh_config_personal/config_personal
53
+
54
+ sheldon build ~/.ssh
55
+ 💥 Sheldon💥 Built .ssh
56
+
57
+ ls -l
58
+ config_dev -> /Users/dave/sheldon/ssh_config_dev/config_dev
59
+ config_personal -> /Users/dave/sheldon/ssh_config_personal/config_personal
60
+ config
61
+
62
+ source ~/.ssh/config
63
+ ```
64
+
65
+ ### Installation:
66
+ 1) `gem install Sheldon-<version>.gem`
67
+
68
+ 2) Sync Sheldon's data directory (`~/sheldon` by default) across all of your machines. You can override the default folder location by setting the`SHELDON_DATA_DIR` environment variable on each host.
69
+
70
+ ### Isn't This Just Homesick?
71
+ Yes, yes it is. Unfortunately, I'd written 90% of Sheldon before I discovered the awesome [homesick](https://github.com/technicalpickles/homesick) so I decided to keep going.
72
+ Sheldon's `build` command is (as far as I know) unique to Sheldon and will perhaps prove useful to those who chunk their configs.
73
+ If nothing else, I hope this code will be a good point of reference for other developers (and indeed my future self).
74
+
75
+ ### Contributing
76
+
77
+ 1. Fork it ( https://github.com/[your-github-username]/sheldon/fork )
78
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
79
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
80
+ 4. Make sure you haven't broken anything `bundle exec rspec`
81
+ 5. Add your own specs for your new feature
82
+ 6. Push to the branch (`git push origin my-new-feature`)
83
+ 7. Create a new Pull Request
84
+
85
+ ### License
86
+ See LICENSE
data/bin/sheldon ADDED
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+ require "thor"
3
+ require_relative "../lib/sheldon"
4
+
5
+ module CLI
6
+ class Sheldon < Thor
7
+ map link: :recall
8
+ map ls: :list
9
+
10
+ desc "build path", "Tell Sheldon to build all config_ files in a directory to single master config"
11
+ def build(rel_path_to_target)
12
+ abs_learn_path = File.expand_path(rel_path_to_target)
13
+ sheldon.build(abs_learn_path)
14
+ announce("Built #{File.basename(rel_path_to_target)}")
15
+ end
16
+
17
+ desc "learn path", "Add a new file/folder to Sheldon's brain. Supply a recall_cue at runtime."
18
+ def learn(rel_path_to_target)
19
+ abs_learn_path = File.expand_path(rel_path_to_target)
20
+ recall_cue = prompt_user("Recall Cue For File/Folder")
21
+ sheldon.learn(recall_cue, abs_learn_path)
22
+ end
23
+
24
+ desc "recall recall_cue", "Symlink a previously learnt file/directory to it's original location on the filesystem.\nUse `sheldon list` for available cues."
25
+ option :i, type: :boolean, desc: "Interactive mode - prompts Y/N for each available recall_cue"
26
+
27
+ def recall(recall_cue=nil)
28
+ if options[:i]
29
+ sheldon.list_cues.each do |recall_cue|
30
+ answer = prompt_user("Recall #{recall_cue}? (Y/N)")
31
+ sheldon.recall(recall_cue) if answer.downcase == "y"
32
+ end
33
+ else
34
+ recall_cue ||= prompt_user("Recall Cue For File/Folder")
35
+ sheldon.recall(recall_cue)
36
+ end
37
+
38
+ announce("Recall Complete.")
39
+ end
40
+
41
+ desc "list", "List all recall cues known by Sheldon"
42
+ def list
43
+ puts sheldon.list_cues
44
+ end
45
+
46
+ desc "version", "Prints the current version of Sheldon"
47
+ def version
48
+ announce ::Sheldon::VERSION
49
+ end
50
+
51
+ private
52
+
53
+ def prompt_user(prompt)
54
+ print(prompt + ": ")
55
+ STDIN.gets.chomp
56
+ end
57
+
58
+ def announce(message)
59
+ logo = "💥".encode("utf-8")
60
+ puts logo + " Sheldon" + logo + " #{message}"
61
+ end
62
+
63
+ def sheldon
64
+ @sheldon ||= ::Sheldon.new(sheldon_data_dir)
65
+ end
66
+
67
+ def sheldon_data_dir
68
+ path = ENV["SHELDON_DATA_DIR"] || "~/sheldon"
69
+ File.expand_path(path)
70
+ end
71
+
72
+ end
73
+ end
74
+
75
+ CLI::Sheldon.start(ARGV)
data/lib/sheldon.rb ADDED
@@ -0,0 +1,7 @@
1
+ require_relative "sheldon/brain"
2
+ require_relative "sheldon/builder"
3
+ require_relative "sheldon/helpers"
4
+ require_relative "sheldon/memory"
5
+ require_relative "sheldon/sheldon"
6
+
7
+ include Helpers
@@ -0,0 +1,51 @@
1
+ class Brain
2
+
3
+ attr_reader :memory
4
+
5
+ def initialize(sheldon_data_dir, opts = {})
6
+ @brain_location = sheldon_data_dir
7
+ @memory = opts[:memory] || Memory.new(@brain_location)
8
+ end
9
+
10
+
11
+ def learn(recall_cue, abs_learn_path)
12
+ cell = get_cell(recall_cue)
13
+ FileUtils.mkdir_p(cell)
14
+ FileUtils.mv(abs_learn_path, cell)
15
+ entry = { filepath: remove_home(abs_learn_path) }
16
+ memory.add(recall_cue, entry)
17
+ end
18
+
19
+ def recall(recall_cue)
20
+ entry = memory.recall(recall_cue)
21
+ destination_path = add_home(entry[:filepath])
22
+ destination_dir = File.dirname(destination_path)
23
+ FileUtils.mkdir_p(destination_dir) unless File.directory?(destination_dir)
24
+ source_cell = get_cell(recall_cue)
25
+ FileUtils.ln_s(read_cell(source_cell), destination_path, force: true)
26
+ end
27
+
28
+ def has_cue?(recall_cue)
29
+ memory.has_cue?(recall_cue)
30
+ end
31
+
32
+ def size
33
+ memory.size
34
+ end
35
+
36
+ def list_cues
37
+ memory.list_cues
38
+ end
39
+
40
+ private
41
+
42
+ def get_cell(recall_cue)
43
+ File.join(@brain_location, recall_cue)
44
+ end
45
+
46
+ def read_cell(cell)
47
+ basename = (Dir.entries(cell) - [".", "..", ".DS_Store"]).first
48
+ File.join(cell, basename)
49
+ end
50
+
51
+ end
@@ -0,0 +1,28 @@
1
+ class Builder
2
+ require "fileutils"
3
+
4
+ def build(abs_build_path)
5
+ entries = Dir.glob(abs_build_path + "/*")
6
+ master_content = entries.inject("") do |buffer, entry|
7
+ is_config?(entry) ? add_entry_to_buffer(entry, buffer) : buffer
8
+ end
9
+
10
+ unless master_content.empty?
11
+ master_path = File.join(abs_build_path, "config")
12
+ File.open(master_path, "w") { |f| f.write(master_content) }
13
+ end
14
+ end
15
+
16
+ private
17
+
18
+ def add_entry_to_buffer(abs_path, buffer)
19
+ content = File.read(abs_path)
20
+ buffer + content + "\n"
21
+ end
22
+
23
+ def is_config?(abs_path)
24
+ basename = File.basename(abs_path)
25
+ File.file?(abs_path) && basename.include?("config_") ? true : false
26
+ end
27
+
28
+ end
@@ -0,0 +1,18 @@
1
+ module Helpers
2
+ require "pathname"
3
+
4
+ def remove_home(path)
5
+ home_path = Pathname(File.expand_path("~"))
6
+ Pathname(path).relative_path_from(home_path).to_s
7
+ end
8
+
9
+ def add_home(path)
10
+ abs_home = File.expand_path("~")
11
+ File.join(abs_home, path).to_s
12
+ end
13
+
14
+ def abs(rel_path)
15
+ File.expand_path(rel_path).to_s
16
+ end
17
+
18
+ end
@@ -0,0 +1,34 @@
1
+ require "yaml/store"
2
+
3
+ class Memory
4
+
5
+ def initialize(brain_location)
6
+ database_path = File.join(brain_location, "db.yml")
7
+ @database = YAML::Store.new(database_path)
8
+ end
9
+
10
+ def add(recall_cue, hash)
11
+ raise "cue already used" if has_cue?(recall_cue)
12
+ @database.transaction do
13
+ @database[recall_cue] = hash
14
+ end
15
+ end
16
+
17
+ def recall(recall_cue)
18
+ raise "no entry for cue" unless has_cue?(recall_cue)
19
+ @database.transaction { @database[recall_cue] }
20
+ end
21
+
22
+ def size
23
+ list_cues.size
24
+ end
25
+
26
+ def list_cues
27
+ @database.transaction { @database.roots }
28
+ end
29
+
30
+ def has_cue?(recall_cue)
31
+ list_cues.any?{ |cue| cue == recall_cue }
32
+ end
33
+
34
+ end
@@ -0,0 +1,35 @@
1
+ require "fileutils"
2
+
3
+ class Sheldon
4
+ VERSION = "0.2.6".freeze
5
+ attr_reader :brain, :builder
6
+
7
+ def initialize(sheldon_data_dir, opts = {})
8
+ raise "Directory #{sheldon_data_dir} does not exist" unless Dir.exists?(sheldon_data_dir)
9
+ @brain = opts[:brain] || Brain.new(sheldon_data_dir)
10
+ @builder = opts[:builder] || Builder.new
11
+ end
12
+
13
+ def build(abs_learn_path)
14
+ builder.build(abs_learn_path)
15
+ end
16
+
17
+ def learn(recall_cue, abs_learn_path)
18
+ if brain.has_cue?(recall_cue)
19
+ raise "This cue has already been used."
20
+ else
21
+ brain.learn(recall_cue, abs_learn_path)
22
+ brain.recall(recall_cue)
23
+ end
24
+ end
25
+
26
+ def list_cues
27
+ brain.list_cues
28
+ end
29
+
30
+ def recall(recall_cue)
31
+ raise "Cue '#{recall_cue}' could not be found." unless brain.has_cue?(recall_cue)
32
+ brain.recall(recall_cue)
33
+ end
34
+
35
+ end
metadata ADDED
@@ -0,0 +1,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheldon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.6
5
+ platform: ruby
6
+ authors:
7
+ - David Jones
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-03-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: thor
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.9'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.9'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.1'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.1'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.3'
55
+ - !ruby/object:Gem::Dependency
56
+ name: simplecov
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.10'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.10'
69
+ description: Another config and dotfile manager for unix environments
70
+ email: david@dvj.me.uk
71
+ executables:
72
+ - sheldon
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - LICENSE
77
+ - README.md
78
+ - bin/sheldon
79
+ - lib/sheldon.rb
80
+ - lib/sheldon/brain.rb
81
+ - lib/sheldon/builder.rb
82
+ - lib/sheldon/helpers.rb
83
+ - lib/sheldon/memory.rb
84
+ - lib/sheldon/sheldon.rb
85
+ homepage: https://github.com/dvjones89/sheldon
86
+ licenses:
87
+ - MIT
88
+ metadata: {}
89
+ post_install_message:
90
+ rdoc_options: []
91
+ require_paths:
92
+ - lib
93
+ required_ruby_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ requirements: []
104
+ rubyforge_project:
105
+ rubygems_version: 2.5.1
106
+ signing_key:
107
+ specification_version: 4
108
+ summary: Another config and dotfile manager for unix environments
109
+ test_files: []