Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileGlobs.py: Recursively extract .npmignore globs #168

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 21 additions & 4 deletions coala_quickstart/generation/FileGlobs.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import os

from coalib.parsing.Globbing import glob_escape
from coala_quickstart.generation.Utilities import get_gitignore_glob
from coala_quickstart.generation.Utilities import (
get_gitignore_glob, get_npmignore_glob)
from coala_utils.Question import ask_question
from coala_quickstart.Strings import GLOB_HELP
from coalib.collecting.Collectors import collect_files
Expand All @@ -23,17 +24,33 @@ def get_project_files(log_printer, printer, project_dir, non_interactive=False):
"""
file_globs = ["**"]

ignore_globs = None
ignore_globs = []
if os.path.isfile(os.path.join(project_dir, ".gitignore")):
printer.print("The contents of your .gitignore file for the project "
"will be automatically loaded as the files to ignore.",
color="green")
ignore_globs = get_gitignore_glob(project_dir)
globs = get_gitignore_glob(project_dir)
for glob in globs:
ignore_globs += [glob]

npmignore_dir_list = []

for dir_name, subdir_name, files in os.walk(project_dir):
if(os.path.isfile(os.path.join(dir_name, ".npmignore"))):
npmignore_dir_list += [dir_name]

if(npmignore_dir_list):
printer.print("The contents of your .npmignore file for the project "
"will be automatically loaded as files to ignore.",
color="green")
globs = get_npmignore_glob(project_dir, npmignore_dir_list)
for glob in globs:
ignore_globs += [glob]

if non_interactive and not ignore_globs:
ignore_globs = []

if ignore_globs is None:
if not ignore_globs:
printer.print(GLOB_HELP)
ignore_globs = ask_question(
"Which files do you want coala to ignore?",
Expand Down
30 changes: 26 additions & 4 deletions coala_quickstart/generation/Utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ def is_glob_exp(line):
return sum(1 for x in results) != 0


def parse_gitignore_line(line):
def parse_ignore_line(line):
"""
Parses the line from ``.gitignore`` and returns a list of globs.
Parses the line from ``.gitignore`` and ``.npmignore``
and returns a list of globs.

:param line: A line from the project's ``.gitignore`` file.
:param line: A line from the project's ``.gitignore`` or ``.npmignore`` file
:return: A list of glob expressions translated to the
syntax used in coala globbing.
"""
Expand Down Expand Up @@ -72,10 +73,31 @@ def get_gitignore_glob(project_dir, filename=".gitignore"):

with open(gitignore, "r") as file:
for line in file:
for glob in parse_gitignore_line(line):
for glob in parse_ignore_line(line):
yield os.path.join(project_dir, glob)


def get_npmignore_glob(project_dir, npmignore_dir_list, filename=".npmignore"):
"""
Generates a list of glob expressions equivalent to the
contents of the user's project's ``.npmignore`` file.

:param project_dir:
The user's project directory.
:param npmignore_dir_list:
A list of directories in project containing .npmignore
:return:
A list generator of glob expressions generated from the
``.npmignore`` file.
"""
for dir_name in npmignore_dir_list:
npmignore = os.path.join(dir_name, filename)
with open(npmignore, "r") as file:
for line in file:
for glob in parse_ignore_line(line):
yield os.path.join(dir_name, glob)


def split_by_language(project_files):
"""
Splits the given files based on language. This ignores unknown extensions.
Expand Down
98 changes: 97 additions & 1 deletion tests/generation/FileGlobs.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
from coala_utils.ContextManagers import (
simulate_console_inputs, suppress_stdout)
from coala_quickstart.generation.FileGlobs import get_project_files
from coala_quickstart.generation.Utilities import get_gitignore_glob
from coala_quickstart.generation.Utilities import (
get_gitignore_glob, get_npmignore_glob)
from coalib.collecting.Collectors import collect_files


Expand Down Expand Up @@ -102,6 +103,101 @@ def test_get_project_files_gitignore(self):
os.remove(".gitignore")
os.chdir(orig_cwd)

def test_get_project_files_npmignore(self):
orig_cwd = os.getcwd()
os.chdir(os.path.dirname(os.path.realpath(__file__)))
os.makedirs("file_globs_npmignore_testfiles", exist_ok=True)
os.chdir("file_globs_npmignore_testfiles")

with open(".gitignore", "w") as f:
f.write("""
# Start of gitignore
buildtest
ignore.c
/testignore
/upload.c
/*.py
*.pyc
__pycache__
# End of gitignore
""")

os.makedirs("other_folder", exist_ok=True)
os.chdir("other_folder")
with open('.npmignore', "w") as file:
file.write("""
#Start of npmignore
*.html
#End of npmignore
""")
os.chdir(os.path.dirname(os.path.realpath(__file__)))
os.chdir("file_globs_npmignore_testfiles")
os.makedirs("sample_data", exist_ok=True)
os.chdir("sample_data")
os.makedirs("data", exist_ok=True)
os.chdir("data")
with open('.npmignore', "w") as file:
file.write("""
#Start of npmignore
*.css
#End of npmignore
""")
os.chdir(os.path.dirname(os.path.realpath(__file__)))
os.chdir("file_globs_npmignore_testfiles")
files = [os.path.join("src", "main.c"),
os.path.join("src", "main.h"),
os.path.join("src", "lib", "ssl.c"),
os.path.join("src", "tests", "main.c"),
os.path.join("src", "abc.py"),
os.path.join("src", "upload.c"),
os.path.join("other_folder", "new_file.c"),
os.path.join("sample_data", "data", "new_script.js"),
os.path.join("sample_data", "example.py"),
".coafile"]
ignored_files = [os.path.join("buildtest", "main.c"),
os.path.join("testignore", "run.c"),
"ignore.c",
os.path.join("src", "ignore.c"),
"glob2.py",
"upload.c",
os.path.join("src", "abc.pyc"),
os.path.join("other_folder", "test.html"),
os.path.join("sample_data", "data", "test.css"),
"run.pyc"]

for file in files + ignored_files:
os.makedirs(os.path.dirname(os.path.abspath(file)), exist_ok=True)
open(file, "w").close()
files += [os.path.join(".gitignore")]
files += [os.path.join("other_folder", ".npmignore")]
files += [os.path.join("sample_data", "data", ".npmignore")]

npmignore_dir_list = [os.path.join(os.getcwd(), "other_folder"),
os.path.join(os.getcwd(), "sample_data", "data")]

globs = list(get_gitignore_glob(os.getcwd()))
globs += list(get_npmignore_glob(os.getcwd(), npmignore_dir_list))

returned_files = collect_files(
[os.path.join(os.getcwd(), "**")],
self.log_printer,
ignored_file_paths=globs)
files = [os.path.normcase(os.path.abspath(file)) for file in files]
ignored_files = [os.path.abspath(file) for file in ignored_files]
self.maxDiff = None
self.assertEqual(sorted(files), sorted(returned_files))

with suppress_stdout():
self.assertEqual(
sorted(get_project_files(
self.log_printer, self.printer, os.getcwd())[0]),
sorted(files))

os.remove(os.path.join("other_folder", ".npmignore"))
os.remove(os.path.join("sample_data", "data", ".npmignore"))
os.remove(".gitignore")
os.chdir(orig_cwd)

def test_get_project_files_ci_mode(self):
orig_cwd = os.getcwd()
os.chdir(os.path.dirname(os.path.realpath(__file__)) +
Expand Down
Empty file.
11 changes: 11 additions & 0 deletions tests/generation/file_globs_npmignore_testfiles/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

# Start of gitignore
buildtest
ignore.c
/testignore
/upload.c
/*.py
*.pyc
__pycache__
# End of gitignore

Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

#Start of npmignore
*.html
#End of npmignore

Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

#Start of npmignore
*.css
#End of npmignore

Empty file.