Запуск Make-файлов в каталогах символьных ссылок из python

#python #makefile

#python #makefile

Вопрос:

У меня есть каталог ~/PROJECTS , содержащий несколько подкаталогов, некоторые из которых являются символическими ссылками на другие каталоги.

 .
├── proj1_symlink_dir
├── proj2_symlink_dir
├── proj3_symlink_dir
├── backup_1_dir
├── backup_2_dir
  

Каждый из этих каталогов символических ссылок (которые указывают на другие каталоги
на моем жестком диске), т.е.
[proj1_symlink_dir, proj2_symlink_dir, proj3_symlink_dir]
каждый содержит Makefile .

Я хочу написать python скрипт для:

  1. Перебирайте только символические ссылки в active directory
  2. Для каждой из этих символических ссылок перейдите в каталог и запустите make clean (или с учетом строкового параметра, содержащего команды make)

Может ли кто-нибудь помочь в написании компактного скрипта на pythonic для выполнения вышеуказанной задачи?

Пока у меня есть следующее для печати символических ссылок (адаптировано отсюда):

 dirname = os.getcwd()
for name in os.listdir(dirname):
    if name not in (os.curdir, os.pardir):
        full = os.path.join(dirname, name)
        if os.path.islink(full):
            print(name, '->', os.readlink(full))
  

Я не уверен, как безопасно работать с запущенными Makefile командами в python

Обновить

С помощью @Marat я создал следующий скрипт с именем runmke.py .

 #!/Usr/bin/env python

import argparse
import os
import json

def run_symlink_makefile_cmd(dirname, make_cmds, verbose):
    """
    Run common make commands from makefiles from 
    all symlinked directories that are located 
    in a specified directory
    """
    make_cmds_str = " ".join(make_cmds)
    for name in os.listdir(dirname):
        if name not in (os.curdir, os.pardir):
            full = os.path.join(dirname, name)
            if os.path.islink(full):
                if verbose:
                    print(f"n>>>>> Running the Make command:")
                    print(f"make -C {full} {make_cmds_str}")
                os.system(f"make -C {full} {make_cmds_str}")

def main(dirname, make_cmds, verbose):
    # Display parameters passed for the given run (includes defaults)
    print(f"""The parameters for this run are:n {json.dumps(locals(), indent=2, default=str)}""")
    run_symlink_makefile_cmd(dirname=dirname,
                             make_cmds=make_cmds,
                             verbose=verbose)
    
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--dirname', action='store', default=os.getcwd(),
                        help='The directory in which symlink directories, default is the current directory')
    parser.add_argument('-m', '--make_cmds', nargs=' ',
                        default=["clean", "latex_style"],
                        help='These are the Makefile commands to run')
    parser.add_argument('-v', '--verbose', action='store_true', default=True,
                        help='If true, print updates while processing.')
    argument_parsed = parser.parse_args()

    main(
        dirname=argument_parsed.dirname,
        make_cmds=argument_parsed.make_cmds,
        verbose=argument_parsed.verbose
    )
  

Однако, когда я запускаю ./runmke.py -m latex_style -v False
свой терминал, я получаю сообщение об ошибке:

 usage: runmke.py [-h] [-d DIRNAME] [-m MAKE_CMDS [MAKE_CMDS ...]] [-v]
runmke.py: error: unrecognized arguments: False
  

Любые идеи, почему verbose логический аргумент не распознается.
Это работает, когда я не передаю это вручную.

Комментарии:

1. что вы пробовали до сих пор?

2. @Marat — я добавил еще несколько подробностей о том, где я нахожусь

3. кажется, вам не хватает только одной строки под инструкцией print: os.system('make -C "%s" clean' % full)

4. @Marat — большое спасибо за вашу любезную помощь. Я добавил свой обновленный код с вашей помощью в качестве скрипта в свой исходный пост. Это имеет небольшую ошибку. Не могли бы вы помочь? Если вы напишите ответ в виде полного ответа, я могу принять его, чтобы вы получили должное признание за решение

5. action=store_true аргументы типа не имеют значения, им присваивается значение True, если ключ просто присутствует в команде. Итак, правильная команда для запуска: ./runmke.py -m latex_style -v

Ответ №1:

С помощью @Marat я создал следующий скрипт с именем runmke.py .

 #!/Usr/bin/env python

import argparse
import os
import json

def run_symlink_makefile_cmd(dirname, make_cmds, verbose):
    """
    Run common make commands from makefiles from 
    all symlinked directories that are located 
    in a specified directory
    """
    make_cmds_str = " ".join(make_cmds)
    for name in os.listdir(dirname):
        if name not in (os.curdir, os.pardir):
            full = os.path.join(dirname, name)
            if os.path.islink(full):
                if verbose:
                    print(f"n>>>>> Running the Make command:")
                    print(f"make -C {full} {make_cmds_str}")
                os.system(f"make -C {full} {make_cmds_str}")

def main(dirname, make_cmds, verbose):
    # Display parameters passed for the given run (includes defaults)
    print(f"""The parameters for this run are:n {json.dumps(locals(), indent=2, default=str)}""")
    run_symlink_makefile_cmd(dirname=dirname,
                             make_cmds=make_cmds,
                             verbose=verbose)
    
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--dirname', action='store', default=os.getcwd(),
                        help='The directory in which symlink directories, default is the current directory')
    parser.add_argument('-m', '--make_cmds', nargs=' ',
                        default=["clean", "latex_style"],
                        help='These are the Makefile commands to run')
    parser.add_argument('-v', '--verbose', action='store_true', default=True,
                        help='If true, print updates while processing.')
    argument_parsed = parser.parse_args()

    main(
        dirname=argument_parsed.dirname,
        make_cmds=argument_parsed.make_cmds,
        verbose=argument_parsed.verbose
    )
  

Его можно запустить на терминале с помощью ./runmke.py -m latex_style -v