xcodesnippets 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +19 -0
- data/README.md +69 -0
- data/bin/xcodesnippets +5 -0
- data/lib/xcode_snippets.rb +25 -0
- data/lib/xcode_snippets/bundle.rb +80 -0
- data/lib/xcode_snippets/main.rb +50 -0
- data/lib/xcode_snippets/manifest.rb +70 -0
- data/lib/xcode_snippets/snippet.rb +45 -0
- data/lib/xcode_snippets/snippet_manager.rb +71 -0
- data/spec/bundle_spec.rb +88 -0
- data/spec/snippet_manager_spec.rb +121 -0
- data/spec/spec_helper.rb +38 -0
- metadata +128 -0
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (c) 2011 Luke Redpath
|
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,69 @@
|
|
1
|
+
# xcodesnippets - a utility for managing Xcode 4 snippet libraries.
|
2
|
+
|
3
|
+
Xcode 4 introduced code snippets; small, re-usable chunks of code that could be inserted using Xcode's native auto-completion system.
|
4
|
+
|
5
|
+
The problem is, Xcode does little to nothing to help you manage these snippets. There isn't an easy way of sharing them or managing them. `xcodesnippets` aims to make snippets a little bit more manageable, and sharable through the concept of snippet bundles.
|
6
|
+
|
7
|
+
My hope is that one day that this utility becomes obsolete and Xcode itself has better support for managing snippets, including organisation into folders and native installation/activation/deactivation of snippet bundles. To that end, I have [filed a bug](http://openradar.appspot.com/radar?id=1214402) (rdar://9587558) which I encourage you to dupe if you feel this would be beneficial.
|
8
|
+
|
9
|
+
## Getting started
|
10
|
+
|
11
|
+
`xcodesnippets` is written in Ruby and distributed as a Ruby gem. Most Macs with development tools installed come with a usable version of Ruby and RubyGems although to date, this gem has only been tested against Ruby 1.9.2. If you have a problem, please [file a bug](https://github.com/lukeredpath/xcodesnippets/issues).
|
12
|
+
|
13
|
+
If you aren't familiar with RubyGems, fire up a Terminal and run the following command:
|
14
|
+
|
15
|
+
$ sudo gem install xcodesnippets
|
16
|
+
|
17
|
+
If you are using a tool like [RVM](https://rvm.beginrescueend.com/), the `sudo` will probably be unnecessary.
|
18
|
+
|
19
|
+
## Installing a code snippet
|
20
|
+
|
21
|
+
Code snippets are distributed as property list files with a `.codesnippet` extension. If you have created any custom code snippets in Xcode 4, you will find them in your home directory, under `~/Library/Developer/Xcode/UserData/CodeSnippets/`. The files are named using GUIDs. Any `codesnippet` file created from within Xcode 4, or manually if you are comfortable editing the files yourself (they are just plists) are installable using `xcodesnippets`.
|
22
|
+
|
23
|
+
To install a snippet, run the following from the terminal:
|
24
|
+
|
25
|
+
$ xcodesnippets install [path-to-snippet-file]
|
26
|
+
|
27
|
+
To install a bundle, run the following:
|
28
|
+
|
29
|
+
$ xcodesnippets install-bundle [path-to-snippet-bundle]
|
30
|
+
|
31
|
+
For a full list of commands and options, run `xcodesnippets --help`.
|
32
|
+
|
33
|
+
## How xcodesnippets works
|
34
|
+
|
35
|
+
`xcodesnippets` stores all of it's snippets inside snippet bundles. Snippet bundles are simply a directory/package with a `.snippetbundle` extension. When creating and sharing snippets, you are encouraged to give them a suitable name that indicates what the snippet does, rather than using the GUID naming scheme that Xcode uses.
|
36
|
+
|
37
|
+
`xcodesnippets` installs all of it's snippets into `~/Library/Developer/Xcode/UserData/ManagedCodeSnippets`. Standalone snippets are stored in a default snippet bundle. Snippets are then symlinked from their installed location to the Xcode code snippets directory with an appropriate GUID, ensuring that they appear in Xcode (you may need to close your current project or workspace before installed snippets appear).
|
38
|
+
|
39
|
+
## TODO
|
40
|
+
|
41
|
+
* Installing snippets and bundles directly from a URL
|
42
|
+
* Generating snippet bundles from a folder of snippets ready for distribution
|
43
|
+
* Commands for listing installed bundles and their contents
|
44
|
+
* Commands for activating and de-activating individual bundles/snippets
|
45
|
+
|
46
|
+
## License
|
47
|
+
|
48
|
+
This project is licensed under the terms of the MIT license.
|
49
|
+
|
50
|
+
Copyright (c) 2011 Luke Redpath
|
51
|
+
|
52
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
53
|
+
of this software and associated documentation files (the "Software"), to deal
|
54
|
+
in the Software without restriction, including without limitation the rights
|
55
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
56
|
+
copies of the Software, and to permit persons to whom the Software is
|
57
|
+
furnished to do so, subject to the following conditions:
|
58
|
+
|
59
|
+
The above copyright notice and this permission notice shall be included in
|
60
|
+
all copies or substantial portions of the Software.
|
61
|
+
|
62
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
63
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
64
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
65
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
66
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
67
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
68
|
+
THE SOFTWARE.
|
69
|
+
|
data/bin/xcodesnippets
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'fileutils'
|
4
|
+
require 'xcode_snippets/main'
|
5
|
+
|
6
|
+
module XcodeSnippets
|
7
|
+
DEFAULT_INSTALLATION_PATH = File.expand_path("~/Library/Developer/Xcode/UserData/ManagedCodeSnippets")
|
8
|
+
DEFAULT_XCODE_SNIPPETS_PATH = File.expand_path("~/Library/Developer/Xcode/UserData/CodeSnippets")
|
9
|
+
|
10
|
+
def self.installation_path
|
11
|
+
@installation_path || DEFAULT_INSTALLATION_PATH
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.installation_path=(path)
|
15
|
+
@installation_path = path
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.xcode_snippets_path
|
19
|
+
@xcode_snippets_path || DEFAULT_XCODE_SNIPPETS_PATH
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.xcode_snippets_path=(path)
|
23
|
+
@xcode_snippets_path = path
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'xcode_snippets/snippet'
|
2
|
+
|
3
|
+
module XcodeSnippets
|
4
|
+
class Bundle
|
5
|
+
attr_reader :path, :snippets
|
6
|
+
|
7
|
+
def initialize(path)
|
8
|
+
@path = path
|
9
|
+
@snippets = []
|
10
|
+
load_snippets
|
11
|
+
end
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def bundle_named(name, install_directory)
|
15
|
+
new(File.join(install_directory, "#{name}.snippetbundle"))
|
16
|
+
end
|
17
|
+
|
18
|
+
def default(directory)
|
19
|
+
bundle = bundle_named("Default", directory)
|
20
|
+
|
21
|
+
if bundle.exists?
|
22
|
+
bundle
|
23
|
+
else
|
24
|
+
bundle.copy_to(directory)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def copy_to(directory)
|
30
|
+
installation_path = File.join(directory, name)
|
31
|
+
FileUtils.mkdir_p(installation_path)
|
32
|
+
|
33
|
+
self.class.new(installation_path).tap do |copied_bundle|
|
34
|
+
snippets.each do |snippet|
|
35
|
+
copied_bundle.add_copy_of_snippet(snippet)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def name
|
41
|
+
File.basename(path)
|
42
|
+
end
|
43
|
+
|
44
|
+
def exists?
|
45
|
+
File.exist?(path)
|
46
|
+
end
|
47
|
+
|
48
|
+
def add_copy_of_snippet_from_file(snippet_path)
|
49
|
+
add_copy_of_snippet Snippet.new(snippet_path)
|
50
|
+
end
|
51
|
+
|
52
|
+
def add_snippet(snippet)
|
53
|
+
@snippets << snippet
|
54
|
+
@snippets.last
|
55
|
+
end
|
56
|
+
|
57
|
+
def add_copy_of_snippet(snippet)
|
58
|
+
@snippets << snippet.copy_to_bundle(self)
|
59
|
+
@snippets.last
|
60
|
+
end
|
61
|
+
|
62
|
+
def delete
|
63
|
+
FileUtils.rm_rf(path)
|
64
|
+
end
|
65
|
+
|
66
|
+
def snippet_named(name)
|
67
|
+
name += ".codesnippet" if name !~ /\.codesnippet$/
|
68
|
+
snippet = Snippet.new(File.join(path, name), self)
|
69
|
+
snippet.exists? ? snippet : nil
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def load_snippets
|
75
|
+
Dir["#{path}/*.codesnippet"].each do |file|
|
76
|
+
add_snippet Snippet.new(file, self)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'clamp/command'
|
2
|
+
require 'xcode_snippets/snippet_manager'
|
3
|
+
|
4
|
+
module XcodeSnippets
|
5
|
+
class Main < Clamp::Command
|
6
|
+
|
7
|
+
subcommand "install", "Install a single snippet" do
|
8
|
+
parameter "FILE ...", "Path to code snippet to install"
|
9
|
+
|
10
|
+
def execute
|
11
|
+
manager.install_snippets_from_paths(file_list)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
subcommand "install-bundle", "Install a snippet bundle" do
|
16
|
+
parameter "FILE", "Name of the installed snippet"
|
17
|
+
|
18
|
+
def execute
|
19
|
+
manager.install_snippet_bundle(file)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
subcommand "uninstall", "Uninstall a single snippet" do
|
24
|
+
parameter "NAME", "Name of the installed snippet"
|
25
|
+
|
26
|
+
def execute
|
27
|
+
manager.uninstall_snippet_named(name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
subcommand "uninstall-bundle", "Uninstall a snippet bundle" do
|
32
|
+
parameter "NAME", "Name of the installed snippet bundle"
|
33
|
+
|
34
|
+
def execute
|
35
|
+
manager.uninstall_snippet_bundle_named(name)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def manager
|
42
|
+
XcodeSnippets::SnippetManager.new(manifest)
|
43
|
+
end
|
44
|
+
|
45
|
+
def manifest
|
46
|
+
Manifest.load(XcodeSnippets.installation_path, XcodeSnippets.xcode_snippets_path)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'plist'
|
2
|
+
|
3
|
+
module XcodeSnippets
|
4
|
+
class Manifest
|
5
|
+
attr_reader :snippets_install_path
|
6
|
+
|
7
|
+
def initialize(snippets_install_path, xcode_snippets_install_path, uuid_generator = UUIDGenerator)
|
8
|
+
@snippets_install_path = snippets_install_path
|
9
|
+
@xcode_snippets_install_path = xcode_snippets_install_path
|
10
|
+
@uuid_generator = uuid_generator
|
11
|
+
@data = {}
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.load(snippets_install_path, xcode_snippets_install_path, uuid_generator = UUIDGenerator)
|
15
|
+
new(snippets_install_path, xcode_snippets_install_path, uuid_generator).tap { |manifest| manifest.load }
|
16
|
+
end
|
17
|
+
|
18
|
+
def add_snippet(snippet)
|
19
|
+
@data[snippet.key] = snippet.symlink
|
20
|
+
end
|
21
|
+
|
22
|
+
def add_snippet!(snippet)
|
23
|
+
add_snippet(snippet)
|
24
|
+
save
|
25
|
+
end
|
26
|
+
|
27
|
+
def remove_snippet(snippet)
|
28
|
+
@data.delete(snippet.key)
|
29
|
+
end
|
30
|
+
|
31
|
+
def remove_snippet!(snippet)
|
32
|
+
remove_snippet(snippet)
|
33
|
+
save
|
34
|
+
end
|
35
|
+
|
36
|
+
def has_snippet?(snippet)
|
37
|
+
@data[snippet.key] && @data[snippet.key] == snippet.symlink
|
38
|
+
end
|
39
|
+
|
40
|
+
def save
|
41
|
+
File.open(path, "w") do |io|
|
42
|
+
io.write @data.to_plist
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def load
|
47
|
+
@data = Plist.parse_xml(path) || {}
|
48
|
+
end
|
49
|
+
|
50
|
+
def symlink_for_snippet(snippet)
|
51
|
+
@data[snippet.key]
|
52
|
+
end
|
53
|
+
|
54
|
+
def generate_new_symlink
|
55
|
+
File.join(@xcode_snippets_install_path, "#{@uuid_generator.generate}.codesnippet")
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def path
|
61
|
+
File.join(@snippets_install_path, "Manifest.plist")
|
62
|
+
end
|
63
|
+
|
64
|
+
class UUIDGenerator
|
65
|
+
def self.generate
|
66
|
+
UUIDTools::UUID.random_create.to_s.upcase
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module XcodeSnippets
|
2
|
+
class Snippet
|
3
|
+
attr_reader :path, :symlink
|
4
|
+
|
5
|
+
def initialize(path, bundle = nil)
|
6
|
+
@path = path
|
7
|
+
@bundle = bundle
|
8
|
+
end
|
9
|
+
|
10
|
+
def copy_to_bundle(bundle)
|
11
|
+
FileUtils.cp(path, bundle.path)
|
12
|
+
self.class.new(File.join(bundle.path, name), bundle)
|
13
|
+
end
|
14
|
+
|
15
|
+
def activate(manifest)
|
16
|
+
@symlink = manifest.generate_new_symlink
|
17
|
+
FileUtils.symlink(path, symlink)
|
18
|
+
manifest.add_snippet(self)
|
19
|
+
end
|
20
|
+
|
21
|
+
def deactivate(manifest)
|
22
|
+
manifest.remove_snippet(self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def delete
|
26
|
+
FileUtils.rm_f(path)
|
27
|
+
end
|
28
|
+
|
29
|
+
def name
|
30
|
+
File.basename(@path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def key
|
34
|
+
@bundle ? "#{@bundle.name}/#{name}" : name
|
35
|
+
end
|
36
|
+
|
37
|
+
def exists?
|
38
|
+
File.exist?(path)
|
39
|
+
end
|
40
|
+
|
41
|
+
def symlinked?
|
42
|
+
symlink && File.exist?(symlink)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'uuidtools'
|
2
|
+
require 'xcode_snippets/bundle'
|
3
|
+
require 'xcode_snippets/manifest'
|
4
|
+
|
5
|
+
module XcodeSnippets
|
6
|
+
class SnippetManager
|
7
|
+
attr_reader :manifest
|
8
|
+
|
9
|
+
def initialize(manifest)
|
10
|
+
@manifest = manifest
|
11
|
+
end
|
12
|
+
|
13
|
+
def install_snippet_from_path(path_to_snippet)
|
14
|
+
install_snippet default_bundle.add_copy_of_snippet_from_file(path_to_snippet)
|
15
|
+
end
|
16
|
+
|
17
|
+
def install_snippets_from_paths(snippet_path_list)
|
18
|
+
snippets = snippet_path_list.map do |path_to_snippet|
|
19
|
+
default_bundle.add_copy_of_snippet_from_file(path_to_snippet)
|
20
|
+
end
|
21
|
+
install_snippets snippets
|
22
|
+
end
|
23
|
+
|
24
|
+
def install_snippet(snippet)
|
25
|
+
snippet.activate(manifest)
|
26
|
+
save_manifest
|
27
|
+
snippet
|
28
|
+
end
|
29
|
+
|
30
|
+
def install_snippets(snippets)
|
31
|
+
snippets.each { |snippet| snippet.activate(manifest) }
|
32
|
+
save_manifest
|
33
|
+
snippets
|
34
|
+
end
|
35
|
+
|
36
|
+
def uninstall_snippet_named(snippet_name)
|
37
|
+
if snippet = default_bundle.snippet_named(snippet_name)
|
38
|
+
uninstall_snippet(snippet)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def uninstall_snippet(snippet)
|
43
|
+
snippet.deactivate(manifest)
|
44
|
+
snippet.delete
|
45
|
+
save_manifest
|
46
|
+
end
|
47
|
+
|
48
|
+
def install_snippet_bundle(path_to_bundle)
|
49
|
+
Bundle.new(path_to_bundle).copy_to(manifest.snippets_install_path).tap do |bundle|
|
50
|
+
install_snippets(bundle.snippets)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def uninstall_snippet_bundle_named(bundle_name)
|
55
|
+
bundle = Bundle.bundle_named(bundle_name, manifest.snippets_install_path)
|
56
|
+
bundle.snippets.each { |snippet| uninstall_snippet(snippet) }
|
57
|
+
bundle.delete
|
58
|
+
save_manifest
|
59
|
+
end
|
60
|
+
|
61
|
+
def save_manifest
|
62
|
+
manifest.save
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
|
67
|
+
def default_bundle
|
68
|
+
Bundle.default(manifest.snippets_install_path)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/spec/bundle_spec.rb
ADDED
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[spec_helper])
|
2
|
+
|
3
|
+
describe "A bundle" do
|
4
|
+
|
5
|
+
before do
|
6
|
+
example_bundle_path = File.join(FIXTURES_PATH, "Example.snippetbundle")
|
7
|
+
@bundle = XcodeSnippets::Bundle.new(example_bundle_path)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "has a name" do
|
11
|
+
@bundle.name.should == "Example.snippetbundle"
|
12
|
+
end
|
13
|
+
|
14
|
+
it "has a snippet for each codesnippet file in the bundle" do
|
15
|
+
@bundle.should have(2).snippets
|
16
|
+
@bundle.snippets[0].name.should == "snippet-one.codesnippet"
|
17
|
+
@bundle.snippets[1].name.should == "snippet-two.codesnippet"
|
18
|
+
end
|
19
|
+
|
20
|
+
context "adding a snippet" do
|
21
|
+
|
22
|
+
before do
|
23
|
+
example_snippet = File.join(FIXTURES_PATH, "example.codesnippet")
|
24
|
+
@snippet = XcodeSnippets::Snippet.new(example_snippet)
|
25
|
+
@bundle.add_snippet(@snippet)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should increase the number of snippets in the bundle" do
|
29
|
+
@bundle.should have(3).snippets
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should not change the path of the snippet" do
|
33
|
+
@bundle.snippets.last.path.should == @snippet.path
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
context "adding a copy of a snippet" do
|
39
|
+
|
40
|
+
before do
|
41
|
+
example_snippet = File.join(FIXTURES_PATH, "example.codesnippet")
|
42
|
+
@snippet = XcodeSnippets::Snippet.new(example_snippet)
|
43
|
+
@bundle.add_copy_of_snippet(@snippet)
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
if @bundle.snippets.last.name == "example.codesnippet"
|
48
|
+
FileUtils.rm(@bundle.snippets.last.path)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should increase the number of snippets in the bundle" do
|
53
|
+
@bundle.should have(3).snippets
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should copy the snippet into the bundle's directory" do
|
57
|
+
@bundle.snippets.last.path.should_not == @snippet.path
|
58
|
+
@bundle.snippets.last.path.should == File.join(@bundle.path, @snippet.name)
|
59
|
+
@bundle.snippets.last.should exist
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
context "adding a copy of a snippet from a file" do
|
65
|
+
|
66
|
+
before do
|
67
|
+
snippet_file_path = File.join(FIXTURES_PATH, "example.codesnippet")
|
68
|
+
@snippet = @bundle.add_copy_of_snippet_from_file(snippet_file_path)
|
69
|
+
end
|
70
|
+
|
71
|
+
after do
|
72
|
+
if @bundle.snippets.last.name == "example.codesnippet"
|
73
|
+
FileUtils.rm(@bundle.snippets.last.path)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should increase the number of snippets in the bundle" do
|
78
|
+
@bundle.should have(3).snippets
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should copy the snippet into the bundle's directory" do
|
82
|
+
@snippet.path.should == File.join(@bundle.path, @snippet.name)
|
83
|
+
@snippet.should exist
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), *%w[spec_helper])
|
2
|
+
|
3
|
+
describe "SnippetManager" do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
manifest = XcodeSnippets::Manifest.load(SNIPPETS_PATH, XCODE_SNIPPET_PATH, FakeUUIDGenerator)
|
7
|
+
@manager = XcodeSnippets::SnippetManager.new(manifest)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "saves it's manifest to disk" do
|
11
|
+
@manager.save_manifest
|
12
|
+
File.exist?(File.join(SNIPPETS_PATH, "Manifest.plist")).should be_true
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#install_snippet_from_path" do
|
16
|
+
|
17
|
+
before do
|
18
|
+
snippet_path = File.join(FIXTURES_PATH, "example.codesnippet")
|
19
|
+
@snippet = @manager.install_snippet_from_path(snippet_path)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "copies the specified snippet file to it's snippets dir in the default bundle" do
|
23
|
+
expected_path = File.join(SNIPPETS_PATH, "Default.snippetbundle", "example.codesnippet")
|
24
|
+
File.exist?(expected_path).should be_true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "creates a GUID symlink to the installed snippet in the Xcode snippets directory" do
|
28
|
+
symlink = @manager.manifest.symlink_for_snippet(@snippet)
|
29
|
+
File.exist?(symlink).should be_true
|
30
|
+
end
|
31
|
+
|
32
|
+
it "updates it's manifest of installed and activated files" do
|
33
|
+
@manager.manifest.should have_snippet(@snippet)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "#install_snippets_from_paths" do
|
39
|
+
|
40
|
+
before do
|
41
|
+
snippet_path = File.join(FIXTURES_PATH, "example.codesnippet")
|
42
|
+
@snippets = @manager.install_snippets_from_paths([snippet_path])
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns an array of all installed snippets" do
|
46
|
+
@snippets.should have(1).item
|
47
|
+
@snippets.first.should exist
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#uninstall_snippet_named" do
|
53
|
+
|
54
|
+
before do
|
55
|
+
snippet_path = File.join(FIXTURES_PATH, "example.codesnippet")
|
56
|
+
@snippet = @manager.install_snippet_from_path(snippet_path)
|
57
|
+
@symlink = @snippet.symlink
|
58
|
+
@manager.uninstall_snippet_named("example")
|
59
|
+
end
|
60
|
+
|
61
|
+
it "removes the snippet file from the default bundle" do
|
62
|
+
@snippet.should_not exist
|
63
|
+
end
|
64
|
+
|
65
|
+
it "removes it's GUID symlink from the Xcode snippets directory" do
|
66
|
+
File.exist?(@symlink).should be_false
|
67
|
+
end
|
68
|
+
|
69
|
+
it "removes the snippet from the manifest" do
|
70
|
+
@manager.manifest.should_not have_snippet(@snippet)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
describe "#install_snippet_bundle" do
|
76
|
+
|
77
|
+
before do
|
78
|
+
bundle_path = File.join(FIXTURES_PATH, "Example.snippetbundle")
|
79
|
+
@bundle = @manager.install_snippet_bundle(bundle_path)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "creates the snippet bundle in the snippets directory" do
|
83
|
+
expected_path = File.join(SNIPPETS_PATH, "Example.snippetbundle")
|
84
|
+
File.directory?(expected_path).should be_true
|
85
|
+
end
|
86
|
+
|
87
|
+
it "copies all of the bundle's snippets to it's installed location" do
|
88
|
+
expected_path = File.join(SNIPPETS_PATH, "Example.snippetbundle", "snippet-one.codesnippet")
|
89
|
+
File.exist?(expected_path).should be_true
|
90
|
+
end
|
91
|
+
|
92
|
+
it "creates a GUID symlink for each bundle snippet in the Xcode snippets directory" do
|
93
|
+
@bundle.snippets.each do |snippet|
|
94
|
+
symlink = @manager.manifest.symlink_for_snippet(snippet)
|
95
|
+
File.exist?(symlink).should be_true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
it "updates it's manifest of installed and activated files" do
|
100
|
+
@bundle.snippets.each do |snippet|
|
101
|
+
@manager.manifest.should have_snippet(snippet)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#uninstall_snippet_bundle_named" do
|
108
|
+
|
109
|
+
before do
|
110
|
+
bundle_path = File.join(FIXTURES_PATH, "Example.snippetbundle")
|
111
|
+
@bundle = @manager.install_snippet_bundle(bundle_path)
|
112
|
+
@manager.uninstall_snippet_bundle_named("Example")
|
113
|
+
end
|
114
|
+
|
115
|
+
it "removes the snippet bundle from the install path" do
|
116
|
+
@bundle.should_not exist
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__) + '/../lib') unless $:.include?(File.dirname(__FILE__) + '/../lib')
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
require 'ruby-debug'
|
5
|
+
require 'xcode_snippets'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.before(:each) do
|
9
|
+
setup_testing_environment!
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
TMP_PATH = File.join(File.dirname(__FILE__), *%w[.. tmp specs])
|
14
|
+
FIXTURES_PATH = File.join(File.dirname(__FILE__), *%w[.. features support fixtures])
|
15
|
+
XCODE_SNIPPET_PATH = File.join(TMP_PATH, "xcode-snippets")
|
16
|
+
SNIPPETS_PATH = File.join(TMP_PATH, "snippets")
|
17
|
+
|
18
|
+
class FakeUUIDGenerator
|
19
|
+
def self.seed(uuids)
|
20
|
+
@uuids = uuids
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.generate
|
24
|
+
@uuids.pop
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def setup_testing_environment!
|
29
|
+
[SNIPPETS_PATH, XCODE_SNIPPET_PATH].each do |dir|
|
30
|
+
FileUtils.rm_rf(dir) && FileUtils.mkdir_p(dir)
|
31
|
+
end
|
32
|
+
|
33
|
+
# seed the generator with enough UUIDs for testing
|
34
|
+
FakeUUIDGenerator.seed [
|
35
|
+
UUIDTools::UUID.timestamp_create,
|
36
|
+
UUIDTools::UUID.timestamp_create
|
37
|
+
]
|
38
|
+
end
|
metadata
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: xcodesnippets
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Luke Redpath
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-07-18 00:00:00.000000000 +01:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: clamp
|
17
|
+
requirement: &2152335840 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ~>
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 0.2.1
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: *2152335840
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: uuidtools
|
28
|
+
requirement: &2152335260 !ruby/object:Gem::Requirement
|
29
|
+
none: false
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.1.2
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: *2152335260
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: plist
|
39
|
+
requirement: &2152334680 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: 3.1.0
|
45
|
+
type: :runtime
|
46
|
+
prerelease: false
|
47
|
+
version_requirements: *2152334680
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
requirement: &2152334200 !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
type: :development
|
57
|
+
prerelease: false
|
58
|
+
version_requirements: *2152334200
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: cucumber
|
61
|
+
requirement: &2152333660 !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: *2152333660
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: ruby-debug19
|
72
|
+
requirement: &2152333120 !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
type: :development
|
79
|
+
prerelease: false
|
80
|
+
version_requirements: *2152333120
|
81
|
+
description:
|
82
|
+
email: luke@lukeredpath.co.uk
|
83
|
+
executables:
|
84
|
+
- xcodesnippets
|
85
|
+
extensions: []
|
86
|
+
extra_rdoc_files:
|
87
|
+
- README.md
|
88
|
+
files:
|
89
|
+
- LICENSE
|
90
|
+
- README.md
|
91
|
+
- bin/xcodesnippets
|
92
|
+
- spec/bundle_spec.rb
|
93
|
+
- spec/snippet_manager_spec.rb
|
94
|
+
- spec/spec_helper.rb
|
95
|
+
- lib/xcode_snippets/bundle.rb
|
96
|
+
- lib/xcode_snippets/main.rb
|
97
|
+
- lib/xcode_snippets/manifest.rb
|
98
|
+
- lib/xcode_snippets/snippet.rb
|
99
|
+
- lib/xcode_snippets/snippet_manager.rb
|
100
|
+
- lib/xcode_snippets.rb
|
101
|
+
has_rdoc: true
|
102
|
+
homepage: http://lukeredpath.co.uk
|
103
|
+
licenses: []
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options:
|
106
|
+
- --main
|
107
|
+
- README.md
|
108
|
+
require_paths:
|
109
|
+
- lib
|
110
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
111
|
+
none: false
|
112
|
+
requirements:
|
113
|
+
- - ! '>='
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
117
|
+
none: false
|
118
|
+
requirements:
|
119
|
+
- - ! '>='
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '0'
|
122
|
+
requirements: []
|
123
|
+
rubyforge_project:
|
124
|
+
rubygems_version: 1.6.2
|
125
|
+
signing_key:
|
126
|
+
specification_version: 3
|
127
|
+
summary: A command-line utility for managing Xcode 4 code snippets
|
128
|
+
test_files: []
|