Skip to content

Commit

Permalink
release
Browse files Browse the repository at this point in the history
  • Loading branch information
zupzup committed Jun 3, 2017
1 parent 94884df commit 84fc9d9
Show file tree
Hide file tree
Showing 22 changed files with 1,589 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
blog-generator
*.o
*.a
*.so
Expand All @@ -22,3 +23,7 @@ _testmain.go
*.exe
*.test
*.prof
tmp
www
config.yml
blog-generator
13 changes: 1 addition & 12 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -175,18 +175,7 @@

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright {yyyy} {name of copyright owner}
Copyright 2016 Mario Zupan

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/zupzup/calories)](https://goreportcard.com/report/github.com/zupzup/calories)

# blog-generator

A static blog generator using a configurable GitHub repository as a data-source. The posts are written in markdown with yml metadata attached to them. [This](https://github.com/zupzup/blog) is an example repo for the blog at [https://zupzup.org/](https://zupzup.org/).

## Features

* Listing
* Sitemap Generator
* RSS Feed
* Code Highlighting
* Archive
* Configurable Static Pages
* Tags

## Installation

```bash
go get github.com/zupzup/blog-generator
```

## Usage

Just execute

```bash
blog-generator
```

in this repository's root directory.

## Customization

### Configure the CLI

Set the following constants in `cli/cli.go`:

```go
// data source for the blog
const RepoURL string = "[email protected]:username/repo.git"
// folder to download the repo into
const TmpFolder string = "./tmp"
// output folder
const DestFolder string = "./www"
```

### Confugure the Generator

Set the following constants in `generator/generator.go`
```go
// url of the blog
const blogURL = "https://www.someblog.com"
// blog language
const blogLanguage = "en-us"
// blog description
const blogDescription = "some description..."
// date format
const dateFormat string = "02.01.2006"
// main Template
const templatePath string = "static/template.html"
// blog title
const blogTitle string = "my Blog's Title"
// displayed posts on landing page
const numPostsFrontPage int = 10
```

You can define and configure the different generators in the `runTasks` function within `generator/generator.go`.

### Templates

Edit templates in `static` folder to your needs.

## Example Blog Repository

[Blog](https://github.com/zupzup/blog)
33 changes: 33 additions & 0 deletions cli/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package cli

import (
"github.com/zupzup/blog-generator/datasource"
"github.com/zupzup/blog-generator/generator"
"log"
)

// RepoURL is the URL of the data-source repository
const RepoURL string = "[email protected]:zupzup/blog.git"

// TmpFolder is the folder where the data-source repo is checked out to
const TmpFolder string = "./tmp"

// DestFolder is the output folder of the static blog
const DestFolder string = "./www"

// Run runs the application
func Run() {
ds := datasource.New()
dirs, err := ds.Fetch(RepoURL, TmpFolder)
if err != nil {
log.Fatal(err)
}
g := generator.New(&generator.SiteConfig{
Sources: dirs,
Destination: DestFolder,
})
err = g.Generate()
if err != nil {
log.Fatal(err)
}
}
11 changes: 11 additions & 0 deletions datasource/datasource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package datasource

// DataSource is the data-source fetching interface
type DataSource interface {
Fetch(from, to string) ([]string, error)
}

// New creates a new GitDataSource
func New() DataSource {
return &GitDataSource{}
}
105 changes: 105 additions & 0 deletions datasource/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package datasource

import (
"fmt"
"os"
"os/exec"
"path/filepath"
)

// GitDataSource is the git data source object
type GitDataSource struct{}

// Fetch creates the output folder, clears it and clones the repository there
func (ds *GitDataSource) Fetch(from, to string) ([]string, error) {
fmt.Printf("Fetching data from %s into %s...\n", from, to)
if err := createFolderIfNotExist(to); err != nil {
return nil, err
}
if err := clearFolder(to); err != nil {
return nil, err
}
if err := cloneRepo(to, from); err != nil {
return nil, err
}
dirs, err := getContentFolders(to)
if err != nil {
return nil, err
}
fmt.Print("Fetching complete.\n")
return dirs, nil
}

func createFolderIfNotExist(path string) error {
if _, err := os.Stat(path); err != nil {
if os.IsNotExist(err) {
if err = os.Mkdir(path, os.ModePerm); err != nil {
return fmt.Errorf("error creating directory %s: %v", path, err)
}
} else {
return fmt.Errorf("error accessing directory %s: %v", path, err)
}
}
return nil
}

func clearFolder(path string) error {
dir, err := os.Open(path)
if err != nil {
return fmt.Errorf("error accessing directory %s: %v", path, err)
}
defer dir.Close()
names, err := dir.Readdirnames(-1)
if err != nil {
return fmt.Errorf("error reading directory %s: %v", path, err)
}

for _, name := range names {
if err = os.RemoveAll(filepath.Join(path, name)); err != nil {
return fmt.Errorf("error clearing file %s: %v", name, err)
}
}
return nil
}

func cloneRepo(path, repositoryURL string) error {
cmdName := "git"
initArgs := []string{"init", "."}
cmd := exec.Command(cmdName, initArgs...)
cmd.Dir = path
if err := cmd.Run(); err != nil {
return fmt.Errorf("error initializing git repository at %s: %v", path, err)
}
remoteArgs := []string{"remote", "add", "origin", repositoryURL}
cmd = exec.Command(cmdName, remoteArgs...)
cmd.Dir = path
if err := cmd.Run(); err != nil {
return fmt.Errorf("error setting remote %s: %v", repositoryURL, err)
}
pullArgs := []string{"pull", "origin", "master"}
cmd = exec.Command(cmdName, pullArgs...)
cmd.Dir = path
if err := cmd.Run(); err != nil {
return fmt.Errorf("error pulling master at %s: %v", path, err)
}
return nil
}

func getContentFolders(path string) ([]string, error) {
var result []string
dir, err := os.Open(path)
if err != nil {
return nil, fmt.Errorf("error accessing directory %s: %v", path, err)
}
defer dir.Close()
files, err := dir.Readdir(-1)
if err != nil {
return nil, fmt.Errorf("error reading contents of directory %s: %v", path, err)
}
for _, file := range files {
if file.IsDir() && file.Name()[0] != '.' {
result = append(result, fmt.Sprintf("%s/%s", path, file.Name()))
}
}
return result, nil
}
Loading

0 comments on commit 84fc9d9

Please sign in to comment.