Commits

Thomas Waldmann committed 46ed410 Merge

merged

  • Participants
  • Parent commits c97528d, f56612f

Comments (0)

Files changed (4)

File MoinMoin/converter/_tests/test_rst_in.py

File contents unchanged.

File MoinMoin/converter/rst_in.py

 from MoinMoin import log
 logging = log.getLogger(__name__)
 
+from flask import request
 from flask import g as flaskg
 
 from MoinMoin import config
 from MoinMoin.util.iri import Iri
-from MoinMoin.util.tree import html, moin_page, xlink
+from MoinMoin.util.tree import html, moin_page, xlink, xinclude
 from MoinMoin.constants.contenttypes import CHARSET
 
 from ._util import allowed_uri_scheme, decode_data, normalize_split_text
         self.header_size = 1
         self.status = ['document']
         self.footnotes = dict()
+        self.last_lineno = 0
+        self.current_lineno = 0
 
     def dispatch_visit(self, node):
         """
         """
         node_name = node.__class__.__name__
         method = getattr(self, 'visit_' + node_name, self.unknown_visit)
+        self.current_lineno = node.line
         return method(node)
 
     def dispatch_departure(self, node):
         pass
 
     def open_moin_page_node(self, mointree_element):
+        if request.user_agent and flaskg.user.edit_on_doubleclick:
+            # add data-lineno attribute for auto-scrolling edit textarea (user_agent is None when running tests)
+            if self.last_lineno < self.current_lineno:
+                mointree_element.attrib[html.data_lineno] = self.current_lineno
+                self.last_lineno = self.current_lineno
         self.current_node.append(mointree_element)
         self.current_node = mointree_element
         self.path.append(mointree_element)
 """
 make.py provides a menu of commands frequently used by moin2 developers and desktop wiki users.
 
-    - duplicates some common moin commands, do "moin --help" for all alternatives
+    - wraps a few commonly used moin commands, do "moin --help" for other alternatives
     - adds default file names for selected moin commands (backup, restore, ...)
     - creates log files for functions with large output, extracts success/failure messages
-    - displays error messages when user tries to run commands out of sequence
+    - displays error messages if user tries to run commands out of sequence
 
 usage (to display a menu of commands):
+
     - unix:     ./m
     - windows:  m
 
 For make.py to work, it needs to know the name of a python executable and the location of a
 virtual env. These needs are met by running "python quickinstall.py" after cloning the moin2
-repository. quickinstall.py creates these files or symlinks in the repo root:
-    - unix: m, activate, moin
-    - windows: m.bat, activate.bat, deactivate.bat, moin.bat
+repository. quickinstall.py creates these files or symlink in the repo root:
+
+    - unix: m, activate
+    - windows: m.bat, activate.bat, deactivate.bat
 
 Executing m.bat or ./m will run make.py. The name of the python executable is within the m.bat or ./m
-script.  The location of the virtual env is within the activate and moin symlinks or activate.bat and
-moin.bat scripts. Depending upon the command to be executed, some mix of the python executable, moin,
+script.  The location of the virtual env is within the activate symlink or activate.bat.
+Depending upon the command to be executed, some mix of the python executable
 or activate will be used to construct a command string to pass to a subprocess call.
 """
 
 EXTRAS = 'm-extras.txt'
 DIST = 'm-create-dist.txt'
 # default files used for backup and restore
-BACKUP_FILENAME = 'wiki/backup.moin'
-JUST_IN_CASE_BACKUP = 'wiki/deleted-backup.moin'
+BACKUP_FILENAME = os.path.normpath('wiki/backup.moin')
+JUST_IN_CASE_BACKUP = os.path.normpath('wiki/deleted-backup.moin')
 
 
 if os.name == 'nt':
     M = 'm'  # customize help to local OS
+    ACTIVATE = 'activate.bat & '
+    SEP = ' & '
     WINDOWS_OS = True
 else:
     M = './m'
+    # in terminal "source activate" works, but Ubuntu shell requires ". ./activate"
+    ACTIVATE = '. ./activate; '
+    SEP = ';'
     WINDOWS_OS = False
 
 
 }
 
 
-help = r"""
+help = """
 
-usage: "%s <target>" where <target> is:
+usage: "{0} <target>" where <target> is:
 
 quickinstall    update virtual environment with required packages
 docs            create moin html documentation
 extras          install OpenID, Pillow, pymongo, sqlalchemy, ldap, upload.py
-interwiki       refresh contrib\interwiki\intermap.txt (hg version control)
+interwiki       refresh contrib/interwiki/intermap.txt (hg version control)
 log <target>    view detailed log generated by <target>, omit to see list
 
 new-wiki        create empty wiki
 sample          create wiki and load sample data
-restore *       create wiki and restore wiki\backup.moin *option, specify file
+restore *       create wiki and restore wiki/backup.moin *option, specify file
 import <dir>    import a moin 1.9 wiki/data instance from <dir>
 
-run             run built-in wiki server with local OS and logging options
+run             run built-in wiki server
 backup *        roll 3 prior backups and create new backup *option, specify file
 
 css             run Stylus to update CSS files
 tests           run tests, output goes to pytest.txt and pytestpep8.txt
 coding-std      correct scripts that taint the repository with trailing spaces..
 api             update moin api docs (files are under hg version control)
-dist            delete wiki data, then create distribution archive in /dist
+dist            delete wiki data, then create distribution archive in dist/
 
 del-all         same as running the 4 del-* commands below
 del-orig        delete all files matching *.orig
 del-pyc         delete all files matching *.pyc
 del-rej         delete all files matching *.rej
 del-wiki        create a backup, then delete all wiki data
-""" % M
+""".format(M)
 
 
 def search_for_phrase(filename):
 
 
 def wiki_exists():
-    """Return truthy if a wiki exists."""
-    return glob.glob('wiki/index/_all_revs_*.toc')
+    """Return true if a wiki exists."""
+    return bool(glob.glob('wiki/index/_all_revs_*.toc'))
 
 
 def make_wiki(command):
     if wiki_exists():
         print 'Error: a wiki exists, delete it and try again.'
     else:
-        print 'Output messages redirected to %s' % NEWWIKI
+        print 'Output messages redirected to {0}.'.format(NEWWIKI)
         with open(NEWWIKI, 'w') as messages:
             result = subprocess.call(command, shell=True, stderr=messages, stdout=messages)
         if result == 0:
 
 def delete_files(pattern):
     """Recursively delete all files matching pattern."""
-    matches = []
+    matches = 0
     for root, dirnames, filenames in os.walk(os.path.abspath(os.path.dirname(__file__))):
         for filename in fnmatch.filter(filenames, pattern):
-            matches.append(os.path.join(root, filename))
-    for match in matches:
-        os.remove(match)
-    print 'Deleted %s files matching "%s".' % (len(matches), pattern)
+            os.remove(os.path.join(root, filename))
+            matches += 1
+    print 'Deleted %s files matching "%s".' % (matches, pattern)
 
 
 class Commands(object):
 
     def cmd_quickinstall(self, *args):
         """create or update a virtual environment with the required packages"""
-        command = '%s quickinstall.py %s' % (sys.executable, ' '.join(args))
-        print 'Running quickinstall.py... output messages redirected to %s' % QUICKINSTALL
+        command = '{0} quickinstall.py {1}'.format(sys.executable, ' '.join(args))
+        print 'Running quickinstall.py... output messages redirected to {0}'.format(QUICKINSTALL)
         with open(QUICKINSTALL, 'w') as messages:
             result = subprocess.call(command, shell=True, stderr=messages, stdout=messages)
         if result != 0:
-            open(QUICKINSTALL, 'a').write('Error: quickinstall passed non-zero return code: %s' % result)
-        print 'Searching %s, important messages are shown below... Do "%s log quickinstall" to see complete log.\n' % (QUICKINSTALL, M)
+            open(QUICKINSTALL, 'a').write('Error: quickinstall passed non-zero return code: {0}'.format(result))
+        print 'Searching {0}, important messages are shown below... Do "{1} log quickinstall" to see complete log.\n'.format(QUICKINSTALL, M)
         search_for_phrase(QUICKINSTALL)
 
     def cmd_docs(self, *args):
         """create local Sphinx html documentation"""
-        if WINDOWS_OS:
-            command = 'activate.bat & cd docs & make.bat html'  # windows separates commands with "&"
-        else:
-            # in terminal "source activate" works, but shell requires "source ./activate"
-            command = 'source ./activate; cd docs; make html'  # unix separates commands with ";"
-        print 'Creating HTML docs... output messages written to %s.' % DOCS
+        command = '{0}cd docs{1} make html'.format(ACTIVATE, SEP)
+        print 'Creating HTML docs... output messages written to {0}.'.format(DOCS)
         with open(DOCS, 'w') as messages:
             result = subprocess.call(command, shell=True, stderr=messages, stdout=messages)
-        print 'Searching %s, important messages are shown below...\n' % DOCS
+        print 'Searching {0}, important messages are shown below...\n'.format(DOCS)
         search_for_phrase(DOCS)
         if result == 0:
-            print 'HTML docs successfully created in docs/_build/html.'
+            print 'HTML docs successfully created in {0}.'.format(os.path.normpath('docs/_build/html'))
         else:
-            print 'Error: creation of HTML docs failed with return code "%s". Do "%s log docs" to see complete log.' % (result, M)
+            print 'Error: creation of HTML docs failed with return code "{0}". Do "{1} log docs" to see complete log.'.format(result, M)
 
     def cmd_extras(self, *args):
         """install optional packages: OpenID, Pillow, pymongo, sqlalchemy, ldap; and upload.py"""
-        upload = '%s MoinMoin/script/win/wget.py https://codereview.appspot.com/static/upload.py upload.py' % sys.executable
+        upload = '{0} MoinMoin/script/win/wget.py https://codereview.appspot.com/static/upload.py upload.py'.format(sys.executable)
         if WINDOWS_OS:
-            print 'Installing OpenId, Pillow, pymongo, sqlalchemy, upload.py... output messages written to %s.' % EXTRAS
+            print 'Installing OpenId, Pillow, pymongo, sqlalchemy, upload.py... output messages written to {0}.'.format(EXTRAS)
             # easy_install is used for windows because it installs binary packages, pip does not
-            command = 'activate.bat & easy_install python-openid & easy_install pillow & easy_install pymongo & easy_install sqlalchemy' + ' & ' + upload
+            command = ACTIVATE + 'easy_install python-openid & easy_install pillow & easy_install pymongo & easy_install sqlalchemy & ' + upload
             # TODO: "easy_install python-ldap" fails on windows
             # try google: installing python-ldap in a virtualenv on windows
             # or, download from http://www.lfd.uci.edu/~gohlke/pythonlibs/#python-ldap
             #   activate.bat
             #   easy_install <path to downloaded .exe file>
         else:
-            print 'Installing OpenId, Pillow, pymongo, sqlalchemy, ldap, upload.py... output messages written to %s.' % EXTRAS
-            command = 'source ./activate; pip install python-openid; pip install pillow; pip install pymongo; pip install sqlalchemy; pip install python-ldap' + '; ' + upload
+            print 'Installing OpenId, Pillow, pymongo, sqlalchemy, ldap, upload.py... output messages written to {0}.'.format(EXTRAS)
+            command = ACTIVATE + 'pip install python-openid; pip install pillow; pip install pymongo; pip install sqlalchemy; pip install python-ldap; ' + upload
         with open(EXTRAS, 'w') as messages:
             subprocess.call(command, shell=True, stderr=messages, stdout=messages)
-        print 'Important messages from %s are shown below. Do "%s log extras" to see complete log.' % (EXTRAS, M)
+        print 'Important messages from {0} are shown below. Do "{1} log extras" to see complete log.'.format(EXTRAS, M)
         search_for_phrase(EXTRAS)
 
     def cmd_interwiki(self, *args):
-        """refresh contrib\interwiki\intermap.txt"""
-        print 'Refreshing contrib\interwiki\intermap.txt...'
-        command = '%s MoinMoin/script/win/wget.py http://master19.moinmo.in/InterWikiMap?action=raw contrib/interwiki/intermap.txt' % sys.executable
+        """refresh contrib/interwiki/intermap.txt"""
+        print 'Refreshing {0}...'.format(os.path.normpath('contrib/interwiki/intermap.txt'))
+        command = '{0} MoinMoin/script/win/wget.py http://master19.moinmo.in/InterWikiMap?action=raw contrib/interwiki/intermap.txt'.format(sys.executable)
         subprocess.call(command, shell=True)
 
     def cmd_log(self, *args):
 
         def log_help(logs):
             """Print list of available logs to view."""
-            print "usage: %s log <target> where <target> is:\n\n" % M
+            print "usage: {0} log <target> where <target> is:\n\n".format(M)
             choices = '{0: <16}- {1}'
             for log in sorted(logs):
                 if os.path.isfile(CMD_LOGS[log]):
         logs = set(CMD_LOGS.keys())
         if args and args[0] in logs and os.path.isfile(CMD_LOGS[args[0]]):
             if WINDOWS_OS:
-                command = 'start %s' % CMD_LOGS[args[0]]
+                command = 'start {0}'.format(CMD_LOGS[args[0]])
             else:
-                command = '${VISUAL:-${FCEDIT:-${EDITOR:-less}}} %s' % CMD_LOGS[args[0]]
+                # .format requires {{ and }} to escape { and }
+                command = '${{VISUAL:-${{FCEDIT:-${{EDITOR:-less}}}}}} {0}'.format(CMD_LOGS[args[0]])
             subprocess.call(command, shell=True)
         else:
             log_help(logs)
 
     def cmd_new_wiki(self, *args):
         """create empty wiki"""
-        if WINDOWS_OS:
-            command = 'moin.bat index-create -s -i'
-        else:
-            command = './moin index-create -s -i'
+        command = '{0}moin index-create -s -i'.format(ACTIVATE)
         print 'Creating a new empty wiki...'
         make_wiki(command)  # share code with loading sample data and restoring backups
 
     def cmd_sample(self, *args):
         """create wiki and load sample data"""
-        if WINDOWS_OS:
-            command = 'moin.bat index-create -s -i & moin.bat load --file contrib/serialized/items.moin & moin.bat index-build'
-        else:
-            command = './moin index-create -s -i; ./moin load --file contrib/serialized/items.moin; ./moin index-build'
+        command = '{0}moin index-create -s -i{1} moin load --file contrib/serialized/items.moin{1} moin index-build'.format(ACTIVATE, SEP)
         print 'Creating a new wiki populated with sample data...'
         make_wiki(command)
 
     def cmd_restore(self, *args):
         """create wiki and load data from wiki/backup.moin or user specified path"""
-        if WINDOWS_OS:
-            command = 'moin.bat index-create -s -i & moin.bat load --file %s & moin.bat index-build'
-        else:
-            command = './moin index-create -s -i; ./moin load --file %s; ./moin index-build'
+        command = '{0} moin index-create -s -i{1} moin load --file %s{1} moin index-build'.format(ACTIVATE, SEP)
         filename = BACKUP_FILENAME
         if args:
             filename = args[0]
         if os.path.isfile(filename):
             command = command % filename
-            print 'Creating a new wiki and loading it with data from %s...' % filename
+            print 'Creating a new wiki and loading it with data from {0}...'.format(filename)
             make_wiki(command)
         else:
-            print 'Error: cannot create wiki because %s does not exist.' % filename
+            print 'Error: cannot create wiki because {0} does not exist.'.format(filename)
 
     def cmd_import(self, *args):
         """import a moin 1.9 wiki directory named dir"""
-        if WINDOWS_OS:
-            command = 'moin.bat import19 -s -i --data_dir %s'
-        else:
-            command = './moin import19 -s -i --data_dir %s'
         if args:
             dirname = args[0]
             if os.path.isdir(dirname):
-                command = command % dirname
-                print 'Creating a new wiki populated with data from %s...' % dirname
+                command = '{0}moin import19 -s -i --data_dir {1}'.format(ACTIVATE, dirname)
+                print 'Creating a new wiki populated with data from {0}...'.format(dirname)
                 make_wiki(command)
             else:
-                print 'Error: cannot create wiki because %s does not exist.' % dirname
+                print 'Error: cannot create wiki because {0} does not exist.'.format(dirname)
         else:
             print 'Error: a path to the Moin 1.9 wiki/data data directory is required.'
 
     def cmd_run(self, *args):
-        """run built-in wiki server with local options"""
+        """run built-in wiki server"""
         if wiki_exists():
-            if os.path.isfile('logging.conf'):
-                if WINDOWS_OS:
-                    logfile = 'set MOINLOGGINGCONF=logging.conf & '
-                else:
-                    logfile = 'MOINLOGGINGCONF=logging.conf; export MOINLOGGINGCONF; '
-            else:
-                logfile = ''
-            if WINDOWS_OS:
-                command = '%smoin.bat moin %s --threaded' % (logfile, ' '.join(args))
-            else:
-                command = '%s./moin moin %s' % (logfile, ' '.join(args))
+            command = '{0}moin moin {1}'.format(ACTIVATE, ' '.join(args))
             try:
                 subprocess.call(command, shell=True)
             except KeyboardInterrupt:
-                pass  # on windows pass eliminates traceback but "Terminate batch job..." message is displayed twice
+                pass  # eliminates traceback on windows
         else:
             print 'Error: a wiki must be created before running the built-in server.'
 
             filename = BACKUP_FILENAME
             if args:
                 filename = args[0]
-                print 'Creating a wiki backup to %s...' % filename
+                print 'Creating a wiki backup to {0}...'.format(filename)
             else:
-                print 'Creating a wiki backup to %s after rolling 3 prior backups...' % filename
+                print 'Creating a wiki backup to {0} after rolling 3 prior backups...'.format(filename)
                 b3 = BACKUP_FILENAME.replace('.', '3.')
                 b2 = BACKUP_FILENAME.replace('.', '2.')
                 b1 = BACKUP_FILENAME.replace('.', '1.')
                 for src, dst in ((b2, b3), (b1, b2), (BACKUP_FILENAME, b1)):
                     if os.path.exists(src):
                         os.rename(src, dst)
-            if WINDOWS_OS:
-                command = 'moin.bat save --all-backends --file %s' % filename
-            else:
-                command = './moin save --all-backends --file %s' % filename
+
+            command = '{0}moin save --all-backends --file {1}'.format(ACTIVATE, filename)
             with open(BACKUPWIKI, 'w') as messages:
                 result = subprocess.call(command, shell=True, stderr=messages, stdout=messages)
             if result == 0:
-                print 'Success: wiki was backed up to %s' % filename
+                print 'Success: wiki was backed up to {0}'.format(filename)
             else:
-                print 'Important messages from %s are shown below. Do "%s log backup" to see complete log.' % (BACKUPWIKI, M)
+                print 'Important messages from {0} are shown below. Do "{1} log backup" to see complete log.'.format(BACKUPWIKI, M)
                 search_for_phrase(BACKUPWIKI)
                 print '\nError: attempt to backup wiki failed.'
         else:
     def cmd_css(self, *args):
         """run Stylus to update CSS files"""
         print 'Running Stylus to update CSS files...'
-        if WINDOWS_OS:
-            command = r'cd MoinMoin\themes\modernized\static\css\stylus & stylus --include-css --compress < main.styl > ../common.css'
-        else:
-            command = 'cd MoinMoin/themes/modernized/static/css/stylus; stylus --include-css --compress < main.styl > ../common.css'
+        command = 'cd {0}{1}stylus --include-css --compress < main.styl > ../common.css'.format(os.path.normpath('MoinMoin/themes/modernized/static/css/stylus'), SEP)
         result = subprocess.call(command, shell=True)
-
-        if WINDOWS_OS:
-            command = r'cd MoinMoin\themes\foobar\static\css\stylus & stylus --include-css --compress < main.styl > ../common.css'
-        else:
-            command = 'cd MoinMoin/themes/foobar/static/css/stylus; stylus --include-css --compress < main.styl > ../common.css'
+        command = 'cd {0}{1} stylus --include-css --compress < main.styl > ../common.css'.format(os.path.normpath('MoinMoin/themes/foobar/static/css/stylus'), SEP)
         result2 = subprocess.call(command, shell=True)
 
         if result == 0 and result2 == 0:
     def cmd_tests(self, *args):
         """run tests, output goes to pytest.txt and pytestpep8.txt"""
         print 'Running tests... output written to %s and %s.' % (PYTEST, PEP8)
-        if WINDOWS_OS:
-            command = 'activate.bat & py.test.exe > %s 2>&1 & py.test.exe --pep8 -k pep8 --clearcache > %s 2>&1' % (PYTEST, PEP8)
-        else:
-            command = 'source ./activate; py.test > %s 2>&1; py.test --pep8 -k pep8 --clearcache > %s 2>&1' % (PYTEST, PEP8)
+        command = '{0}py.test > {1} 2>&1{2} py.test --pep8 -k pep8 --clearcache > {3} 2>&1'.format(ACTIVATE, PYTEST, SEP, PEP8)
         result = subprocess.call(command, shell=True)
-        print 'Summary message from %s is shown below. Do "%s log pytest" to see complete log.' % (PYTEST, M)
+        print 'Summary message from {0} is shown below. Do "{1} log pytest" to see complete log.'.format(PYTEST, M)
         search_for_phrase(PYTEST)
-        print 'Summary message from %s is shown below. Do "%s log pep8" to see complete log.' % (PEP8, M)
+        print 'Summary message from {0} is shown below. Do "{1} log pep8" to see complete log.'.format(PEP8, M)
         search_for_phrase(PEP8)
 
     def cmd_coding_std(self, *args):
         """update Sphinx API docs, these docs are under hg version control"""
         print 'Refreshing api docs...'
         if WINDOWS_OS:
-            command = 'activate.bat & sphinx-apidoc -f -o docs/devel/api MoinMoin & %s MoinMoin/script/win/dos2unix.py docs/devel/api' % sys.executable
+            # after update, convert DOS line endings to unix
+            command = '{0}sphinx-apidoc -f -o docs/devel/api MoinMoin & {1} MoinMoin/script/win/dos2unix.py docs/devel/api'.format(ACTIVATE, sys.executable)
         else:
-            command = 'source ./activate; sphinx-apidoc -f -o docs/devel/api MoinMoin'
+            command = '{0}sphinx-apidoc -f -o docs/devel/api MoinMoin'.format(ACTIVATE)
         result = subprocess.call(command, shell=True)
 
     def cmd_dist(self, *args):
         """create distribution archive in dist/"""
-        print 'Deleting wiki data, then creating distribution archive in /dist, output written to %s.' % DIST
+        print 'Deleting wiki data, then creating distribution archive in /dist, output written to {0}.'.format(DIST)
         self.cmd_del_wiki(*args)
-        command = '%s setup.py sdist' % sys.executable
+        command = '{0} setup.py sdist'.format(sys.executable)
         with open(DIST, 'w') as messages:
             result = subprocess.call(command, shell=True, stderr=messages, stdout=messages)
-        print 'Summary message from %s is shown below:' % DIST
+        print 'Summary message from {0} is shown below:'.format(DIST)
         search_for_phrase(DIST)
         if result == 0:
-            print 'Success: a distribution archive was created in /dist.'
+            print 'Success: a distribution archive was created in {0}.'.format(os.path.normpath('/dist'))
         else:
-            print 'Error: create dist failed with return code = %s. Do "%s log dist" to see complete log.' % (result, M)
+            print 'Error: create dist failed with return code = {0}. Do "{1} log dist" to see complete log.'.format(result, M)
 
     def cmd_del_all(self, *args):
         """same as running the 4 del-* commands below"""
 
     def cmd_del_wiki(self, *args):
         """create a just-in-case backup, then delete all wiki data"""
-        if WINDOWS_OS:
-            command = 'moin.bat save --all-backends --file %s' % JUST_IN_CASE_BACKUP
-        else:
-            command = './moin save --all-backends --file %s' % JUST_IN_CASE_BACKUP
+        command = '{0}moin save --all-backends --file {1}'.format(ACTIVATE, JUST_IN_CASE_BACKUP)
         if wiki_exists():
-            print 'Creating a backup named %s; then deleting all wiki data and indexes...' % JUST_IN_CASE_BACKUP
+            print 'Creating a backup named {0}; then deleting all wiki data and indexes...'.format(JUST_IN_CASE_BACKUP)
             with open(DELWIKI, 'w') as messages:
                 result = subprocess.call(command, shell=True, stderr=messages, stdout=messages)
             if result != 0:
-                print 'Error: backup failed with return code = %s. Complete log is in %s.' % (result, DELWIKI)
+                print 'Error: backup failed with return code = {0}. Complete log is in {1}.'.format(result, DELWIKI)
         # destroy wiki even if backup fails
         if os.path.isdir('wiki/data') or os.path.isdir('wiki/index'):
             shutil.rmtree('wiki/data')

File quickinstall.py

 from make import Commands, WINDOWS_OS, M
 
 
-WIN_INFO = 'm.bat, activate.bat, deactivate.bat, and moin.bat are created by quickinstall.py'
-NIX_INFO = 'the m bash script and the activate and moin symlinks are created by quickinstall.py'
+WIN_INFO = 'm.bat, activate.bat, and deactivate.bat are created by quickinstall.py'
+NIX_INFO = 'the m bash script and the activate symlink are created by quickinstall.py'
 
 
 def create_m():
 
     def do_helpers(self):
         """Create small helper scripts or symlinks in repo root, avoid keying the long path to virtual env."""
-        create_m()  # recreate m.bat or ./m to insure it is consistent with activate and moin
+        create_m()  # recreate m.bat or ./m to insure it is consistent with activate
         if WINDOWS_OS:
-            # windows commands are: activate | deactivate | moin
+            # windows commands are: activate | deactivate
             self.create_wrapper('activate.bat', 'activate.bat')
             self.create_wrapper('deactivate.bat', 'deactivate.bat')
-            self.create_wrapper('moin.bat', 'moin.exe')
+            if os.path.exists('moin.bat'):  # cleanup obsolete file - TODO remove after 2014-04
+                os.remove('moin.bat')
         else:
-            # linux commands are: source activate | deactivate | ./moin
+            # linux commands are: source activate | deactivate
             if os.path.exists('activate'):
                 os.unlink('activate')
-            if os.path.exists('moin'):
+            os.symlink(os.path.join(self.dir_venv_bin, 'activate'), 'activate')  # no need to define deactivate on unix
+            if os.path.exists('moin'):  # cleanup obsolete file - TODO remove after 2014-04
                 os.unlink('moin')
-            os.symlink(os.path.join(self.dir_venv_bin, 'activate'), 'activate')  # no need to define deactivate on unix
-            os.symlink(os.path.join(self.dir_venv_bin, 'moin'), 'moin')
 
 
 if __name__ == '__main__':