Repository: pre-commit/pre-commit

Issue:
hook using node doesn't work on FreeBSD
We have a hook using doctoc, the node package. I cannot install the hook, this is the output:

```
desktop1% pre-commit install --install-hooks                                                                                                                                                                                                  
pre-commit installed at .git/hooks/pre-commit
[INFO] Initializing environment for git@github.com:jockej/pre-commit-hooks.git.
[INFO] Initializing environment for https://github.com/thlorenz/doctoc.
[INFO] Initializing environment for https://gitlab.com/pycqa/flake8.
[INFO] Initializing environment for https://github.com/jorisroovers/gitlint.
[INFO] Installing environment for https://github.com/thlorenz/doctoc.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/bin/node', '/usr/local/bin/npm', 'install', '-g', '.')
return code: 254
expected return code: 0
stdout: (none)
stderr:
    npm ERR! code ENOENT
    npm ERR! syscall chmod
    npm ERR! path /home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/lib/node_modules/doctoc/doctoc.js
    npm ERR! errno -2
    npm ERR! enoent ENOENT: no such file or directory, chmod '/home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/lib/node_modules/doctoc/doctoc.js'
    npm ERR! enoent This is related to npm not being able to find a file.
    npm ERR! enoent 
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /home/joakim/.npm/_logs/2020-05-07T10_30_16_218Z-debug.log
    
Check the log at /home/joakim/.cache/pre-commit/pre-commit.log
```
These hooks all install and run perfectly on GNU/Linux.

I believe it happens because pre-commit tries to use the --prebuilt flag to nodeenv, however this doesn't work for FreeBSD since there are no prebuilt packages (the URL constructed gives a 404). I have node installed so it should be possible to use --system, but I haven't been able to make it work myself.

Nodeenv itself seems to work fine with --system.

Please let me know if I can help with trying things on FreeBSD.



Discussion:
please provide the log file, I can't reproduce
Sure, here is the log file. Do you mean it works for you on FreeBSD?

[pre-commit.log](https://github.com/pre-commit/pre-commit/files/4592940/pre-commit.log)

I was trying on a different BSD so maybe that's why it works for me

it's using `nodeenv -n system` (you can see from the `repo..../node_env-system/...` path

I wonder why that's not working for you though 🤔 

does this work for you?

```bash
nodeenv nenv -n system
. nenv/bin/activate
npm install -g doctoc
```
Yes, that works fine for me. I tried installing doctoc manually before, in the directory created by pre-commit, but running pre-commit install --install-hooks seems to remove it.
yeah those directories are "private" implementation detail, so if you're not managing it in the way pre-commit expects it will delete your files

it seems very odd that the commands outside of pre-commit are working, pre-commit runs exactly the same thing

can you show the output of that, and maybe your pre-commit configuration and nodeenv version?
sure. I must admit I don't know much of what's going on.

```
desktop1% nodeenv nenv -n system
desktop1% . nenv/bin/activate
(nenv) desktop1% npm install -g doctoc
/usr/home/joakim/nenv/bin/doctoc -> /usr/home/joakim/nenv/lib/node_modules/doctoc/doctoc.js
+ doctoc@1.4.0
added 67 packages from 41 contributors in 4.432s
(nenv) desktop1% 
```

```
repos:
  - repo: local
    hooks:
      - id: uncrustify
        name: Check C source code style
        entry: company-tools/code-style/uncrustify-check-style.sh
        language: script
        log_file: uncrustify.patch
        types: [c]
        stages: [commit]
  - repo: git@github.com:company/pre-commit-hooks.git
    rev: v1.0.1
    hooks:
      - id: check-copyright
        exclude: '^(.*\.(sha256|txt|uncrustify-ignore|gitmodules))$'
        exclude_types: [markdown, yaml, gitignore]
  - repo: https://github.com/thlorenz/doctoc
    rev: v1.4.0
    hooks:
      - id: doctoc
        # Assume second level heading and GitHub flavouring.
        args: [--title=## Contents, --github]
        stages: [commit]
  - repo: https://gitlab.com/pycqa/flake8
    rev: 3.7.9
    hooks:
      - id: flake8
        # We've only pulled the OAD tool from the Simplelink SDK
        exclude: '^company-tools/oad/.*$'
        stages: [commit]
  - repo: https://github.com/jorisroovers/gitlint
    rev: v0.13.1
    hooks:
      - id: gitlint
        stages: [commit-msg]
```

```
desktop1% nodeenv --version
1.3.5
```

I know that in the past I've had some issues with the fact that $HOME on FreeBSD is actually /usr/home/joakim, don't know if that could have an effect.
hmm and I'm having trouble setting up a freebsd vm :S  can't seem to get an internet connection out of virtualbox
ok I got it working and can't reproduce your issue

```console
$ history
     1	8:04	df -jh
     2	8:04	df -h
     3	8:04	growfs
     4	8:04	growfs /dev/ada0p3
     5	8:04	sduo growfs /dev/ada0p3
     6	8:04	sudo growfs /dev/ada0p3
     7	8:05	service growfs onestart
     8	8:05	growfs /dev/ada0p3
     9	8:05	df -h
    10	8:05	pkg install node
    11	8:06	pkg install npm
    12	8:06	pkg install python3
    13	8:07	pkg install curl git
    14	8:09	curl https://asottile.github.io/get-virtualenv.py | python3 - venv
    15	8:09	git init x
    16	8:09	pkg install nano
    17	8:09	cd x
    18	8:09	ls
    19	8:09	nano .pre-commit-config.yaml
    20	8:10	nano README.md
    21	8:10	git status
    22	8:10	git add .
    23	8:10	../venv/bin/pip install pre-commit
    24	8:10	whohc node
    25	8:10	which node
    26	8:10	which npm
    27	8:10	wtf
    28	8:10	../venv/bin/pre-commit run --all-files
    29	8:11	pkg install sqlite
    30	8:11	../venv/bin/pre-commit run --all-files
    31	8:11	pkg install sqlite3
    32	8:11	pkg install libsqlite3
    33	8:12	pkg install py37-sqlite3
    34	8:12	../venv/bin/pre-commit run --all-files
    35	8:12	pkg install bash
    36	8:12	../venv/bin/pre-commit run --all-files
    37	8:13	history
    38	8:14	../venv/bin/pip install fpb
    39	8:14	../venv/bin/pip install fluffy
    40	8:14	history | ../venv/bin/fpb
```

![Capture25](https://user-images.githubusercontent.com/1810591/81312014-f4ee9200-903a-11ea-8520-f3defbcb43f6.png)

Strange! I get the same error in a freshly created repo. (I forgot to cat the files in the beginning, they are at the end)
```
desktop1% cd test 
desktop1% ls
desktop1% mkdir test-pre-commit
desktop1% cd test-pre-commit 
desktop1% git init
Initialized empty Git repository in /usr/home/joakim/test/test-pre-commit/.git/
desktop1% pre-commit install
pre-commit installed at .git/hooks/pre-commit
desktop1% pre-commit run --all-files
[INFO] Installing environment for https://github.com/thlorenz/doctoc.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
An unexpected error has occurred: CalledProcessError: command: ('/home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/bin/node', '/usr/local/bin/npm', 'install', '-g', '.')
return code: 254
expected return code: 0
stdout: (none)
stderr:
    npm ERR! code ENOENT
    npm ERR! syscall chmod
    npm ERR! path /home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/lib/node_modules/doctoc/doctoc.js
    npm ERR! errno -2
    npm ERR! enoent ENOENT: no such file or directory, chmod '/home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/lib/node_modules/doctoc/doctoc.js'
    npm ERR! enoent This is related to npm not being able to find a file.
    npm ERR! enoent 
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /home/joakim/.npm/_logs/2020-05-08T12_00_15_940Z-debug.log
    
Check the log at /home/joakim/.cache/pre-commit/pre-commit.log
desktop1% cat .pre-commit-config.yaml 
repos:
  - repo: https://github.com/thlorenz/doctoc
    rev: v1.4.0
    hooks:
      - id: doctoc
        # Assume second level heading and GitHub flavouring.
        args: [--title=## Contents, --github]
        stages: [commit]
desktop1% cat README.md 
hejsan

hej hej
desktop1% 
```

But it works as root!
```
desktop1% sudo -i 
Password:
root@desktop1:~ # pwd
/root
root@desktop1:~ # cd /tmp/
root@desktop1:/tmp # mkdir test-pre-commit
root@desktop1:/tmp # cd test-pre-commit/
root@desktop1:/tmp/test-pre-commit # git init
Initialized empty Git repository in /tmp/test-pre-commit/.git/
root@desktop1:/tmp/test-pre-commit # cp /home/joakim/test/test-pre-commit/README.md .
root@desktop1:/tmp/test-pre-commit # cp /home/joakim/test/test-pre-commit/.pre-commitconfig.yaml .
root@desktop1:/tmp/test-pre-commit # pre-commit install
pre-commit installed at .git/hooks/pre-commit
root@desktop1:/tmp/test-pre-commit # pre-commit install --install-hooks
pre-commit installed at .git/hooks/pre-commit
[INFO] Initializing environment for https://github.com/thlorenz/doctoc.
[INFO] Installing environment for https://github.com/thlorenz/doctoc.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
root@desktop1:/tmp/test-pre-commit # 
```
Perhaps it is because roots home folder doesn't have the same weirdness as a users on FreeBSD. Could you try creating a user in your virtual machine and try the recipe again? 
Indeed it seems to be something about that weird FreeBSD $HOME.

```
desktop1% mkdir test-pre-commit5
desktop1% cd test-pre-commit5 
desktop1% cp ../test-pre-commit/README.md .
desktop1% cp ../test-pre-commit/.pre-commit-config.yaml .
desktop1% git init
Initialized empty Git repository in /usr/home/joakim/test/test-pre-commit5/.git/
desktop1% echo $HOME        
/home/joakim
desktop1% realpath $HOME
/usr/home/joakim
desktop1% export HOME=/usr/home/joakim
desktop1% pre-commit install --install-hooks
pre-commit installed at .git/hooks/pre-commit
[INFO] Initializing environment for https://github.com/thlorenz/doctoc.
[INFO] Installing environment for https://github.com/thlorenz/doctoc.
[INFO] Once installed this environment will be reused.
[INFO] This may take a few minutes...
desktop1% pre-commit run --all-files
doctoc...............................................(no files to check)Skipped
desktop1% 
```
is your HOME on nfs or some weird filesystem?
No, plain zfs. But it is always the case on FreeBSD that /home is a symlink to /usr/home. Don't ask me why... it's cause me some grief in the past.
if you run the nodeenv commands in a subdir of your homedir do you see the same thing?  I can't really see how this is possibly a pre-commit problem when we're just calling out to `npm`
Plain nodeenv seems to work fine.
```
desktop1% echo $HOME            
/home/joakim
desktop1% nodeenv nenv -n system
desktop1% . nenv/bin/activate
(nenv) desktop1% npm install -g doctoc
/usr/home/joakim/nenv/bin/doctoc -> /usr/home/joakim/nenv/lib/node_modules/doctoc/doctoc.js
+ doctoc@1.4.0
added 67 packages from 41 contributors in 6.285s
(nenv) desktop1% 
```
It has to be something about how pre-commit calls nodeenv, no? When it works it uses the path /usr/home/joakim (like above), when it doesn't, it seems to be using /home/joakim:

```
An unexpected error has occurred: CalledProcessError: command: ('/home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/bin/node', '/usr/local/bin/npm', 'install', '-g', '.')
return code: 254
expected return code: 0
stdout: (none)
stderr:
    npm ERR! code ENOENT
    npm ERR! syscall chmod
    npm ERR! path /home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/lib/node_modules/doctoc/doctoc.js
    npm ERR! errno -2
    npm ERR! enoent ENOENT: no such file or directory, chmod '/home/joakim/.cache/pre-commit/repoizbdwm4g/node_env-system/lib/node_modules/doctoc/doctoc.js'
    npm ERR! enoent This is related to npm not being able to find a file.
    npm ERR! enoent 
    
    npm ERR! A complete log of this run can be found in:
    npm ERR!     /home/joakim/.npm/_logs/2020-05-08T12_00_15_940Z-debug.log
    
Check the log at /home/joakim/.cache/pre-commit/pre-commit.log
```

how about a subdir of your home directory?
here's the exact commands if you'd want to reproduce them: https://github.com/pre-commit/pre-commit/blob/450d617dece6e2a8805b7333326b3c17d69dec24/pre_commit/languages/node.py#L83-L98

essentially:

```
python3 -m nodeenv --prebuilt --clean-src nenv -n system
export NODE_VIRTUAL_ENV="$PWD/nenv"
export NPM_CONFIG_PREFIX="$PWD/nenv/bin"
export npm_config_prefix="$PWD/nenv/bin"
export NODE_PATH="$PWD/nenv/lib/node_modules"
export PATH="$PWD/nenv/bin:$PATH"
npm install  # inside a git clone of doctoc
npm install -g .
```
Seems to work.
```
desktop1% echo $PWD
/home/joakim/test
desktop1% echo $HOME
/home/joakim
desktop1% python3 -m nodeenv --prebuilt --clean-src nenv -n system
desktop1% export NODE_VIRTUAL_ENV="$PWD/nenv"
export NPM_CONFIG_PREFIX="$PWD/nenv/bin"
export npm_config_prefix="$PWD/nenv/bin"
export NODE_PATH="$PWD/nenv/lib/node_modules"
export PATH="$PWD/nenv/bin:$PATH"
desktop1% echo $PATH
/home/joakim/test/nenv/bin:/usr//home/joakim/progs:/home/joakim/progs/bin:/usr/local/bin:/usr//home/joakim/progs:/home/joakim/progs/bin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin:/home/joakim/bin
desktop1% echo $NODE_PATH
/home/joakim/test/nenv/lib/node_modules
desktop1% git clone git@github.com:thlorenz/doctoc
Cloning into 'doctoc'...
remote: Enumerating objects: 630, done.
remote: Total 630 (delta 0), reused 0 (delta 0), pack-reused 630
Receiving objects: 100% (630/630), 114.14 KiB | 652.00 KiB/s, done.
Resolving deltas: 100% (315/315), done.
desktop1% cd doctoc
desktop1% npm install
npm WARN deprecated request@2.79.0: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated hawk@3.1.3: This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
npm WARN deprecated boom@2.10.1: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated hoek@2.16.3: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated cryptiles@2.0.5: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated sntp@1.0.9: This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm notice created a lockfile as package-lock.json. You should commit this file.
added 365 packages from 251 contributors and audited 793 packages in 7.251s
found 58 vulnerabilities (26 low, 7 moderate, 24 high, 1 critical)
  run `npm audit fix` to fix them, or `npm audit` for details
desktop1% npm install -g .
/usr/home/joakim/test/nenv/bin/doctoc -> /usr/home/joakim/test/nenv/lib/node_modules/doctoc/doctoc.js
+ doctoc@1.4.0
added 1 package from 1 contributor in 0.428s
desktop1% 
```

is it maybe a path length thing? what happens at a deeper path 🤔 
Honestly I can't imagine that's the problem... I think it must have something to do with the path handling.

changing:
```
    def path(self, *parts: str) -> str:
        return os.path.normpath(os.path.join(self.prefix_dir, *parts))
```

to:
```
    def path(self, *parts: str) -> str:
        return os.path.realpath(os.path.normpath(os.path.join(self.prefix_dir, *parts)))
```

Fixes it for me. I don't really know python that well, so I don't know the proper way to do it. But somwhere there lies the rub.
ok I can now reproduce your findings

also I can reproduce this with only nodeenv / npm

adjusting the directions above:

```console
python3 -m nodeenv --prebuilt --clean-src nenv -n system
export NODE_VIRTUAL_ENV="$PWD/nenv"
export NPM_CONFIG_PREFIX="$PWD/nenv/bin"
export npm_config_prefix="$PWD/nenv/bin"
export NODE_PATH="$PWD/nenv/lib/node_modules"
export PATH="$PWD/nenv/bin:$PATH"
$(which node) $(which npm) install  # inside a git clone of doctoc
$(which node) $(which npm) install -g .
```

and indeed, `npm` is building a broken symlink at that location:

![](https://i.fluffy.cc/n3Bcxvxl3kP7FxfkLXKBLJ252DVXDLVH.png)

so this appears to be an npm bug, but also a strange behaviour of `env` to resolve symlinks 🤔 
and here's a reproduction using only node and npm on linux:

```dockerfile
FROM ubuntu:focal

RUN : \
    && apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        ca-certificates \
        curl \
        git \
        gnupg2 \
        software-properties-common \
    && curl --silent https://deb.nodesource.com/gpgkey/nodesource.gpg.key | apt-key add - \
    && add-apt-repository https://deb.nodesource.com/node_12.x \
    && apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        nodejs \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# simulate the home layout of freebsd
RUN : \
    && rmdir /home \
    && mkdir -p /usr/home \
    && ln -s /usr/home /home

RUN : \
    && useradd -d /home/asottile asottile \
    && mkdir -p /home/asottile \
    && chown asottile /home/asottile
USER asottile

# cd before each command is chosen instead of `WORKDIR` as the latter
# dereferences symlinks

RUN : \
    && cd /home/asottile \
    && git clone https://github.com/thlorenz/doctoc doctoc \
    && cd doctoc \
    && git checkout v1.4.0

# this simulates how `nodeenv` builds a separate environment
ENV \
    NODE_VIRTUAL_ENV=/home/asottile/doctoc/nenv \
    NPM_CONFIG_PREFIX=/home/asottile/doctoc/nenv \
    npm_config_prefix=/home/asottile/doctoc/nenv \
    NODE_PATH=/home/asottile/doctoc/nenv/lib/node_modules \
    PATH=/home/asottile/doctoc/nenv/bin:$PATH

RUN : \
    && cd /home/asottile/doctoc \
    && /usr/bin/node /usr/bin/npm install \
    && /usr/bin/node /usr/bin/npm install -g . || ( \
        # adjust this to look at the failures
        ls -al "$NODE_PATH" && \
        exit 1\
    )
```

```console
$ docker build -t test .
...
Step 8/8 : RUN :     && cd /home/asottile/doctoc     && /usr/bin/node /usr/bin/npm install     && /usr/bin/node /usr/bin/npm install -g . || (         ls -al "$NODE_PATH" &&         exit 1    )
 ---> Running in f9d8526451ae
npm WARN deprecated request@2.79.0: request has been deprecated, see https://github.com/request/request/issues/3142
npm WARN deprecated hawk@3.1.3: This module moved to @hapi/hawk. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
npm WARN deprecated hoek@2.16.3: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated cryptiles@2.0.5: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated boom@2.10.1: This version has been deprecated in accordance with the hapi support policy (hapi.im/support). Please upgrade to the latest version to get the best features, bug fixes, and security patches. If you are unable to upgrade at this time, paid support is available for older versions (hapi.im/commercial).
npm WARN deprecated sntp@1.0.9: This module moved to @hapi/sntp. Please make sure to switch over as this distribution is no longer supported and may contain bugs and critical security issues.
npm WARN deprecated core-js@2.6.11: core-js@<3 is no longer maintained and not recommended for usage due to the number of issues. Please, upgrade your dependencies to the actual version of core-js@3.
npm notice created a lockfile as package-lock.json. You should commit this file.
added 365 packages from 251 contributors and audited 793 packages in 21.694s

21 packages are looking for funding
  run `npm fund` for details

found 58 vulnerabilities (26 low, 7 moderate, 24 high, 1 critical)
  run `npm audit fix` to fix them, or `npm audit` for details
npm ERR! code ENOENT
npm ERR! syscall chmod
npm ERR! path /home/asottile/doctoc/nenv/lib/node_modules/doctoc/doctoc.js
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, chmod '/home/asottile/doctoc/nenv/lib/node_modules/doctoc/doctoc.js'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/asottile/.npm/_logs/2020-05-08T20_13_59_212Z-debug.log
total 8
drwxr-xr-x 2 asottile asottile 4096 May  8 20:13 .
drwxr-xr-x 3 asottile asottile 4096 May  8 20:13 ..
lrwxrwxrwx 1 asottile asottile   42 May  8 20:13 doctoc -> ../../../../../../usr/home/asottile/doctoc
The command '/bin/sh -c :     && cd /home/asottile/doctoc     && /usr/bin/node /usr/bin/npm install     && /usr/bin/node /usr/bin/npm install -g . || (         ls -al "$NODE_PATH" &&         exit 1    )' returned a non-zero code: 1
```
here's the npm bug: https://github.com/npm/cli/issues/1264

I believe you can work around this issue by setting `PRE_COMMIT_HOME=/usr/home/$USER/.cache/pre-commit` (perhaps with `pre-commit clean` beforehand to clear the previous cache)

I'm going to adjust the cache dir logic to dereference that symlink anyway, but already-cloned repos will not get fixed

Resolving patch:
diff --git a/pre_commit/store.py b/pre_commit/store.py
--- a/pre_commit/store.py
+++ b/pre_commit/store.py
@@ -30,10 +30,11 @@ def _get_default_directory() -> str:
     `Store.get_default_directory` can be mocked in tests and
     `_get_default_directory` can be tested.
     """
-    return os.environ.get('PRE_COMMIT_HOME') or os.path.join(
+    ret = os.environ.get('PRE_COMMIT_HOME') or os.path.join(
         os.environ.get('XDG_CACHE_HOME') or os.path.expanduser('~/.cache'),
         'pre-commit',
     )
+    return os.path.realpath(ret)
 
 
 class Store:


Test patch:
diff --git a/tests/store_test.py b/tests/store_test.py
--- a/tests/store_test.py
+++ b/tests/store_test.py
@@ -25,7 +25,8 @@ def test_our_session_fixture_works():
 def test_get_default_directory_defaults_to_home():
     # Not we use the module level one which is not mocked
     ret = _get_default_directory()
-    assert ret == os.path.join(os.path.expanduser('~/.cache'), 'pre-commit')
+    expected = os.path.realpath(os.path.expanduser('~/.cache/pre-commit'))
+    assert ret == expected
 
 
 def test_adheres_to_xdg_specification():
@@ -33,7 +34,8 @@ def test_adheres_to_xdg_specification():
         os.environ, {'XDG_CACHE_HOME': '/tmp/fakehome'},
     ):
         ret = _get_default_directory()
-        assert ret == os.path.join('/tmp/fakehome', 'pre-commit')
+    expected = os.path.realpath('/tmp/fakehome/pre-commit')
+    assert ret == expected
 
 
 def test_uses_environment_variable_when_present():
@@ -41,7 +43,8 @@ def test_uses_environment_variable_when_present():
         os.environ, {'PRE_COMMIT_HOME': '/tmp/pre_commit_home'},
     ):
         ret = _get_default_directory()
-        assert ret == '/tmp/pre_commit_home'
+    expected = os.path.realpath('/tmp/pre_commit_home')
+    assert ret == expected
 
 
 def test_store_init(store):