postwave 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|