123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- /*
- * Copyright (C) 2024 Puter Technologies Inc.
- *
- * This file is part of Puter.
- *
- * Puter is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published
- * by the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- const fs = require('fs');
- const fsp = fs.promises;
- const path_ = require('path');
- const EXCLUDE_LISTS = {
- NOT_SOURCE: [
- /^\.git/,
- /^volatile\//,
- /^node_modules\//,
- /\/node_modules$/,
- /^node_modules$/,
- /package-lock\.json/,
- /src\/backend\/src\/public\/assets/,
- /^src\/gui\/src\/lib/
- ]
- };
- const hl_readdir = async path => {
- const names = await fs.promises.readdir(path);
- const entries = [];
-
- for ( const name of names ) {
- // wet: copied from phoenix shell
- const stat_path = path_.join(path, name);
- const stat = await fs.promises.lstat(stat_path);
- entries.push({
- name,
- is_dir: stat.isDirectory(),
- is_symlink: stat.isSymbolicLink(),
- symlink_path: stat.isSymbolicLink() ? await fs.promises.readlink(stat_path) : null,
- size: stat.size,
- modified: stat.mtimeMs / 1000,
- created: stat.ctimeMs / 1000,
- accessed: stat.atimeMs / 1000,
- mode: stat.mode,
- uid: stat.uid,
- gid: stat.gid,
- });
- }
-
- return entries;
- };
- const walk = async function* walk (options, root_path, components = []) {
- const current_path = path_.join(root_path, ...components);
- const entries = await hl_readdir(current_path);
- outer:
- for ( const entry of entries ) {
- entry.dirpath = current_path;
- entry.path = path_.join(current_path, entry.name);
- // TODO: labelled break?
- for ( const exclude_regex of (options.excludes ?? []) ) {
- if ( exclude_regex.test(entry.path) ) {
- continue outer;
- }
- }
- if ( ! options.pre_order ) yield entry;
- if ( entry.is_dir ) {
- yield* walk(options, root_path, [...components, entry.name]);
- }
- if ( options.pre_order ) yield entry;
- }
- };
- const modes = {
- primary_source_files: {
- excludes: [
- ]
- },
- };
- const util = require('util');
- const exec = util.promisify(require('child_process').exec);
- async function git_blame(path) {
- const abs_path = path_.resolve(path);
-
- try {
- const { stdout } = await exec(`git blame -f "${abs_path}"`, {
- maxBuffer: 1024 * 1024
- });
-
- const blameLines = stdout.split('\n');
- const parsedBlame = blameLines
- .map(line => {
- if (!line.trim()) return null;
-
- // console.log(line);
- const parts = line.split(/\s+/);
- let [commitHash, path, author, timestamp, lineNumber, , ,] = parts;
- author = author.slice(1);
-
- const o = {
- commitHash,
- author,
- timestamp,
- lineNumber: parseInt(lineNumber, 10),
- };
- return o;
- })
- .filter(item => item !== null)
- ;
-
- return parsedBlame;
- } catch (error) {
- console.log('AZXV')
- throw new Error(`Error executing git blame: ${error.message}`);
- }
- }
- // Example usage
- const blame = async (path) => {
- try {
- const result = await git_blame(path);
- // console.log('result?', result)
- return result;
- } catch ( e ) {
- console.log('SKIPPED: ' + e.message);
- }
- return [];
- }
- const walk_test = async () => {
- // console.log(await hl_readdir('.'));
- for await ( const value of walk({
- excludes: EXCLUDE_LISTS.NOT_SOURCE,
- }, '.') ) {
- if ( ! value.is_dir ) continue;
- console.log('value', value.path);
- }
- }
- const authors = {};
- const blame_test = async () => {
- // const results = await blame('src/backend/src/services/HostDiskUsageService.js');
- // const results = await blame('package.json');
- console.log('results', results)
- return;
- for ( const result of results ) {
- if ( ! authors[result.author] ) {
- authors[result.author] = { lines: 0 };
- }
- authors[result.author].lines++;
- }
-
- console.log('AUTHORS', authors);
- }
- /*
- Contribution count function to test file walking and
- git blame parsing.
- */
- const walk_and_blame = async () => {
- // console.log(await hl_readdir('.'));
- for await ( const value of walk({
- excludes: EXCLUDE_LISTS.NOT_SOURCE,
- }, '.') ) {
- if ( value.is_dir ) continue;
- console.log('value', value.path);
- const results = await blame(value.path);
- for ( const result of results ) {
- if ( ! authors[result.author] ) {
- authors[result.author] = { lines: 0 };
- }
- authors[result.author].lines++;
- }
- }
- console.log('AUTHORS', authors);
- }
- if ( require.main === module ) {
- const main = walk_and_blame;
- main();
- }
- module.exports = {
- walk,
- EXCLUDE_LISTS,
- };
|