zsh-workers
 help / color / mirror / code / Atom feed
* Implementation of simple newuser module (how to start?)
@ 2005-07-17 20:16 Keir Mierle
  2005-07-18 10:13 ` Peter Stephenson
  2005-07-20 14:01 ` PATCH: " Peter Stephenson
  0 siblings, 2 replies; 9+ messages in thread
From: Keir Mierle @ 2005-07-17 20:16 UTC (permalink / raw)
  To: zsh-workers

It appears there is some consesus on how we can start making zsh more
usable. The idea of a 'newuser' module is great; there's tons of
things we could put in to make it easy for new user while not
frustrating zsh veterans.

I know absolutely nothing about the zsh codebase, so I've started
poking around. Now, in the interest in maximizing the amount of work I
get done while minimizing the amount of time I spend (because I don't
have much time to spend on open source stuff), could the list give me
a brief synopsis of what files I should be looking at, and what files
I should create?

To start, I was thinking of just creating a zsh script to walk the
user through setting up their prompt, turning on completion, and
telling them about autocd and a couple other options.

New idea: Create a 'tips' module that is disabled by default, but
during the newuser tutorial/setup phase, the user can choose to turn
on tips. Tips are very useful because the information is presented one
bit at a time, so users are more likely to remember it. I find startup
tips annoying with GUI programs, because I can usually discover
whatever it is the tip says without any docs just by clicking around,
but for obvious reasons this isn't the case with ZSH, making it an
excellent candidate for tips.

Thanks again,
Keir


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: Implementation of simple newuser module (how to start?)
  2005-07-17 20:16 Implementation of simple newuser module (how to start?) Keir Mierle
@ 2005-07-18 10:13 ` Peter Stephenson
  2005-07-20 14:01 ` PATCH: " Peter Stephenson
  1 sibling, 0 replies; 9+ messages in thread
From: Peter Stephenson @ 2005-07-18 10:13 UTC (permalink / raw)
  To: zsh-workers

Keir Mierle wrote:
> It appears there is some consesus on how we can start making zsh more
> usable. The idea of a 'newuser' module is great; there's tons of
> things we could put in to make it easy for new user while not
> frustrating zsh veterans.

We have to finalise what paths to search and what files to look for.
Bart suggested checking for autoloadable functions.  It's a bit fraught
checking for this in the normal fpath or even in site-functions,
however, unless we use a name that we can be reasonably sure won't
already exist.

I still quite like the idea of simply sourcing, say, the first of
<zsh-files-prefix>/$VERSION/newuser or <zsh-files-prefix>/newuser that
appears.  This can always define or autoload a function and then run
it.  The file also stands out---it's easy to see if you're system's set
up to support the feature, and remove it if you don't want it, and it's
easy to see if there's a file overriding the version-specific one.
The default version could then contain "autoload -U zsh-new-user-setup;
zsh-new-user-setup", for example, and the function could be in, say
Functions/Newuser and installed as part of the newuser module.  (We
would have to add something to the .mdd file to install the newuser file
itself.)

Another question is if zsh/newuser should be loaded before or after
/etc/zshenv (it can't be any later than just after that).

Presumably the code for zsh/newuser will be fairly small, so there's
some reason for it being linked in by default when it's in use (this
doesn't stop it being formally "unloaded" even though it's still
present in virtual memory).  That's easy to configure, however, and we
can mention it in the release notes, so I don't think we need to alter
it in the distribution.

> I know absolutely nothing about the zsh codebase, so I've started
> poking around. Now, in the interest in maximizing the amount of work I
> get done while minimizing the amount of time I spend (because I don't
> have much time to spend on open source stuff), could the list give me
> a brief synopsis of what files I should be looking at, and what files
> I should create?

There's an argument that only .zshrc needs creating.  It varies from
person to person how much people want transferring in .zshenv.  I set
options like extended_glob there so the environment is sane when I run,
say, grep from inside Emacs.  However, some people like a fairly clean
.zshenv.  It's usually OK to set variables there.

Probably just .zshrc would do for now.

> To start, I was thinking of just creating a zsh script to walk the
> user through setting up their prompt, turning on completion, and
> telling them about autocd and a couple other options.

That's probably a good idea, although it needs an easy way to abort and
ensure it's never run again ("touch ${ZDOTDIR:-$HOME}/.zshrc" will do)
and perhaps also to defer running it until the next time (simply
aborting will do).  Also, there are some advantages in having a function
rather than a script, as suggested it above (it can "unfunction" itself
at the end to remove it from memory).  Have you looked at
Completion/compinstall?  It serves as a model for one way of doing this.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************


^ permalink raw reply	[flat|nested] 9+ messages in thread

* PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-17 20:16 Implementation of simple newuser module (how to start?) Keir Mierle
  2005-07-18 10:13 ` Peter Stephenson
@ 2005-07-20 14:01 ` Peter Stephenson
  2005-07-20 18:04   ` Peter Stephenson
  1 sibling, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2005-07-20 14:01 UTC (permalink / raw)
  To: zsh-workers

Here is an initial attempt at the zsh/newuser module.

Note the logic:  the module is loaded and immediately unloaded just
before .zshenv would be run, and under exactly the same conditions (so
/etc/zshenv has just been executed if it exists).  This seems to me to
be about the best choice.  It does mean that the module will be run if
the shell is non-interactive; it is up to the newuser script or whatever
it calls to handle this.  (This might be made clearer in the manual
entry, or alternatively the module could only be run for an interactive
shell.)

I haven't provided any newuser file yet.  Arrangements will have to be
made to instal that: not entirely sure where from, since it's not a
function, possibly Etc which at least has a Makefile.  However, this
should be good enough to play around with your own ideas.  (When I've
worked out how to install it, I may provide an initial newuser file
which simply creates .zshrc with a comment.)

Please suggest improvements to the manual entry if I've made it too
tortuous.

Index: configure.ac
===================================================================
RCS file: /cvsroot/zsh/zsh/configure.ac,v
retrieving revision 1.34
diff -u -r1.34 configure.ac
--- configure.ac	31 May 2005 07:44:11 -0000	1.34
+++ configure.ac	20 Jul 2005 13:59:34 -0000
@@ -286,6 +286,30 @@
 AC_SUBST(sitefndir)dnl
 AC_SUBST(FUNCTIONS_SUBDIRS)dnl
 
+dnl Directories for scripts such as newuser.
+
+ifdef([scriptdir],[undefine([scriptdir])])dnl
+AC_ARG_ENABLE(scriptdir,
+[  --enable-scriptdir=DIR     the directory in which to install scripts],
+dnl ${VERSION} to be determined at compile time.
+[if test $enableval = yes; then
+  scriptdir=${datadir}/${tzsh_name}/'${VERSION}'
+else
+  scriptdir="$enableval"
+fi], [scriptdir=${datadir}/${tzsh_name}/'${VERSION}'])
+
+ifdef([sitescriptdir],[undefine([sitescriptdir])])dnl
+AC_ARG_ENABLE(site-scriptdir,
+[  --enable-site-scriptdir=DIR  same for site scripts (not version specific)],
+[if test $enableval = yes; then
+  sitescriptdir=${datadir}/${tzsh_name}
+else
+  sitescriptdir="$enableval"
+fi], [sitescriptdir=${datadir}/${tzsh_name}])
+
+AC_SUBST(scriptdir)dnl
+AC_SUBST(sitescriptdir)dnl
+
 dnl Do you want maildir support?
 ifdef([maildir_support],[undefine([maildir_support])])dnl
 AH_TEMPLATE([MAILDIR_SUPPORT],
Index: Config/defs.mk.in
===================================================================
RCS file: /cvsroot/zsh/zsh/Config/defs.mk.in,v
retrieving revision 1.9
diff -u -r1.9 defs.mk.in
--- Config/defs.mk.in	4 Feb 2005 16:59:40 -0000	1.9
+++ Config/defs.mk.in	20 Jul 2005 13:59:35 -0000
@@ -43,6 +43,8 @@
 datadir         = @datadir@
 fndir           = @fndir@
 sitefndir       = @sitefndir@
+scriptdir       = @scriptdir@
+sitescriptdir   = @sitescriptdir@
 htmldir         = $(datadir)/$(tzsh)/htmldoc
 
 # compilation
Index: Doc/Makefile.in
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Makefile.in,v
retrieving revision 1.24
diff -u -r1.24 Makefile.in
--- Doc/Makefile.in	6 May 2005 15:53:02 -0000	1.24
+++ Doc/Makefile.in	20 Jul 2005 13:59:35 -0000
@@ -59,7 +59,8 @@
 Zsh/mod_computil.yo \
 Zsh/mod_datetime.yo Zsh/mod_deltochar.yo \
 Zsh/mod_example.yo Zsh/mod_files.yo \
-Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_parameter.yo Zsh/mod_pcre.yo \
+Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_newuser.yo \
+Zsh/mod_parameter.yo Zsh/mod_pcre.yo \
 Zsh/mod_sched.yo Zsh/mod_socket.yo \
 Zsh/mod_stat.yo  Zsh/mod_system.yo Zsh/mod_tcp.yo \
 Zsh/mod_termcap.yo Zsh/mod_terminfo.yo \
Index: Doc/Zsh/mod_newuser.yo
===================================================================
RCS file: Doc/Zsh/mod_newuser.yo
diff -N Doc/Zsh/mod_newuser.yo
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Doc/Zsh/mod_newuser.yo	20 Jul 2005 13:59:36 -0000
@@ -0,0 +1,37 @@
+COMMENT(!MOD!zsh/newuser
+Arrange for files for new users to be installed.
+!MOD!)
+The tt(zsh/newuser) module is loaded at boot if it is
+available, the tt(RCS) option is set, and the tt(PRIVILEGED) option is not
+set (all three are true by default).  This takes
+place immediately after commands in the global tt(zshenv) file (typically
+tt(/etc/zshenv)), if any, have been executed.  If the module is not
+available it is silently ignored by the shell; the module may safely be
+removed from tt($MODULE_PATH) by the administrator if it is not required.
+
+On loading, the module tests if any of the start-up files tt(.zshenv),
+tt(.zprofile), tt(.zshrc) or tt(.zlogin) exist in the directory given by
+the environment variable tt(ZDOTDIR), or the user's home directory if that
+is not set.
+
+If none of the start-up files were found, the module then looks for the
+file tt(newuser) first in a sitewide directory, usually the parent
+directory of the tt(site-functions) directory, and if that is not found the
+module searches in a version-specific directory, usually the parent of the
+tt(functions) directory containing version-specific functions.  (These
+directories can be configured when zsh is built using the
+tt(--enable-site-scriptdir=)var(dir) and tt(--enable-scriptdir=)var(dir)
+flags to tt(configure), respectively; the defaults are
+var(prefix)tt(/share/zsh) and var(prefix)tt(/share/zsh/$ZSH_VERSION) where
+the default var(prefix) is tt(/usr/local).)
+
+If the file tt(newuser) is found, it is then sourced in the same manner as
+a start-up file.  The file is expected to contain code to install start-up
+files for the user, however any valid shell code will be executed.
+
+The tt(zsh/newuser) module is then unconditionally unloaded.
+
+Note that it is possible to achieve exactly the same effect as the
+tt(zsh/newuser) module by adding code to tt(/etc/zshenv).  The module
+exists simply to allow the shell to make arrangements for new users without
+the need for invervention by package maintainers and system administrators.
Index: Src/init.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/init.c,v
retrieving revision 1.54
diff -u -r1.54 init.c
--- Src/init.c	15 Jul 2005 17:41:53 -0000	1.54
+++ Src/init.c	20 Jul 2005 13:59:36 -0000
@@ -948,8 +948,20 @@
 #ifdef GLOBAL_ZSHENV
 	source(GLOBAL_ZSHENV);
 #endif
+
 	if (isset(RCS) && unset(PRIVILEGED))
+	{
+	    /*
+	     * Always attempt to load the newuser module to perform
+	     * checks for new zsh users.  Don't care if we can't load it.
+	     */
+	    if (load_module_silence("zsh/newuser", 1)) {
+		/* Unload it immediately. */
+		unload_named_module("zsh/newuser", "zsh", 1);
+	    }
+
 	    sourcehome(".zshenv");
+	}
 	if (islogin) {
 #ifdef GLOBAL_ZPROFILE
 	    if (isset(RCS) && isset(GLOBALRCS))
Index: Src/module.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/module.c,v
retrieving revision 1.17
diff -u -r1.17 module.c
--- Src/module.c	12 Jan 2005 12:19:06 -0000	1.17
+++ Src/module.c	20 Jul 2005 13:59:36 -0000
@@ -434,12 +434,12 @@
 
 /**/
 static void *
-do_load_module(char const *name)
+do_load_module(char const *name, int silent)
 {
     void *ret;
 
     ret = try_load_module(name);
-    if (!ret) {
+    if (!ret && !silent) {
 	int waserr = errflag;
 	zerr("failed to load module: %s", name, 0);
 	errflag = waserr;
@@ -452,11 +452,12 @@
 
 /**/
 static void *
-do_load_module(char const *name)
+do_load_module(char const *name, int silent)
 {
     int waserr = errflag;
 
-    zerr("failed to load module: %s", name, 0);
+    if (!silent)
+	zerr("failed to load module: %s", name, 0);
     errflag = waserr;
 
     return NULL;
@@ -748,6 +749,13 @@
 mod_export int
 load_module(char const *name)
 {
+    return load_module_silence(name, 0);
+}
+
+/**/
+mod_export int
+load_module_silence(char const *name, int silent)
+{
     Module m;
     void *handle = NULL;
     Linkedmod linked;
@@ -755,7 +763,8 @@
     int set;
 
     if (!modname_ok(name)) {
-	zerr("invalid module name `%s'", name, 0);
+	if (!silent)
+	    zerr("invalid module name `%s'", name, 0);
 	return 0;
     }
     /*
@@ -766,7 +775,7 @@
     queue_signals();
     if (!(node = find_module(name, 1, &name))) {
 	if (!(linked = module_linked(name)) &&
-	    !(handle = do_load_module(name))) {
+	    !(handle = do_load_module(name, silent))) {
 	    unqueue_signals();
 	    return 0;
 	}
@@ -811,7 +820,7 @@
     m->flags |= MOD_BUSY;
     if (m->deps)
 	for (n = firstnode(m->deps); n; incnode(n))
-	    if (!load_module((char *) getdata(n))) {
+	    if (!load_module_silence((char *) getdata(n), silent)) {
 		m->flags &= ~MOD_BUSY;
 		unqueue_signals();
 		return 0;
@@ -820,7 +829,7 @@
     if (!m->u.handle) {
 	handle = NULL;
 	if (!(linked = module_linked(name)) &&
-	    !(handle = do_load_module(name))) {
+	    !(handle = do_load_module(name, silent))) {
 	    unqueue_signals();
 	    return 0;
 	}
@@ -886,7 +895,7 @@
 	    return 0;
 	}
     } else
-	ret = load_module(module);
+	ret = load_module_silence(module, 0);
     unqueue_signals();
 
     return ret;
@@ -1549,6 +1558,50 @@
     return 0;
 }
 
+
+/**/
+int
+unload_named_module(char *modname, char *nam, int silent)
+{
+    const char *mname;
+    LinkNode node;
+    Module m;
+    int ret = 0;
+
+    node = find_module(modname, 1, &mname);
+    if (node) {
+	LinkNode mn, dn;
+	int del = 0;
+
+	for (mn = firstnode(modules); mn; incnode(mn)) {
+	    m = (Module) getdata(mn);
+	    if (m->deps && m->u.handle)
+		for (dn = firstnode(m->deps); dn; incnode(dn))
+		    if (!strcmp((char *) getdata(dn), mname)) {
+			if (m->flags & MOD_UNLOAD)
+			    del = 1;
+			else {
+			    zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname, 0);
+			    return 1;
+			}
+		    }
+	}
+	m = (Module) getdata(node);
+	if (del)
+	    m->wrapper++;
+	if (unload_module(m, node))
+	    ret = 1;
+	if (del)
+	    m->wrapper--;
+    } else if (!silent) {
+	zwarnnam(nam, "no such module %s", modname, 0);
+	ret = 1;
+    }
+
+    return ret;
+}
+
+
 /**/
 static int
 bin_zmodload_load(char *nam, char **args, Options ops)
@@ -1558,39 +1611,9 @@
     int ret = 0;
     if(OPT_ISSET(ops,'u')) {
 	/* unload modules */
-	const char *mname = *args;
 	for(; *args; args++) {
-	    node = find_module(*args, 1, &mname);
-	    if (node) {
-		LinkNode mn, dn;
-		int del = 0;
-
-		for (mn = firstnode(modules); mn; incnode(mn)) {
-		    m = (Module) getdata(mn);
-		    if (m->deps && m->u.handle)
-			for (dn = firstnode(m->deps); dn; incnode(dn))
-			    if (!strcmp((char *) getdata(dn), mname)) {
-				if (m->flags & MOD_UNLOAD)
-				    del = 1;
-				else {
-				    zwarnnam(nam, "module %s is in use by another module and cannot be unloaded", mname, 0);
-				    ret = 1;
-				    goto cont;
-				}
-			    }
-		}
-		m = (Module) getdata(node);
-		if (del)
-		    m->wrapper++;
-		if (unload_module(m, node))
-		    ret = 1;
-		if (del)
-		    m->wrapper--;
-	    } else if (!OPT_ISSET(ops,'i')) {
-		zwarnnam(nam, "no such module %s", *args, 0);
+	    if (unload_named_module(*args, nam, OPT_ISSET(ops,'i')))
 		ret = 1;
-	    }
-	    cont: ;
 	}
 	return ret;
     } else if(!*args) {
@@ -1645,7 +1668,7 @@
 	    /* This is a definition for an autoloaded condition, load the *
 	     * module if we haven't tried that already. */
 	    if (f) {
-		load_module(p->module);
+		load_module_silence(p->module, 0);
 		f = 0;
 		p = NULL;
 	    } else {
@@ -2086,7 +2109,7 @@
 
 		removemathfunc(q, p);
 
-		load_module(n);
+		load_module_silence(n, 0);
 
 		return getmathfunc(name, 0);
 	    }
Index: Src/zsh.mdd
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/zsh.mdd,v
retrieving revision 1.12
diff -u -r1.12 zsh.mdd
--- Src/zsh.mdd	15 Feb 2005 18:32:39 -0000	1.12
+++ Src/zsh.mdd	20 Jul 2005 13:59:36 -0000
@@ -38,6 +38,12 @@
 
 zshpaths.h: Makemod $(CONFIG_INCS)
 	@echo '#define MODULE_DIR "'$(MODDIR)'"' > zshpaths.h.tmp
+	@if test x$(sitescriptdir) != xno; then \
+	  echo '#define SITESCRIPT_DIR "'$(sitescriptdir)'"' >> zshpaths.h.tmp; \
+	fi
+	@if test x$(scriptdir) != xno; then \
+	  echo '#define SCRIPT_DIR "'$(scriptdir)'"' >> zshpaths.h.tmp; \
+	fi
 	@if test x$(sitefndir) != xno; then \
 	  echo '#define SITEFPATH_DIR "'$(sitefndir)'"' >> zshpaths.h.tmp; \
 	fi
Index: Src/Modules/newuser.c
===================================================================
RCS file: Src/Modules/newuser.c
diff -N Src/Modules/newuser.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Src/Modules/newuser.c	20 Jul 2005 13:59:36 -0000
@@ -0,0 +1,99 @@
+/*
+ * newuser.c - handler for easy setup for new zsh users
+ *
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 2005 Peter Stephenson
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Peter Stephenson or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Peter Stephenson and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Peter Stephenson and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose.  The software
+ * provided hereunder is on an "as is" basis, and Peter Stephenson and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+
+#include "newuser.mdh"
+#include "newuser.pro"
+
+#include "../zshpaths.h"
+
+/**/
+int
+setup_(UNUSED(Module m))
+{
+    return 0;
+}
+
+/**/
+static int
+check_dotfile(const char *dotdir, const char *fname)
+{
+    VARARR(char, buf, strlen(dotdir) + strlen(fname) + 2);
+    sprintf(buf, "%s/%s", dotdir, fname);
+
+    return access(buf, F_OK);
+}
+
+/**/
+int
+boot_(UNUSED(Module m))
+{
+    const char *dotdir = getsparam("ZDOTDIR");
+    const char *spaths[] = {
+#ifdef SITESCRIPT_DIR
+	SITESCRIPT_DIR,
+#endif
+#ifdef SCRIPT_DIR
+	SCRIPT_DIR,
+#endif
+	0 };
+    const char **sp;
+
+    if (!dotdir)
+	dotdir = home;
+
+    if (check_dotfile(dotdir, ".zshenv") == 0 ||
+	check_dotfile(dotdir, ".zprofile") == 0 ||
+	check_dotfile(dotdir, ".zshrc") == 0 ||
+	check_dotfile(dotdir, ".zlogin") == 0)
+	return 0;
+
+    for (sp = spaths; *sp; sp++) {
+	VARARR(char, buf, strlen(*sp) + 9);
+	sprintf(buf, "%s/newuser", *sp);
+
+	if (!source(buf))
+	    break;
+    }
+
+    return 0;
+}
+
+/**/
+int
+cleanup_(UNUSED(Module m))
+{
+    return 0;
+}
+
+/**/
+int
+finish_(UNUSED(Module m))
+{
+    return 0;
+}
Index: Src/Modules/newuser.mdd
===================================================================
RCS file: Src/Modules/newuser.mdd
diff -N Src/Modules/newuser.mdd
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Src/Modules/newuser.mdd	20 Jul 2005 13:59:36 -0000
@@ -0,0 +1,12 @@
+name=zsh/newuser
+link=dynamic
+# We will always try to load newuser, but there is
+# no error if it fails.
+load=no
+
+objects="newuser.o"
+
+:<<\Make
+newuser.o:  ../zshpaths.h
+
+Make

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-20 14:01 ` PATCH: " Peter Stephenson
@ 2005-07-20 18:04   ` Peter Stephenson
  2005-07-23  5:10     ` Bart Schaefer
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2005-07-20 18:04 UTC (permalink / raw)
  To: zsh-workers

Here's a basic newuser script to be installed and the outline of the
function that will be doing the work.  The function zsh-install-newuser
is the file to edit to do the work; everything else should work as it is.

We don't want to distribute the shell with this default version of
zsh-install-newuser, which will simply make it harder to fix things
later on; it would be better to have it do nothing.  However, I assume
it will be doing something by then.

I've created a separate Scripts directory for files which will be run
directly by the shell (actually sourced in this case) and adapted the
function installation system to install them.

Index: Makefile.in
===================================================================
RCS file: /cvsroot/zsh/zsh/Makefile.in,v
retrieving revision 1.13
diff -u -r1.13 Makefile.in
--- Makefile.in	3 Mar 2004 19:37:53 -0000	1.13
+++ Makefile.in	20 Jul 2005 17:59:57 -0000
@@ -84,6 +84,7 @@
 	  test x$(sitefndir) != xno && \
 	    $(SHELL) $(sdir_top)/mkinstalldirs $(DESTDIR)$(sitefndir); \
 	  sdir_top="$(sdir_top)" fndir="$(fndir)" dir_top="$(dir_top)" \
+	  scriptdir="$(scriptdir)" \
 	  FUNCTIONS_SUBDIRS="$(FUNCTIONS_SUBDIRS)" \
 	  INSTALL_DATA="$(INSTALL_DATA)" \
 	  DESTDIR="$(DESTDIR)" VERSION="$(VERSION)" \
@@ -94,6 +95,7 @@
 uninstall.fns:
 	if test x$(fndir) != x && test x$(fndir) != xno; then \
 	  fndir="$(fndir)" dir_top="$(dir_top)" \
+	  scriptdir="$(scriptdir)" \
 	  FUNCTIONS_SUBDIRS="$(FUNCTIONS_SUBDIRS)" \
 	  DESTDIR="$(DESTDIR)" VERSION="$(VERSION)" \
 	  $(SHELL) $(sdir_top)/Config/uninstallfns.sh || exit 1; \
Index: Config/installfns.sh
===================================================================
RCS file: /cvsroot/zsh/zsh/Config/installfns.sh,v
retrieving revision 1.10
diff -u -r1.10 installfns.sh
--- Config/installfns.sh	13 Feb 2003 16:34:36 -0000	1.10
+++ Config/installfns.sh	20 Jul 2005 17:59:57 -0000
@@ -1,6 +1,7 @@
 #!/bin/sh
 
 fndir=$DESTDIR$fndir
+scriptdir=$DESTDIR$scriptdir
 
 /bin/sh $sdir_top/mkinstalldirs $fndir || exit 1;
 
@@ -25,13 +26,23 @@
       Completion/*)
         instdir="$fndir/Completion"
         ;;
+      Scripts/*)
+        instdir="$scriptdir"
+	;;
       *)
         subdir="`echo $file | sed -e 's%/[^/]*$%%' -e 's%^Functions/%%'`"
         instdir="$fndir/$subdir"
         ;;
       esac
     else
-      instdir="$fndir"
+      case "$file" in
+      Scripts/*)
+        instdir="$scriptdir"
+	;;
+      *)
+        instdir="$fndir"
+        ;;
+      esac
     fi
     test -d $instdir || /bin/sh $sdir_top/mkinstalldirs $instdir || exit 1
     $INSTALL_DATA $sdir_top/$file $instdir || exit 1
Index: Config/uninstallfns.sh
===================================================================
RCS file: /cvsroot/zsh/zsh/Config/uninstallfns.sh,v
retrieving revision 1.3
diff -u -r1.3 uninstallfns.sh
--- Config/uninstallfns.sh	4 Dec 2000 19:21:07 -0000	1.3
+++ Config/uninstallfns.sh	20 Jul 2005 17:59:57 -0000
@@ -1,6 +1,7 @@
 #!/bin/sh
 
 fndir=$DESTDIR$fndir
+scriptdir=$DESTDIR$scriptdir
 
 allfuncs="`grep ' functions=' ${dir_top}/config.modules |
   sed -e '/^#/d' -e '/ link=no/d' -e 's/^.* functions=//'`"
@@ -10,10 +11,6 @@
 case $fndir in
   *$VERSION*)
      # Version specific function directory, safe to remove completely.
-     # However, we don't remove the top-level version directory since
-     # it could have other things than functions in it.  We could
-     # do that instead in the top-level Makefile on a full uninstall,
-     # if we wanted.
      rm -rf $fndir
      ;;
   *) # The following will only apply with a custom install directory
@@ -22,15 +19,39 @@
      # We now have a list of files, but we need to use `test -f' to check
      # (1) the glob got expanded (2) we are not looking at directories.
      for file in $allfuncs; do
-       if test -f $sdir_top/$file; then
-	 if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then
-	   file=`echo $file | sed -e 's%%^Functions/%'`
-	   rm -f $fndir/$file;
-	 else
-	   bfile="`echo $file | sed -e 's%^.*/%%'`"
-	   rm -f "$fndir/$bfile"; \
-	 fi
-       fi
+       case $file in
+       Scripts/*)
+	 ;;
+       *)
+         if test -f $sdir_top/$file; then
+	   if test x$FUNCTIONS_SUBDIRS != x -a x$FUNCTIONS_SUBDIRS != xno; then
+	     file=`echo $file | sed -e 's%%^(Functions|Completion)/%'`
+	     rm -f $fndir/$file
+	   else
+	     bfile="`echo $file | sed -e 's%^.*/%%'`"
+	     rm -f "$fndir/$bfile"
+	   fi
+         fi
+	 ;;
+       esac
+     done
+     ;;
+esac
+
+case $scriptdir in
+  *$VERSION*)
+     # $scriptdir might be the parent of fndir.
+     rm -rf $scriptdir
+     ;;
+  *) for file in $allfuncs; do
+	case $file in
+	Scripts/*)
+	  if test -f $sdir_top/$file; then
+	    bfile="`echo $file | sed -e 's%^.*/%%'`"
+	    rm -f "$scriptdir/$bfile"
+	  fi
+	  ;;
+	esac
      done
      ;;
 esac
Index: Functions/Newuser/zsh-install-newuser
===================================================================
RCS file: Functions/Newuser/zsh-install-newuser
diff -N Functions/Newuser/zsh-install-newuser
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Functions/Newuser/zsh-install-newuser	20 Jul 2005 17:59:57 -0000
@@ -0,0 +1,11 @@
+# Function to install startup files for a new user.
+# This dummy version simply creates a new .zshrc with a comment.
+# FIXME: we don't want to distribute a file that does that, it
+# would be preferable to do nothing at all.
+
+# Sanitize environment.
+emulate -L zsh
+
+echo "# Created by newuser for $ZSH_VERSION" >${ZDOTDIR:-$HOME}/.zshrc
+
+unfunction zsh-install-newuser
Index: Scripts/newuser
===================================================================
RCS file: Scripts/newuser
diff -N Scripts/newuser
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Scripts/newuser	20 Jul 2005 17:59:57 -0000
@@ -0,0 +1,6 @@
+# zsh script sourced at startup when a user is found to have
+# no startup files.  See the documentation for the zsh/newuser
+# module in zshmodules(1).
+
+autoload -U zsh-install-newuser
+zsh-install-newuser
Index: Src/Modules/newuser.mdd
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/Modules/newuser.mdd,v
retrieving revision 1.1
diff -u -r1.1 newuser.mdd
--- Src/Modules/newuser.mdd	20 Jul 2005 16:08:23 -0000	1.1
+++ Src/Modules/newuser.mdd	20 Jul 2005 17:59:57 -0000
@@ -1,8 +1,9 @@
 name=zsh/newuser
 link=dynamic
-# We will always try to load newuser, but there is
-# no error if it fails.
+# We will always try to load newuser, but there should
+# be no error if it fails, so don't use the standard mechanism.
 load=no
+functions='Scripts/newuser Functions/Newuser/*'
 
 objects="newuser.o"
 
-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-20 18:04   ` Peter Stephenson
@ 2005-07-23  5:10     ` Bart Schaefer
  2005-07-25  9:36       ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 2005-07-23  5:10 UTC (permalink / raw)
  To: zsh-workers

On Jul 20,  7:04pm, Peter Stephenson wrote:
} Subject: Re: PATCH: Re: Implementation of simple newuser module (how to st
}
} Here's a basic newuser script to be installed and the outline of the
} function that will be doing the work.
} 
} +# zsh script sourced at startup when a user is found to have
} +# no startup files.  See the documentation for the zsh/newuser
} +# module in zshmodules(1).
} +
} +autoload -U zsh-install-newuser
} +zsh-install-newuser

I suggest that instead this be:

 autoload -U +X zsh-install-newuser && zsh-install-newuser

That is, don't execute the function if it can't be autoloaded, and don't
redefine it if it is already defined.


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-23  5:10     ` Bart Schaefer
@ 2005-07-25  9:36       ` Peter Stephenson
  2005-07-26 10:21         ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2005-07-25  9:36 UTC (permalink / raw)
  To: zsh-workers

Bart Schaefer wrote:
> } +autoload -U zsh-install-newuser
> } +zsh-install-newuser
> 
> I suggest that instead this be:
> 
>  autoload -U +X zsh-install-newuser && zsh-install-newuser
> 
> That is, don't execute the function if it can't be autoloaded, and don't
> redefine it if it is already defined.

But autoload +X returns false if the function was already defined, so it
wouldn't execute the function in that case.

I have belatedly realised that zsh-newuser-install would probably be a
better name, since if the function gets split up into smaller functions
it gives a namespace.

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-25  9:36       ` Peter Stephenson
@ 2005-07-26 10:21         ` Peter Stephenson
  2005-07-26 14:12           ` Bart Schaefer
  0 siblings, 1 reply; 9+ messages in thread
From: Peter Stephenson @ 2005-07-26 10:21 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson wrote:
> Bart Schaefer wrote:
> > } +autoload -U zsh-install-newuser
> > } +zsh-install-newuser
> > 
> > I suggest that instead this be:
> > 
> >  autoload -U +X zsh-install-newuser && zsh-install-newuser
> > 
> > That is, don't execute the function if it can't be autoloaded, and don't
> > redefine it if it is already defined.
> 
> But autoload +X returns false if the function was already defined, so it
> wouldn't execute the function in that case.

The following takes account of that.

> I have belatedly realised that zsh-newuser-install would probably be a
> better name, since if the function gets split up into smaller functions
> it gives a namespace.

I'll change this at the same time.

I've made the function a bit safer, so that if it gets run automatically
it doesn't trash .zshrc.  In future it may well be smart enough to be
able to update existing files, in which case the test won't be
appropriate.

Index: Functions/Newuser/.distfiles
===================================================================
RCS file: /cvsroot/zsh/zsh/Functions/Newuser/.distfiles,v
retrieving revision 1.1
diff -u -r1.1 .distfiles
--- Functions/Newuser/.distfiles	21 Jul 2005 13:45:27 -0000	1.1
+++ Functions/Newuser/.distfiles	26 Jul 2005 10:18:55 -0000
@@ -1,4 +1,4 @@
 DISTFILES_SRC='
 .distfiles
-zsh-install-newuser
+zsh-newuser-install
 '
Index: Functions/Newuser/zsh-install-newuser
===================================================================
RCS file: Functions/Newuser/zsh-install-newuser
diff -N Functions/Newuser/zsh-install-newuser
--- Functions/Newuser/zsh-install-newuser	20 Jul 2005 18:08:53 -0000	1.1
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,11 +0,0 @@
-# Function to install startup files for a new user.
-# This dummy version simply creates a new .zshrc with a comment.
-# FIXME: we don't want to distribute a file that does that, it
-# would be preferable to do nothing at all.
-
-# Sanitize environment.
-emulate -L zsh
-
-echo "# Created by newuser for $ZSH_VERSION" >${ZDOTDIR:-$HOME}/.zshrc
-
-unfunction zsh-install-newuser
Index: Functions/Newuser/zsh-newuser-install
===================================================================
RCS file: Functions/Newuser/zsh-newuser-install
diff -N Functions/Newuser/zsh-newuser-install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Functions/Newuser/zsh-newuser-install	26 Jul 2005 10:18:55 -0000
@@ -0,0 +1,23 @@
+# Function to install startup files for a new user.
+# This dummy version simply creates a new .zshrc with a comment.
+# FIXME: we don't want to distribute a file that does that, it
+# would be preferable to do nothing at all.
+
+# Sanitize environment.
+emulate -L zsh
+
+local zd=${ZDOTDIR:-$HOME}
+
+# The zsh/newuser module already tests for the following, so this test only
+# triggers if zsh-newuser-install is run by hand.
+#
+# In future we may want to use this mechanism to update startup files.
+if [[ -e $zd/.zshenv || -e $zd/.zprofile || -e $zd/.zshrc || -e $zs/.zlogin ]]
+then
+  print "zsh-newuser-install:  startup files exist, aborting" >&2
+  return 1
+fi
+
+echo "# Created by newuser for $ZSH_VERSION" >$zd/.zshrc
+
+unfunction zsh-newuser-install
Index: Scripts/newuser
===================================================================
RCS file: /cvsroot/zsh/zsh/Scripts/newuser,v
retrieving revision 1.1
diff -u -r1.1 newuser
--- Scripts/newuser	20 Jul 2005 18:08:53 -0000	1.1
+++ Scripts/newuser	26 Jul 2005 10:18:55 -0000
@@ -2,5 +2,7 @@
 # no startup files.  See the documentation for the zsh/newuser
 # module in zshmodules(1).
 
-autoload -U zsh-install-newuser
-zsh-install-newuser
+if functions zsh-newuser-install >/dev/null 2>&1 ||
+   autoload -U +X zsh-newuser-install; then
+   zsh-newuser-install
+fi

-- 
Peter Stephenson <pws@csr.com>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-26 10:21         ` Peter Stephenson
@ 2005-07-26 14:12           ` Bart Schaefer
  2005-07-26 15:08             ` Peter Stephenson
  0 siblings, 1 reply; 9+ messages in thread
From: Bart Schaefer @ 2005-07-26 14:12 UTC (permalink / raw)
  To: zsh-workers

On Jul 26, 11:21am, Peter Stephenson wrote:
} Subject: Re: PATCH: Re: Implementation of simple newuser module (how to st
}
} Peter Stephenson wrote:
} > Bart Schaefer wrote:
} > >  autoload -U +X zsh-install-newuser && zsh-install-newuser
} > 
} > But autoload +X returns false if the function was already defined,
} > so it wouldn't execute the function in that case.
} 
} The following takes account of that.

Sorry, I forgot to respond to this thread yesterday ...

It was actually my intention that the function not be executed if it
is not the same function loaded by this module.  If the sysadmin has
gone to the trouble of defining a zsh-install-newuser [sic] then he
ought to run it himself, or be able to decide when it is run, without
this module jumping in.

However, I don't have any strong objection to what's in your patch.

} I've made the function a bit safer, so that if it gets run
} automatically it doesn't trash .zshrc.

You mean, if it gets run manually?

I'd have been tempted to setopt noclobber after the emulate ...


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: PATCH: Re: Implementation of simple newuser module (how to start?)
  2005-07-26 14:12           ` Bart Schaefer
@ 2005-07-26 15:08             ` Peter Stephenson
  0 siblings, 0 replies; 9+ messages in thread
From: Peter Stephenson @ 2005-07-26 15:08 UTC (permalink / raw)
  To: zsh-workers

Bart Schaefer wrote:
> It was actually my intention that the function not be executed if it
> is not the same function loaded by this module.  If the sysadmin has
> gone to the trouble of defining a zsh-install-newuser [sic] then he
> ought to run it himself, or be able to decide when it is run, without
> this module jumping in.

OK, I can see that's reasonable, but I would hope any sysadmin
sophisticated enough to have their own mechanism would remove the
zsh/newuser module.  (We will need to add notes to INSTALL and probably
README when we know what it actually does to give the sufficiently aware
notice.)

> } I've made the function a bit safer, so that if it gets run
> } automatically it doesn't trash .zshrc.
> 
> You mean, if it gets run manually?

Yes.

> I'd have been tempted to setopt noclobber after the emulate ...

As I indicated, I imagine the code will mature in such away as to make
this less relevant, but I think we're covered for now.

pws


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2005-07-26 15:08 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-07-17 20:16 Implementation of simple newuser module (how to start?) Keir Mierle
2005-07-18 10:13 ` Peter Stephenson
2005-07-20 14:01 ` PATCH: " Peter Stephenson
2005-07-20 18:04   ` Peter Stephenson
2005-07-23  5:10     ` Bart Schaefer
2005-07-25  9:36       ` Peter Stephenson
2005-07-26 10:21         ` Peter Stephenson
2005-07-26 14:12           ` Bart Schaefer
2005-07-26 15:08             ` Peter Stephenson

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).