Skip to content

Commit

Permalink
Merge pull request #1 from viniciusalonso/generate-skeleton
Browse files Browse the repository at this point in the history
Generate skeleton
  • Loading branch information
viniciusalonso authored Oct 5, 2023
2 parents 25e4ea4 + 5d775df commit 35200bc
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 0 deletions.
42 changes: 42 additions & 0 deletions lib/mix/tasks/simple_blog/new.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
defmodule Mix.Tasks.SimpleBlog.New do
use Mix.Task

@moduledoc """
Module responsible for generate the skeleton of a new blog.
"""

@doc """
It generates a new project skeleton
## Examples
iex> Mix.Tasks.SimpleBlog.New.run([])
:ok
"""
@impl Mix.Task
def run([]), do: Mix.shell().info(usage())

def run([path]) do
source = Path.expand("static")

destination =
Path.expand(path)
|> Path.join(["blog"])

case File.cp_r(source, destination) do
{:ok, _} ->
Mix.shell().info("Blog created with success!")

{:error, _} ->
Mix.shell().error("Error while create the blog in the path: #{path}")
end
end

def usage() do
"""
To generate a new blog you should pass a valid path:
$ mix simple_blog.new .
"""
end
end
47 changes: 47 additions & 0 deletions lib/mix/tasks/simple_blog/post/new.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
defmodule Mix.Tasks.SimpleBlog.Post.New do
use Mix.Task

@moduledoc """
Module responsible for generate a new blog post.
"""

@doc """
It generates a new blog post
## Examples
# iex> Mix.Tasks.SimpleBlog.Post.New.run(["My first blog post"])
# :ok
"""
@impl Mix.Task
def run([]), do: Mix.shell().info(usage())

def run([title]) do
today =
Date.utc_today()
|> Date.to_string()

filename = SimpleBlog.Post.generate_filename(%SimpleBlog.Post{title: title, date: today})

case File.open(filename, [:write]) do
{:ok, file} ->
IO.binwrite(file, "## " <> title)
File.close(file)

{:error, :enoent} ->
Mix.shell().info("""
There is a directory missing, please run the following command:
$ mix simple_blog.new .
""")
end
end

def usage() do
"""
To generate a new blog post you should pass a title as string:
$ mix simple_blog.post.new "My first blog post"
"""
end
end
27 changes: 27 additions & 0 deletions lib/simple_blog/post.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule SimpleBlog.Post do
@moduledoc """
Module responsible for Post
"""

@extension "md"

defstruct title: "", tags: [], body: "", date: ""

@doc """
Generate filename for blog post
## Examples
iex> SimpleBlog.Post.generate_filename(%SimpleBlog.Post{ title: "My first blog post", date: ~D[2023-10-04] })
"blog/_posts/2023-10-04-my-first-blog-post.md"
"""
def generate_filename(%SimpleBlog.Post{title: title, date: date}) do
normalized_title =
title
|> String.downcase()
|> String.replace(" ", "-", global: true)

filename = "#{date}-#{normalized_title}.#{@extension}"
"blog/_posts/#{filename}"
end
end
Empty file added static/_posts/.gitkeep
Empty file.
5 changes: 5 additions & 0 deletions static/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!doctype html>
<html>
<head></head>
<body></body>
</html>
41 changes: 41 additions & 0 deletions test/mix/tasks/simple_blog/new_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
defmodule Mix.Tasks.SimpleBlog.NewTest do
use ExUnit.Case
import ExUnit.CaptureIO
doctest Mix.Tasks.SimpleBlog.New

@instructions """
To generate a new blog you should pass a valid path:
$ mix simple_blog.new .
"""

describe "run" do
setup do
on_exit(fn -> File.rm_rf("blog") end)
end

test "returns instructions for no arguments" do
message = capture_io(fn -> Mix.Tasks.SimpleBlog.New.run([]) end)

assert message == "#{@instructions}\n"
end

test "show success message for created structure" do
message = capture_io(fn -> Mix.Tasks.SimpleBlog.New.run(["."]) end)

assert message == "Blog created with success!\n"
end

test "create folder structure for blog" do
Mix.Tasks.SimpleBlog.New.run(["."])

assert File.exists?("blog")
end
end

describe "usage" do
test "returns instructions" do
assert Mix.Tasks.SimpleBlog.New.usage() == @instructions
end
end
end
50 changes: 50 additions & 0 deletions test/mix/tasks/simple_blog/post/new_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
defmodule Mix.Tasks.SimpleBlog.Post.NewTest do
use ExUnit.Case
import ExUnit.CaptureIO
doctest Mix.Tasks.SimpleBlog.Post.New

@instructions """
To generate a new blog post you should pass a title as string:
$ mix simple_blog.post.new "My first blog post"
"""

@error_instructions """
There is a directory missing, please run the following command:
$ mix simple_blog.new .
"""

describe "run" do
setup do
on_exit(fn -> File.rm_rf("blog") end)
end

test "returns instructions for no arguments" do
Mix.Tasks.SimpleBlog.New.run(["."])
message = capture_io(fn -> Mix.Tasks.SimpleBlog.Post.New.run([]) end)

assert message == "#{@instructions}\n"
end

test "show success message for created blog post" do
Mix.Tasks.SimpleBlog.New.run(["."])
Mix.Tasks.SimpleBlog.Post.New.run(["My First Blog Post"])

today = Date.utc_today() |> Date.to_string()

assert File.exists?("blog/_posts/#{today}-my-first-blog-post.md")
end

test "show error message when blog does not exist" do
message = capture_io(fn -> Mix.Tasks.SimpleBlog.Post.New.run(["My First Blog Post"]) end)
assert message == "#{@error_instructions}\n"
end
end

describe "usage" do
test "returns instructions" do
assert Mix.Tasks.SimpleBlog.Post.New.usage() == @instructions
end
end
end
13 changes: 13 additions & 0 deletions test/simple_blog/post_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
defmodule SimpleBlog.PostTest do
use ExUnit.Case
doctest SimpleBlog.Post

describe "generate_filename" do
test "generate filename with date" do
title = "Introduction to elixir"
date = ~D[2023-10-04]
filename = SimpleBlog.Post.generate_filename(%SimpleBlog.Post{title: title, date: date})
assert "blog/_posts/2023-10-04-introduction-to-elixir.md" == filename
end
end
end

0 comments on commit 35200bc

Please sign in to comment.