Repository: getnikola/nikola

Issue:
Sections conflict with pages that would replace them
> ERROR: Two different tasks can't have a common target.'output/sec1/index.html' is a target for render_pages:output/sec1/index.html and render_taxonomies:output/sec1/index.html.

To reproduce:

* set POSTS and PAGES to output to the root of the site
* create `posts/sec1/foo.rst` and `pages/sec1.rst`

`should_generate_classification_page` is supposed to prevent this, but it fails — `post_list` only contains posts from the section, so it doesn’t check the page, and thus fails. Perhaps we could fix it by giving all posts/pages to that function?
Sections conflict with pages that would replace them
> ERROR: Two different tasks can't have a common target.'output/sec1/index.html' is a target for render_pages:output/sec1/index.html and render_taxonomies:output/sec1/index.html.

To reproduce:

* set POSTS and PAGES to output to the root of the site
* create `posts/sec1/foo.rst` and `pages/sec1.rst`

`should_generate_classification_page` is supposed to prevent this, but it fails — `post_list` only contains posts from the section, so it doesn’t check the page, and thus fails. Perhaps we could fix it by giving all posts/pages to that function?


Discussion:
The function already has access to all posts and pages because it has access to the `site` object.
The function already has access to all posts and pages because it has access to the `site` object.

Resolving patch:
diff --git a/nikola/plugins/task/sections.py b/nikola/plugins/task/sections.py
--- a/nikola/plugins/task/sections.py
+++ b/nikola/plugins/task/sections.py
@@ -142,9 +142,11 @@ def postprocess_posts_per_classification(self, posts_per_section_per_language, f
     def should_generate_classification_page(self, dirname, post_list, lang):
         """Only generates list of posts for classification if this function returns True."""
         short_destination = dirname + '/' + self.site.config['INDEX_FILE']
-        for post in post_list:
-            # If there is an index.html pending to be created from a page, do not generate the section page.
-            # The section page would be useless anyways. (via Issue #2613)
+        # If there is an index.html pending to be created from a page, do not generate the section page.
+        # The section page would be useless anyways. (via Issue #2613)
+        for post in self.site.timeline:
+            if not self.site.config["SHOW_UNTRANSLATED_POSTS"] and not post.is_translation_available(lang):
+                continue
             if post.destination_path(lang, sep='/') == short_destination:
                 return False
         return True


Test patch:
diff --git a/tests/test_integration.py b/tests/test_integration.py
--- a/tests/test_integration.py
+++ b/tests/test_integration.py
@@ -545,6 +545,55 @@ def fill_site(self):
             outf.write("foo")
 
 
+class SectionPageCollisionTest(EmptyBuildTest):
+    """Test if section indexes avoid pages."""
+
+    @classmethod
+    def patch_site(self):
+        """Enable post sections."""
+        conf_path = os.path.join(self.target_dir, "conf.py")
+        with io.open(conf_path, "a", encoding="utf8") as outf:
+            outf.write("""\n\nPOSTS_SECTIONS = True\nPOSTS_SECTIONS_ARE_INDEXES = True\nPRETTY_URLS = True\nPOSTS = (('posts/*.txt', '', 'post.tmpl'),)\nPAGES = (('pages/*.txt', '', 'story.tmpl'),)\n\n""")
+
+    @classmethod
+    def fill_site(self):
+        """Add subdirectories and create a post in section "sec1" and a page with the same URL as the section index."""
+        self.init_command.create_empty_site(self.target_dir)
+        self.init_command.create_configuration(self.target_dir)
+
+        pages = os.path.join(self.target_dir, "pages")
+        posts = os.path.join(self.target_dir, "posts")
+        sec1 = os.path.join(posts, "sec1")
+
+        nikola.utils.makedirs(pages)
+        nikola.utils.makedirs(sec1)
+
+        with io.open(os.path.join(pages, 'sec1.txt'), "w+", encoding="utf8") as outf:
+            outf.write(".. title: Page 0\n.. slug: sec1\n\nThis is Page 0.\n")
+
+        with io.open(os.path.join(sec1, 'foo.txt'), "w+", encoding="utf8") as outf:
+            outf.write(".. title: Post 0\n.. slug: post0\n.. date: 2013-03-06 19:08:15\n\nThis is Post 0.\n")
+
+    def _make_output_path(self, dir, name):
+        """Make a file path to the output."""
+        return os.path.join(dir, name + '.html')
+
+    def test_section_index_avoidance(self):
+        """Test section index."""
+        sec1 = os.path.join(self.target_dir, "output", "sec1")
+        foo = os.path.join(self.target_dir, "output", "sec1", "post0")
+
+        # Do all files exist?
+        self.assertTrue(os.path.isfile(self._make_output_path(sec1, 'index')))
+        self.assertTrue(os.path.isfile(self._make_output_path(foo, 'index')))
+
+        # Is it really a page?
+        with io.open(os.path.join(sec1, 'index.html'), 'r', encoding='utf-8') as fh:
+            page = fh.read()
+        self.assertTrue('This is Page 0' in page)
+        self.assertTrue('This is Post 0' not in page)
+
+
 class PageIndexTest(EmptyBuildTest):
     """Test if PAGE_INDEX works, with PRETTY_URLS disabled."""