Repository: getnikola/nikola

Issue:
new_page [path] relative to conf.py not $PWD
Steps to replicate:

```
(site)tritium@gesa:~$ nikola init -q foo
[2014-06-12T10:37:00Z] INFO: init: Created empty site at foo.
(site)tritium@gesa:~$ cd foo
(site)tritium@gesa:~/foo$ cd stories
(site)tritium@gesa:~/foo/stories$ mkdir bar
(site)tritium@gesa:~/foo/stories$ cd bar
(site)tritium@gesa:~/foo/stories/bar$ nikola new_page -t 'Spam' ./spam.txt
Creating New Page
-----------------

Title: Spam
Scanning posts....done!
[2014-06-12T10:37:46Z] INFO: new_page: Your page's text is at: ./spam.txt
(site)tritium@gesa:~/foo/stories/bar$ tree ~/foo
/home/tritium/foo
├── conf.py
├── conf.pyc
├── files
├── galleries
├── listings
├── posts
├── spam.txt
└── stories
    └── bar

6 directories, 3 files
(site)tritium@gesa:~/foo/stories/bar$
```

This struck me as entirely counter-intuitive, as traditionally, command line applications specify paths relative to $PWD, not an arbitrary file (conf.py).  In attempting to work around #1326, this was discovered.

A proposed new semantics for the command is to assume that all paths giving in to the `new_page` and `new_post` commands be relative to $PWD.
- This matches the expectation of users familiar with command line tools (very few tools that accept relative paths will treat them as anything but relative to $PWD)
- This should not greatly affect users familiar with the current semantics; the current semantics would still be valid if the user is currently in the root (conf.py) directory of the project.



Discussion:
Nikola believes people usually would do `nikola new_page -t 'Spam' spam.txt`, and thus doesn’t know about your idea.

Now, the bug comes the fact that we have to work in the source root to make most things work, including `import conf` and generating everything — we work on relative paths in most places.  And that nobody really thought `./spam.txt` would be a thing.

To fix this, we would need to:
- memorize the initial working directory in `__main__.py`
- if it’s in POSTS/PAGES or any subdir of those, go back there when doing `nikola new_post` (and thus `new_page` which is just a simple link to `new_post -p`) so we put it where the user would expect it (even if they didn’t say `./` explicitly)

Thought:
You could break the command up... rather than taking a path argument at the end, it takes a file name argument at the end (thus keeping the behavior the command was designed for), and simply add an option (-d/--dir or the like) to override the default location. I think you would only have to add this to pages, as I dont think it makes much sense for posts... but it may... >.>

It makes sense for posts, if you do filenames like `2014/06/14/post-on-my-blog/`.  And also, even if it didn’t make sense, we couldn’t implement something only for `new_page`, as (internally) it’s just a wrapper over `new_post`.

But yes, your new proposal sounds saner.

I don't understand what new behaviour this change allows. If it doesn't let you do anything new, then what does it fix?

Maybe we should close this issue and replace it with a proposed feature one instead?

Note to future viewers: the original bug report was updated at this point.


Resolving patch:
diff --git a/nikola/__main__.py b/nikola/__main__.py
--- a/nikola/__main__.py
+++ b/nikola/__main__.py
@@ -90,6 +90,8 @@ def main(args=None):
         quiet = True
     global config
 
+    original_cwd = os.getcwd()
+
     # Those commands do not require a `conf.py`.  (Issue #1132)
     # Moreover, actually having one somewhere in the tree can be bad, putting
     # the output of that command (the new site) in an unknown directory that is
@@ -145,6 +147,7 @@ def main(args=None):
     config['__invariant__'] = invariant
     config['__quiet__'] = quiet
     config['__configuration_filename__'] = conf_filename
+    config['__cwd__'] = original_cwd
 
     site = Nikola(**config)
     DN = DoitNikola(site, quiet)
diff --git a/nikola/nikola.py b/nikola/nikola.py
--- a/nikola/nikola.py
+++ b/nikola/nikola.py
@@ -285,6 +285,7 @@ def __init__(self, **config):
         self.colorful = config.pop('__colorful__', False)
         self.invariant = config.pop('__invariant__', False)
         self.quiet = config.pop('__quiet__', False)
+        self.original_cwd = config.pop('__cwd__', False)
         self.configuration_filename = config.pop('__configuration_filename__', False)
         self.configured = bool(config)
         self.injected_deps = defaultdict(list)
diff --git a/nikola/plugins/command/new_post.py b/nikola/plugins/command/new_post.py
--- a/nikola/plugins/command/new_post.py
+++ b/nikola/plugins/command/new_post.py
@@ -345,7 +345,7 @@ def _execute(self, options, args):
         if not path:
             txt_path = os.path.join(output_path, slug + suffix)
         else:
-            txt_path = path
+            txt_path = os.path.join(self.site.original_cwd, path)
 
         if (not onefile and os.path.isfile(meta_path)) or \
                 os.path.isfile(txt_path):


Test patch: