Search code examples
makefilepelican

Permission denied with make newpost (pelican)


I'm trying to follow the Pelican instructions to configure a newpost function and hitting this:

Robins-MBPX:ghpages robinedwards$ make newpost NAME='Test'
echo "Title: Test" >  /Users/robinedwards/Documents/OSU/ghpages/content/test.md
echo "Slug: test" >> /Users/robinedwards/Documents/OSU/ghpages/content/test.md
echo "Date: 2017-02-16 13\:25\:36" >> /Users/robinedwards/Documents/OSU/ghpages/content/test.md
echo ""           >> /Users/robinedwards/Documents/OSU/ghpages/content/test.md
echo ""           >> /Users/robinedwards/Documents/OSU/ghpages/content/test.md
/Users/robinedwards/Documents/OSU/ghpages/content/test.md &
/bin/sh: /Users/robinedwards/Documents/OSU/ghpages/content/test.md: Permission denied

Checking permissions:

Robins-MBPX:ghpages robinedwards$ ls -lah
total 80
drwxr-xr-x  14 robinedwards  staff   476B 15 Feb 16:56 .
drwxr-xr-x   5 robinedwards  staff   170B 15 Feb 17:12 ..
-rw-r--r--@  1 robinedwards  staff   6.0K 16 Feb 09:49 .DS_Store
drwxr-xr-x  14 robinedwards  staff   476B 15 Feb 17:54 .git
-rw-r--r--   1 robinedwards  staff    16B 15 Feb 17:54 .gitignore
-rw-r--r--   1 robinedwards  staff   5.1K 16 Feb 11:47 Makefile
-rw-r--r--   1 robinedwards  staff    44B 15 Feb 17:55 README.md
drwxr-xr-x   4 robinedwards  staff   136B 14 Feb 15:15 __pycache__
drwxr-xr-x   7 robinedwards  staff   238B 16 Feb 13:25 content
-rwxr-xr-x   1 robinedwards  staff   2.2K 14 Feb 14:43 develop_server.sh
-rw-r--r--   1 robinedwards  staff   2.4K 14 Feb 14:43 fabfile.py
drwxr-xr-x  13 robinedwards  staff   442B 14 Feb 14:45 output
-rw-r--r--   1 robinedwards  staff   850B 14 Feb 15:05 pelicanconf.py
-rw-r--r--   1 robinedwards  staff   534B 14 Feb 15:15 publishconf.py
Robins-MBPX:ghpages robinedwards$ ls -lah content/
total 8
drwxr-xr-x   3 robinedwards  staff   102B 16 Feb 13:33 .
drwxr-xr-x  14 robinedwards  staff   476B 15 Feb 16:56 ..
-rw-r--r--   1 robinedwards  staff    53B 16 Feb 13:25 test.md

This is my Makefile:

PY?=python3
PELICAN?=pelican
PELICANOPTS=

BASEDIR=$(CURDIR)
INPUTDIR=$(BASEDIR)/content
OUTPUTDIR=$(BASEDIR)/output
CONFFILE=$(BASEDIR)/pelicanconf.py
PUBLISHCONF=$(BASEDIR)/publishconf.py

FTP_HOST=localhost
FTP_USER=anonymous
FTP_TARGET_DIR=/

SSH_HOST=localhost
SSH_PORT=22
SSH_USER=root
SSH_TARGET_DIR=/var/www

S3_BUCKET=my_s3_bucket

CLOUDFILES_USERNAME=my_rackspace_username
CLOUDFILES_API_KEY=my_rackspace_api_key
CLOUDFILES_CONTAINER=my_cloudfiles_container

DROPBOX_DIR=~/Dropbox/Public/

GITHUB_PAGES_BRANCH=master

DEBUG ?= 0
ifeq ($(DEBUG), 1)
    PELICANOPTS += -D
endif

RELATIVE ?= 0
ifeq ($(RELATIVE), 1)
    PELICANOPTS += --relative-urls
endif

help:
    @echo 'Makefile for a pelican Web site                                         '
    @echo '                                                                       '
    @echo 'Usage:                                                                   '
    @echo '   make html                        (re)generate the web site          '
    @echo '   make clean                          remove the generated files         '
    @echo '   make regenerate                    regenerate files upon modification '
    @echo '   make publish                      generate using production settings '
    @echo '   make serve [PORT=8000]              serve site at http://localhost:8000'
    @echo '   make serve-global [SERVER=0.0.0.0]  serve (as root) to $(SERVER):80   '
    @echo '   make devserver [PORT=8000]          start/restart develop_server.sh   '
    @echo '   make stopserver                    stop local server                '
    @echo '   make ssh_upload                    upload the web site via SSH        '
    @echo '   make rsync_upload                upload the web site via rsync+ssh  '
    @echo '   make dropbox_upload                upload the web site via Dropbox    '
    @echo '   make ftp_upload                    upload the web site via FTP        '
    @echo '   make s3_upload                      upload the web site via S3         '
    @echo '   make cf_upload                      upload the web site via Cloud Files'
    @echo '   make github                        upload the web site via gh-pages   '
    @echo '                                                                       '
    @echo 'Set the DEBUG variable to 1 to enable debugging, e.g. make DEBUG=1 html   '
    @echo 'Set the RELATIVE variable to 1 to enable relative urls                   '
    @echo '                                                                       '

html:
    $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)

clean:
    [ ! -d $(OUTPUTDIR) ] || rm -rf $(OUTPUTDIR)

regenerate:
    $(PELICAN) -r $(INPUTDIR) -o $(OUTPUTDIR) -s $(CONFFILE) $(PELICANOPTS)

serve:
ifdef PORT
    cd $(OUTPUTDIR) && $(PY) -m pelican.server $(PORT)
else
    cd $(OUTPUTDIR) && $(PY) -m pelican.server
endif

serve-global:
ifdef SERVER
    cd $(OUTPUTDIR) && $(PY) -m pelican.server 80 $(SERVER)
else
    cd $(OUTPUTDIR) && $(PY) -m pelican.server 80 0.0.0.0
endif


devserver:
ifdef PORT
    $(BASEDIR)/develop_server.sh restart $(PORT)
else
    $(BASEDIR)/develop_server.sh restart
endif

stopserver:
    $(BASEDIR)/develop_server.sh stop
    @echo 'Stopped Pelican and SimpleHTTPServer processes running in background.'

publish:
    $(PELICAN) $(INPUTDIR) -o $(OUTPUTDIR) -s $(PUBLISHCONF) $(PELICANOPTS)

ssh_upload: publish
    scp -P $(SSH_PORT) -r $(OUTPUTDIR)/* $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR)

rsync_upload: publish
    rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude

dropbox_upload: publish
    cp -r $(OUTPUTDIR)/* $(DROPBOX_DIR)

ftp_upload: publish
    lftp ftp://$(FTP_USER)@$(FTP_HOST) -e "mirror -R $(OUTPUTDIR) $(FTP_TARGET_DIR) ; quit"

s3_upload: publish
    s3cmd sync $(OUTPUTDIR)/ s3://$(S3_BUCKET) --acl-public --delete-removed --guess-mime-type --no-mime-magic --no-preserve

cf_upload: publish
    cd $(OUTPUTDIR) && swift -v -A https://auth.api.rackspacecloud.com/v1.0 -U $(CLOUDFILES_USERNAME) -K $(CLOUDFILES_API_KEY) upload -c $(CLOUDFILES_CONTAINER) .

github: publish
    ghp-import -m "Generate Pelican site" -b $(GITHUB_PAGES_BRANCH) $(OUTPUTDIR)
    git push origin $(GITHUB_PAGES_BRANCH)

.PHONY: html help clean regenerate serve serve-global devserver stopserver publish ssh_upload rsync_upload dropbox_upload ftp_upload s3_upload cf_upload github

## make newpost function

# https://github.com/getpelican/pelican/wiki/Tips-n-Tricks

PAGESDIR=$(INPUTDIR)/pages
DATE := $(shell date +'%Y-%m-%d %H\:%M\:%S')
SLUG := $(shell echo '${NAME}' | sed -e 's/[^[:alnum:]]/-/g' | tr -s '-' | tr A-Z a-z)
EXT ?= md

newpost:
ifdef NAME
    echo "Title: $(NAME)" >  $(INPUTDIR)/$(SLUG).$(EXT)
    echo "Slug: $(SLUG)" >> $(INPUTDIR)/$(SLUG).$(EXT)
    echo "Date: $(DATE)" >> $(INPUTDIR)/$(SLUG).$(EXT)
    echo ""           >> $(INPUTDIR)/$(SLUG).$(EXT)
    echo ""           >> $(INPUTDIR)/$(SLUG).$(EXT)
    ${EDITOR} ${INPUTDIR}/${SLUG}.${EXT} &
else
    @echo 'Variable NAME is not defined.'
    @echo 'Do make newpost NAME='"'"'Post Name'"'"
endif

editpost:
ifdef NAME
    ${EDITOR} ${INPUTDIR}/${SLUG}.${EXT} &
else
    @echo 'Variable NAME is not defined.'
    @echo 'Do make editpost NAME='"'"'Post Name'"'"
endif

newpage:
ifdef NAME
    echo "Title: $(NAME)" >  $(PAGESDIR)/$(SLUG).$(EXT)
    echo "Slug: $(SLUG)" >> $(PAGESDIR)/$(SLUG).$(EXT)
    echo ""           >> $(PAGESDIR)/$(SLUG).$(EXT)
    echo ""           >> $(PAGESDIR)/$(SLUG).$(EXT)
    ${EDITOR} ${PAGESDIR}/${SLUG}.$(EXT)
else
    @echo 'Variable NAME is not defined.'
    @echo 'Do make newpage NAME='"'"'Page Name'"'"
endif

editpage:
ifdef NAME
    ${EDITOR} ${PAGESDIR}/${SLUG}.$(EXT)
else
    @echo 'Variable NAME is not defined.'
    @echo 'Do make editpage NAME='"'"'Page Name'"'"
endif

I'm on macOS Sierra. Very grateful for any pointers what's going on here.


Solution

  • The makefile rule creates the output file (in this case /Users/robinedwards/Documents/OSU/ghpages/content/test.md), and then it tries to invoke an editor on that file:

    ${EDITOR} ${INPUTDIR}/${SLUG}.${EXT} &
    

    It's a little odd to have an editor invoked from a make recipe but whatever.

    You don't have the environment variable EDITOR set in your environment, so that variable expands to the empty string and so make thinks you're trying to run a program named /Users/robinedwards/Documents/OSU/ghpages/content/test.md which is of course bogus.

    You should do two things: first, edit your makefile to set the EDITOR variable if it's not already set:

    EDITOR ?= emacs
    

    or whatever editor you want... although based on this code it looks like it expects a graphical editor that will start in a new window, because it tries to put the editor in the background,

    And second, you should set your environment variable EDITOR to your preferred editor; many UNIX programs expect that so they can start editors for you. Make sure you export it: export EDITOR=emacs or whatever.