Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Global installation #50

Open
BarbzYHOOL opened this issue Jan 13, 2019 · 7 comments
Open

Global installation #50

BarbzYHOOL opened this issue Jan 13, 2019 · 7 comments

Comments

@BarbzYHOOL
Copy link
Contributor

I think when we install fundle in /etc/fish, the plugins should also be in a global directory so all users use the same plugins instead of installing each plugin for each user (which wastes time and disk)

@hunter-richardson
Copy link
Contributor

hunter-richardson commented Feb 13, 2019

One way I got this to work is place fundle.fish under /root/.config/fish/functions:

for i in functions completions
	command sudo wget https://raw.githubusercontent.com/danhper/fundle/master/$i/fundle.fish -O /root/.config/fish/$i/fundle.fish
	command sudo chmod o+x /root/.config/fish/$i/fundle.fish
end

... in /root/.config/fish/config.fish (or a file it references), set up the plugins and ln the loaded files to /etc/fish:

builtin source /root/.config/fish/functions/fundle.fish
fundle plugin 'one-line/per-plugin'
fundle init
if test ! -d /root/.config/fish/fundle
	fundle install
	for i in (fundle list | command grep -v https://github.com)
		for f in functions completions
			builtin test -d /root/.config/fish/fundle/$i/$f;
				and command chmod a+x /root/.config/fish/fundle/$i/$f/*;
				and command ln -v /root/.config/fish/fundle/$i/$f/* /etc/fish/$f/
		end
	end
end

Then just make sure root is the only one who updates fundle:

function __update_fundle
	command sudo --user=root fish -c "builtin source /root/.config/fish/functions/fundle.fish; fundle self-update; and fundle clean; and fundle update"
end

It's definitely not ideal, but it works.

@BarbzYHOOL
Copy link
Contributor Author

yeah, with symlink there is always a solution xD but it's damn dirty

thank you for idea, for now I just install it on every user (hopefully in my final setup I'll have only 2 users lol)

@BarbzYHOOL
Copy link
Contributor Author

@danhper

@danhper
Copy link
Owner

danhper commented Oct 26, 2022

Hey, I agree this would be nicer indeed!
Would you have time to send a PR for this please?

@BarbzYHOOL
Copy link
Contributor Author

I don't know how to code this, I know a bit of fish scripting but what would be a good way to do all of this? at least if there was a plan to follow, me or someone could attempt to follow it

@hunter-richardson
Copy link
Contributor

hunter-richardson commented Oct 26, 2022

Okay, let's place functions/fundle.fish under /root/.config/fish/functions, and optionally sym-link it to /etc/fish/functions to allow non-sudoer plugin installation:

for i in functions completions
	command sudo mkdir -pv /etc/fish/$i /root/.config/$i
		and command sudo wget --show-progress -v https;//raw.githubusercontent.com/danhper/fundle/master/$i/fundle.fish -O /root/.config/fish/$i/
		and command sudo ln -v /root/.config/fish/$i/fundle.fish /etc/fish/$i/ # allows non-sudoer plugin installation
		and command chmod -c a+rx /root/.config/$i/fundle.fish # allows non-sudoer plugin installation
end

Configure /root/.config/fish/config.fish for fundle, if necessary:

builtin source /root/.config/fish/functions/fundle.fish

Write the following functions to functions/fundle.fish:

function __fundle_validate_sudo -d "test whether the user is a sudoer"
	command sudo -v
	builtin set -l temp $status
	builtin printf 'You are %sa sudoer!' (builtin test $temp -eq 0
											or builtin printf 'not ')
	builtin return $temp
end

functions __fundle_is_global -d "test whether fundle is installed globally or locally"
	builtin string match -qr (builtin printf '^/home/%s' (command whoami)) (builtin status fish-path)
		and builtin printf 'You should have installed fundle globally!\nSee https://github.com/danhper/fundle#global-installation'
		and builtin return 1
	builtin return 0
end

functions __fundle_list_plugins -d "list installed plugins under given directory" -a dir
	builtin test -n "$dir" -a -d $dir -a -r $dir
		and command find $dir -type d -mindepth 2 -maxdepth 2 2>/dev/null | command string replace $dir ''
end

function __fundle_local_plugins -d "list locally installed plugins"
	__fundle_list_plugins __fundle_plugins_dir
end

function __fundle_global_plugins -d "list globally installed plugins"
	__fundle_list_plugins /etc/fish/fundle
end

function __fundle_plugins -d "list all available plugins"
	begin; __fundle_global_plugins; and __fundle_local_plugins; end | command sort -dfu
end

function __fundle_global_plugin -d "install global plugin to fundle"
	__fundle_is_global
		or builtin return $status
	__fundle_validate_sudo
		or builtin return $status
	builtin set -l name (command awk -F '[[:blank:]@]+' '{print $1}' "$argv")
	command sudo --user=root fish -c "fundle plugin $argv; and fundle init; and fundle install; and command chmod -cR a+rx /root/.config/fish"
		and for f in (command find -L /root/.config/fish/fundle/$name -type f -name '*.fish')
				builtin set -l dir (builtin string replace /root/.config /etc (command dirname $f))
					and command mkdir -pv $dir
					and command sudo ln -v $f $dir
			end
end

function __fundle_update_global -d "update global plugins" -a name
	__fundle_is_global
		or builtin return $status
	__fundle_validate_sudo
		or builtin return $status
	builtin test -n "$name"
		and command sudo --user=root fish -c "fundle update $name"
		or command sudo --user=root fish -c "fundle update"
end

The following cases under the switch in the fundle function itself:

		case "global-plugin"
			__fundle_global_plugin $sub_args
		case "global-update"
			__fundle_update_global $sub_args

And the following lines to completions/fundle.fish:

builtin complete -f -c fundle -n '__fish_prog_needs_command' -a global-plugin -d "add a global plugin"
builtin complete -f -c fundle -n '__fish_prog_needs_command' -a global-update -d "update existing global plugin"
builtin complete -f -c fundle -n '__fish_prog_using_command global-plugin' -l url -d "set the plugin URL"
builtin complete -f -c fundle -n '__fish_prog_using_command global-plugin' -l path -d "set the plugin load path"

Now prevent the local installation of plugins already installed globally:

functions __fundle_plugin -d "add plugin to fundle" -a name
	...
		if not contains $name (__fundle_plugins)
			...
		end
end

Then configure the global /etc/fish/config.fish to search for sym-links, depth-last (this might break for paths containing whitespace):

for f in (command find /etc/fish -type l -name '*.fish' -printf '%d %p\n' | command sort | command cut -d' ' -f2-)
	builtin source (command readlink -f "$f")
end

Now (unless I missed something) a sudoer may choose to install/update plugins for all users, and to allow non-sudoers to install any other plugin.

NOTE: Due to complexity of the __fundle_global_plugin function (which is due to the sym-linking), there's no need to run fundle init or after fundle global-plugin <plugin-identifier>. They simply need to source /etc/fish/config.fish to load freshly-installed global plugins.

@BarbzYHOOL
Copy link
Contributor Author

BarbzYHOOL commented Oct 27, 2022

Why not make a PR if you have sorted it out Hunter?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants