summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/ide/lib/files.js
blob: 51278640b5b97a05d807505caf34a9df7e163911 (plain)
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
import { viewerInformationForPath } from '~/vue_shared/components/content_viewer/lib/viewer_utils';
import { decorateData, sortTree } from '../stores/utils';

export const escapeFileUrl = fileUrl => encodeURIComponent(fileUrl).replace(/%2F/g, '/');

export const splitParent = path => {
  const idx = path.lastIndexOf('/');

  return {
    parent: idx >= 0 ? path.substring(0, idx) : null,
    name: idx >= 0 ? path.substring(idx + 1) : path,
  };
};

/**
 * Create file objects from a list of file paths.
 */
export const decorateFiles = ({
  data,
  projectId,
  branchId,
  tempFile = false,
  content = '',
  base64 = false,
  binary = false,
  rawPath = '',
}) => {
  const treeList = [];
  const entries = {};

  // These mutable variable references end up being exported and used by `createTempEntry`
  let file;
  let parentPath;

  const insertParent = path => {
    if (!path) {
      return null;
    } else if (entries[path]) {
      return entries[path];
    }

    const { parent, name } = splitParent(path);
    const parentFolder = parent && insertParent(parent);
    parentPath = parentFolder && parentFolder.path;

    const tree = decorateData({
      projectId,
      branchId,
      id: path,
      name,
      path,
      url: `/${projectId}/tree/${branchId}/-/${escapeFileUrl(path)}/`,
      type: 'tree',
      parentTreeUrl: parentFolder ? parentFolder.url : `/${projectId}/tree/${branchId}/`,
      tempFile,
      changed: tempFile,
      opened: tempFile,
      parentPath,
    });

    Object.assign(entries, {
      [path]: tree,
    });

    if (parentFolder) {
      parentFolder.tree.push(tree);
    } else {
      treeList.push(tree);
    }

    return tree;
  };

  data.forEach(path => {
    const { parent, name } = splitParent(path);

    const fileFolder = parent && insertParent(parent);

    if (name) {
      const previewMode = viewerInformationForPath(name);
      parentPath = fileFolder && fileFolder.path;

      file = decorateData({
        projectId,
        branchId,
        id: path,
        name,
        path,
        url: `/${projectId}/blob/${branchId}/-/${escapeFileUrl(path)}`,
        type: 'blob',
        parentTreeUrl: fileFolder ? fileFolder.url : `/${projectId}/blob/${branchId}`,
        tempFile,
        changed: tempFile,
        content,
        base64,
        binary: (previewMode && previewMode.binary) || binary,
        rawPath,
        previewMode,
        parentPath,
      });

      Object.assign(entries, {
        [path]: file,
      });

      if (fileFolder) {
        fileFolder.tree.push(file);
      } else {
        treeList.push(file);
      }
    }
  });

  return {
    entries,
    treeList: sortTree(treeList),
    file,
    parentPath,
  };
};