andsens / homeshick

git dotfiles synchronizer written in bash
MIT License
2.08k stars 147 forks source link

Support linking different files on different systems #77

Open andsens opened 10 years ago

andsens commented 10 years ago

@iron8core has forked the repo and implemented a nifty feature: linking based on the machine os. Files are disambiguated by appending #OS to them. This would make a lot of sense for cross-platform deployments of e.g. Sublime Text, which stores its config in $HOME/Library/Application Support/Sublime Text 3 on OSX and in $HOME/.config/sublime-text-3 on Linux.

That would allow you to create a repo like so:

$HOME/.homesick/repos/
└─subl/
    ├─home/
    │ ├─Library#os=OSX/Application.../.../User ➞ ......../settings
    │ └─.config#os=Linux/.config/.../User ➞ ...../settings
    └─settings/
      ├─Preferences.sublime-settings
      └─...

He also added hostname disambiguation, but I think that would kill the simplicity of it.

The downside of course is that any hashmarks in folder names could clash with this feature.

Any comments?

EDIT:

Summary

Delimiters

So far I have only seen @jjlin disagree with the choice of # as a delimiter. The alternative was lifted from the ClearCase VCS, where the argument was also made for a two-character delimiter. Since there will be a need for an escape character regardless, we should stick to a single character delimiter and in the absence of arguments against #, I say we use it.

Escape characters

Apparantely homeshick works on Cygwin (I honestly had no clue :-)), so the backslash will definitely break stuff and there's no need to do that. Short of smashing a random key on the keyboard maybe we can find something that still makes semantic sense?

The escape character will be used for all three special characters (#, =, ,) and for the escape character itself.

When would the escape character need escaping? Only when it preceeds one of the other special characters?

Filters

Filters are AND'ed and separated with commas. Key and value are separated by a =. The same escape character for , and = should also be used for the delimiter.

Keys should be insensitive and values should be case sensitive (just an idea, open to suggestions).

Possible filter keys

@iron8core discovered and fixed another problem (see comment below): What to do when two files with different filters but the same name match? Possible solutions:

The problem from #28 (Unlink deleted files) rears its head a second time. homeshick should check if unmatched files with filters are symlinked and remove those symlinks (e.g. an env variable changed). This may however be something that should be discussed in issue #28.

ngaloppo commented 10 years ago

I'd be in favor of this or any other system to have platform-specific linking of files. :+1:

squaresurf commented 10 years ago

I'm also in favor of this. The only downside is if there are any conflicts with existing castles. I think we need to update homeshick to use semantic versioning as I lay out in the second part of this https://github.com/andsens/homeshick/issues/95#issuecomment-41280814.

squaresurf commented 10 years ago

@ngaloppo in response to you comment here: https://github.com/andsens/homeshick/issues/95#issuecomment-41302272

I'm not exactly sure how #77 would break someone's existing config. Could you give an example?

It is quite unlikely, but what if I had a dir in a castle at home/awesome#linux that gets symlinked to $HOME/awesome#linux. Once I update homeshick to include this code then my folder would be moved to $HOME/awesome. Thus affecting any other setup I have that depends on that name in my $HOME folder.

squaresurf commented 10 years ago

I'm definitely in favor of this. I just think that we need a mechanism to let homeshick users know that there are potential breaking changes in the latest update.

ngaloppo commented 10 years ago

Makes sense, although unlikely for any existing users of homeshick. While I don't disagree that semantic versioning is a useful feature, at this point in time I don't think it should be a blocker to have #77 implemented.

On Thu, Apr 24, 2014 at 9:42 AM, Daniel Searles notifications@github.comwrote:

I'm definitely in favor of this, I just think that we need a mechanism to let homeshick users know that there are potential breaking changes in the latest update.

— Reply to this email directly or view it on GitHubhttps://github.com/andsens/homeshick/issues/77#issuecomment-41302988 .

jjlin commented 10 years ago

A few thoughts:

squaresurf commented 10 years ago

@ngaloppo I'm replying to this https://github.com/andsens/homeshick/issues/95#issuecomment-41319500 here since this is the feature we're talking about.

@squaresurf You had mentioned before that you currently use os-specific castles. How would that compare with this proposed feature?

This feature #77 is quite a bit more robust than how I use multiple castles. I don't have an elegant solution to the original use case, but I do have files that I only want on a single os or another. For example I have a main .bashrc that then sources these files if they exist:

I have the linux bashrc in a linux castle and the mac bashrc in a mac castle. The local bashrc is an option for me to have machine local bashrc overrides that don't get added to source control.

squaresurf commented 10 years ago

@jjlin I like this idea:

Maybe for future extensibility (and less likelihood of conflict with existing setups), you could do a keyword-based approach, like foo@@os=Linux,hostname=foo.bar.

Support for hostname would be really cool.

AFS does look robust, although it seems a bit overkill.

andsens commented 10 years ago

Makes sense, although unlikely for any existing users of homeshick.

I agree, but this is also about sending a message to users that we really care about not breaking their setup. If they are warned about potential breakage, no matter how small, it builds trust.

While I don't disagree that semantic versioning is a useful feature, at this point in time I don't think it should be a blocker to have #77 implemented.

Me neither, but for other reasons. The dependency chain is very long now and it goes like this:

92 ⇢ #93 ⇢ #94 ⇢ #95 ⇢ #77 (⇢ #96)

If we keep going, we won't be finished by christmas, so let's keep it at #95 and let it be the one that breaks the chain (besides, if someone has a .git# folder in their repo I'd be really surprised), then we can always discuss if we can get #96 done before #77.

squaresurf commented 10 years ago

@andsens do you like using a # as the delimiter? What do you think about using @@ like @jjlin mentioned?

andsens commented 10 years ago

It might be a good idea to use a more unique delimiter. For example, the ClearCase version control system uses @@ to specify a branch/version, like /dir/file@@/main/1.

While I agree that # is not very unique it can still be escaped and it communicates the notion of a "comment", something that you wont see when linked. Using two characters irks me a little because the escaping method is unclear: "Do you escape both chars or only one? Which one of them? What if I only have one char, should that still be escaped?"

Maybe for future extensibility (and less likelihood of conflict with existing setups), you could do a keyword-based approach, like foo@@os=Linux,hostname=foo.bar.

I was thinking the exact same thing, that approach is a lot more extensible, you can even add an environment var test like `foo#env_SHELL=/bin/zsh

Not directly applicable, and I don't think the AFS model is actually a good fit here, but might be interesting to read about anyway if you're not familiar with it.

Looks interesting. It can definitely serve as inspiration :-)

jjlin commented 10 years ago

Maybe I missed it, but what form of escaping is being proposed? I'm not sure I really buy the need to escape if the delimiter is fairly unique. Doubling a character is a somewhat time-honored way of doing that, e.g. identifiers of the form __FOO__ being reserved in C. If you further use the keyword approach, I think naming conflicts are very unlikely.

andsens commented 10 years ago

Maybe I missed it, but what form of escaping is being proposed?

Woops, that was discussed in #95. It's basically just saying that we could use \ to escape stuff. This would be necessary anyways for the = and , in the keyword based approach.
If people use homeshick track to add files to a castle, these escape characters can be added automatically.

I think naming conflicts are very unlikely.

Why settle for less when you can have it all with the same amount of effort?

jjlin commented 10 years ago

I'd argue that foo# should by default mean exactly that, or else people need to be aware of this feature they may not use or care about otherwise. For people who insist on using = or ,, I'd say quoting would be a better choice, but that might be over-engineering things. In any case, I'm not sure \ is a great escape character since it's a valid path separator on Windows, and I think it's just kind of confusing to look at.

NemesisRE commented 10 years ago

@squaresurf

Instead of overwriting the users .bashrc I would rather go the way to add a .bashrc.homeshick which is included to the users local .bashrc so it doesn't break anything on user side. In my own project I use this:

grep -xq 'source "$HOME/.bashrc_homesick"' $HOME/.bashrc || printf '\nsource "$HOME/.bashrc_homesick"' >> $HOME/.bashrc
ngaloppo commented 10 years ago

I have the linux bashrc in a linux castle and the mac bashrc in a mac castle. The local bashrc is an option for me to have machine local bashrc overrides that don't get added to source control.

@squaresurf That sounds like a good way to do it. I was wondering why you think that the proposed feature will be better than what you have today.

squaresurf commented 10 years ago

@NemesisRE I'm not sure what you're talking about. I wasn't proposing any changes to homeshick that would affect any bashrc for users of homeshick. I was just giving an example for @ngaloppo how I use os specific repos with the current version of homeshick.

@ngaloppo #77 is quite a bit more flexible than what I've been doing. It allows for different paths for the same file depending on the os whereas my scenario only really works for different files for different operating systems.

NemesisRE commented 10 years ago

@squaresurf I see. Was not meant as an offence, just an idea if you wanted to change that behavior. Bash-it had overwritten my .bashrc this is why I was alerted ;)

squaresurf commented 10 years ago

@NemesisRE I'm sorry if I came off as offended. That wasn't the case at all :) I just wanted to be clear that I wasn't suggesting mucking with users .bashrc as that would be inappropriate to do automatically.

andsens commented 10 years ago

I'd argue that foo# should by default mean exactly that, or else people need to be aware of this feature they may not use or care about otherwise.

That would lead to an inconsistent implementation where the interface for linking is less predictable. We need regularity - an empty filter (e.g. ..#hostname=xx would be a filter for the hostname) shouldn't be a special case.

I'm not sure \ is a great escape character since it's a valid path separator on Windows, and I think it's just kind of confusing to look at.

Backslash is used pretty much everywhere in unix to escape things with. Windows is the odd one out here.

ghost commented 10 years ago

I support changing # to two #'s, just in case someone number files with #'s as pointed out above. I have another system for handling bashrc/bash_profile though, which works similarly but with directories instead of #'s. If you're interested to see how, check out homesick-bumod (shameless plug).

jjlin commented 10 years ago

Backslash is used pretty much everywhere in unix to escape things with. Windows is the odd one out here.

Backslash is used a lot in string data, but filenames aren't really normal strings. I don't plan to have to escape anything, so I guess it doesn't really impact me, but I would still strongly advise against using backslash this way. For example, Cygwin users would be unable to escape using backslash, since they can't create files with backslash in them (maybe there's a way around that, but they can't in the default configuration).

thetrompf commented 10 years ago

I would like this feature as well, as I'm using multiple systems myself, I really don't care what you choose as delimiter, as long as you make sure that you can escape it somehow, and sure make it obscure so you don't run into it in every day usage.

ngaloppo commented 10 years ago

I support changing # to two #'s, just in case someone number files with #'s as pointed out above. I have another system for handling bashrc/bash_profile though, which works similarly but with directories instead of #'s. If you're interested to see how, check out homesick-bumod (shameless plug).

@iron8core Why do you have two separate systems? Couldn't you handle bashrc/bash_profile through the same system as proposed here (and implemented in your fork)?

ghost commented 10 years ago

@ngaloppo The function proposed here would be for just linking to correct file, not sourcing it (unless it's named according to files sourced by the shell of course). The homesick-bumod castle is used for the function to split up bash environment files (aliases, functions and so on) that then get sourced depending on OS+host. For instance, if I install program "i-have-a-really-long-name" to in location not in my PATH, and also always run the program with "-i-am-an-option", I would just create the a file in the castle named anything.sh containing (either at top-level or depending on OS or OS+hostname): export PATH=$PATH:newpath alias foo="i-have-a-really-long-name -i-am-an-option"

On 27 April 2014 08:55, ngaloppo notifications@github.com wrote:

I support changing # to two #'s, just in case someone number files with

's as pointed out above. I have another system for handling

bashrc/bash_profile though, which works similarly but with directories instead of #'s. If you're interested to see how, check out homesick-bumod (shameless plug).

@iron8core https://github.com/iron8core Why do you have two separate systems? Couldn't you handle bashrc/bash_profile through the same system as proposed here (and implemented in your fork)?

— Reply to this email directly or view it on GitHubhttps://github.com/andsens/homeshick/issues/77#issuecomment-41489810 .

ngaloppo commented 10 years ago

@iron8core Makes sense!

squaresurf commented 10 years ago

@jjlin brings up a good point:

Backslash is used a lot in string data, but filenames aren't really normal strings. I don't plan to have to escape anything, so I guess it doesn't really impact me, but I would still strongly advise against using backslash this way. For example, Cygwin users would be unable to escape using backslash, since they can't create files with backslash in them (maybe there's a way around that, but they can't in the default configuration).

I agree that filenames aren't strings like in other programs that you would escape a character with. @andsens are you opposed to using a different escape character such as the backtick (`) character?

andsens commented 10 years ago

@jjlin:

For example, Cygwin users would be unable to escape using backslash, since they can't create files with backslash in them (maybe there's a way around that, but they can't in the default configuration).

This is a non-issue, since windows support is not going to happen (see #99).

@squaresurf:

I agree that filenames aren't strings like in other programs that you would escape a character with.

But you do escape whitespace and special characters on the commandline with backslash, it's not entirely the same, but I think it's what people are used to. \ is the most common escape character I can think of.

@andsens are you opposed to using a different escape character such as the backtick (`) character?

That would be even more annoying :-) You'd have to escape that character itself in the shell (backtick launches a subshell like $() does).

I think we need to bring parts of the discussion to a close.

Delimiters

So far I have only seen @jjlin disagree with the choice of # as a delimiter. The alternative was lifted from the ClearCase VCS, where the argument was also made for a two-character delimiter. Since there will be a need for an escape character regardless, we should stick to a single character delimiter and in the absence of arguments against #, I say we use it.

Escape characters

Apparantely homeshick works on Cygwin (I honestly had no clue :-)), so the backslash will definitely break stuff and there's no need to do that. Short of smashing a random key on the keyboard maybe we can find something that still makes semantic sense?

Filters

Filters are AND'ed and separated with commas. Key and value are separated by a =. The same escape character for , and = should also be used for the delimiter.

Keys should be insensitive and values should be case sensitive (just an idea, open to suggestions).

Possible filter keys

Challenges

The problem from #28 (Unlink deleted files) rears its head a second time. homeshick should check if unmatched files with filters are symlinked and remove those symlinks (e.g. an env variable changed).

I have put all of this in the first message of the issue so people can easily find it.

jjlin commented 10 years ago

Regarding escape characters, just a thought, but there is some precedent for doubling a character to escape it. So maybe ## could be interpreted as #.

Regarding os for Cygwin, on my system uname -s returns CYGWIN_NT-6.1-WOW64 (presumably WOW64 because I'm running 32-bit Cygwin on 64-bit Windows), while uname -o returns Cygwin. So there are some different ways to implement that check, and I don't care too much about the details, but I'd prefer the filter written as os=Cygwin.

And maybe shorten hostname to host, and username to user.

ngaloppo commented 10 years ago

Regarding os for Cygwin, on my system uname -s returns CYGWIN_NT-6.1-WOW64 (presumably WOW64 because I'm running 32-bit Cygwin on 64-bit Windows), while uname -o returns Cygwin. So there are some different ways to implement that check, and I don't care too much about the details, but I'd prefer the filter written as os=Cygwin.

Regarding the filter keys: we may want to consider those to be case-insensitive substring matched, rather than exact matched. So os=Cygwin would match CYGWIN_NT-6.1-WOW64 as well as CYGWIN_NT-6.1-32, etc.

squaresurf commented 10 years ago

Doh! @andsens you're right that the backtick escape character would be extremely annoying! I can't believe I overlooked that. This is a great example why its good to talk things through first :) I was thinking that it kinda looked like a short backslash. Thus helping readabililty. I'm kinda at a loss as to what we should use as an escape character though. It doesn't look as pretty but does ~ have any special meaning except as a shortcut to the home dir at the beginning of a file path?

@andsens thank you for boiling down the discussion. I agree with your decisions so far :+1:

andsens commented 10 years ago

@jjlin

Regarding escape characters, just a thought, but there is some precedent for doubling a character to escape it. So maybe ## could be interpreted as #.

We will need to escape = and , as well, doubling those characters will become quite awkward and I think we should use the same escaping method for #, =, , and the escape character itself.

So there are some different ways to implement that check, and I don't care too much about the details, but I'd prefer the filter written as os=Cygwin.

Agreed, I think some normalization is in order here.

And maybe shorten hostname to host, and username to user.

Sure, lets do that.

@ngaloppo

we may want to consider those to be case-insensitive substring matched, rather than exact matched

I think normalization is the better path to take here, substring matching is not what the user would expect when using =.

@squaresurf

It doesn't look as pretty but does ~ have any special meaning except as a shortcut to the home dir at the beginning of a file path?

True. It looks like you only need to escape ~ when it's at the beginning of the path. I do think that its usage might still be a bit confusing though. What about %? It doesn't need escaping at any point, is rarely used in filenames and has no special meaning when dealing with paths.

EDIT: Updates to summary

+ The escape character will be used for all three special characters (`#`, `=`, `,`) and for the escape character itself.
+ 
+ When would the escape character need escaping? Only when it preceeds one of the other special characters?

-   * `Windows` (or is `Cygwin` better?)
+   * `Cygwin`

- * `hostname`: Hostname of the system
- * `username`: Username of the executing user
+ * `host`: Hostname of the system
+ * `user`: Username of the executing user
squaresurf commented 10 years ago

I like % :+1:

mrmachine commented 10 years ago

Is anything blocking this or still being decided?

andsens commented 10 years ago

The "Challenges" section still needs a solution, but that's about it. Regardless, it's a big change and I haven't had the time to try getting a proof of concept up and running. PRs are of course welcome!

ghost commented 10 years ago

I've created a simple proof-of-concept version based on master (as of today). See my fork at https://github.com/iron8core/homeshick/tree/master. I've only modified symlinking and added a "homeshick symscores" function, so anything else will probably fail.

andsens commented 10 years ago

Good point about the conflicting filters! I like your solution.

Though I wonder if there is any way to make this simpler. What about a meta-priority filter, where if there is no priority attached homeshick simply chooses the first or last listed file (and issues a warning)? I think that would require less code, i.e. less potential bugs, less testing required etc.

ghost commented 10 years ago

Could you give an example of how it would work? I've pushed new changes that simplifies the changes to the symlink function as well as some additions. And how about handling directories? It's hard to know if a directory is actually the correct one when it's not a link.

andsens commented 10 years ago

I'm currently on vacation, so I'll not really be able to code properly until I'm back at the end of the month.

Could you give an example of how it would work?

.config#os=linux,prio=1
.config#hostname=machine01,prio=2
.config#username=user01,prio=2

On a linux machine named machine01 with the user user01, the first file is chosen since it has a higher priority. On a freeBSD box with the same name and the same user, the last file is chosen, since it is last alphabetically (though in this case an "undefined behavior" would be fine by me as well).

ngaloppo commented 9 years ago

Hi there. Anything that can be done to get some progress on this issue?

andsens commented 9 years ago

Short of sending a PR, a pseudo code suggestion for how the filtering might be implemented would be cool. I have something of an idea on how to do it, but maybe there are others that have something really short and sweet to solve it.

I have been busy with a few challenges in the linking code, which is exactly where we would need to add code to implement this issue. It is rather stable now I'd say, so there's a chance I might start on an implementation.

ngaloppo commented 9 years ago

Wouldn't @iron8core's implementation be a good start?

andsens commented 9 years ago

Yes. It would be, note that I have written a spec/summary in the first comment if this issue. I'm updating it until everything is clear.

andsens commented 9 years ago

I think @iron8core's solution with a scoring mechanism is a neat solution, but I am wondering whether it wouldn't be simpler to just rank the filters in absolute terms. os, domain, host and user will never match twice in one filter, so the accumulated score of the first three will never exceed that of user, in essence its just a ranking of the filters. Only on the off chance that you have two or more env vars will it make a difference.

I'd keep the ranking from @iron8core's fork and then make ordering of the filter values significant. So #user=andsens,env_blah=foo wins over #env_blah=foo,user=andsens, because the more significant filter key comes first.

What should homeshick do when there are two files on different paths where both match and they are located in folders that both match as well? My suggestion would be that the parent dir overrides all, so whichever directory wins gets to link its files, while the files in the losing dir are ignored regardless of whether they'd win against files in the winning dir. Agreed?

Also, I thought of a new filter: cmd. It checks whether a command is available. So you could have a .vim#cmd=vim, .tmux.conf#cmd=tmux and .config/sublime-text-3#cmd=subl. The command would be checked with the type command, which I have found to be most reliable since it also checks aliases and functions.

ghost commented 9 years ago

I've been busy with other stuff lately so haven't had time to try and adapt the changes according to the summary draft (also, as Debian <= Wheezy users might have noticed my fork wouldn't/won't(?) work due to using associative arrays).

Just so I'm following, should the "score" (for lack of a better term) be calculated from the entire path or for one file/dir only (for Linux etc systems, everything between two slashes)?

I'm not sure about the use cases for all these examples, but just so we're clear on everything.

Example 1: "/home/i8c/.folder/folder2/folder3/.tmux.conf#domain=example.com,host=hostname-example,env_blah=foo,cmd=tmux" results in linking (iff all conditions are true) ".folder/folder2/folder3/.tmux.conf"

Example 2: "/home/i8c/.folder#domain=example.com/folder2#host=hostname-example/folder3#env_blah=foo/.tmux.conf#cmd=tmux", if ALL those conditions AND:ed result in true, link ".folder/folder2/folder3/.tmux.conf".

But, if let's say only the conditions on .folder and folder2 match (domain and hostname), should we link to .folder/folder2? It would allow for a hierarchical structure of dirs/files, but would probably complicate things too much.

Example 3: "/home/i8c/.folder/folder2/folder3#domain=example.com,host=hostname-example,env_blah=foo/.tmux.conf#cmd=tmux" result in first AND:ing the folder3#-conditions, and then if that results in a link to ".folder/folder2/folder3", AND the conditions in .tmux.conf and iff true, link ".folder/folder2/folder3/.tmux.conf"

At the moment I'm actually using two separate mechanisms to handle my dotfiles. First my homeshick fork (which at the moment works good enough for me but ugly code, and the #cmd-condition sounds awesome), and then another level of scoring for my zsh config files that are cached and sourced also according to pretty much the same conditions as in homeshick (but I wrote that in zsh, not bash).

mrmachine commented 9 years ago

We appear to be heading deeper and deeper into the rabbit hole now. Some of the examples above are nearly incomprehensible to anyone who is not intimately familiar with the inner workings of this feature and its scoring system. I can't imagine how difficult it is going to be to document and clearly explain to end-users.

How about this as an alternative.

Inside each castle, there's users can create a special dotfile (e.g. .env-extensions) that contains an extension on each line for files that should not be linked normally like other files are. E.g. osx, linux, host-name.

Then, users execute a command like homeshick env osx or homeshick env linux, and this will create/update another local dotfile (not committed) e.g. ~/.homeshick/.env-extensions to add the extension (again, one per line).

Then, when homeshick does its linking, it links all files that don't end in an extension that is in the castle's .env-extensions file, and all files that do end in an extension in the local ~/.homeshick/.env-extensions file.

You could also do homeshick env -r osx to remove an extension.

Then we don't need to worry about naming variables and escape characters in filenames. They can use foo.whatever-they-want and still have absolute control over which systems will link that file, without having to learn any variable names or scoring system.

andsens commented 9 years ago

@mrmachine

We appear to be heading deeper and deeper into the rabbit hole now. Some of the examples above are nearly incomprehensible to anyone who is not intimately familiar with the inner workings of this feature and its scoring system. I can't imagine how difficult it is going to be to document and clearly explain to end-users.

I don't agree. The reason the examples are getting more and more complicated is because we are exploring edge-cases - to figure out how homeshick should behave in the extremes. I know that I myself will most likely use only one filter key (cmd) or two at the most. Looking at my repo structure I will instantly know when something is linked and when it is not, configuring filters through filenames I think is a very simple and intuitively understandable solution to an otherwise complicated problem.

Your suggested solution works fine when you can group setups and they don't overlap. The existing solution allows for much more freedom in that regard and does not require users to learn yet another command -- though I must admit that it is otherwise an elegant solution, the control over which files are linked is much more explicit than in the current solution.

On a different note: @iron8core I agree with the behavior on all your examples (especially # 3, that's exactly what I meant in the previous comment).

But, if let's say only the conditions on .folder and folder2 match (domain and hostname), should we link to .folder/folder2? It would allow for a hierarchical structure of dirs/files, but would probably complicate things too much.

I don't think so, linking folder2 regardless of whether anything inside it matches would be the expected behavior - not linking it would actually be confusing, because ...well, the filter matches, doesn't it?

I have a simpler solution to the ranking by the way (spurred by @mrmachine's comment). How about we forget all about the ranking and simply pick the first file that matches lexicographically? Isn't a conflict so much an edge-case that we would rather have the user change his filters if he wants another file to be linked?

Also: Error handling Should we notify users when a file looks like a filter but really isn't? Some kind of helper that outputs a warning in verbose mode? i.e. there's a file called .folder2/.configfile#cmd=prg;user=andsens (note the semicolon instead of a comma). The chances of the user wanting to write comma here are very high - but maybe just having to write the code for handling this violates the KISS principle. What do you think?

Conflicting files: We could instead of picking a file when two or more filters match simply throw an error and tell the user to fix the situation, it might force the user to configure the castle in a more sane manner (i.e. use mutually exclusive filters for the same filename instead of relying on some scoring mechanism or alphabetical ordering).

Hm, I rather like that last part. It encourages user to not complicate things too much in their castles.

mrmachine commented 9 years ago

@andsens

Sure, having a system such as the one being discussed is more powerful and flexible. And we might be talking about edge cases, but the complexity of the system is what allows all these edge cases to occur. Power and flexibility come at a cost. A simpler system will have far fewer possibilities for edge cases to occur, and will be far easier to document and easier for users to learn. It should also easily cover the most common use-cases.

It can still work for overlapping groups. Just name your file with multiple extensions. foo.osx.linux. The only deficiency is that the user has to tell homeshick on each environment which extensions should be linked in that environment, but an easy to use and remember command like homeshick env linux should make that super easy and explicit.

I think this is a good thing. Seriously, who not only has so many environments to manage, but also regularly has so many new environments to manage, that they need homeshick to automatically work this stuff out? And if they do, what happens when people want to start adding in exceptions? E.g. link this file on os=linux, but not if host=foo?