Skip to main content

Modernización del código heredado con GitHub Copilot

Copilot Chat ayuda a modernizar el código heredado al sugerir refactorizaciones y crear pruebas para detectar posibles problemas.

Note

Las respuestas que se muestran en este artículo son ejemplos. Las respuestas del Copilot Chat no son deterministas, por lo que puedes obtener respuestas diferentes a las aquí mostradas.

El código heredado es código antiguo, obsoleto o que ya no recibe soporte de los desarrolladores originales. Puede ser difícil mantener y ampliar porque es posible que no siga los procedimientos recomendados modernos, como el uso de convenciones de nomenclatura coherentes o la escritura de documentación clara.

La modernización del código heredado puede ayudarte a:

  • Mejorar el rendimiento y la escalabilidad.
  • Facilitar el mantenimiento y la extensión del código.
  • Reducir el riesgo de introducir errores al realizar cambios.
  • Facilitar la prueba del código.

Copilot puede ayudarte a modernizar el código heredado al:

  • Proporcionar sugerencias para refactorizar el código para seguir los procedimientos recomendados modernos.
  • Generar documentación para ayudarte a comprender cómo funciona el código.
  • Generar pruebas para ayudarte a comprobar que los cambios no han introducido errores.

Escenario de ejemplo

En este ejemplo, examinaremos un sistema de administración de cuentas escrito en COBOL y lo modernizaremos en Node.js. Puedes encontrar el código de COBOL en el repositorio modernize-legacy-cobol-app.

El sistema de administración de cuentas consta de tres archivos clave:

  • main.cob: el programa principal que lee la entrada del usuario y llama al subprograma adecuado.
  • operations.cob: subprograma que realiza operaciones en los datos de la cuenta, como crédito, débito y visualización del saldo.
  • data.cob: un subprograma que administra el almacenamiento del saldo de la cuenta.

Paso 1: Obtener una copia local del repositorio

Antes de compilar y ejecutar el programa, debes tener el código localmente. Si aún no has clonado el repositorio, ve al directorio donde deseas almacenar el proyecto y ejecuta el siguiente comando:

Shell
git clone https://github.com/continuous-copilot/modernize-legacy-cobol-app.git

Paso 2: Compilar y ejecutar el programa

Puedes instalar un compilador de COBOL en tu entorno de desarrollo preferido (por ejemplo, el compilador GnuCOBOL de código abierto) o usar Copilot Chat en GitHub Codespaces.

Si usas MacOS, puedes instalar GnuCOBOL mediante Homebrew:

Shell
brew install gnu-cobol

Si usas Codespaces o un sistema Ubuntu Linux, puedes instalar GnuCOBOL mediante apt:

Shell
sudo apt-get update && \
sudo apt-get install gnucobol

Para compilar el código, vincula los archivos y crea un archivo ejecutable, ejecuta el siguiente comando desde la raíz del repositorio:

Shell
cobc -x main.cob operations.cob data.cob -o accountsystem

Para ejecutar el programa, usa el siguiente comando:

Shell
./accountsystem

Paso 3: Explicar los archivos y el código

El primer paso para modernizar el código es comprender cómo funciona. Puedes pedirle a Copilot Chat que explique el código en cada archivo.

Abre el repositorio en el IDE y, a continuación, en el panel de Copilot Chat, escribe la siguiente solicitud.

Indicación de ejemplo 1

/explain #file:main.cob #file:operations.cob #file:data.cob Can you please create a high level overview of the app. It will be great if you can explain each file in detail and how they are linked.

Respuesta de ejemplo 1

Esto es un extracto de la respuesta a la solicitud anterior:

Sure! Here's a high-level overview of the COBOL application, along with detailed explanations of each file and how they are linked together.

High-Level Overview

This COBOL application simulates an account management system. It allows users to view the current balance, credit the account, debit the account, and exit the application. The application is divided into three main COBOL source files: main.cob, operations.cob, and data.cob. ...

Paso 4: Gráfico del flujo de datos entre los archivos

El siguiente paso es comprender cómo están vinculados los archivos. Puedes usar @workspace para crear un diagrama de flujo de datos para la aplicación.

Note

El participante del chat @workspace en VS Code y Visual Studio proporciona Copilot con contexto sobre todo el código del área de trabajo. Puedes usar @workspace cuando quieras que Copilot tenga en cuenta la estructura del proyecto y, cómo interactúan las distintas partes del código. Si usas un IDE de JetBrains, utiliza @project en lugar de @workspace.

Indicación de ejemplo 2

@workspace can you create a sequence diagram of the app showing the data flow of the app. Please create this in mermaid format so that I can render this in a markdown file.

Copilot genera el marcado Mermaid para un diagrama de secuencia completo que muestra cómo funciona la aplicación. Puedes copiar y pegar este marcado en una aplicación Mermaid para generar el diagrama.

Paso 5: Generación de un plan de pruebas

Crea un plan de pruebas para asegurarte de que la aplicación funciona según lo previsto después de realizar cambios. Puedes usar @workspace para generar un plan de prueba que abarque todos los archivos del proyecto.

Indicación de ejemplo 3

@workspace The current Cobol app has no tests. Can you please create a test plan of current business logic that I can use to validate with business stakeholders about the current implementation.

Later I would like to use this test plan to create unit and integration tests in a node.js app. I am in the middle of transforming the current Cobol app to a node.js app.

The test plan should include the following:

1. Test Case ID
2. Test Case Description
3. Pre-conditions
4. Test Steps
5. Expected Result
6. Actual Result
7. Status (Pass/Fail)
8. Comments

Please create the test plan in a markdown table format. The test plan should cover all the business logic in the current Cobol app.

Convert this to markdown syntax to insert as a new file

Copilot genera un plan de prueba en formato Markdown que puedes usar para validar la aplicación. Para usar este plan más adelante en el proceso, crea un archivo denominado TESTPLAN.md y copia el plan sugerido en él. Esto te permitirá hacer referencia al plan de prueba al generar casos de prueba en los pasos siguientes.

Paso 6: Convertir los archivos de COBOL a Node.js

El siguiente paso es convertir los archivos COBOL en Node.js. Es importante tener en cuenta las siguientes prácticas de indicaciones:

  • Proporciona contexto
  • Proporciona instrucciones claras
  • Sé específico sobre el resultado que deseas lograr

Empieza por crear un directorio temporal en el proyecto, en el que se guardarán los archivos de JavaScript que vas a crear.

Shell
mkdir temp-JS-project-directory

A continuación, convierte iterativamente los archivos COBOL en Node.js.

Indicación de ejemplo 4

Can you convert code in #file:main.cob to node.js?

Respuesta de ejemplo 4

Sure! Here is the equivalent Node.js code for the main.cob file. This code will simulate the same account management system functionality.

### COBOL Code:

main.cob

```COBOL
IDENTIFICATION DIVISION.
       PROGRAM-ID. MainProgram.

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  CONTINUE-FLAG      PIC X VALUE 'Y'.
       01  USER-CHOICE        PIC 9.
       01  FINAL-BALANCE      PIC 9(6)V99 VALUE 1000.00.

       PROCEDURE DIVISION.
           PERFORM UNTIL CONTINUE-FLAG = 'N'
               DISPLAY "1. View Balance"
               DISPLAY "2. Credit Account"
               DISPLAY "3. Debit Account"
               DISPLAY "4. Exit"
               ACCEPT USER-CHOICE

               EVALUATE USER-CHOICE
                   WHEN 1
                       CALL 'Operations' USING 'TOTAL'
                   WHEN 2
                       CALL 'Operations' USING 'CREDIT'
                   WHEN 3
                       CALL 'Operations' USING 'DEBIT'
                   WHEN 4
                       MOVE 'N' TO CONTINUE-FLAG
                       DISPLAY "Exiting the program. Goodbye!"
                   WHEN OTHER
                       DISPLAY "Invalid choice. Please try again."
               END-EVALUATE
           END-PERFORM
           STOP RUN.

### Node.js Code: `main.js`
```javascript
const readline = require('readline');

let continueFlag = 'Y';
let finalBalance = 1000.00;

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});

function displayMenu() {
    console.log("1. View Balance");
    console.log("2. Credit Account");
    console.log("3. Debit Account");
    console.log("4. Exit");
}

function handleUserChoice(choice) {
    switch (choice) {
        case '1':
            viewBalance();
            break;
        case '2':
            creditAccount();
            break;
        case '3':
            debitAccount();
            break;
        case '4':
            continueFlag = 'N';
            console.log("Exiting the program. Goodbye!");
            rl.close();
            break;
        default:
            console.log("Invalid choice. Please try again.");
            promptUser();
            break;
    }
}

function viewBalance() {
    console.log(`Current balance: ${finalBalance.toFixed(2)}`);
    promptUser();
}

function creditAccount() {
    rl.question("Enter credit amount: ", (amount) => {
        amount = parseFloat(amount);
        if (!isNaN(amount) && amount > 0) {
            finalBalance += amount;
            console.log(`Amount credited. New balance: ${finalBalance.toFixed(2)}`);
        } else {
            console.log("Invalid amount. Please try again.");
        }
        promptUser();
    });
}

function debitAccount() {
    rl.question("Enter debit amount: ", (amount) => {
        amount = parseFloat(amount);
        if (!isNaN(amount) && amount > 0) {
            if (finalBalance >= amount) {
                finalBalance -= amount;
                console.log(`Amount debited. New balance: ${finalBalance.toFixed(2)}`);
            } else {
                console.log("Insufficient funds for this debit.");
            }
        } else {
            console.log("Invalid amount. Please try again.");
        }
        promptUser();
    });
}

function promptUser() {
    if (continueFlag === 'Y') {
        displayMenu();
        rl.question("Select an option: ", handleUserChoice);
    }
}

promptUser();

This Node.js code replicates the functionality of the COBOL main.cob file, providing a simple command-line interface for viewing the balance, crediting the account, debiting the account, and exiting the application.

Debes revisar el código sugerido de forma exhaustiva antes de usarlo. Una vez que estés satisfecho con el código generado, sigue estos pasos para guardarlo localmente y completar la conversión:

  1. En el directorio temporal que creaste anteriormente, crea un archivo denominado main.js.
  2. Copia el código generado del panel Copilot Chat y pégalo en main.js.
  3. Guarde el archivo.
  4. Usa indicaciones similares para convertir operations.cob y data.cob en Node.js.
  5. Crea los archivos de JavaScript correspondientes operations.js y data.js, en el mismo directorio temporal.
  6. Copia y pega el código generado en cada archivo y guárdalos.

Una vez que hayas convertido todos los archivos en Node.js, debes vincularlos y configurar un proyecto de Node.js funcional.

  1. Ve al directorio temporal en el terminal.

  2. Ejecuta el comando siguiente para crear un archivo package.json:

    Shell
    npm init -y
    
  3. Si la aplicación requiere paquetes externos, instálalos mediante la ejecución de:

    Shell
    npm install
    
  4. Inicie la aplicación; para ello, ejecute:

    Shell
    npm start
    

En este momento, es posible que la aplicación Node.js no replique completamente la funcionalidad del programa COBOL original. Por ejemplo, es posible que los saldos no se actualicen correctamente o que los cálculos no coincidan con la lógica de COBOL.

Para refinar la aplicación, deberás hacer lo siguiente:

  • Identifica el comportamiento incorrecto ejecutando el programa y comparándolo con la versión de COBOL.

  • Trabaja iterativamente con Copilot para ajustar la lógica hasta que el programa de Node.js se comporte según lo previsto.

  • Usa indicaciones dirigidas para depurar y mejorar partes específicas del código, como:

    @workspace - analyze main.js and ensure account balance updates correctly when crediting an account.

La refactorización del código heredado no siempre es un proceso de un solo paso: Copilot puede ayudar a depurar y mejorar la funcionalidad a medida que refinas la nueva implementación de Node.js.

Paso 8: Generación de pruebas unitarias y de integración

El siguiente paso es generar pruebas unitarias y de integración para asegurarte de que la aplicación funciona según lo previsto. Puedes usar @workspace para generar un plan de prueba que abarque todos los archivos del proyecto.

Indicación de ejemplo 5

@workspace I would like to create unit and integration tests cases from the test plan mentioned in #file:TESTPLAN.md file The node.js code is in node-accounting-app folder and I am looking to generate tests for #file:operations.js file. Use a popular testing framework and also provide all the dependencies required to run the tests.

Respuesta de ejemplo 5

Copilot genera una serie de pruebas en Jest, un marco de pruebas de JavaScript, con una guía paso a paso completa sobre cómo implementarlas y ejecutarlas.

Esto es un extracto de la respuesta a la solicitud anterior:

“This test plan covers the main functionalities of the COBOL application, including viewing the balance, crediting the account, debiting the account, and exiting the application. The test cases are implemented using Jest, a popular testing framework for Node.js. Validate this test plan with the business stakeholders to ensure it meets the business requirements. Once validated, you can use this plan to create corresponding unit tests and integration tests for the Node.js application.”

Paso 9: Ejecutar pruebas y refinar el código

Después de generar el plan de prueba y escribir las pruebas, deberás ejecutarlas y corregir las pruebas con errores. Las pruebas son un proceso iterativo, es posible que tengas que modificar el código para resolver problemas y, a continuación, volver a ejecutar las pruebas hasta que se supere todo.

Si se produce un error en una prueba, usa Copilot para ayudar a depurar y refinar la implementación.

Indicación de ejemplo 6

@workspace - analyze test failures in operations.test.js and suggest fixes to match the expected behavior.

Incluso si se superan todas las pruebas, es posible que el programa todavía tenga problemas. Las pruebas automatizadas no siempre detectan errores de funcionalidad o lógica que faltan, por lo que es necesario realizar pruebas manuales para asegurarte de que la aplicación se comporta según lo previsto.

Paso 10: Mover el proyecto de JavaScript a una nueva ubicación

Una vez que la aplicación funciona según lo previsto, mueve el nuevo proyecto de JavaScript fuera del directorio de COBOL para mantenerlo separado.

  1. Ve al directorio primario del proyecto de COBOL.

  2. Mueve el proyecto de JavaScript a una nueva ubicación:

    Shell
    mv modernize-legacy-cobol-app new-js-project
    
  3. Ve al nuevo directorio del proyecto y confirma que todo se ejecuta correctamente:

    Shell
    cd new-js-project
    npm start
    

Ahora, la aplicación de Node.js refactorizada se encuentra en su propia carpeta de proyecto independiente, separada de los archivos COBOL originales.

Conclusión

En este ejemplo, examinamos un sistema de administración de cuentas escrito en COBOL y lo modernizamos en Node.js. Usamos Copilot Chat para explicar el código, trazar el flujo de datos, generar un plan de prueba y convertir el código en Node.js. Siguiendo estos pasos, puedes modernizar el código heredado y facilitar el mantenimiento y la extensión. Estas son algunas sugerencias adicionales para modernizar el código heredado:

  • Los procedimientos recomendados de indicaciones son clave: la calidad de las indicaciones determina la calidad de las sugerencias de Copilot. Proporciona contexto claro, divide tareas complejas en pasos más pequeños, proporciona ejemplos y proporciona objetivos específicos a Copilot como objetivo. Esto hace que el flujo de trabajo sea más fluido y los resultados más precisos
  • Revisa el código antes de usarlo: asegúrate de comprender el código que Copilot proporciona antes de usarlo en la aplicación. Esto te ayudará a detectar posibles problemas y a asegurarte de que el código cumple los requisitos.
  • Valida los cambios: después de realizar cambios en el código, es importante validar que la aplicación sigue funcionando según lo previsto. Puedes usar el plan de prueba generado por Copilot para crear pruebas unitarias y de integración para la aplicación.

Información adicional