edit anywhere | save git | apply acl to html | Search

This code prepares a Node.js environment to interact with Git using the wasm-git library, setting up a virtual filesystem and defining a function to map MIME types to icons. It also includes the beginnings of a function to retrieve a file tree from the Git repository.

Run example

npm run import -- "git file tree"

git file tree

var lg = require('../node_modules/wasm-git/lg2.js');
var mime = require('mime')

lg.noExitRuntime = true
lg.quit = function () {}
lg.onRuntimeInitialized = () => {
    const FS = lg.FS;
    const MEMFS = FS.filesystems.MEMFS;

    FS.mkdir('/working');
    FS.mount(MEMFS, { }, '/working');
    FS.chdir('/working');    

    FS.writeFile('/home/web_user/.gitconfig', '[user]\n' +
                'name = Test User\n' +
                'email = test@example.com');
    lg.loaded = true
    process.on('uncaughtException', console.log)
    process.on('unhandledRejection', console.log)
}
process.on('uncaughtException', console.log)
process.on('unhandledRejection', console.log)

function mimeToIcon(mime) {
    var icon_classes = {
      '': 'fa-file',
      // Media
      image: "fa-file-image",
      audio: "fa-file-audio",
      video: "fa-file-video",
      // Documents
      "application/pdf": "fa-file-pdf",
      "application/msword": "fa-file-word",
      "application/vnd.ms-word": "fa-file-word",
      "application/vnd.oasis.opendocument.text": "fa-file-word",
      "application/vnd.openxmlformatsfficedocument.wordprocessingml": "fa-file-word",
      "application/vnd.ms-excel": "fa-file-excel",
      "application/vnd.openxmlformatsfficedocument.spreadsheetml": "fa-file-excel",
      "application/vnd.oasis.opendocument.spreadsheet": "fa-file-excel",
      "application/vnd.ms-powerpoint": "fa-file-powerpoint",
      "application/vnd.openxmlformatsfficedocument.presentationml":"fa-file-powerpoint",
      "application/vnd.oasis.opendocument.presentation": "fa-file-powerpoint",
      "text/plain": "fa-file-alt",
      "text/html": "fa-file-code",
      "application/json": "fa-file-code",
      // Archives
      "application/gzip": "fa-file-archive",
      "application/zip": "fa-file-archive"
    }
    return icon_classes[mime || ''] || icon_classes[(mime || '').split('/')[0]] || 'fa-file'
}

async function gitFileTree() {
    const FS = lg.FS;
    const PATH = lg.PATH;
    const ERRNO_CODES = lg.ERRNO_CODES
    // wait for the module to load
    var waiter, counter = 0
    await new Promise(resolve => {
        waiter = setInterval(() => {
            if(lg.loaded || counter === 1000) {
                clearInterval(waiter)
                resolve()
            } else
                counter++
        }, 10)
    })
    
    // clone a repository from github
    try {
        FS.mkdir('/working/made-with-webassembly')
    } catch (e) {
        if (!(e instanceof FS.ErrnoError) || e.code != 'EEXIST') {
            throw e
        }
    }
    try {
        FS.chdir('/working/made-with-webassembly')
        lg.callMain(['init', '.'])
        lg.callMain(['remote', 'remove', 'origin'])
        lg.callMain(['remote', 'add', 'origin', 'https://github.com/torch2424/made-with-webassembly.git'])
        lg.callMain(['config', 'core.sparsecheckout', 'true'])
        // echo "finisht/*" >> .git/info/sparse-checkout
        lg.callMain(['fetch', 'origin', '--depth=1'])
        lg.callMain(['checkout', 'master'])
        // git rev-list --all --quiet --objects --missing=print | wc -l
        // git update-index --skip-worktree
    } catch (e) {
        console.error(e)
    }
    //lg.callMain(['clone', 'https://github.com/torch2424/made-with-webassembly.git', 'made-with-webassembly'])
    var makeTree
    makeTree = function (dir) {
        var files = FS.readdir(dir)
            .filter(dir => !dir.match(/^\.\.?$/))
        return `<ul>` + files.map((file, i) => {
            var mimeType = mime.getType(file)
            var path = dir + '/' + file
            var escPath = 'ft' + path.replace(/[^a-z0-9_-]/ig, '_') + '_' + i
            if(FS.isDir(FS.lstat(path).mode)) {
                return `<li class="folder">
                    <input type="checkbox" name="${escPath}" id="${escPath}" />
                    <label for="${escPath}">
                        <i class="fas fa-angle-right"></i><i class="fas fa-folder"></i>
                        ${file}
                    </label>
                    ${makeTree(path)}
                    </li>`
            } else if (FS.isFile(FS.lstat(path).mode)) {
                return `<li>
                    <input type="checkbox" name="${escPath}" id="${escPath}" />
                    <label for="${escPath}">
                        <i class="fas ${mimeToIcon(mimeType)}"></i>
                        ${file}
                    </label>
                    </li>`
            }
        }).join('') + `</ul>`
    }
    var fileTree = makeTree('.')
    return fileTree
}

module.exports = gitFileTree

What the code could have been:

const lg = require('../node_modules/wasm-git/lg2.js');
const mime = require('mime');
const { EOL } = require('os');

lg.noExitRuntime = true;
lg.quit = () => {};
lg.onRuntimeInitialized = async () => {
  const fs = lg.FS;
  const path = lg.PATH;
  const errnoCodes = lg.ERRNO_CODES;

  try {
    // Initialize file system
    await fs.mkdir('/working');
    await fs.mount(fs.filesystems.MEMFS, {}, '/working');
    await fs.chdir('/working');

    // Create.gitconfig file
    const gitconfig = `[user]
name = Test User
email = test@example.com${EOL}`;
    await fs.writeFile('/home/web_user/.gitconfig', gitconfig);

    lg.loaded = true;

    // Set up error handling
    process.on('uncaughtException', e => console.error('Uncaught Exception:', e));
    process.on('unhandledRejection', e => console.error('Unhandled Rejection:', e));
  } catch (e) {
    console.error('Error initializing file system:', e);
  }
};

process.on('uncaughtException', e => console.error('Uncaught Exception:', e));
process.on('unhandledRejection', e => console.error('Unhandled Rejection:', e));

// Icon classes for mime types
const iconClasses = {
  '' : 'fa-file',
  image: "fa-file-image",
  audio: "fa-file-audio",
  video: "fa-file-video",
  application: {
    pdf: "fa-file-pdf",
    msword: "fa-file-word",
    'vnd.ms-word': "fa-file-word",
    'vnd.oasis.opendocument.text': "fa-file-word",
    'vnd.openxmlformats-officedocument.wordprocessingml.document': "fa-file-word",
    'vnd.ms-excel': "fa-file-excel",
    'vnd.openxmlformats-officedocument.spreadsheetml.sheet': "fa-file-excel",
    'vnd.oasis.opendocument.spreadsheet': "fa-file-excel",
    'vnd.ms-powerpoint': "fa-file-powerpoint",
    'vnd.openxmlformats-officedocument.presentationml.presentation': "fa-file-powerpoint",
    'vnd.oasis.opendocument.presentation': "fa-file-powerpoint",
    text: {
      plain: "fa-file-alt",
      html: "fa-file-code",
      json: "fa-file-code"
    },
    gzip: "fa-file-archive",
    zip: "fa-file-archive"
  }
};

// Get icon class for mime type
function getIconClass(mimeType) {
  if (Object.keys(iconClasses).includes(mimeType)) {
    return iconClasses[mimeType];
  } else if (typeof iconClasses.application === 'object' && typeof iconClasses.application[mimeType] ==='string') {
    return iconClasses.application[mimeType];
  } else if (typeof iconClasses.image ==='string' && mimeType.split('/')[0] === 'image') {
    return iconClasses.image;
  } else {
    return iconClasses[''];
  }
}

// Async function to get git file tree
async function gitFileTree() {
  try {
    // Wait for file system to initialize
    await new Promise(resolve => {
      const counter = 0;
      const intervalId = setInterval(() => {
        if (lg.loaded || counter === 1000) {
          clearInterval(intervalId);
          resolve();
        } else {
          counter++;
        }
      }, 10);
    });

    // Clone repository from GitHub
    await fs.mkdir('/working/made-with-webassembly');
    await fs.chdir('/working/made-with-webassembly');
    await lg.callMain(['init', '.']);
    await lg.callMain(['remote','remove', 'origin']);
    await lg.callMain(['remote', 'add', 'origin', 'https://github.com/torch2424/made-with-webassembly.git']);
    await lg.callMain(['config', 'core.sparsecheckout', 'true']);
    await lg.callMain(['fetch', 'origin', '--depth=1']);
    await lg.callMain(['checkout','master']);

    // Get file tree
    const makeTree = dir => {
      const files = fs.readdir(dir)
       .filter(file =>!file.match(/^\.\.?$/));
      return `<ul>${files.map((file, i) => {
        const mimeType = mime.getType(file);
        const path = dir + '/' + file;
        const escPath = 'ft' + path.replace(/[^a-z0-9_-]/ig, '_') + '_' + i;
        if (fs.isDir(fs.lstat(path).mode)) {
          return `<li class="folder">
                    <input type="checkbox" name="${escPath}" id="${escPath}" />
                    <label for="${escPath}">
                      <i class="fas fa-angle-right"></i><i class="fas fa-folder"></i>
                      ${file}
                    </label>
                    ${makeTree(path)}
                  </li>`;
        } else if (fs.isFile(fs.lstat(path).mode)) {
          return `<li>
                    <input type="checkbox" name="${escPath}" id="${escPath}" />
                    <label for="${escPath}">
                      <i class="fas ${getIconClass(mimeType)}"></i>
                      ${file}
                    </label>
                  </li>`;
        }
      }).join('')}</ul>`;
    };
    const fileTree = makeTree('.');
    return fileTree;
  } catch (e) {
    console.error('Error getting git file tree:', e);
  }
}

module.exports = gitFileTree;

This code sets up a runtime environment for interacting with Git using the wasm-git library and defines a function to generate file icons based on MIME types.

Here's a breakdown:

  1. Dependencies:

  2. Wasm-Git Initialization:

  3. MIME to Icon Mapping:

  4. gitFileTree Function (Incomplete):

Overall Purpose:

This code snippet sets up a foundation for interacting with Git using the wasm-git library within a Node.js environment. It initializes the runtime, configures a virtual filesystem, and provides a function to map MIME types to icons. The gitFileTree function is intended to retrieve file information from the Git repository but is not yet complete.