Skip to main content

Usando GitHub Copilot para migrar um project para outra linguagem de programação

Copilot Chat do GitHub pode ajudá-lo a mover um projeto para um idioma diferente. Este guia descreve o que está envolvido em um processo de migração e fornece um exemplo de migração de PHP para Python.

Introdução

Migrar um project para uma nova linguagem de programação pode ser uma tarefa difícil e demorada. GitHub Copilot pode ajudá-lo com esse processo explicando as alterações que você precisa fazer e sugerindo código de substituição no novo idioma.

Princípios de migração de um project para um novo idioma

Considere estes pontos antes de iniciar um processo de migração:

  • Conhecimento sobre codificação

    Certifique-se de ter uma boa compreensão das duas linguagens de programação. Embora Copilot possa traduzir código para você, você precisa entender as escolhas que ele propõe e decidir se deseja usar suas sugestões ou solicitar uma sugestão alternativa.

  • Conhecimento sobre o sistema que você está migrando

    Certifique-se de entender a arquitetura e a lógica do sistema atual, além da funcionalidade e dos recursos que ele fornece aos usuários. Você precisa ser capaz de verificar se o código traduzido executa todas as mesmas operações que o código original e produz os mesmos resultados.

  • Use a IA para ajudar você

    Se você não entender uma parte específica do código que você está prestes a traduzir, use o recurso "explicar" do Copilot, seja em todo o arquivo ou em um trecho selecionado do código dentro de um arquivo. Consulte Fazendo perguntas ao GitHub Copilot no seu IDE.

  • Reserve tempo para concluir a migração

    A conversão é um processo de várias fases. Quanto maior o projeto que você estiver convertendo, maior será o número de etapas que você precisará executar. Reserve bastante tempo para concluir todo o processo.

  • Trabalhe iterativamente

    Tente converter componentes discretos do projeto separadamente. Verifique se você verificou todas as alterações feitas antes de passar para outra parte do project. Escreva testes para as partes individuais do projeto conforme você avança, para que possa confirmar se cada um dos novos componentes trabalha conforme o esperado.

  • Evite introduzir complexidade ao processo

    Inicialmente, tente fazer uma conversão para algo semelhante. Isso não será possível para todo o código em seu projeto. No entanto, para evitar adicionar complexidade à tarefa de migração, tente limitar o número de novas alterações introduzidas, além de traduzir o código e usar uma nova estrutura e as dependências apropriadas.

  • Estabeleça um parâmetro de comparação e refatore o código traduzido

    Depois de concluir a conversão inicial e ter um sistema em funcionamento, você poderá estabelecer o parâmetro de comparação para comparar os sistemas antigo e novo. Você pode refatorar o código na nova linguagem. Essa é uma oportunidade para otimizar o código e reduzir a dívida técnica.

Usar Copilot para ajudá-lo a migrar um projeto para um novo idioma

Supondo que você já tenha se familiarizado com o projeto existente, uma boa maneira de começar uma migração é abrir uma ramificação do repositório no seu editor e pedir ajuda a Copilot.

  1. No seu editor, abra o painel Bate-papo do Copilot. Consulte Fazendo perguntas ao GitHub Copilot no seu IDE.

  2. Peça Copilot para descrever as etapas necessárias para migrar o projeto para o novo idioma.

    Por exemplo, para uma migração de PHP para Python, você pode perguntar:

    Copilot prompt
    @workspace I want to migrate this project from PHP to Python. Give me a high-level overview of the steps I need to take. Don't go into detail at this stage.
    

    Observação

    O participante do chat @workspace define os arquivos no workspace atual como o contexto da pergunta que você faz.

Copilot normalmente retornará com uma lista de etapas que você precisa seguir para migrar o projeto.

  1. Copie a resposta de Copilot e salve-a em algum lugar para consultá-la ao longo de todo o processo.

  2. Percorra cada etapa do processo, pedindo ajuda detalhada a Copilot conforme necessário.

    Considere cuidadosamente cada sugestão de Copilot. Certifique-se de entender o código que ele está sugerindo e avaliar se ele é apropriado para sua project. Se você não tiver certeza, peça Copilot para explicar o código para você.

    Se você acha que uma alteração sugerida por Copilot não está certa de alguma forma, peça uma sugestão alternativa.

  3. Assim que migrar um componente para um estado que pode ser executado, verifique se ele funciona conforme o esperado. Se aparecer um erro, copie a mensagem de erro para a visualização Bate-papo do Copilot e peça a Copilot que ajude você a corrigi-lo.

  4. Depois de concluir a conversão inicial, use Copilot para ajudá-lo a refatorar o código no novo idioma. Para obter mais informações, consulte Refatorando código com GitHub Copilot.

Exemplo: migrar um project PHP para Python

O exemplo a seguir descreve a migração de um aplicativo Web simples de PHP para Python. Mesmo que essas não sejam as linguagens de programação que você está usando para sua migração, talvez seja útil acompanhar as etapas descritas aqui para se familiarizar com a migração de um projeto. As etapas serão semelhantes para migrar outros pequenos projetos de uma linguagem para outra.

Captura de tela do 'Site PHP simples' antes da migração de PHP para Python.

Este exemplo pressupõe que:

  • Você está trabalhando em Visual Studio Code.
  • Você tem as duas linguagens instaladas: PHP e Python versão 3.12 ou posterior.

Migrar um projeto de site simples

Vamos migrar o código neste repositório público em GitHub: docs/simple-php-website.

O repositório é composto pelos arquivos a seguir.

.gitignore
.htaccess
LICENSE
content
├── 404.phtml
├── about-us.phtml
├── contact.phtml
├── home.phtml
└── products.phtml
includes
├── config.php
└── functions.php
index.php
readme.md
template
├── style.css
└── template.php

Este exemplo fornece os prompts que você pode inserir em Bate-papo do Copilot para concluir a migração, e as respostas retornadas por Copilot em uma instância desta migração. O GPT-4.1 modelo foi usado para gerar essas respostas. Bate-papo do Copilot as respostas são não determinísticas, portanto, você provavelmente obterá respostas ligeiramente diferentes para as mostradas aqui.

Durante um processo de migração, é provável que você receba erros que precisa corrigir antes de avançar. Copilot pode ajudá-lo com isso. O exemplo inclui alguns erros e mostra como você pode usar Copilot para ajudar a corrigi-los.

Como as respostas que você receberá de Bate-papo do Copilot provavelmente serão diferentes das mostradas aqui, você poderá se deparar com erros diferentes. Portanto, pode ser mais fácil acompanhar este exemplo de migração usando as respostas mostradas aqui, em vez daquelas que você mesmo obtém de Copilot.

Depois de concluir esta migração de exemplo, você pode usar a mesma metodologia em seu próprio project.

  1. Comece clonando uma cópia do repositório para o computador local.

  2. Execute o aplicativo para verificar se ele funciona.

    Para fazer isso, em um terminal, navegue até a raiz do repositório clonado e execute o seguinte comando:

    Shell
     php -S localhost:8000
    

    Em um navegador, acesse: http://localhost:8000.

  3. Clique nas opções do site para conhecê-lo melhor, para que você possa verificar se a migração foi bem-sucedida.

  4. Crie uma ramificação de trabalho no seu repositório e abra-a como um novo espaço de trabalho em Visual Studio Code.

  5. Familiarize-se com o conteúdo e a arquitetura do projeto existente. Copilot pode ajudá-lo com isso:

    1. Abra o modo de exibição Bate-papo do Copilot .

    2. Insira um prompt, como:

      Copilot prompt
      @workspace Describe this project in detail, explaining what the various components do and how they interact.
      
  6. Peça Copilot uma visão geral de alto nível do processo de migração:

    Copilot prompt
    @workspace I want to migrate this project from PHP to Python. Give me a high-level overview of the steps I need to take. Don't go into detail at this stage.
    

Copilot responderá com instruções como:

To migrate this project from PHP to Python, follow these high-level steps:

1. Set Up Python Environment:
   - Install Python and set up a virtual environment.
   - Install necessary packages (e.g., Flask for web framework).

2. Convert Configuration:
   - Translate the configuration settings from config.php to a Python configuration file.

3. Rewrite Functions:
   - Convert PHP functions in functions.php to Python functions.

4. Create Flask Application:
   - Set up a Flask application to handle routing and views.
   - Map the routes to corresponding views.

5. Convert Templates:
   - Translate template.php to a Jinja2 template.
   - Update the CSS file path in the template.

6. Convert Content Pages:
   - Convert .phtml content files to HTML or Jinja2 templates.

7. Update .htaccess Rules:
   - Translate .htaccess rewrite rules to Flask route handling.

8. Run and Test:
   - Run the Flask application and test all routes and functionalities.
   - Ensure the site works as expected and fix any issues.

9. Documentation:
   - Update the readme.md with new instructions for running the Python project.
  1. Copie a resposta de Copilot e salve-a em algum local para consultá-la ao longo do restante deste processo. Você seguirá cada uma dessas etapas, pedindo ajuda a Copilot à medida que avança.

  2. Se você ainda não decidiu qual estrutura de Python deseja usar, pode pedir Copilot conselhos:

    Copilot prompt
    @workspace What Python frameworks can I use for this project once it is migrated to Python? Give me a selection of options, with a brief summary of the pros and cons of each in relation to this website project. Which framework would you recommend?
    

Copilot responde com informações sobre várias estruturas e conclui:

For a project like yours - which is a simple, content-driven website - Flask is highly recommended. Its simplicity, flexibility, and ease of use (especially with its templating system that can easily replace your current PHP template structure) make it a great fit.

Seguiremos os Copilotconselhos e usaremos Flask.

  1. Voltando à visão geral de alto nível de Copilot, a primeira etapa é configurar um ambiente Python e instalar os pacotes necessários. Para descobrir como fazer isso, insira Bate-papo do Copilot:

    Copilot prompt
    @workspace I want to use Flask. Tell me how to set up a virtual environment and install the necessary packages.
    

Copilot responderá com instruções como:

1. Create a virtual environment:
   - Open a terminal and navigate to your project directory.
   - Run the following command to create a virtual environment:
     python3 -m venv venv

2. Activate the virtual environment:
   - On macOS and Linux:
     source venv/bin/activate

   - On Windows:
     venv\Scripts\activate

3. Install Flask and necessary packages:
   - With the virtual environment activated, run the following command
     to install Flask and other necessary packages:
     pip install Flask

4. Verify the installation:
   - You can verify that Flask is installed by running:
     pip list
  1. Siga Copilotas instruções e use pip list para verificar se o Flask está instalado.

  2. Voltando à visão geral de Copilot sobre o processo de migração, a próxima etapa é converter a configuração. Peça ajuda com isso a Copilot. Por exemplo:

    Copilot prompt
    @workspace As the first step in migrating this project from PHP to Python, create a Python configuration file by converting the functions in functions.php to Python functions. Tell me where to locate the Python config file in the project.
    

Copilot sugere que você crie um arquivo chamado config.py no includes diretório, contendo o código a seguir.

Python
config = {
   'name': 'Simple Python Website',
   'site_url': '',
   'pretty_uri': False,
   'nav_menu': {
      '': 'Home',
      'about-us': 'About Us',
      'products': 'Products',
      'contact': 'Contact',
   },
  'template_path': 'template',
  'content_path': 'content',
  'version': 'v3.1',
}

def get_config(key=''):
   return config.get(key, None)

def site_name():
   return get_config('name')

def site_url():
   return get_config('site_url')

def site_version():
   return get_config('version')

def nav_menu(sep=' | '):
   nav_menu = ''
   nav_items = get_config('nav_menu')

   for uri, name in nav_items.items():
      query_string = request.args.get('page', '')
      class_active = ' active' if query_string == uri else ''
      url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"

      nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'

   return nav_menu.strip(sep)

def page_title():
   page = request.args.get('page', 'Home')
   return ' '.join(word.capitalize() for word in page.split('-'))

def page_content():
   page = request.args.get('page', 'home')
   path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')

   if not os.path.exists(path):
      path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')

   with open(path, 'r') as file:
      return file.read()

def init():
   template_path = os.path.join(get_config('template_path'), 'template.html')
   with open(template_path, 'r') as file:
      return file.read()
  1. Crie o arquivo includes/config.py e exclua o arquivo includes/config.php existente.

  2. Retornando à visão geral novamente, peça Copilot para ajudá-lo a reescrever as funções php.

    Copilot prompt
    @workspace Continuing the migration of this project from PHP to Python, create Python functions to replace the existing PHP functions. Tell me where to locate the Python functions in the project.
    

Copilot sugere que você crie um arquivo chamado functions.py no includes diretório, contendo o código a seguir.

Python
import os
from flask import request
from .config import get_config

def site_name():
   return get_config('name')

def site_url():
   return get_config('site_url')

def site_version():
   return get_config('version')

def nav_menu(sep=' | '):
   nav_menu = ''
   nav_items = get_config('nav_menu')

   for uri, name in nav_items.items():
      query_string = request.args.get('page', '')
      class_active = ' active' if query_string == uri else ''
      url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"

      nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'

   return nav_menu.strip(sep)

def page_title():
   page = request.args.get('page', 'Home')
   return ' '.join(word.capitalize() for word in page.split('-'))

def page_content():
   page = request.args.get('page', 'home')
   path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')

   if not os.path.exists(path):
      path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')

   with open(path, 'r') as file:
      return file.read()

def init():
   template_path = os.path.join(get_config('template_path'), 'template.html')
   with open(template_path, 'r') as file:
      return file.read()
  1. Crie o arquivo includes/functions.py e exclua o arquivo includes/functions.php existente.

  2. Continuando com a visão geral, a próxima etapa é criar um aplicativo Flask. Peça Copilot para ajudá-lo com isso:

    Copilot prompt
    @workspace Set up a Flask application to handle routing and views, and map the routes to corresponding views. Tell me the location of any files that need to be created or changed.
    

Copilot sugere que você crie um arquivo chamado app.py na raiz do projeto, contendo o código a seguir.

Python
from flask import Flask, render_template, request
import os

app = Flask(__name__)

config = {
   'name': 'Simple Python Website',
   'site_url': '',
   'pretty_uri': False,
   'nav_menu': {
      '': 'Home',
      'about-us': 'About Us',
      'products': 'Products',
      'contact': 'Contact',
   },
   'template_path': 'template',
   'content_path': 'content',
   'version': 'v3.1',
}

def get_config(key=''):
   return config.get(key, None)

@app.route('/')
@app.route('/<page>')
def index(page='home'):
   page_content = get_page_content(page)
   page_title = get_page_title(page)
   nav_menu = get_nav_menu()
   return render_template('template.html', page_title=page_title, page_content=page_content, nav_menu=nav_menu)

def get_page_title(page):
   return ' '.join(word.capitalize() for word in page.split('-'))

def get_page_content(page):
   path = os.path.join(os.getcwd(), get_config('content_path'), f'{page}.phtml')
   if not os.path.exists(path):
      path = os.path.join(os.getcwd(), get_config('content_path'), '404.phtml')
   with open(path, 'r') as file:
      return file.read()

def get_nav_menu(sep=' | '):
   nav_menu = ''
   nav_items = get_config('nav_menu')
   for uri, name in nav_items.items():
      query_string = request.args.get('page', '')
      class_active = ' active' if query_string == uri else ''
      url = f"{get_config('site_url')}/{'' if get_config('pretty_uri') or uri == '' else '?page='}{uri}"
      nav_menu += f'<a href="{url}" title="{name}" class="item{class_active}">{name}</a>{sep}'
   return nav_menu.strip(sep)

if __name__ == '__main__':
   app.run(debug=True)

Copilot também sugere renomear template/template.php``template/template.html e atualizar o arquivo para usar a sintaxe de modelagem Jinja2:

HTML

<!DOCTYPE html>
<html>
<head>
   <meta charset="utf-8" />
   <meta http-equiv="x-ua-compatible" content="ie=edge"/>
   <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
   <title>{{ page_title }} | {{ get_config('name') }}</title>
   <link href="{{ get_config('site_url') }}/template/style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div class="wrap">

   <header>
      <h1>{{ get_config('name') }}</h1>
      <nav class="menu">
         {{ nav_menu|safe }}
      </nav>
   </header>

   <article>
      <h2>{{ page_title }}</h2>
      {{ page_content|safe }}
   </article>

   <footer>
      <small>&copy;{{ get_config('version') }} {{ get_config('name') }}.<br>{{ get_config('version') }}</small>
   </footer>

</div>
</body>
</html>

  1. Crie os arquivos app.py e template/template.html conforme sugerido.

  2. Copilot também pode sugerir que, depois de criar esses arquivos, você execute python app.py no terminal, a partir da raiz do repositório, e, em seguida, acesse http://127.0.0.1:5000.

    Observação

    Dependendo de como o Python está instalado em seu computador, talvez seja necessário usar o comando python3 app.py em vez de python app.py para garantir que a versão correta do Python seja usada.

    Ao fazer isso, você verá mensagens de erro no navegador.

  3. Copie a mensagem de erro inicial TemplateNotFound para o modo de exibição Bate-papo do Copilot e pergunte como você pode corrigir isso. Por exemplo:

    Copilot prompt
    @workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.TemplateNotFound: template.html`. How can I fix this?
    

Copilot responde que o erro indica que o Flask não consegue localizar o template.html arquivo.

Ele informa que, por padrão, o Flask procura modelos em uma pasta chamada templates no diretório raiz do project. No entanto, seu arquivo template.html está localizado no diretório template. Para corrigir isso, você precisa especificar a pasta do modelo correta ao criar o aplicativo Flask. Ele aconselha você a atualizar seu arquivo app.py, alterando a atribuição app = Flask(__name__) para incluir o parâmetro template_folder:

Python
app = Flask(__name__, template_folder='template')
  1. Supondo que o servidor de desenvolvimento do Flask ainda esteja em execução, se você atualizar a página do navegador em http://127.0.0.1:5000/, verá um novo erro relacionado à função get_config.

    Copie esta mensagem de erro para o modo de exibição Bate-papo do Copilot e peça ajuda.

    Copilot prompt
    @workspace When I run `python3 app.py`, I get the following error in the browser: `jinja2.exceptions.UndefinedError: 'get_config' is undefined.` How can I fix this?
    

Copilot responde que o erro ocorre porque get_config não está disponível no contexto do modelo Jinja2. Ele aconselha você a adicionar o seguinte código ao arquivo app.py, diretamente antes da linha @app.route('/'):

Python
app.jinja_env.globals.update(get_config=get_config)
  1. Atualize o navegador e provavelmente agora você verá o site.

    Captura de tela do 'Website Simples em Python' sem estilo CSS.

    No entanto, nenhum dos estilos CSS está sendo aplicado. Corrigiremos isso em seguida.

  2. Pergunte a Copilot:

    Copilot prompt
    @workspace The deployed website does not use the CSS styles. How can I fix this?
    

Copilot informa que o Flask espera que seu arquivo CSS esteja em um diretório chamado static. Ele sugere mover o arquivo style.css existente do diretório template para um novo diretório static e atualizar o caminho para o arquivo style.css dentro da parte head do arquivo template.html. Altere para:

HTML

<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

Quando você atualiza o navegador, o site agora deverá ser renderizado corretamente.

Para concluir a migração inicial, continue trabalhando nas etapas na visão geral de alto nível que Copilot lhe deu, solicitando ajuda conforme necessário.

Concluindo a migração

O trabalho adicional para concluir com êxito o processo de migração envolveria:

  • Verificar a migração inicial minuciosamente.
  • Correção de erros. Por exemplo, no momento, no exemplo descrito aqui, os links de página só funcionarão se você definir pretty_uri como True na seção config do arquivo app.py. Se você quiser a opção de usar parâmetros de cadeia de caracteres de consulta nas URLs da página ou se quiser remover essa opção do código, peça Copilot para ajudá-lo a fazer isso.
  • Escrever testes para o projeto migrado.
  • Limpando o projeto removendo todos os arquivos que não são mais necessários.
  • Refatorar o código na nova linguagem. O processo de migração resultou em um project python cuja arquitetura é baseada na do project php original. Tendo feito a migração inicial, agora você pode refatorar o código para fazer o melhor uso dos recursos da linguagem Python e da estrutura Flask.
  • Atualizar a documentação. O arquivo readme.md está desatualizado e precisa ser reescrito.