Using .goosehints Files with Goose 🦢
Lymah
Posted on November 19, 2024
Introduction
According to the official goose website, Goose 🦢 is a developer agent that supercharges your software development by automating an array of coding tasks directly within your terminal or IDE. Guided by you, it can intelligently assess your project's needs, generate the required code or modifications, and implement these changes on its own. Goose can interact with a multitude of tools via external APIs such as Jira, GitHub, Slack, infrastructure and data pipelines, and more -- if your task uses a shell command or can be carried out by a Python script, Goose can do it for you too! Like semi-autonomous driving, Goose handles the heavy lifting, allowing you to focus on other priorities. Simply set it on a task and return later to find it completed, boosting your productivity with less manual effort. In this post, we’ll explore what .goosehints
files are.
Learn more
What are .goosehints files and why use them
Understanding .goosehints
The
hints
file is meant to provide additional context about your project. The context can be user-specific or at the project level in which case, you can commit it to git.
A .goosehints
file is a plain-text configuration file that provides Goose with supplemental information about your project. It acts as a guide to help Goose better understand the project’s structure, purpose, or even specific coding conventions you’re using. By providing Goose with additional context, you enable it to make smarter decisions, tailor its suggestions, and generate more accurate code or configurations.
For example, a .goosehints
file might include:
- Project-specific information: Key modules, folder structures, or domain knowledge.
- Development conventions: Custom coding styles, naming conventions, or frameworks.
- User preferences: Personal preferences for code formatting or tool usage.
Think of the .goosehints
file as a guide that helps Goose better understand your project's structure, conventions, and requirements.
Why Use .goosehints?
Here’s why .goosehints
files are a game-changer:
-
Enhanced Context: Goose performs best when it understands the nuances of your project. A
.goosehints
file provides the extra detail needed for Goose to make informed decisions. - Consistency Across Teams: By committing a
.goosehints
file to your project’s repository, you ensure that all team members benefit from the same guidance. Goose will adhere to your project’s standards consistently, reducing discrepancies. - User-Specific Customization: If you prefer personal preferences over global standards, you can create user-specific
.goosehints
files to tailor Goose’s behavior just for you. - Time Savings: With a
.goosehints
file, Goose doesn’t need to ask repetitive questions or make assumptions. This saves time and ensures that tasks are completed faster.
Setting up .goosehints in Your Project
- Create the File
# At your project root
touch .goosehints
- Choose the Right Location Project-wide hints: Place in the root directory User-specific hints: Place in your home directory as ~/.goosehints Directory-specific hints: Place in relevant subdirectories
Basic Configuration Template
Start with this basic template and customize it for your needs:
project:
name: "Your Project Name"
repository: "https://github.com/username/repo"
type: "web-
Using Jinja templating in .goosehints
Goose 🦢 is powerful on its own, but its true potential shines when you combine it with dynamic and adaptable configurations. One way to achieve this is by incorporating Jinja templating into your .goosehints
files. With Jinja, you can make your hints dynamic, reusable, and adaptable to various environments or user preferences.
What Is Jinja Templating?
Jinja is a Python-based templating engine that allows you to use placeholders and logic (e.g., loops, conditions) in your text files. It’s widely used in web frameworks like Flask and tools like Ansible, and it’s perfect for creating dynamic .goosehints
files.
By embedding Jinja in your .goosehints
, you can:
- Dynamically adjust hints based on environment variables or user input.
- Reuse templates across multiple projects.
- Add logic to make
.goosehints
files more modular and flexible.
Why Use Jinja in .goosehints?
Here are some benefits of using Jinja templating in your .goosehints
file:
- Dynamic Configuration: Adjust hints for different environments (e.g., staging, production) without editing the file manually.
-
Reusability: Use the same
.goosehints
template across multiple projects by dynamically injecting project-specific details. - Customization: Enable developers to pass in their own variables for more personalized hints.
- Reduced Redundancy: Use loops and macros to simplify repetitive structures in your hints.
Setting Up Jinja in .goosehints
- Enable Jinja Rendering in Goose
To use Jinja in
.goosehints
, you need to ensure Goose is configured to process Jinja templates. While Goose typically supports templating natively, check the documentation to verify it’s enabled or use the appropriate flag:
goose --hints-file .goosehints --enable-jinja
If you’re using an external file renderer, you may also process the file manually before passing it to Goose:
jinja2 .goosehints.template --format=json > .goosehints
goose --hints-file .goosehints
- Writing a .goosehints Template
A .goosehints
file using Jinja templating looks similar to a regular .goosehints
file but includes Jinja-specific syntax.
Here’s an example:
- Environment-Specific Configuration example
# Project Information
Project Name: {{ project_name }}
Environment: {{ environment }}
# Framework
Framework: {{ framework }}
Version: {{ framework_version }}
# Key Modules
{% for module in modules %}
- {{ module.name }}: {{ module.description }}
{% endfor %}
# Preferences
- Code Formatting: {{ preferences.code_formatting }}
- Add Comments to Migrations: {{ preferences.comments }}
Rendering the File
To render this file, you’ll need to provide the required variables (e.g., via a .json
or .yaml
file).
jinja2 .goosehints.template -D project_name="Ticket Manager" -D environment="production" \
-D framework="Django" -D framework_version="4.2" \
-D modules='[{"name": "events", "description": "Handles events"}, {"name": "users", "description": "User management"}]' \
-D preferences='{"code_formatting": "PEP8", "comments": "Yes"}' > .goosehints
The rendered .goosehints
file would look like this:
# Project Information
Project Name: Ticket Manager
Environment: production
# Framework
Framework: Django
Version: 4.2
# Key Modules
- events: Handles events
- users: User management
# Preferences
- Code Formatting: PEP8
- Add Comments to Migrations: Yes
Advanced Jinja Features for .goosehints
Jinja offers powerful features to make your .goosehints
even more dynamic:
- Conditionals
# Deployment Settings
{% if environment == "production" %}
Use Optimized Database Connections: Yes
Enable Debug Mode: No
{% else %}
Use Optimized Database Connections: No
Enable Debug Mode: Yes
{% endif %}
- Loop
# Active Features
{% for feature in active_features %}
- {{ feature }}
{% endfor %}
- Macros
Reuse blocks of logic with macros:
{% macro module_info(module) %}
- {{ module.name }}: {{ module.description }}
{% endmacro %}
# Key Modules
{% for module in modules %}
{{ module_info(module) }}
{% endfor %}
Best Practices for Jinja in .goosehints
-
Keep It Modular: Break down your
.goosehints
file into reusable sections using macros. - Validate Input Data: Ensure variables passed to the Jinja template are complete and correct.
-
Use Comments: Annotate complex logic in your
.goosehints
file for easier maintenance. - Avoid Over-Engineering: Use Jinja only when necessary. For simple projects, a static
.goosehints
file may suffice. -
Test Before Committing: Render the
.goosehints
file locally and verify it works as expected before committing to your repository.
Example Use Case: Multi-Environment .goosehints
Here’s an example of a .goosehints
file designed for both staging and production environments:
# Project Info
Project: {{ project_name }}
Environment: {{ environment }}
# Database Settings
Database:
{% if environment == "production" %}
Host: {{ production_db.host }}
Port: {{ production_db.port }}
{% else %}
Host: {{ staging_db.host }}
Port: {{ staging_db.port }}
{% endif %}
# Logging Settings
Log Level: {{ "DEBUG" if environment == "staging" else "INFO" }}
Rendering Example:
jinja2 .goosehints.template -D project_name="MyApp" -D environment="staging" \
-D production_db='{"host": "prod-db.example.com", "port": 5432}' \
-D staging_db='{"host": "staging-db.example.com", "port": 5432}'
Rendered file for staging:
# Project Info
Project: MyApp
Environment: staging
# Database Settings
Database:
Host: staging-db.example.com
Port: 5432
# Logging Settings
Log Level: DEBUG
Project-level vs user-specific hints
Understanding the distinction between project-level and user-specific hints is crucial for maintaining a clean and efficient development environment. Each type serves different purposes and follows different management practices.
Project-Level Hints
Project-level hints are shared across all team members and are typically committed to version control.
Location and Naming
your-project/
├── .goosehints # Main project hints
├── .goosehints.default # Template for user-specific hints
├── src/
└── ...
Appropriate Content for Project-Level Hints
# .goosehints
project:
name: "example-project"
repository: "https://github.com/org/example-project"
standards:
code_style:
indent: 2
max_line_length: 80
quotes: "single"
architecture:
patterns:
- "Repository pattern for data access"
- "CQRS for complex operations"
testing:
framework: "jest"
coverage:
minimum: 80
excludes:
- "src/types/"
- "src/migrations/"
ci:
required_checks:
- "lint"
- "test"
- "build"
User-Specific Hints
User-specific hints contain personal preferences and local environment configurations. These should never be committed to version control.
Location and Naming
~/.goosehints # Global user hints
your-project/.goosehints.local # Project-specific user hints
Appropriate Content for User-Specific Hints
# .goosehints.local
editor:
path: "/usr/local/bin/vim"
config:
theme: "monokai"
line_numbers: true
local_env:
database_url: "postgresql://localhost:5432/mydb"
api_keys:
service_a: "your-personal-key"
service_b: "another-personal-key"
debug:
verbose: true
log_level: "debug"
breakpoints:
- "src/critical/function.ts"
- "src/auth/login.ts"
shortcuts:
build: "npm run build && npm run test"
deploy: "kubectl apply -f ./my-local-config.yaml"
Managing Both Types
- Setup Template for New Team Members
Create a
.goosehints.default
template:
# .goosehints.default
# Copy this file to .goosehints.local and customize
local_env:
database:
host: "localhost"
port: 5432
name: "project_db"
# Add your username and password here
username: ""
password: ""
services:
cache:
port: 6379
queue:
port: 5672
development:
hot_reload: true
mock_services: false # Set to true if not running all services locally
- Git Configuration
Add to .gitignore
:
# .gitignore
.goosehints.local
*/.goosehints.local
~/.goosehints
- Precedence Rules
# Priority order (highest to lowest):
# 1. .goosehints.local (user-specific, project directory)
# 2. ~/.goosehints (user-specific, global)
# 3. .goosehints (project-level)
# 4. .goosehints.default (template)
Best Practices and tips for Managing Hints
- Clear Separation of Concerns Project-Level (.goosehints)
# Things that should be consistent across all developers
standards:
formatting:
indent_style: "space"
indent_size: 2
build:
target_node: "16.x"
optimization_level: "production"
User-Specific (.goosehints.local)
# Personal preferences and local setup
workspace:
editor_command: "code"
terminal: "iterm2"
debug:
verbose_logging: true
break_on_error: true
Documentation
Add comments in both files to help team members understand the purpose
# .goosehints
# Project-wide configuration that should be consistent across all developers.
# Changes to this file should be reviewed by the team.
# .goosehints.local
# Local developer configurations. Customize as needed.
# DO NOT commit this file to version control.
Migration and Updates
- Updating Project-Level Hints
# Create a pull request for project-level changes
git checkout -b update-hints
edit .goosehints
git commit -m "Update project hints: Add new testing standards"
git push origin update-hints
- Updating User-Specific Hints
Create a script to help users update their local hints
#!/bin/bash
# update-local-hints.sh
if [ -f .goosehints.local ]; then
echo "Backing up current local hints..."
cp .goosehints.local .goosehints.local.backup
fi
echo "Updating from default template..."
cp .goosehints.default .goosehints.local
echo "Please update your personal settings in .goosehints.local"
Real-World Examples
To better understand how to utilize .goosehints
files with Goose 🦢, let’s explore some real-world scenarios where project-level and user-specific hints can make a significant difference. These examples demonstrate how .goosehints
help automate workflows, maintain consistency, and streamline development tasks.
Web Development Team
A team is building a React application with a Node.js backend and PostgreSQL database. They want to enforce coding standards and automate development tasks across the project.
- Project-Level .goosehints
The team creates a .goosehints
file in the project’s root directory to ensure consistency.
Framework: React
Backend: Node.js
Database: PostgreSQL
Linting: ESLint
Prettier: Enabled
Test Command: npm test
Build Command: npm run build
Deploy Command: ./scripts/deploy.sh
Directories:
- src/
- public/
- tests/
- scripts/
How Goose Helps
- Automatically runs
npm
test before merging branches. - Validates code style using ESLint and Prettier.
Deploys the app using the
./scripts/deploy.sh
script.User-Specific .goosehints
Developers can add their own .goosehints
file for local preferences.
Editor: VS Code
Node Path: /usr/local/bin/node
Custom Command: npm run dev
Personal Shortcut:
Start Server: npm start
Build App: npm run build
How Goose Helps
- Automatically launches npm start when the developer opens the project.
- Suggests personalized shortcuts for frequent tasks.
Data Science Workflow
A team of data scientists is collaborating on a machine learning pipeline using Python, Jupyter Notebooks, and TensorFlow. They want Goose to handle repetitive setup and deployment tasks.
- Project-Level .goosehints
The team sets up a .goosehints
file to define the environment and project structure.
Framework: TensorFlow
Python Version: 3.10
Virtual Environment: .venv/
Install Command: pip install -r requirements.txt
Train Model Command: python train.py
Directories:
- notebooks/
- models/
- data/
- scripts/
How Goose Helps
Installs dependencies with
pip install -r requirements.txt.
Ensures everyone uses Python 3.10 with the.venv/
environment.
Automates runningpython train.py
during model training.User-Specific .goosehints
Individual data scientists use personal .goosehints
files to customize their workflows.
Notebook Path: ~/projects/ml_project/notebooks
Data Path: /mnt/data/
Shortcut:
Open Notebook: jupyter notebook
Run All: python scripts/run_all.py
How Goose Helps
- Opens Jupyter Notebooks in the specified
path
. - Automates running
run_all.py
to preprocess data and train models.
Open Source Project Contributor
An open-source project is built using Django and has contributors from around the world. The project maintainers provide .goosehints
to onboard new contributors quickly.
- Project-Level .goosehints
The maintainers define a .goosehints
file in the repository to guide contributors.
Framework: Django
Database: SQLite (for development)
Python Version: 3.9
Virtual Environment: venv/
Runserver Command: python manage.py runserver
Test Command: python manage.py test
Linting: Enabled
Directories:
- app/
- templates/
- static/
- tests/
How Goose Helps
- Guides contributors in setting up the environment with
python -m venv venv
and installing dependencies. - Runs python
manage.py
runserver to launch the local server. Enforces linting and test rules.
User-Specific .goosehints
A contributor customizes their local configuration with a personal .goosehints
file.
Editor: PyCharm
Python Path: /usr/bin/python3
Custom Command: python manage.py makemigrations
Shortcut:
Start Server: python manage.py runserver --noreload
Run Tests: python manage.py test --verbosity=2
How Goose Helps
- Suggests using
--noreload
for faster server restarts during debugging. - Runs tests with detailed output using the
--verbosity=2
flag.
Creative Uses for .goosehints
- Interactive Documentation Generator
- Team Onboarding Assistant
- AI-Assisted Code Review Guide
- Dynamic Testing Scenarios Generator
- Development Workflow Automator
Check out how to get Goose running if you are a window user here
If you want to know more about Goose, checkout
Posted on November 19, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.