aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/blogc-make.1.ronn7
-rw-r--r--man/blogcfile.5.ronn3
-rw-r--r--src/blogc-make/atom.c41
-rw-r--r--src/blogc-make/atom.h1
-rw-r--r--src/blogc-make/rules.c22
-rw-r--r--tests/blogc-make/check_atom.c212
-rwxr-xr-xtests/blogc-make/check_blogc_make.sh.in38
7 files changed, 311 insertions, 13 deletions
diff --git a/man/blogc-make.1.ronn b/man/blogc-make.1.ronn
index 6516216..43778c7 100644
--- a/man/blogc-make.1.ronn
+++ b/man/blogc-make.1.ronn
@@ -60,6 +60,13 @@ Watch for changes in the source files, rebuilding as needed.
Rebuilds are done by running `blogc-make all` internally.
+### atom_dump
+
+Dump default Atom feed template based on current blogcfile(5) settings.
+
+The template is dumped to the standard output, and can be used as a base
+for customized Atom feed templates.
+
## BUILD RULES
### index
diff --git a/man/blogcfile.5.ronn b/man/blogcfile.5.ronn
index edca45c..21f2651 100644
--- a/man/blogcfile.5.ronn
+++ b/man/blogcfile.5.ronn
@@ -67,7 +67,8 @@ however these rules can be customized with the following settings, from the
* `atom_template` (default: internal template)
The template file that should be used when building Atom feeds. This file
is relative to `template_dir`. If not provided, an internal default template
- will be used instead.
+ will be used instead. The internal template can be dumped using the `atom_dump`
+ blogc-make(1) rule.
* `content_dir` (default: `content`):
The directory that stores the source files. This directory is relative
diff --git a/src/blogc-make/atom.c b/src/blogc-make/atom.c
index 9dde35e..207b718 100644
--- a/src/blogc-make/atom.c
+++ b/src/blogc-make/atom.c
@@ -48,20 +48,11 @@ static const char atom_template[] =
char*
-bm_atom_deploy(bm_settings_t *settings, bc_error_t **err)
+bm_atom_generate(bm_settings_t *settings)
{
- if (settings == NULL || err == NULL || *err != NULL)
+ if (settings == NULL)
return NULL;
- // this is not really portable
- char fname[] = "/tmp/blogc-make_XXXXXX";
- int fd;
- if (-1 == (fd = mkstemp(fname))) {
- *err = bc_error_new_printf(BLOGC_MAKE_ERROR_ATOM,
- "Failed to create temporary atom template: %s", strerror(errno));
- return NULL;
- }
-
const char *atom_prefix = bc_trie_lookup(settings->settings, "atom_prefix");
const char *atom_ext = bc_trie_lookup(settings->settings, "atom_ext");
const char *post_prefix = bc_trie_lookup(settings->settings, "post_prefix");
@@ -93,13 +84,39 @@ bm_atom_deploy(bm_settings_t *settings, bc_error_t **err)
entry_id = bc_strdup(post_url);
}
- char *content = bc_strdup_printf(atom_template, atom_url->str, atom_url->str,
+ char *rv = bc_strdup_printf(atom_template, atom_url->str, atom_url->str,
entry_id, post_url);
bc_string_free(atom_url, true);
free(post_url);
free(entry_id);
+ return rv;
+}
+
+
+char*
+bm_atom_deploy(bm_settings_t *settings, bc_error_t **err)
+{
+ if (settings == NULL || err == NULL || *err != NULL)
+ return NULL;
+
+ // this is not really portable
+ char fname[] = "/tmp/blogc-make_XXXXXX";
+ int fd;
+ if (-1 == (fd = mkstemp(fname))) {
+ *err = bc_error_new_printf(BLOGC_MAKE_ERROR_ATOM,
+ "Failed to create temporary atom template: %s", strerror(errno));
+ return NULL;
+ }
+
+ char *content = bm_atom_generate(settings);
+ if (content == NULL) {
+ close(fd);
+ unlink(fname);
+ return NULL;
+ }
+
if (-1 == write(fd, content, strlen(content))) {
*err = bc_error_new_printf(BLOGC_MAKE_ERROR_ATOM,
"Failed to write to temporary atom template: %s", strerror(errno));
diff --git a/src/blogc-make/atom.h b/src/blogc-make/atom.h
index 9f47adc..ed3875d 100644
--- a/src/blogc-make/atom.h
+++ b/src/blogc-make/atom.h
@@ -12,6 +12,7 @@
#include "../common/error.h"
#include "settings.h"
+char* bm_atom_generate(bm_settings_t *settings);
char* bm_atom_deploy(bm_settings_t *settings, bc_error_t **err);
void bm_atom_destroy(const char *fname);
diff --git a/src/blogc-make/rules.c b/src/blogc-make/rules.c
index 9d599cc..d95edd8 100644
--- a/src/blogc-make/rules.c
+++ b/src/blogc-make/rules.c
@@ -13,6 +13,7 @@
#include <time.h>
#include <math.h>
#include "../common/utils.h"
+#include "atom.h"
#include "ctx.h"
#include "exec.h"
#include "exec-native.h"
@@ -626,6 +627,20 @@ watch_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
}
+// ATOM DUMP RULE
+
+static int
+atom_dump_exec(bm_ctx_t *ctx, bc_slist_t *outputs, bc_trie_t *args)
+{
+ char *content = bm_atom_generate(ctx->settings);
+ if (content == NULL)
+ return 3;
+ printf("%s", content);
+ free(content);
+ return 0;
+}
+
+
const bm_rule_t rules[] = {
{
.name = "all",
@@ -713,6 +728,13 @@ const bm_rule_t rules[] = {
.exec_func = watch_exec,
.generate_files = false,
},
+ {
+ .name = "atom_dump",
+ .help = "dump default Atom feed template based on current settings",
+ .outputlist_func = NULL,
+ .exec_func = atom_dump_exec,
+ .generate_files = false,
+ },
{NULL, NULL, NULL, NULL, false},
};
diff --git a/tests/blogc-make/check_atom.c b/tests/blogc-make/check_atom.c
index f58f2ba..d04abd3 100644
--- a/tests/blogc-make/check_atom.c
+++ b/tests/blogc-make/check_atom.c
@@ -22,6 +22,214 @@
static void
+test_atom_generate_empty_file(void **state)
+{
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
+ bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
+ bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
+ bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
+
+ char *cmp = bm_atom_generate(settings);
+
+ assert_non_null(cmp);
+
+ assert_string_equal(cmp,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
+ "{{ FILTER_TAG }}{% endif %}</title>\n"
+ " <id>{{ BASE_URL }}{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
+ "{% else %}/index{% endif %}.xml</id>\n"
+ " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}"
+ "/{{ FILTER_TAG }}{% else %}/index{% endif %}.xml\" rel=\"self\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
+ " {% block listing %}\n"
+ " <entry>\n"
+ " <title type=\"text\">{{ TITLE }}</title>\n"
+ " <id>{{ BASE_URL }}/{{ FILENAME }}.html</id>\n"
+ " <updated>{{ DATE_FORMATTED }}</updated>\n"
+ " <published>{{ DATE_FORMATTED }}</published>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}.html\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
+ " </entry>\n"
+ " {% endblock %}\n"
+ "</feed>\n");
+
+ free(cmp);
+ bc_trie_free(settings->settings);
+ free(settings);
+}
+
+
+static void
+test_atom_generate_empty_dir(void **state)
+{
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "atom_prefix", bc_strdup(""));
+ bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
+ bc_trie_insert(settings->settings, "post_prefix", bc_strdup(""));
+ bc_trie_insert(settings->settings, "html_ext", bc_strdup("/index.html"));
+
+ char *cmp = bm_atom_generate(settings);
+
+ assert_non_null(cmp);
+
+ assert_string_equal(cmp,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
+ "{{ FILTER_TAG }}{% endif %}</title>\n"
+ " <id>{{ BASE_URL }}{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
+ "{% endif %}/index.xml</id>\n"
+ " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}{% ifdef FILTER_TAG %}"
+ "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
+ " {% block listing %}\n"
+ " <entry>\n"
+ " <title type=\"text\">{{ TITLE }}</title>\n"
+ " <id>{{ BASE_URL }}/{{ FILENAME }}/index.html</id>\n"
+ " <updated>{{ DATE_FORMATTED }}</updated>\n"
+ " <published>{{ DATE_FORMATTED }}</published>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/{{ FILENAME }}/index.html\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
+ " </entry>\n"
+ " {% endblock %}\n"
+ "</feed>\n");
+
+ free(cmp);
+ bc_trie_free(settings->settings);
+ free(settings);
+}
+
+
+static void
+test_atom_generate_file(void **state)
+{
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
+ bc_trie_insert(settings->settings, "atom_ext", bc_strdup(".xml"));
+ bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
+ bc_trie_insert(settings->settings, "html_ext", bc_strdup(".html"));
+
+ char *cmp = bm_atom_generate(settings);
+
+ assert_non_null(cmp);
+
+ assert_string_equal(cmp,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
+ "{{ FILTER_TAG }}{% endif %}</title>\n"
+ " <id>{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
+ "{% endif %}.xml</id>\n"
+ " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
+ "/{{ FILTER_TAG }}{% endif %}.xml\" rel=\"self\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
+ " {% block listing %}\n"
+ " <entry>\n"
+ " <title type=\"text\">{{ TITLE }}</title>\n"
+ " <id>{{ BASE_URL }}/post/{{ FILENAME }}.html</id>\n"
+ " <updated>{{ DATE_FORMATTED }}</updated>\n"
+ " <published>{{ DATE_FORMATTED }}</published>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}.html\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
+ " </entry>\n"
+ " {% endblock %}\n"
+ "</feed>\n");
+
+ free(cmp);
+ bc_trie_free(settings->settings);
+ free(settings);
+}
+
+
+static void
+test_atom_generate_dir(void **state)
+{
+ bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
+ settings->settings = bc_trie_new(free);
+ bc_trie_insert(settings->settings, "atom_prefix", bc_strdup("atom"));
+ bc_trie_insert(settings->settings, "atom_ext", bc_strdup("/index.xml"));
+ bc_trie_insert(settings->settings, "post_prefix", bc_strdup("post"));
+ bc_trie_insert(settings->settings, "html_ext", bc_strdup("/index.html"));
+
+ char *cmp = bm_atom_generate(settings);
+
+ assert_non_null(cmp);
+
+ assert_string_equal(cmp,
+ "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ "<feed xmlns=\"http://www.w3.org/2005/Atom\">\n"
+ " <title type=\"text\">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - "
+ "{{ FILTER_TAG }}{% endif %}</title>\n"
+ " <id>{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}"
+ "{% endif %}/index.xml</id>\n"
+ " <updated>{{ DATE_FIRST_FORMATTED }}</updated>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/\" />\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/atom{% ifdef FILTER_TAG %}"
+ "/{{ FILTER_TAG }}{% endif %}/index.xml\" rel=\"self\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <subtitle type=\"text\">{{ SITE_TAGLINE }}</subtitle>\n"
+ " {% block listing %}\n"
+ " <entry>\n"
+ " <title type=\"text\">{{ TITLE }}</title>\n"
+ " <id>{{ BASE_URL }}/post/{{ FILENAME }}/index.html</id>\n"
+ " <updated>{{ DATE_FORMATTED }}</updated>\n"
+ " <published>{{ DATE_FORMATTED }}</published>\n"
+ " <link href=\"{{ BASE_DOMAIN }}{{ BASE_URL }}/post/{{ FILENAME }}/index.html\" />\n"
+ " <author>\n"
+ " <name>{{ AUTHOR_NAME }}</name>\n"
+ " <email>{{ AUTHOR_EMAIL }}</email>\n"
+ " </author>\n"
+ " <content type=\"html\"><![CDATA[{{ CONTENT }}]]></content>\n"
+ " </entry>\n"
+ " {% endblock %}\n"
+ "</feed>\n");
+
+ free(cmp);
+ bc_trie_free(settings->settings);
+ free(settings);
+}
+
+
+static void
test_atom_empty_file(void **state)
{
bm_settings_t *settings = bc_malloc(sizeof(bm_settings_t));
@@ -399,6 +607,10 @@ int
main(void)
{
const UnitTest tests[] = {
+ unit_test(test_atom_generate_empty_file),
+ unit_test(test_atom_generate_empty_dir),
+ unit_test(test_atom_generate_file),
+ unit_test(test_atom_generate_dir),
unit_test(test_atom_empty_file),
unit_test(test_atom_empty_dir),
unit_test(test_atom_file),
diff --git a/tests/blogc-make/check_blogc_make.sh.in b/tests/blogc-make/check_blogc_make.sh.in
index 35a7c41..c62cd65 100755
--- a/tests/blogc-make/check_blogc_make.sh.in
+++ b/tests/blogc-make/check_blogc_make.sh.in
@@ -1639,8 +1639,46 @@ rm "${TEMP}/output.txt"
unset OUTPUT_DIR
+
+### atom_dump rule
+
+${TESTS_ENVIRONMENT} @abs_top_builddir@/blogc-make -f "${TEMP}/proj/blogcfile" atom_dump | tee "${TEMP}/atom.xml"
+
+cat > "${TEMP}/expected-atom-dump.xml" <<EOF
+<?xml version="1.0" encoding="utf-8"?>
+<feed xmlns="http://www.w3.org/2005/Atom">
+ <title type="text">{{ SITE_TITLE }}{% ifdef FILTER_TAG %} - {{ FILTER_TAG }}{% endif %}</title>
+ <id>{{ BASE_URL }}/atoom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}{% endif %}/index.xml</id>
+ <updated>{{ DATE_FIRST_FORMATTED }}</updated>
+ <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/" />
+ <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/atoom{% ifdef FILTER_TAG %}/{{ FILTER_TAG }}{% endif %}/index.xml" rel="self" />
+ <author>
+ <name>{{ AUTHOR_NAME }}</name>
+ <email>{{ AUTHOR_EMAIL }}</email>
+ </author>
+ <subtitle type="text">{{ SITE_TAGLINE }}</subtitle>
+ {% block listing %}
+ <entry>
+ <title type="text">{{ TITLE }}</title>
+ <id>{{ BASE_URL }}/poost/{{ FILENAME }}.html</id>
+ <updated>{{ DATE_FORMATTED }}</updated>
+ <published>{{ DATE_FORMATTED }}</published>
+ <link href="{{ BASE_DOMAIN }}{{ BASE_URL }}/poost/{{ FILENAME }}.html" />
+ <author>
+ <name>{{ AUTHOR_NAME }}</name>
+ <email>{{ AUTHOR_EMAIL }}</email>
+ </author>
+ <content type="html"><![CDATA[{{ CONTENT }}]]></content>
+ </entry>
+ {% endblock %}
+</feed>
+EOF
+diff -uN "${TEMP}/atom.xml" "${TEMP}/expected-atom-dump.xml"
+
+rm "${TEMP}/atom.xml"
rm -rf "${TEMP}/proj"
+
###############################################################################
### empty prefixes with some posts