diff options
-rw-r--r-- | man/blogc-make.1.ronn | 7 | ||||
-rw-r--r-- | man/blogcfile.5.ronn | 3 | ||||
-rw-r--r-- | src/blogc-make/atom.c | 41 | ||||
-rw-r--r-- | src/blogc-make/atom.h | 1 | ||||
-rw-r--r-- | src/blogc-make/rules.c | 22 | ||||
-rw-r--r-- | tests/blogc-make/check_atom.c | 212 | ||||
-rwxr-xr-x | tests/blogc-make/check_blogc_make.sh.in | 38 |
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 |