Skip to content

Commit

Permalink
Merge branch 'release/1.0.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
Jan David committed Nov 25, 2015
2 parents 47c2f85 + 656bf3a commit c39a9f2
Show file tree
Hide file tree
Showing 16 changed files with 7,002 additions and 3 deletions.
Binary file added 487A8098-1037-4523-BCA6-B04539B70A80.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
44 changes: 41 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,48 @@

**gitignore** is an [Alfred](https://www.alfredapp.com) workflow that lets you
create _.gitignore_ files from Alfred's input interface. It uses templates
provided by [GitHub](https://github.com), allowing you to simply type in the
names of all templates you want to combine into your own _.gitignore_ file.
provided by [GitHub](https://github.com), and combines them into a single
.gitignore file.

# License
## Requirements

Although it should be pretty self-explanatory, these are the requirements for
this workflow:

- **OS X**
- **Alfred 2**
- **Git**

## Installation

After installing the workflow, you need to download the templates. Enter the
following command into Alfred:

```
gitignore-update
```

Executing this will clone the [github/gitignore](https://github.com/github/gitignore)
repository, and make the templates in it available to you.

## Usage

To use this workflow, simply type in `gitignore`. You will now see a list of all
templates installed on your machine. You can search for specific templates by
typing in their name. Selecting a template will place add it to the command
line.

If you've selected all templates that you want to combine, simply select the
first item in the list called "Build .gitignore file". This will start the
generation of the template, and open it in TextEdit once it has been created.

Copy & paste the contents of the file and paste them into the `.gitignore` file
in your project.

The temporary file is created in `/tmp/`, and will automatically be deleted
after three days.

## License

Copyright (c) 2015 Jan David Nose

Expand Down
50 changes: 50 additions & 0 deletions gitignore-build.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# encoding: utf-8

import glob
import hashlib
import os
import sys
from workflow import Workflow, ICON_SYNC, ICON_WARNING, web

workflow = Workflow()
repo_dir = workflow.datafile("gitignore")

def main(wf):
if len(sys.argv) < 2:
print "No templates were selected, so nothing was built."
return

if not os.path.isdir(repo_dir):
print "Please run gitignore-update first to download the templates."

templates = sys.argv[1:]

tmp_file_name = hashlib.md5(" ".join(templates)).hexdigest()
tmp_file_path = "/tmp/" + tmp_file_name

if os.path.isfile(tmp_file_path):
os.system("open %s" % tmp_file_path)
return

formatted_templates = set()

for t in templates:
formatted_templates.add(t.lower() + ".gitignore")

for root, dirs, files in os.walk(repo_dir):
for name in files:
if name.lower() in formatted_templates:
with open(os.path.join(root, name)) as in_file:
with open(tmp_file_path, "a+") as out_file:
out_file.write("### %s\n\n" % name)
for line in in_file:
out_file.write(line)
out_file.write("\n\n")

print "Successfully built .gitignore file. Have fun!"
os.system("open %s" % tmp_file_path)
return


if __name__ == u"__main__":
sys.exit(workflow.run(main))
88 changes: 88 additions & 0 deletions gitignore-input.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# encoding: utf-8

import argparse
import os
import sys
from workflow import Workflow, ICON_SYNC, ICON_WARNING, web

workflow = Workflow()


def main(wf):
parser = argparse.ArgumentParser()
parser.add_argument('query', nargs='*', default=None)

args = parser.parse_args(wf.args)
templates = wf.stored_data("templates")

current_query = ""

if len is None:
wf.add_item(
title="Templates missing",
subtitle="Please run gitignore-update to download the templates...",
icon=ICON_WARNING,
valid=False
)
else:
if args.query:
query = args.query
input = query[-1]
current_query = " ".join(query[:-1])
filtered_templates = [i for i in templates if input.lower() in i.lower()]

if len(filtered_templates) >= 1:
templates = filtered_templates

wf.add_item(
title="Build .gitignore file",
subtitle="Combine the chosen templates to a single .gitignore file...",
uid="build_gitignore",
arg=" ".join(query),
valid=True,
)

for i in templates:
add_template(i, query=current_query)
else:
for i in templates:
add_template(i)

wf.send_feedback()


def add_template(template_name, query=""):
"""
Add template to output.
This function adds the given template as a new item to the XML output.
"""
autocomplete = build_autocomplete(template_name, query)

workflow.add_item(
title=template_name,
uid=template_name,
autocomplete=autocomplete,
valid=False
)


def build_autocomplete(template_name, query):
"""
Build the autocomplete string.
From the template name and the current query a new string is built that can
be used as the value for an item's autocomplete attribute.
"""
autocomplete = ""

if len(query) > 0:
autocomplete = " ".join([query, template_name])
else:
autocomplete = template_name

return " ".join([autocomplete, ""])


if __name__ == u"__main__":
sys.exit(workflow.run(main))
151 changes: 151 additions & 0 deletions gitignore-update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# encoding: utf-8

import os
import re
import sys
from sh import git, pwd, sh
from workflow import Workflow, ICON_SYNC, web

workflow = Workflow()
repo_dir = workflow.datafile("gitignore")


def main(wf):
"""
Run script.
This script checks whether or not the gitignore repository has already been
cloned, and either clones it or pulls the latest changes from the remote
repository. In both cases, the list of templates is stored in the persistent
storage provided by the Workflow's data API.
"""
if not os.path.isdir(repo_dir):
clone_repo()
else:
pull_repo()

update_templates()

print "Templates have been successfully updated."


def clone_repo():
"""
Clone the Git repository 'github/gitignore' to the data directory.
This function clones the gitignore repository from GitHub and saves the
local copy in the workflow's data directory. It uses the module sh to invoke
the git executable. If the git executable cannot execute properly, an
exception is thrown.
"""
try:
os.chdir(workflow.datafile(""))
git.clone("https://github.com/github/gitignore.git")
except:
handle_exception()
return 0


def pull_repo():
"""
Pull the recent changes from origin master.
This function pulls all recent changes from the gitignore repository on
GitHub. It uses the module sh to invoke the git executable. If the git
executable cannot execute properly, an exception is thrown.
"""
try:
os.chdir(repo_dir)
git.pull()
except:
handle_exception()
return 0


def handle_exception():
"""
Handle the last thrown exception.
This function handles the last thrown exception. It compares the exception's
class to a number of known exceptions, and prints the respective error
message. If the exception is not known, a generic error message is printed.
"""
e = sys.exc_info()[0]
if e.__name__ == "ErrorReturnCode_128":
print "'git clone' failed due to an unknown reason. Please contact the support."
else:
print "An unknown error occured. Please contact the support."
sys.exit(-1)


def update_templates():
"""
Update the list of templates stored with the Workflow's data API.
This function updates the list of templates that is stored with the
Workflow's data API. To avoid duplicate data entries, it first deletes any
existing data before saving the current list of templates.
"""
workflow.clear_data(lambda f: f.startswith("templates"))
store_template_names()
return 0


def store_template_names():
"""
Save the template names using the Workflow's data API.
This function reads the names of the currently available templates from the
directory, and saves them in the persistent data storage provided by the
Workflow library.
"""
templates = get_template_names()
templates.sort()

workflow.store_data('templates', templates)
return 0


def get_template_names():
"""
Return the names of all templates in the local repository.
This function goes recursively through the local copy of the gitignore
repository, and returns the name of all templates within it. Templates are
identified by their file extension, which is '.gitignore'.
"""
file_names = get_file_names_in_dir(repo_dir)
templates = []

for f in file_names:
file_name = str(f)
if re.search(".\.gitignore$", file_name):
templates.append(file_name[:-10])

return templates


def get_file_names_in_dir(directory):
"""
Return the names of all files in the given directory.
Arguments:
- directory: Path of the directory whose files should be returned
This function goes recursively through the given directory and returns the
name of all files within it.
"""
file_names = []

for root, subdirs, files in os.walk(directory):
for subdir in subdirs:
file_names.append(get_file_names_in_dir(subdir))

for f in files:
file_names.append(f)

return file_names


if __name__ == u"__main__":
sys.exit(workflow.run(main))
Binary file added gitignore.alfredworkflow
Binary file not shown.
Binary file added icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit c39a9f2

Please sign in to comment.