mirror of
https://github.com/nvbn/thefuck.git
synced 2025-01-31 02:01:13 +00:00
completed changes for makefile rule
This commit is contained in:
parent
cf1beb6b89
commit
dcef21e778
@ -288,6 +288,7 @@ following rules are enabled by default:
|
||||
* `ln_s_order` – fixes `ln -s` arguments order;
|
||||
* `ls_all` – adds `-A` to `ls` when output is empty;
|
||||
* `ls_lah` – adds `-lah` to `ls`;
|
||||
* `makefile` – fixes wrong `make` commands;
|
||||
* `man` – changes manual section;
|
||||
* `man_no_space` – fixes man commands without spaces, for example `mandiff`;
|
||||
* `mercurial` – fixes wrong `hg` commands;
|
||||
|
129
tests/rules/test_makefile.py
Normal file
129
tests/rules/test_makefile.py
Normal file
@ -0,0 +1,129 @@
|
||||
import pytest
|
||||
import os
|
||||
from thefuck.rules.makefile import match, get_new_command
|
||||
from thefuck.types import Command
|
||||
|
||||
@pytest.mark.parametrize('command,expected', [
|
||||
(Command('make fo', "make: *** No rule to make target 'fo'. Stop."), True),
|
||||
(Command('make ba', "make: *** No rule to make target 'ba'. Stop."), True),
|
||||
(Command('mak foo', "mak: command not found"), True),
|
||||
(Command('mak oo', "mak: command not found"), True),
|
||||
(Command('meak foo', "meak: command not found"), True),
|
||||
(Command('maek bar', "maek: command not found"), True),
|
||||
(Command('maek br', "maek: command not found"), True),
|
||||
(Command('amke foo', "amke: command not found"), True),
|
||||
(Command('make foo', "make: command not found"), False),
|
||||
(Command('cd foo', 'cd: foo: No such file or directory'), False),
|
||||
(Command('java foo.java', 'error message'), False),
|
||||
(Command('make partone parttwo', "make: *** No rule to make target 'partone parttwo'. Stop."), True)
|
||||
])
|
||||
def test_match(command,expected):
|
||||
"""
|
||||
Tests the match function with inputs such as misspelled makes,
|
||||
misspelled targets, irrelevant commands, and correctly formatted commands.
|
||||
Tests with makefiles named Makefile, makefile, and GNUmakefile
|
||||
"""
|
||||
with open("Makefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("bar:\n")
|
||||
result = match(command)
|
||||
os.remove("Makefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
||||
with open("makefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("bar:\n")
|
||||
result = match(command)
|
||||
os.remove("makefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
||||
with open("GNUmakefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("bar:\n")
|
||||
result = match(command)
|
||||
os.remove("GNUmakefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
||||
|
||||
|
||||
@pytest.mark.parametrize('command,expected', [
|
||||
(Command('make foo', "no error"), False),
|
||||
(Command('make fo', "make: *** No rule to make target 'fo'. Stop."), False),
|
||||
(Command('maek bar', "maek: command not found"), False),
|
||||
(Command('cd foo', 'cd: foo: No such file or directory'), False)
|
||||
])
|
||||
def test_match_no_makefile(command,expected):
|
||||
"""
|
||||
Tests the match function with no available makefile
|
||||
"""
|
||||
result = match(command)
|
||||
assert result == expected
|
||||
|
||||
|
||||
@pytest.mark.parametrize('command,expected', [
|
||||
(Command('make fo', "make: *** No rule to make target 'fo'. Stop."), "make foo"),
|
||||
(Command('make ba', "make: *** No rule to make target 'ba'. Stop."), "make bar"),
|
||||
(Command('make for', "make: *** No rule to make target 'for'. Stop."), "make foo"),
|
||||
(Command('mak foo', "mak: command not found"), "make foo"),
|
||||
(Command('mak oo', "mak: command not found"), "make foo"),
|
||||
(Command('meak foo', "meak: command not found"), "make foo"),
|
||||
(Command('maek bar', "maek: command not found"), "make bar"),
|
||||
(Command('maek br', "maek: command not found"), "make bar"),
|
||||
(Command('amke foo', "amke: command not found"), "make foo"),
|
||||
(Command('amke qwe', "amke: command not found"), "make foo"),
|
||||
])
|
||||
def test_get_new_command(command,expected):
|
||||
"""
|
||||
Test the correct functionality of generating the new command.
|
||||
Tests with makefiles named Makefile, makefile, and GNUmakefile
|
||||
"""
|
||||
|
||||
with open("Makefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("\tg++ testfoo.cpp\n")
|
||||
openfile.write("bar:\n")
|
||||
openfile.write("\tg++ testbar.cpp\n")
|
||||
result = get_new_command(command)
|
||||
os.remove("Makefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
||||
with open("makefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("\tg++ testfoo.cpp\n")
|
||||
openfile.write("bar:\n")
|
||||
openfile.write("\tg++ testbar.cpp\n")
|
||||
result = get_new_command(command)
|
||||
os.remove("makefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
||||
with open("GNUmakefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("\tg++ testfoo.cpp\n")
|
||||
openfile.write("bar:\n")
|
||||
openfile.write("\tg++ testbar.cpp\n")
|
||||
result = get_new_command(command)
|
||||
os.remove("GNUmakefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
||||
@pytest.mark.parametrize('command,expected', [
|
||||
(Command('make fo', "make: *** No rule to make target 'fo'. Stop."), "make foo"),
|
||||
(Command('make foodo', "make: *** No rule to make target 'foodo'. Stop."), "make food"),
|
||||
(Command('make dfoo', "make: *** No rule to make target 'dfoo'. Stop."), "make foo"),
|
||||
])
|
||||
def test_get_new_command_2(command,expected):
|
||||
with open("Makefile", "w") as openfile:
|
||||
# Creates Temporary makefile for testing
|
||||
openfile.write("foo:\n")
|
||||
openfile.write("\tg++ testfoo.cpp\n")
|
||||
openfile.write("food:\n")
|
||||
openfile.write("\tg++ testfood.cpp\n")
|
||||
result = get_new_command(command)
|
||||
os.remove("Makefile") # Removes Temporary Makefile
|
||||
assert result == expected
|
||||
|
61
thefuck/rules/makefile.py
Normal file
61
thefuck/rules/makefile.py
Normal file
@ -0,0 +1,61 @@
|
||||
import os
|
||||
from os.path import isfile, join
|
||||
from thefuck.utils import get_closest
|
||||
|
||||
TOLERANCE = 0.6
|
||||
COMMON_MISSPELLINGS = ['mke', 'maek', 'amke', 'meak', 'mkae', 'ake', 'mae', 'mak', 'makee', 'mmake', 'nake', 'makr', 'mske']
|
||||
|
||||
def makefile_in_directory():
|
||||
"""
|
||||
Returns the name of the Makefile in the current directory.
|
||||
Will return a blank string if no makefile found.
|
||||
"""
|
||||
name_of_makefile = ""
|
||||
file_list = [f for f in os.listdir(os.getcwd()) if isfile(join(os.getcwd(), f))]
|
||||
if 'GNUmakefile' in file_list:
|
||||
name_of_makefile = 'GNUmakefile'
|
||||
elif 'makefile' in file_list:
|
||||
name_of_makefile = 'makefile'
|
||||
elif 'Makefile' in file_list:
|
||||
name_of_makefile = 'Makefile'
|
||||
return name_of_makefile
|
||||
|
||||
def match(command):
|
||||
"""Match function that determines if this rule could fix this command"""
|
||||
if len(makefile_in_directory()) == 0:
|
||||
# This would mean there is no makefile in the directory, we do not have a match
|
||||
return False
|
||||
first_word = command.script_parts[0].lower()
|
||||
if first_word in COMMON_MISSPELLINGS:
|
||||
# There is a Makefile and the first word of the command was a misspelling of 'make'
|
||||
return True
|
||||
if 'no rule to make target' in command.output.lower():
|
||||
# The target passed into the make command was misspelled or did not exist
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def get_new_command(command):
|
||||
"""
|
||||
Attempt to rebuild the make command by spellchecking the targets.
|
||||
If it fails (i.e. no targets are a close enough match), then it
|
||||
defaults to first make target in the file.
|
||||
Change sensitivity by changing TOLERANCE. Default value is 0.6
|
||||
"""
|
||||
# Get possible targets from makefile and find the most similar.
|
||||
name_of_makefile = makefile_in_directory()
|
||||
possible_targets = []
|
||||
with open(name_of_makefile, 'r') as openfile:
|
||||
lines = openfile.readlines()
|
||||
for line in lines: # Loop through the makefile lines and find all targets
|
||||
line = line.strip()
|
||||
parts = line.split(':')
|
||||
if len(parts) > 1: # If there is a colon
|
||||
if parts[0][0] != '.': # If it is a valid target
|
||||
possible_targets.append(parts[0])
|
||||
new_target = get_closest(' '.join(command.script_parts[1:]), possible_targets, cutoff=TOLERANCE)
|
||||
return "make " + new_target
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user