Repository: getnikola/nikola

Issue:
Stop rebuilding RSS files for tags that don’t need it
1. Add a few posts with some tags
2. nikola build
3. Edit any one of the posts and add a new tag
4. nikola build

All tags’ RSS files are rebuilt to facilitate adding one new tag. Even when not all of them have changing content. They get new `<lastBuildDate>` which causes utilities like rsync and git to treat them as new files.

We should be more selective about what feeds need rebuilding.



Discussion:
In case we do that, we must be careful about:
- new posts
- edited posts
- posts with added tags
- deleted posts
- tags deleted from posts

Which is quite a lot of things, and I might have missed something.  I guess the current solution is easier.

But it’s still possible to do only the tags that need rebuilding if we get dependencies right.

We could just remove the optional lastBuildDate element. git and rsync shouldn’t pick them up as updated even though we spend time rebuilding them.

rsync will:

```
[kwpolska@kw-cassandra s1]% echo 'hello' > foo
[kwpolska@kw-cassandra s1]% rsync -rav . /tmp/s2/
sending incremental file list
./
foo

sent 132 bytes  received 38 bytes  340.00 bytes/sec
total size is 6  speedup is 0.04
[kwpolska@kw-cassandra s1]% rsync -rav . /tmp/s2/
sending incremental file list

sent 76 bytes  received 12 bytes  176.00 bytes/sec
total size is 6  speedup is 0.07

# nothing is sent on second attempt

[kwpolska@kw-cassandra s1]% touch foo # contents stay, last modified date changes

[kwpolska@kw-cassandra s1]% rsync -rav . /tmp/s2/
sending incremental file list
foo

sent 133 bytes  received 35 bytes  336.00 bytes/sec
total size is 6  speedup is 0.04

# file is sent again
```

Actually, adding a new tag (or category) will not only trigger a rebuild of all tag RSS files, but also of all tag pages. The reason for this is that in the `tags.py` plugin, one of the first functions when creating tasks which is called is `RenderTags.list_tags_page`, which inserts a list of _all tags and categories_ into `kw` (as `kw['tags']` and `kw['categories']`). This affects all later tasks created by that plugin, including all tag/category page tasks and all tag/category RSS tasks.

Does any of these tasks _needs_ this information in `kw`? I think not. If you all agree, I'd like to change `RenderTags._create_tags_page` to add the list of tags and categories to only a  copy of `kw`.


Resolving patch:
diff --git a/nikola/plugins/task/tags.py b/nikola/plugins/task/tags.py
--- a/nikola/plugins/task/tags.py
+++ b/nikola/plugins/task/tags.py
@@ -84,7 +84,7 @@ def gen_tasks(self):
         self.site.scan_posts()
         yield self.group_task()
 
-        yield self.list_tags_page(kw)  # this also adds category and tag list to kw
+        yield self.list_tags_page(kw)
 
         if not self.site.posts_per_tag and not self.site.posts_per_category:
             return
@@ -169,6 +169,7 @@ def _create_tags_page(self, kw, include_tags=True, include_categories=True):
         has_tags = (tags != ['']) and include_tags
         has_categories = (categories != ['']) and include_categories
         template_name = "tags.tmpl"
+        kw = kw.copy()
         if include_tags:
             kw['tags'] = tags
         if include_categories:


Test patch: