postwave 0.0.1
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 +7 -0
- data/.gitignore +1 -0
- data/Gemfile +4 -0
- data/README.md +108 -0
- data/Rakefile +10 -0
- data/bin/postwave +44 -0
- data/lib/postwave/blog_builder.rb +105 -0
- data/lib/postwave/blog_creator.rb +49 -0
- data/lib/postwave/blog_utilities.rb +40 -0
- data/lib/postwave/display_helper.rb +80 -0
- data/lib/postwave/post.rb +89 -0
- data/lib/postwave/post_creator.rb +40 -0
- data/lib/postwave/version.rb +3 -0
- data/lib/postwave.rb +21 -0
- data/postwave.gemspec +25 -0
- metadata +86 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f460f1e6202c2d56b2c355266fd8819691cdb2a8f12b6aa33febd8a0c6b5d580
|
4
|
+
data.tar.gz: 5159c6aa7c213bfff6ec6f1a2f3fdb8c4f1ef8f03dbe9ff5014b93709ee8c625
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5102d693e92f76288dbdf152f00cfdf6a386e0b4a27bb4415ba8baccdd13d64b04e624f136bb993046bf7b71facbf5d78848716aa8c146abe6a1f9d006b91282
|
7
|
+
data.tar.gz: cfbb408e719c8a56e54ef81614ae5e7a7a362e1b3f7f863e4e462d449dfab3188beca5e4536fe13381097c1eb14d8b43842c9108d5429f44909aaf87a765961a
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# Postwave 🌊
|
2
|
+
|
3
|
+
Write your posts statically. Interact with them dynamically.
|
4
|
+
|
5
|
+
## What is Postwave?
|
6
|
+
|
7
|
+
Postwave is an opinionated flat-file based based blog engine.
|
8
|
+
|
9
|
+
It lets you write posts in Markdown and then display them on a dynamic site using a client library.
|
10
|
+
|
11
|
+
## Getting Started
|
12
|
+
|
13
|
+
### Installation
|
14
|
+
|
15
|
+
```
|
16
|
+
gem install postwave
|
17
|
+
```
|
18
|
+
|
19
|
+
### Setup
|
20
|
+
|
21
|
+
```
|
22
|
+
> postwave new
|
23
|
+
```
|
24
|
+
|
25
|
+
Run this from the root directory of your project. It will create a `postwave.yaml` config file in the current directory and a `/_posts/` directory. This is where you will write your posts.
|
26
|
+
|
27
|
+
Here is what will be created:
|
28
|
+
|
29
|
+
```
|
30
|
+
|- _posts/
|
31
|
+
| |- meta/
|
32
|
+
| |- tags/
|
33
|
+
| |- index.csv
|
34
|
+
| |- summary.yaml
|
35
|
+
postwave.yaml
|
36
|
+
```
|
37
|
+
|
38
|
+
`_posts/`: This is where you write all your posts in Markdown
|
39
|
+
|
40
|
+
`_posts/meta/tags/`: This will contain files for every tag your define in your posts
|
41
|
+
|
42
|
+
`_posts/meta/index.csv`: This will contain an ordered list of all the posts
|
43
|
+
|
44
|
+
`_posts/meta/summary.yaml`: This file will contain some summary information about the posts. Total count, etc.
|
45
|
+
|
46
|
+
`postwave.yaml`: The config file for Postwave.
|
47
|
+
|
48
|
+
### Create A New Blog Post
|
49
|
+
|
50
|
+
```
|
51
|
+
> postwave post
|
52
|
+
```
|
53
|
+
|
54
|
+
This will generate at new Markdown file in the `_posts/` directory. The filename will be the current timestamp. This will eventually be overwritten by the `build` command, so don't worry too much about it. The file will have a general structure like this:
|
55
|
+
|
56
|
+
```
|
57
|
+
---
|
58
|
+
title:
|
59
|
+
date: 2022-01-01
|
60
|
+
tags:
|
61
|
+
---
|
62
|
+
|
63
|
+
Start writing!
|
64
|
+
```
|
65
|
+
Tags should be comma separated.
|
66
|
+
|
67
|
+
You can keep a post in "draft" status (meaning it won't get processed or added to the index) by adding `draft: true` to the top section of the post.
|
68
|
+
|
69
|
+
```
|
70
|
+
---
|
71
|
+
title: This Post Isn't Quite Ready
|
72
|
+
date: 2022-01-01
|
73
|
+
tags:
|
74
|
+
draft: true
|
75
|
+
---
|
76
|
+
```
|
77
|
+
|
78
|
+
### Build the Blog
|
79
|
+
|
80
|
+
```
|
81
|
+
> postwave build
|
82
|
+
```
|
83
|
+
|
84
|
+
This will "build" the blog. This involves:
|
85
|
+
- regenerating the `index.csv` file
|
86
|
+
- generating slugs for each posts based on the post title and ensuring that there are no duplicate slugs
|
87
|
+
- changing the post file names to match `yyyy-dd-mm-slug.md`
|
88
|
+
- updating the `summary.yaml`
|
89
|
+
- creating and updating tag files (which will be `/tags/[tag-name].yaml` files for each tag)
|
90
|
+
|
91
|
+
## Available Client Libraries
|
92
|
+
|
93
|
+
- [Ruby](https://github.com/dorkrawk/postwave-ruby-client)
|
94
|
+
|
95
|
+
## What is Postwave Not?
|
96
|
+
|
97
|
+
Postwave is not for everything.
|
98
|
+
|
99
|
+
It is not:
|
100
|
+
- for people who want to generate a purely static site
|
101
|
+
- for people who want unlimited customization
|
102
|
+
- for giant blogs with many many thousands of posts (maybe?)
|
103
|
+
|
104
|
+
## Why did you build another blogging tool?
|
105
|
+
|
106
|
+
I don't know. I probably like writing blog engines more than I like writing blog posts.
|
107
|
+
|
108
|
+
I wanted something that would let me writing simple Markdown posts but still let me just embed the index and post content into a custom dynamic site. This scratched an itch and seemed like it would be fun to build.
|
data/Rakefile
ADDED
data/bin/postwave
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require_relative '../lib/postwave'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
|
8
|
+
subtext = <<HELP
|
9
|
+
Commands:
|
10
|
+
new : creates new Postwave project in the current directory
|
11
|
+
post : creates a new post in the /_posts/ directory
|
12
|
+
build : builds the posts and meta information for the blog
|
13
|
+
See 'postwave COMMAND --help' for more information on a specific command.
|
14
|
+
HELP
|
15
|
+
|
16
|
+
global = OptionParser.new do |opts|
|
17
|
+
opts.banner = "Usage: postwave [options] [command]"
|
18
|
+
opts.on '-v', '--version', 'Show version' do |v|
|
19
|
+
options[:version] = v
|
20
|
+
end
|
21
|
+
opts.separator ""
|
22
|
+
opts.separator subtext
|
23
|
+
end
|
24
|
+
|
25
|
+
subcommands = {
|
26
|
+
'new' => OptionParser.new do |opts|
|
27
|
+
opts.banner = "Usage: new"
|
28
|
+
end,
|
29
|
+
'post' => OptionParser.new do |opts|
|
30
|
+
opts.banner = "Usage: post"
|
31
|
+
end,
|
32
|
+
'build' => OptionParser.new do |opts|
|
33
|
+
opts.banner = "Usage: build [options]"
|
34
|
+
opts.on("-q", "--quiet", "quietly run ") do |v|
|
35
|
+
options[:quiet] = v
|
36
|
+
end
|
37
|
+
end
|
38
|
+
}
|
39
|
+
|
40
|
+
global.order!
|
41
|
+
command = ARGV.shift
|
42
|
+
subcommands[command].order! if command
|
43
|
+
|
44
|
+
Postwave.call(command, options)
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "yaml"
|
3
|
+
require "singleton"
|
4
|
+
require 'csv'
|
5
|
+
require 'time'
|
6
|
+
require_relative "blog_utilities"
|
7
|
+
require_relative "display_helper"
|
8
|
+
require_relative "post"
|
9
|
+
|
10
|
+
module Postwave
|
11
|
+
class BlogBuilder
|
12
|
+
include Singleton
|
13
|
+
include BlogUtilities
|
14
|
+
include DisplayHelper
|
15
|
+
|
16
|
+
INDEX_HEADERS = ["slug", "date", "title"]
|
17
|
+
|
18
|
+
def build
|
19
|
+
start = Time.now
|
20
|
+
|
21
|
+
output_building
|
22
|
+
|
23
|
+
if !is_set_up?
|
24
|
+
output_missing_setup
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
# load, rename, and sort post file names
|
29
|
+
posts = load_posts
|
30
|
+
posts = ensure_unique_slugs(posts).sort_by { |p| p.date }.reverse
|
31
|
+
draft_posts, published_posts = posts.partition { |p| p.respond_to?(:draft) ? p.draft : false }
|
32
|
+
tags = {}
|
33
|
+
|
34
|
+
CSV.open(File.join(Dir.pwd, POSTS_DIR, META_DIR, INDEX_FILE_NAME), "w") do |csv|
|
35
|
+
csv << INDEX_HEADERS
|
36
|
+
published_posts.each do |post|
|
37
|
+
post.update_file_name!
|
38
|
+
|
39
|
+
csv << [post.slug, post.date, post.title]
|
40
|
+
|
41
|
+
post.tags.each do |tag|
|
42
|
+
if tags.has_key? tag
|
43
|
+
tags[tag] << post.slug
|
44
|
+
else
|
45
|
+
tags[tag] = [post.slug]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
output_post_processed(published_posts)
|
51
|
+
output_drafts_skipped(draft_posts)
|
52
|
+
|
53
|
+
build_tags_files(tags)
|
54
|
+
build_summary(published_posts, tags)
|
55
|
+
|
56
|
+
build_time = Time.now - start
|
57
|
+
output_build_completed(build_time)
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_posts
|
61
|
+
posts = []
|
62
|
+
Dir.glob(File.join(Dir.pwd, POSTS_DIR, "*.md")) do |post_file_path|
|
63
|
+
posts << Postwave::Post.new_from_file_path(post_file_path)
|
64
|
+
end
|
65
|
+
posts
|
66
|
+
end
|
67
|
+
|
68
|
+
def ensure_unique_slugs(posts)
|
69
|
+
slug_count = {}
|
70
|
+
|
71
|
+
posts.sort_by { |p| p.date }.each do |post|
|
72
|
+
title_slug = post.title_slug
|
73
|
+
if slug_count.key?(title_slug)
|
74
|
+
slug_count[title_slug] += 1
|
75
|
+
post.slug = "#{title_slug}-#{slug_count[title_slug]}"
|
76
|
+
else
|
77
|
+
slug_count[title_slug] = 0
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
posts
|
82
|
+
end
|
83
|
+
|
84
|
+
def build_tags_files(tags)
|
85
|
+
tags.each do |tag, post_slugs|
|
86
|
+
tag_info = {
|
87
|
+
count: post_slugs.count,
|
88
|
+
post_slugs: post_slugs
|
89
|
+
}
|
90
|
+
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, TAGS_DIR, "#{tag}.yaml"), tag_info.to_yaml)
|
91
|
+
end
|
92
|
+
output_tags_created(tags)
|
93
|
+
end
|
94
|
+
|
95
|
+
def build_summary(posts, tags)
|
96
|
+
summary = {
|
97
|
+
post_count: posts.count,
|
98
|
+
most_recent_file_name: posts.first.file_name,
|
99
|
+
most_recent_date: posts.first.date,
|
100
|
+
tags: tags.keys
|
101
|
+
}
|
102
|
+
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME), summary.to_yaml)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "yaml"
|
3
|
+
require "singleton"
|
4
|
+
require_relative "blog_utilities"
|
5
|
+
require_relative "display_helper"
|
6
|
+
|
7
|
+
module Postwave
|
8
|
+
class BlogCreator
|
9
|
+
include Singleton
|
10
|
+
include BlogUtilities
|
11
|
+
include DisplayHelper
|
12
|
+
|
13
|
+
def create
|
14
|
+
output_creating_blog
|
15
|
+
|
16
|
+
if is_set_up?
|
17
|
+
output_exising_setup
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
build_directories
|
22
|
+
build_files
|
23
|
+
write_initial_summary_contents
|
24
|
+
|
25
|
+
output_blog_created
|
26
|
+
end
|
27
|
+
|
28
|
+
def build_directories
|
29
|
+
directory_paths.each do |path|
|
30
|
+
FileUtils.mkdir_p(path)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_files
|
35
|
+
file_paths.each do |path|
|
36
|
+
FileUtils.touch(path)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def write_initial_summary_contents
|
41
|
+
summary = {
|
42
|
+
post_count: 0,
|
43
|
+
tags: []
|
44
|
+
}
|
45
|
+
|
46
|
+
File.write(File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME), summary.to_yaml)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Postwave
|
2
|
+
module BlogUtilities
|
3
|
+
CONFIG_FILE_NAME = "postwave.yaml"
|
4
|
+
INDEX_FILE_NAME = "index.csv"
|
5
|
+
SUMMARY_FILE_NAME = "summary.yaml"
|
6
|
+
POSTS_DIR = "_posts"
|
7
|
+
META_DIR = "meta"
|
8
|
+
TAGS_DIR = "tags"
|
9
|
+
|
10
|
+
def is_set_up?
|
11
|
+
missing_paths = find_missing_paths
|
12
|
+
missing_paths.empty?
|
13
|
+
end
|
14
|
+
|
15
|
+
def file_paths
|
16
|
+
[
|
17
|
+
File.join(Dir.pwd, CONFIG_FILE_NAME),
|
18
|
+
File.join(Dir.pwd, POSTS_DIR, META_DIR, INDEX_FILE_NAME),
|
19
|
+
File.join(Dir.pwd, POSTS_DIR, META_DIR, SUMMARY_FILE_NAME),
|
20
|
+
]
|
21
|
+
end
|
22
|
+
|
23
|
+
def directory_paths
|
24
|
+
[
|
25
|
+
File.join(Dir.pwd, POSTS_DIR),
|
26
|
+
File.join(Dir.pwd, POSTS_DIR, META_DIR),
|
27
|
+
File.join(Dir.pwd, POSTS_DIR, META_DIR, TAGS_DIR),
|
28
|
+
]
|
29
|
+
end
|
30
|
+
|
31
|
+
def find_missing_paths
|
32
|
+
paths_to_check = directory_paths + file_paths
|
33
|
+
missing_paths = []
|
34
|
+
paths_to_check.each do |path|
|
35
|
+
missing_paths << path if !FileTest.exists?(path)
|
36
|
+
end
|
37
|
+
missing_paths
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module Postwave
|
2
|
+
module DisplayHelper
|
3
|
+
|
4
|
+
# new
|
5
|
+
|
6
|
+
def output_creating_blog
|
7
|
+
puts "🌊 Creating new blog..."
|
8
|
+
end
|
9
|
+
|
10
|
+
def output_blog_created
|
11
|
+
puts "New blog set up.".green
|
12
|
+
end
|
13
|
+
|
14
|
+
# post
|
15
|
+
|
16
|
+
def output_creating_post
|
17
|
+
puts "🌊 Creating new post..."
|
18
|
+
end
|
19
|
+
|
20
|
+
def output_post_created(post_path)
|
21
|
+
puts "New post created at: #{post_path}".green
|
22
|
+
end
|
23
|
+
|
24
|
+
# build
|
25
|
+
|
26
|
+
def output_building
|
27
|
+
puts "🌊 Building..."
|
28
|
+
end
|
29
|
+
|
30
|
+
def output_post_processed(posts)
|
31
|
+
count = posts.count
|
32
|
+
puts "Processed #{count} #{simple_pluralizer("post", count)}."
|
33
|
+
end
|
34
|
+
|
35
|
+
def output_drafts_skipped(drafts)
|
36
|
+
if drafts.any?
|
37
|
+
count = drafts.count
|
38
|
+
puts "Skipped #{count} #{simple_pluralizer("draft", count)}."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def output_tags_created(tags)
|
43
|
+
count = tags.count
|
44
|
+
puts "Built tag files for #{count} #{simple_pluralizer("tag", count)}."
|
45
|
+
end
|
46
|
+
|
47
|
+
def output_build_completed(build_time)
|
48
|
+
puts "Built succesfully in #{build_time} seconds.".green
|
49
|
+
end
|
50
|
+
|
51
|
+
# errors
|
52
|
+
|
53
|
+
def output_exising_setup
|
54
|
+
puts "A blog already exists in this location.".red
|
55
|
+
end
|
56
|
+
|
57
|
+
def output_missing_setup
|
58
|
+
puts "You need to set up a blog first.".red
|
59
|
+
end
|
60
|
+
|
61
|
+
def output_general_error
|
62
|
+
puts "Something went wrong.".red
|
63
|
+
end
|
64
|
+
|
65
|
+
private
|
66
|
+
def simple_pluralizer(word, count)
|
67
|
+
if count == 1
|
68
|
+
word
|
69
|
+
else
|
70
|
+
word + "s"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
# 🐒 patch String to add terminal colors
|
77
|
+
class String
|
78
|
+
def red; "\e[31m#{self}\e[0m" end
|
79
|
+
def green; "\e[32m#{self}\e[0m" end
|
80
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require_relative "blog_utilities"
|
2
|
+
|
3
|
+
module Postwave
|
4
|
+
class Post
|
5
|
+
include BlogUtilities
|
6
|
+
|
7
|
+
KNOWN_FIELDS = %w(title date tags title_slug body draft)
|
8
|
+
REQUIRED_FIELDS = %w(title date)
|
9
|
+
MEATADATA_DELIMTER = "---"
|
10
|
+
|
11
|
+
attr_accessor :file_name
|
12
|
+
|
13
|
+
def self.new_from_file_path(path)
|
14
|
+
metadata_delimter_count = 0
|
15
|
+
body_buffer_count = 0
|
16
|
+
field_content = { "body" => "" }
|
17
|
+
|
18
|
+
File.readlines(path).each do |line|
|
19
|
+
clean_line = line.strip
|
20
|
+
if clean_line == MEATADATA_DELIMTER
|
21
|
+
metadata_delimter_count += 1
|
22
|
+
next
|
23
|
+
end
|
24
|
+
|
25
|
+
if metadata_delimter_count == 0
|
26
|
+
next
|
27
|
+
elsif metadata_delimter_count == 1
|
28
|
+
field, value = clean_line.split(":", 2).map(&:strip)
|
29
|
+
field_content[field] = value
|
30
|
+
else
|
31
|
+
if body_buffer_count == 0
|
32
|
+
body_buffer_count += 1
|
33
|
+
next if clean_line.empty?
|
34
|
+
end
|
35
|
+
|
36
|
+
field_content["body"] += "#{line}\n"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# turn "tags" into an array
|
41
|
+
if field_content["tags"]
|
42
|
+
field_content["tags"] = field_content["tags"].split(",").map do |tag|
|
43
|
+
tag.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# turn "draft" into boolean
|
48
|
+
if field_content["draft"]
|
49
|
+
field_content["draft"] = field_content["draft"].downcase == "true"
|
50
|
+
end
|
51
|
+
|
52
|
+
self.new(path, field_content)
|
53
|
+
end
|
54
|
+
|
55
|
+
def initialize(file_name, field_content = {})
|
56
|
+
@file_name = file_name
|
57
|
+
|
58
|
+
field_content.each do |field, value|
|
59
|
+
instance_variable_set("@#{field}", value)
|
60
|
+
self.class.send(:attr_accessor, field)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def title_slug
|
65
|
+
@title_slug ||= @title.downcase.strip.gsub(' ', '-').gsub(/[^\w-]/, '')
|
66
|
+
end
|
67
|
+
|
68
|
+
def slug
|
69
|
+
@slug ||= @title_slug
|
70
|
+
end
|
71
|
+
|
72
|
+
def slug=(new_slug)
|
73
|
+
@slug = new_slug
|
74
|
+
end
|
75
|
+
|
76
|
+
def generated_file_name
|
77
|
+
# YYYY-MM-DD-slug-from-title.md
|
78
|
+
"#{@date[..9]}-#{slug}.md"
|
79
|
+
end
|
80
|
+
|
81
|
+
def update_file_name!
|
82
|
+
desired_file_name = generated_file_name
|
83
|
+
return false if @file_name == desired_file_name
|
84
|
+
|
85
|
+
File.rename(@file_name, File.join(Dir.pwd, POSTS_DIR, desired_file_name))
|
86
|
+
@file_name = desired_file_name
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "singleton"
|
3
|
+
require_relative "blog_utilities"
|
4
|
+
require_relative "display_helper"
|
5
|
+
|
6
|
+
|
7
|
+
module Postwave
|
8
|
+
class PostCreator
|
9
|
+
include Singleton
|
10
|
+
include BlogUtilities
|
11
|
+
include DisplayHelper
|
12
|
+
|
13
|
+
def create
|
14
|
+
output_creating_post
|
15
|
+
|
16
|
+
if !is_set_up?
|
17
|
+
output_missing_setup
|
18
|
+
return
|
19
|
+
end
|
20
|
+
|
21
|
+
now = Time.now
|
22
|
+
post_file_name = "#{now.to_i}.md"
|
23
|
+
|
24
|
+
initial_content = <<~CONTENT
|
25
|
+
---
|
26
|
+
title: #{(0...8).map { (65 + rand(26)).chr }.join}
|
27
|
+
date: #{now.strftime("%F %R")}
|
28
|
+
tags:
|
29
|
+
---
|
30
|
+
|
31
|
+
Start writing!
|
32
|
+
CONTENT
|
33
|
+
|
34
|
+
|
35
|
+
File.write(File.join(Dir.pwd, POSTS_DIR, post_file_name), initial_content)
|
36
|
+
|
37
|
+
output_post_created(File.join(POSTS_DIR, post_file_name))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/postwave.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require_relative "postwave/blog_creator"
|
2
|
+
require_relative "postwave/blog_builder"
|
3
|
+
require_relative "postwave/post_creator"
|
4
|
+
require_relative "postwave/version"
|
5
|
+
|
6
|
+
module Postwave
|
7
|
+
def self.call(command, options)
|
8
|
+
case command
|
9
|
+
when "new"
|
10
|
+
Postwave::BlogCreator.instance.create
|
11
|
+
when "post"
|
12
|
+
Postwave::PostCreator.instance.create
|
13
|
+
when "build"
|
14
|
+
Postwave::BlogBuilder.instance.build
|
15
|
+
else
|
16
|
+
if options[:version]
|
17
|
+
puts "postwave #{VERSION} [ruby]"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/postwave.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'postwave/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "postwave"
|
8
|
+
spec.version = Postwave::VERSION
|
9
|
+
spec.authors = ["Dave Schwantes"]
|
10
|
+
spec.email = ["dave.schwantes@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "An opinionated flatfile based blog engine."
|
13
|
+
spec.description = "Write your posts statically. Interact with them dynamically."
|
14
|
+
spec.homepage = "https://github.com/dorkrawk/postwave"
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.executables = ['postwave']
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# spec.add_dependency ""
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler"
|
24
|
+
spec.add_development_dependency "rake", "~> 12.3"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: postwave
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dave Schwantes
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-09-15 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: '0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '12.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '12.3'
|
41
|
+
description: Write your posts statically. Interact with them dynamically.
|
42
|
+
email:
|
43
|
+
- dave.schwantes@gmail.com
|
44
|
+
executables:
|
45
|
+
- postwave
|
46
|
+
extensions: []
|
47
|
+
extra_rdoc_files: []
|
48
|
+
files:
|
49
|
+
- ".gitignore"
|
50
|
+
- Gemfile
|
51
|
+
- README.md
|
52
|
+
- Rakefile
|
53
|
+
- bin/postwave
|
54
|
+
- lib/postwave.rb
|
55
|
+
- lib/postwave/blog_builder.rb
|
56
|
+
- lib/postwave/blog_creator.rb
|
57
|
+
- lib/postwave/blog_utilities.rb
|
58
|
+
- lib/postwave/display_helper.rb
|
59
|
+
- lib/postwave/post.rb
|
60
|
+
- lib/postwave/post_creator.rb
|
61
|
+
- lib/postwave/version.rb
|
62
|
+
- postwave.gemspec
|
63
|
+
homepage: https://github.com/dorkrawk/postwave
|
64
|
+
licenses:
|
65
|
+
- MIT
|
66
|
+
metadata: {}
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
require_paths:
|
70
|
+
- lib
|
71
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ">="
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '0'
|
81
|
+
requirements: []
|
82
|
+
rubygems_version: 3.2.22
|
83
|
+
signing_key:
|
84
|
+
specification_version: 4
|
85
|
+
summary: An opinionated flatfile based blog engine.
|
86
|
+
test_files: []
|