File size: 3,799 Bytes
bc20498
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
"use strict";

const state = require('./state');
const logger = require('../logger');
const fs = require('../fs');
const util = require('../util');
const {
  join
} = require('path');
const Table = require('cli-table3');
const dayjs = require('dayjs');
const relativeTime = require('dayjs/plugin/relativeTime');
const chalk = require('chalk');
const _ = require('lodash');
const getFolderSize = require('./get-folder-size');
const Bluebird = require('bluebird');
dayjs.extend(relativeTime);

// output colors for the table
const colors = {
  titles: chalk.white,
  dates: chalk.cyan,
  values: chalk.green,
  size: chalk.gray
};
const logCachePath = () => {
  logger.always(state.getCacheDir());
  return undefined;
};
const clear = () => {
  return fs.removeAsync(state.getCacheDir());
};
const prune = () => {
  const cacheDir = state.getCacheDir();
  const checkedInBinaryVersion = util.pkgVersion();
  let deletedBinary = false;
  return fs.readdirAsync(cacheDir).then(versions => {
    return Bluebird.all(versions.map(version => {
      if (version !== checkedInBinaryVersion) {
        deletedBinary = true;
        const versionDir = join(cacheDir, version);
        return fs.removeAsync(versionDir);
      }
    }));
  }).then(() => {
    if (deletedBinary) {
      logger.always(`Deleted all binary caches except for the ${checkedInBinaryVersion} binary cache.`);
    } else {
      logger.always(`No binary caches found to prune.`);
    }
  }).catch({
    code: 'ENOENT'
  }, () => {
    logger.always(`No Cypress cache was found at ${cacheDir}. Nothing to prune.`);
  });
};
const fileSizeInMB = size => {
  return `${(size / 1024 / 1024).toFixed(1)}MB`;
};

/**
 * Collects all cached versions, finds when each was used
 * and prints a table with results to the terminal
 */
const list = showSize => {
  return getCachedVersions(showSize).then(binaries => {
    const head = [colors.titles('version'), colors.titles('last used')];
    if (showSize) {
      head.push(colors.titles('size'));
    }
    const table = new Table({
      head
    });
    binaries.forEach(binary => {
      const versionString = colors.values(binary.version);
      const lastUsed = binary.accessed ? colors.dates(binary.accessed) : 'unknown';
      const row = [versionString, lastUsed];
      if (showSize) {
        const size = colors.size(fileSizeInMB(binary.size));
        row.push(size);
      }
      return table.push(row);
    });
    logger.always(table.toString());
  });
};
const getCachedVersions = showSize => {
  const cacheDir = state.getCacheDir();
  return fs.readdirAsync(cacheDir).filter(util.isSemver).map(version => {
    return {
      version,
      folderPath: join(cacheDir, version)
    };
  }).mapSeries(binary => {
    // last access time on the folder is different from last access time
    // on the Cypress binary
    const binaryDir = state.getBinaryDir(binary.version);
    const executable = state.getPathToExecutable(binaryDir);
    return fs.statAsync(executable).then(stat => {
      const lastAccessedTime = _.get(stat, 'atime');
      if (!lastAccessedTime) {
        // the test runner has never been opened
        // or could be a test simulating missing timestamp
        return binary;
      }
      const accessed = dayjs(lastAccessedTime).fromNow();
      binary.accessed = accessed;
      return binary;
    }, e => {
      // could not find the binary or gets its stats
      return binary;
    });
  }).mapSeries(binary => {
    if (showSize) {
      const binaryDir = state.getBinaryDir(binary.version);
      return getFolderSize(binaryDir).then(size => {
        return {
          ...binary,
          size
        };
      });
    }
    return binary;
  });
};
module.exports = {
  path: logCachePath,
  clear,
  prune,
  list,
  getCachedVersions
};