jekyll-staging 1.0.0

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: 6020ad38797b56d852844f8db29899e0fbd9ac34
4
+ data.tar.gz: dde6e55d3ebe572ea2051df4c47ed24a14a85379
5
+ SHA512:
6
+ metadata.gz: f0a937a46f74e61e9129eef773355a6e061ad5d1c8e0f79ea5e509612a2744aefc7976e8d6c4743c2a98e494823c96b0d8cd815843902f2cacf56cd4714986a4
7
+ data.tar.gz: bc5cb0143fa852b69340b80839879e26a9a14cb98dbf7654623dcf1d5f6a2dc3a3b7e11436feb505499ef4a64e2a9d1ba255bbb5bb38c512258ade0baa3ff91a
data/.gitignore ADDED
@@ -0,0 +1,34 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /test/tmp/
9
+ /test/version_tmp/
10
+ /tmp/
11
+
12
+ ## Specific to RubyMotion:
13
+ .dat*
14
+ .repl_history
15
+ build/
16
+
17
+ ## Documentation cache and generated files:
18
+ /.yardoc/
19
+ /_yardoc/
20
+ /doc/
21
+ /rdoc/
22
+
23
+ ## Environment normalisation:
24
+ /.bundle/
25
+ /lib/bundler/man/
26
+
27
+ # for a library or gem, you might want to ignore these files since the code is
28
+ # intended to run in multiple environments; otherwise, check them in:
29
+ # Gemfile.lock
30
+ # .ruby-version
31
+ # .ruby-gemset
32
+
33
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.markdown ADDED
@@ -0,0 +1,7 @@
1
+ Creative Commons Attribution-Sharealike
2
+
3
+ http://creativecommons.org/licenses/by-sa/4.0/
4
+
5
+
6
+
7
+ I'd also appreciate hearing from anyone who uses this. Contact info is in the README file.
data/README.markdown ADDED
@@ -0,0 +1,106 @@
1
+ # Jekyll-Staging
2
+
3
+ by [Matt Gemmell](http://mattgemmell.com/)
4
+
5
+
6
+ ## What is it?
7
+
8
+ It's a Ruby gem that stages and unstages draft posts for Jekyll's internal server.
9
+
10
+
11
+ ## What are its requirements?
12
+
13
+ All you need is Ruby. Grab it by running `gem install jekyll-staging` in your terminal.
14
+
15
+
16
+ ## What does it do?
17
+
18
+ This script is for people who:
19
+
20
+ 1. Use [Jekyll](http://jekyllrb.com) to build their static sites.
21
+
22
+ 2. Keep their drafts _outside_ of Jekyll's folder structure.
23
+
24
+ 3. Like to work on posts using Jekyll's built-in web server.
25
+
26
+ If you have a lot of posts, Jekyll's rebuild process can take a while, so it can be handy to temporarily move all of your existing posts aside while you work on a draft. That's what this script does.
27
+
28
+ It lets you specify a given draft post, and it'll move it into Jekyll's folder structure (appropriately prefixing its filename with today's date). Then, it moves all other posts aside temporarily. That way, Jekyll's build and regeneration process will be super-fast while you're working on the draft.
29
+
30
+ It can also reverse the process when you're done, of course, putting the draft back into your drafts folder and restoring all your existing posts.
31
+
32
+ Note: It's assumed that your drafts' filenames _don't_ already have date-prefixes. Personally, I only add the date-prefixes when I'm ready to publish a new post. I often work on posts for several days, so it's easier that way.
33
+
34
+
35
+ ## How do I use it?
36
+
37
+ First, specify the two appropriate paths in the script's Configuration block, and check that the post file-extension ("markdown" by default) matches your posts and drafts.
38
+
39
+ Then, run the script without any arguments to see usage instructions.
40
+
41
+ Basically:
42
+
43
+ - **`stage FILENAME_GLOB`** stages the first matching draft.
44
+ - **`stage -u`** unstages the first staged post.
45
+ - **`stage -u FILENAME_GLOB`** unstages the first matching staged post.
46
+
47
+ You don't need to specify full paths, because it'll be looking in your drafts folder anyway. Feel free to use partial filenames, and shell glob patterns. If there's more than one match, it'll use the first one, and it'll output the full list of matches as well as the filename it chose.
48
+
49
+ Let's say you had a draft whose filename was `got-a-new-iphone.markdown`. A typical workflow would be:
50
+
51
+ 1. **`stage iphone`** (stage the draft for Jekyll)
52
+
53
+ 2. **`jekyll serve`** (start the built-in web server, changing to your Jekyll directory first)
54
+
55
+ 3. Edit your post as you see fit, and view it in your browser. When you're done, kill Jekyll's web server.
56
+
57
+ 4. **`stage -u`** (unstage the draft, putting it back in your drafts folder)
58
+
59
+ You can then decide whether to publish the post, and build and deploy your site as usual.
60
+
61
+
62
+ ## Where does it temporarily put my other posts?
63
+
64
+ In a directory called "`_stash`", in your Jekyll site's local root directory. The directory will be created if necessary. You can set a configuration option to make it use a different directory, if you want.
65
+
66
+
67
+ ## Should I run it on my server?
68
+
69
+ Nope. I run it on my local machine, and so should you.
70
+
71
+
72
+ ## Who made it?
73
+
74
+ Matt Gemmell (that's me).
75
+
76
+ - My website is at [mattgemmell.com](http://mattgemmell.com)
77
+
78
+ - I'm on Twitter as [@mattgemmell](http://twitter.com/mattgemmell)
79
+
80
+ - This code is on github at [github.com/mattgemmell/Jekyll-Staging](http://github.com/mattgemmell/Jekyll-Staging)
81
+
82
+
83
+ ## What license is the code released under?
84
+
85
+ Creative Commons [Attribution-Sharealike](http://creativecommons.org/licenses/by-sa/4.0/).
86
+
87
+
88
+ ## Can you provide support?
89
+
90
+ Nope. If you find a bug, please fix it and [submit a pull request on github](https://github.com/mattgemmell/Jekyll-Staging/pulls).
91
+
92
+
93
+ ## I have a feature request or bug report.
94
+
95
+ Please [create an issue on github](https://github.com/mattgemmell/Jekyll-Staging/issues).
96
+
97
+
98
+ ## How can I thank you?
99
+
100
+ You can:
101
+
102
+ - [Support my writing](https://www.patreon.com/mattgemmell).
103
+
104
+ - Check out [my Amazon wishlist](http://www.amazon.co.uk/registry/wishlist/1BGIQ6Z8GT06F).
105
+
106
+ - Say thanks [on Twitter](http://twitter.com/mattgemmell).
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/stage ADDED
@@ -0,0 +1,307 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Staging/unstaging script for Jekyll blog posts.
4
+ #
5
+ # by Matt Gemmell
6
+ #
7
+ # Web: http://mattgemmell.com
8
+ # Twitter: http://twitter.com/mattgemmell
9
+
10
+
11
+ # This script moves a specified draft post into Jekyll's folder structure,
12
+ # and temporarily stashes all other posts so the site will build quickly.
13
+ #
14
+ # This is for people who keep their drafts outside of Jekyll's folder structure.
15
+ #
16
+ # It can also reverse the process when you're done, of course.
17
+ #
18
+ # This is useful when you're working on a post using Jekyll's server.
19
+
20
+
21
+ # Requirements: just Ruby itself.
22
+
23
+
24
+ # Usage: Run the script with no arguments to see usage instructions.
25
+
26
+
27
+ # License: CC Attribution-ShareAlike
28
+ # http://creativecommons.org/licenses/by-sa/4.0/
29
+
30
+
31
+ # ========================================
32
+ # Configuration
33
+ # ========================================
34
+
35
+ # Load in configuration file, or ask and populate.
36
+ def read_or_ask_for_configuration
37
+ require 'yaml'
38
+ conf_file = File.join(ENV['HOME'], '.jekyll-stagingrc')
39
+ if File.exist?(conf_file)
40
+ YAML.load_file(conf_file)
41
+ else
42
+ conf = {}
43
+ print "Where is your Jekyll site located? (full path, '~' is ok) "
44
+ conf['jekyll_root'] = STDIN.gets
45
+ print "Where are your drafts located? (full path, '~' is ok) "
46
+ conf['drafts_dir'] = STDIN.gets
47
+ print "What file extension do you use for your drafts and posts? (no period) "
48
+ conf['file_extension'] = STDIN.gets
49
+ File.open(conf_file, 'wb') { |f| f.write(YAML.dump(conf)) }
50
+ conf
51
+ end
52
+ end
53
+
54
+
55
+ configuration = read_or_ask_for_configuration
56
+
57
+ # Your Jekyll site's local root directory (it has the "_config.yml" file in it).
58
+ $jekyll_root = configuration['jekyll_root']
59
+
60
+ # Wherever you keep your local in-progress drafts, outside of your Jekyll site.
61
+ $drafts_dir = configuration['drafts_dir']
62
+
63
+ # File-extension for your drafts and post files.
64
+ $file_extension = configuration['file_extension']
65
+
66
+ # Note: It's assumed that your drafts' filenames DON'T have date-prefixes.
67
+
68
+
69
+ # ========================================
70
+ # You probably DON'T need to touch anything below here!
71
+ # ========================================
72
+
73
+
74
+ # Other directories within Jekyll's root. The defaults should be fine.
75
+ $posts_dir_name = "_posts" # Should already be in the root directory.
76
+ $stash_dir_name = "_stash" # Will be created if necessary.
77
+
78
+ # Filename details for posts. The defaults should be fine.
79
+ $file_date_prefix_format = "%Y\-%m\-%d\-" # for Ruby's DateTime strftime
80
+ $file_date_prefix_regexp = /\d+-\d+-\d+-/ # regexp to match date format above
81
+
82
+
83
+ # === Start of functions ===
84
+
85
+
86
+ def first_matching_file_in_dir(the_filename_glob, the_dir_path)
87
+ Dir.chdir(the_dir_path)
88
+ matches = Dir.glob(the_filename_glob)
89
+ if matches.count == 0
90
+ puts "No matches found in #{the_dir_path}."
91
+ return false
92
+ elsif matches.count > 1
93
+ puts "Found #{matches.count} matching files (#{matches.join(", ")})"
94
+ end
95
+
96
+ filename = matches[0]
97
+ puts "Using file \"#{filename}\"."
98
+ return filename
99
+ end
100
+
101
+
102
+ def directory_exists(the_dir_path)
103
+ # Check for a directory at path.
104
+
105
+ if File.exist?(the_dir_path)
106
+ # Something's there. Check if it's a directory.
107
+ #puts "Found something at given path."
108
+ if File.directory?(the_dir_path)
109
+ # It exists, and it's a directory. We're done.
110
+ #puts "It's a directory."
111
+ return true
112
+ else
113
+ # Abort
114
+ #puts "It's not a directory"
115
+ end
116
+ end
117
+
118
+ return false
119
+ end
120
+
121
+
122
+ def create_dir_if_necessary(the_dir_path)
123
+ # Check for a directory at path, creating it if necessary.
124
+
125
+ # Check to see if an item exists at that path.
126
+ if directory_exists(the_dir_path)
127
+ return true
128
+ else
129
+ # It doesn't exist. Create it.
130
+ #puts "Nothing found at given path."
131
+ begin
132
+ Dir.mkdir(the_dir_path, 0755)
133
+ #puts "Created the directory: #{the_dir_path}"
134
+ return true
135
+ rescue SystemCallError
136
+ # If we failed to create the directory, abort.
137
+ #puts "Failed to create the directory."
138
+ return false
139
+ end
140
+ end
141
+
142
+ return false
143
+ end
144
+
145
+
146
+ def isolate(the_filename_glob)
147
+ # Moves all files from posts to stash, except those matching the glob.
148
+
149
+ # Move all files from posts into stash.
150
+ cmd = "mv #{$posts_dir}/*.#{$file_extension} #{$stash_dir}/"
151
+ result = `#{cmd}`
152
+
153
+ # Move the matching files back into posts.
154
+ cmd = "mv #{$stash_dir}/*#{the_filename_glob}* #{$posts_dir}/"
155
+ result = `#{cmd}`
156
+ end
157
+
158
+
159
+ def integrate()
160
+ # Moves all files from stash back into posts.
161
+
162
+ # Move all files from stash into posts.
163
+ cmd = "mv #{$stash_dir}/*.#{$file_extension} #{$posts_dir}/"
164
+ result = `#{cmd}`
165
+ end
166
+
167
+
168
+ def stage_file(the_filename_glob)
169
+ # Stages the given file.
170
+
171
+ puts "Staging \"#{the_filename_glob}\"…"
172
+
173
+ # Grab specified file (glob) from drafts folder.
174
+ full_glob = "*#{the_filename_glob}*.#{$file_extension}"
175
+ filename = first_matching_file_in_dir(full_glob, $drafts_dir)
176
+ if filename == false
177
+ puts "Couldn't find a file to stage. Aborting."
178
+ exit
179
+ end
180
+
181
+ # Move file to posts directory, prefixing its filename with today's date.
182
+ require "Date"
183
+ today = DateTime.now()
184
+ prefix = today.strftime($file_date_prefix_format)
185
+ new_filename = "#{prefix}#{filename}"
186
+
187
+ cmd = "mv #{$drafts_dir}/#{filename} #{$posts_dir}/#{new_filename}"
188
+ result = `#{cmd}`
189
+
190
+ # Isolate the staged file in posts, moving all other posts to stash.
191
+ isolate(new_filename)
192
+
193
+ puts "File staged as \"#{new_filename}\"."
194
+ end
195
+
196
+
197
+ def unstage_file(the_filename_glob)
198
+ # Unstages the given file, or the first staged file if none is specified.
199
+
200
+ if (the_filename_glob)
201
+ puts "Unstaging \"#{the_filename_glob}\"…"
202
+ else
203
+ puts "Unstaging first staged file…"
204
+ end
205
+
206
+ # Grab specified file (glob) from posts folder.
207
+ if (the_filename_glob)
208
+ full_glob = "*#{the_filename_glob}*.#{$file_extension}"
209
+ else
210
+ full_glob = "*.#{$file_extension}"
211
+ end
212
+ filename = first_matching_file_in_dir(full_glob, $posts_dir)
213
+ if filename == false
214
+ puts "Couldn't find a file to unstage. Aborting."
215
+ exit
216
+ end
217
+
218
+ # Move file to drafts directory, removing date from its filename.
219
+ new_filename = filename.sub($file_date_prefix_regexp, "")
220
+
221
+ cmd = "mv #{$posts_dir}/#{filename} #{$drafts_dir}/#{new_filename}"
222
+ result = `#{cmd}`
223
+
224
+ # Move all stashed files back into posts.
225
+ integrate()
226
+
227
+ puts "Unstaging complete."
228
+ end
229
+
230
+
231
+ def show_help()
232
+ puts "`#{$0} FILENAME_GLOB` stages the first matching draft."
233
+ puts "`#{$0} #{$unstage_flag}` unstages the first staged post."
234
+ puts "`#{$0} #{$unstage_flag} FILENAME_GLOB` unstages the first matching staged post."
235
+ end
236
+
237
+
238
+ # === End of functions ===
239
+
240
+
241
+ # Handle input
242
+ $unstage_flag = "-u" # flag passed to the script to request unstaging
243
+ filename_glob = nil
244
+ unstage = false
245
+
246
+ if ARGV.count == 0
247
+ puts "No filename or arguments specified."
248
+ show_help()
249
+ exit
250
+ elsif ARGV.count == 1
251
+ if ARGV[0] == $unstage_flag
252
+ # This is the "unstage" flag without a filename.
253
+ unstage = true
254
+ else
255
+ # This is the "stage" command with a filename.
256
+ filename_glob = ARGV[0]
257
+ end
258
+ elsif ARGV.count == 2
259
+ # If there are two arguments, the second one is the filename.
260
+ filename_glob = ARGV[1]
261
+ if ARGV[0] == $unstage_flag
262
+ unstage = true
263
+ else
264
+ puts "Input not recognised."
265
+ show_help()
266
+ exit
267
+ end
268
+ end
269
+
270
+ # All paths MUST be expanded before we begin.
271
+ $drafts_dir = File.expand_path($drafts_dir)
272
+ $jekyll_root = File.expand_path($jekyll_root)
273
+ $stash_dir = "#{$jekyll_root}/#{$stash_dir_name}"
274
+ $posts_dir = "#{$jekyll_root}/#{$posts_dir_name}"
275
+
276
+ # Check that drafts, root, and posts directories exist.
277
+ if directory_exists($drafts_dir) == false
278
+ puts "Drafts directory doesn't exist: #{$drafts_dir}"
279
+ exit
280
+ end
281
+ if directory_exists($jekyll_root) == false
282
+ puts "Jekyll root directory doesn't exist: #{$jekyll_root}"
283
+ exit
284
+ end
285
+ if directory_exists($posts_dir) == false
286
+ puts "Jekyll posts directory doesn't exist: #{$posts_dir}"
287
+ exit
288
+ end
289
+
290
+ # Ensure stash_dir exists, creating it if necessary.
291
+ if directory_exists($stash_dir) == false
292
+ if create_dir_if_necessary($stash_dir) == false
293
+ # Something went wrong. Abort.
294
+ puts "Couldn't create stash directory: #{$stash_dir}"
295
+ puts "Aborting."
296
+ exit
297
+ else
298
+ puts "Created stash directory: #{$stash_dir}"
299
+ end
300
+ end
301
+
302
+ # Get the job done. It's a bit anticlimactic, really.
303
+ if unstage
304
+ unstage_file(filename_glob)
305
+ else
306
+ stage_file(filename_glob)
307
+ end
@@ -0,0 +1,18 @@
1
+ # coding: utf-8
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "jekyll-staging"
5
+ spec.version = "1.0.0"
6
+ spec.authors = ["Matt Gemmell"]
7
+ spec.email = ["matt@mattgemmell.com"]
8
+ spec.summary = %q{Stage and unstage draft posts in Jekyll.}
9
+ spec.homepage = "https://github.com/mattgemmell/Jekyll-Staging"
10
+ spec.license = "MIT"
11
+
12
+ spec.files = `git ls-files -z`.split("\x0")
13
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
14
+ spec.require_paths = ["lib"]
15
+
16
+ spec.add_development_dependency "bundler", "~> 1.7"
17
+ spec.add_development_dependency "rake", "~> 10.0"
18
+ end
metadata ADDED
@@ -0,0 +1,80 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jekyll-staging
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Matt Gemmell
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ description:
42
+ email:
43
+ - matt@mattgemmell.com
44
+ executables:
45
+ - stage
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Gemfile
51
+ - LICENSE.markdown
52
+ - README.markdown
53
+ - Rakefile
54
+ - bin/stage
55
+ - jekyll-staging.gemspec
56
+ homepage: https://github.com/mattgemmell/Jekyll-Staging
57
+ licenses:
58
+ - MIT
59
+ metadata: {}
60
+ post_install_message:
61
+ rdoc_options: []
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - '>='
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ requirements: []
75
+ rubyforge_project:
76
+ rubygems_version: 2.0.14
77
+ signing_key:
78
+ specification_version: 4
79
+ summary: Stage and unstage draft posts in Jekyll.
80
+ test_files: []