sheldon 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []