seantiz / dryfold-cli

A tool to help me plan C++ codebase migration ahead of time. Dryfold breaks the work down into kanban-board tasks.
Apache License 2.0
0 stars 0 forks source link

feature: POST to gh API to populate Github Project with tasks #7

Closed seantiz closed 1 week ago

seantiz commented 2 weeks ago

Possible feature that would be really cool since Github Projects currently has no import feature.

Implementation

#!/usr/bin/env bash

# Install GitHub CLI https://cli.github.com/manual/installation
# Login with `gh auth login`

function create_fields() {
  echo "Creting project's fields"
  fields=$(head -n1 $2)
  for field in $fields; do
    echo $field
    gh project field-create $1 --owner "@me" --name $field --data-type TEXT
  done
}

function create_items() {
  echo "Create project items"
  titles=$(tail -n +2 $2 | cut -f 1)
  for title in $titles; do
    echo $title
    gh project item-create $1 --owner "@me" --title $title
  done
}

# Static values
PROJECT_NO=2
TSV_PATH=~/Code/github/projects/blueprint.tsv

# Execute functions
create_fields $PROJECT_NO $TSV_PATH
create_items $PROJECT_NO $TSV_PATH

More info: https://stackoverflow.com/questions/76594802/how-to-import-data-into-github-projects-view

seantiz commented 2 weeks ago

We might also be able to carry over the Complexity Score to a number field

https://docs.github.com/en/issues/planning-and-tracking-with-projects/understanding-fields/about-text-and-number-fields

seantiz commented 1 week ago

Bug: duplication was happening because analyseFeatureComplexity() was written to count every class_specifier as its own instance of a class, whenever it detected a mention of it inside module content.

For now the fix is to put a filter method on our classNodes variable, but there may be a cleaner way to do this in review:


const classNodes = tree.rootNode.descendantsOfType('class_specifier')
    .filter(node => {
        // Only include nodes that are actual class definitions
        // Check if node has a body/implementation
        return node.childForFieldName('body') !== null;
    });
seantiz commented 1 week ago

The other fix was cleaning up the way features were appended in general in analyseFeatureComplexity


export function analyseFeatureComplexity(moduleMap: Map<string, ModuleMapValues>) {
    for (const [file, data] of moduleMap) {
        if (!data.complexity?.tree?.rootNode) continue;

        const localFeatureMap = new Map(); // Create a new map for each file
        const tree = data.complexity.tree;
        const classNodes = tree.rootNode.descendantsOfType('class_specifier')
    .filter(node => {
        // Only include nodes that are actual class definitions
        // Check if node has a body/implementation
        return node.childForFieldName('body') !== null;
    });

        classNodes.forEach((classNode) => {
            const className = classNode.childForFieldName('name')?.text;
            if (!className) return;

            const methods = classNode.descendantsOfType('function_definition')
            const classType = determineClassType(classNode, methods, className);

            localFeatureMap.set(className, {
                type: classType,
                methods: methods.map(m => ({
                    name: m.text,
                    visibility: 'public'
                })),
                metrics: {
                    inheritsFrom: [],
                    uses: [],
                    usedBy: []
                },
                occurrences: [file]
            });
        });

        // Store relationships immediately for this file
        if (!data.complexity.classRelationships) {
            data.complexity.classRelationships = {};
        }

        // Only add classes found in this specific file
        for (const [className, featureData] of localFeatureMap) {
            data.complexity.classRelationships[className] = {
                type: featureData.type,
                methods: featureData.methods,
                metrics: featureData.metrics,
                occurrences: featureData.occurrences
            };
        }
    }

    return moduleMap;
}
seantiz commented 1 week ago

This is done!

See - 4bc7693