Skip to content

Latest commit

 

History

History
361 lines (288 loc) · 9.93 KB

File metadata and controls

361 lines (288 loc) · 9.93 KB

Making the TIL Tool Installable

This technical specification outlines approaches for making the TIL CLI tool globally installable, allowing it to be used from any directory while maintaining its functionality.

Current Limitations

The TIL tool has the following dependency on its location:

  1. It assumes the TIL collection is located in the current working directory (see line 345-346):

    root_dir = Path.cwd()
    collection = TILCollection(root_dir)
  2. This means the tool only works when run from the root of the TIL repository.

Solution Approaches

1. Package Installation with Configuration

Implementation

  1. Create a Python package structure:

    til/
    ├── setup.py
    ├── til/
    │   ├── __init__.py
    │   ├── __main__.py  # Current til script
    │   └── ...
    
  2. Modify the tool to accept a configurable repository location:

    def get_til_repo_path():
        # Priority order:
        # 1. Command line argument
        # 2. Environment variable
        # 3. Config file
        # 4. Current directory (fallback)
        
        # Check environment variable
        env_path = os.environ.get('TIL_REPO_PATH')
        if env_path and Path(env_path).is_dir():
            return Path(env_path)
            
        # Check config file in user's home directory
        config_path = Path.home() / '.tilconfig'
        if config_path.exists():
            try:
                config = config_path.read_text().strip()
                if Path(config).is_dir():
                    return Path(config)
            except:
                pass
                
        # Fallback to current directory
        return Path.cwd()
  3. Update line 345-346 to use this function:

    root_dir = get_til_repo_path()
    collection = TILCollection(root_dir)
  4. Create setup.py file:

    from setuptools import setup, find_packages
    
    setup(
        name="til-cli",
        version="1.0.0",
        packages=find_packages(),
        entry_points={
            "console_scripts": [
                "til=til.__main__:main",
            ],
        },
        python_requires=">=3.12",
    )
  5. Add a configuration command:

    # Add to subparsers in main()
    config_parser = subparsers.add_parser('config', help='Configure TIL repository location')
    config_parser.add_argument('path', help='Path to TIL repository')
    
    # Handle in the command section
    elif args.command == 'config':
        config_path = Path.home() / '.tilconfig'
        config_path.write_text(str(Path(args.path).resolve()))
        print(f"TIL repository path set to: {args.path}")

Installation Instructions

# Clone the repo (one time)
git clone https://github.com/yourusername/til.git
cd til

# Install the package
pip install -e .  # For development
# or
pip install .     # For regular installation
# or
pipx install .    # Recommended for CLI tools

# Configure the repo location
til config /path/to/til/repo

2. Shell Wrapper with Repository Detection

Create a shell script wrapper that detects the repository location and sets the working directory.

  1. Create a shell wrapper:

    #!/bin/bash
    
    # Find the TIL repository path
    if [ -n "$TIL_REPO_PATH" ] && [ -d "$TIL_REPO_PATH" ]; then
        REPO_PATH="$TIL_REPO_PATH"
    elif [ -f "$HOME/.tilconfig" ]; then
        REPO_PATH=$(cat "$HOME/.tilconfig")
    else
        echo "Error: TIL repository not found. Please set TIL_REPO_PATH environment variable or create ~/.tilconfig"
        exit 1
    fi
    
    # Save current directory
    ORIG_DIR="$(pwd)"
    
    # Change to repository directory
    cd "$REPO_PATH" || { echo "Error: Could not change to repository directory"; exit 1; }
    
    # Run the actual TIL script with all arguments
    ./til "$@"
    
    # Return to original directory
    cd "$ORIG_DIR" || true
  2. Make it executable and add to your PATH:

    chmod +x /path/to/til-wrapper.sh
    # Add to .bashrc or .zshrc
    export PATH="$PATH:/path/to/directory/containing/wrapper"
  3. Create a configuration utility:

    #!/bin/bash
    
    if [ $# -ne 1 ]; then
        echo "Usage: til-config /path/to/til/repository"
        exit 1
    fi
    
    if [ ! -d "$1" ]; then
        echo "Error: Directory does not exist: $1"
        exit 1
    fi
    
    echo "$1" > "$HOME/.tilconfig"
    echo "TIL repository configured to: $1"

3. Using pipx with Custom Environment Variables

  1. Update the TIL script to use environment variable:

    root_dir = Path(os.environ.get('TIL_REPO_PATH', Path.cwd()))
  2. Install with pipx and set the environment variable:

    pipx install .
    pipx runpip til-cli inject-environment TIL_REPO_PATH=/path/to/til/repo

Recommended Approach

The package installation with configuration (option 1) is the most robust approach because:

  1. It's cross-platform
  2. It allows for multiple configuration methods (env vars, config file, CLI args)
  3. It follows Python packaging best practices
  4. It doesn't require shell-specific scripts

Additional Considerations

  1. Repository Updates: Add an update command to automatically update the TIL repository:

    # Add to subparsers in main()
    update_parser = subparsers.add_parser('update', help='Update TIL repository with latest changes')
    
    # Handle in the command section
    elif args.command == 'update':
        repo_path = get_til_repo_path()
        print(f"Updating TIL repository at: {repo_path}")
        try:
            # Check if it's a git repository
            git_dir = repo_path / '.git'
            if not git_dir.is_dir():
                logger.error(f"Error: Not a git repository: {repo_path}")
                return 1
                
            # Run git pull
            result = subprocess.run(
                ['git', 'pull'],
                cwd=repo_path,
                capture_output=True,
                text=True
            )
            
            if result.returncode == 0:
                print(f"Successfully updated:\n{result.stdout}")
                return 0
            else:
                logger.error(f"Error updating repository:\n{result.stderr}")
                return 1
        except Exception as e:
            logger.error(f"Error updating repository: {e}")
            return 1
  2. Easy Installation: Create a simple one-line installer script:

    #!/bin/bash
    # til-installer.sh
    
    set -e  # Exit on error
    
    # Check for pipx
    if ! command -v pipx &> /dev/null; then
        echo "Installing pipx..."
        pip install pipx
        pipx ensurepath
        # Source the updated PATH
        if [[ -f ~/.bashrc ]]; then
            source ~/.bashrc
        elif [[ -f ~/.zshrc ]]; then
            source ~/.zshrc
        fi
    fi
    
    # Clone the repository if not already done
    REPO_DIR="$HOME/.til-repo"
    if [[ ! -d "$REPO_DIR" ]]; then
        echo "Cloning TIL repository..."
        git clone https://github.com/yourusername/til.git "$REPO_DIR"
    else
        echo "TIL repository already exists, updating..."
        (cd "$REPO_DIR" && git pull)
    fi
    
    # Install the package
    echo "Installing TIL CLI tool..."
    (cd "$REPO_DIR" && pipx install .)
    
    # Configure the repository location
    echo "Configuring repository location..."
    til config "$REPO_DIR"
    
    echo "Installation complete! You can now use 'til' from anywhere."
    echo "Try 'til list' to see all entries or 'til help' for more options."

    Installation would be as simple as:

    curl -sSL https://raw.githubusercontent.com/yourusername/til/main/install.sh | bash
  3. Multiple TIL Repositories: The configuration could be extended to support multiple repositories by storing a list in the config file.

  4. Command Completion: Add shell completion scripts for bash/zsh to make the tool more user-friendly.

Implementation Steps

  1. Restructure the code as a proper Python package
  2. Add repository location configuration
  3. Update the CLI to support the new configuration options
  4. Add the update command for repository updates
  5. Create setup.py and packaging files
  6. Create the installer script for one-line installation
  7. Test installation and functionality
  8. Create documentation for installation and usage

Sample Code for Installer

Create a file named install.sh in the repository root:

#!/bin/bash
# TIL Tool Installer Script

set -e  # Exit on error

# Default installation directory
REPO_DIR="${TIL_INSTALL_DIR:-$HOME/.til-repo}"

# Banner
echo "============================================="
echo "  Installing TIL CLI Tool"
echo "============================================="

# Check for pipx
if ! command -v pipx &> /dev/null; then
    echo "Installing pipx..."
    pip install --user pipx
    pipx ensurepath
    
    # Add pipx to PATH for this session
    export PATH="$PATH:$HOME/.local/bin"
fi

# Clone the repository if not already done
if [[ ! -d "$REPO_DIR" ]]; then
    echo "Cloning TIL repository to $REPO_DIR..."
    git clone https://github.com/yourusername/til.git "$REPO_DIR"
else
    echo "TIL repository already exists at $REPO_DIR, updating..."
    (cd "$REPO_DIR" && git pull)
fi

# Install the package
echo "Installing TIL CLI tool..."
(cd "$REPO_DIR" && pipx install --force .)

# Configure the repository location
echo "Configuring repository location..."
til config "$REPO_DIR"

echo ""
echo "Installation complete! You can now use 'til' from anywhere."
echo ""
echo "Examples:"
echo "  til list              # List all entries"
echo "  til search git        # Search for entries related to git"
echo "  til update            # Update the repository with latest entries"
echo "  til help              # Show all available commands"
echo ""
echo "Your TIL repository is located at: $REPO_DIR"

Make it executable:

chmod +x install.sh

The user can then install with:

# From a local clone
./install.sh

# Or directly from GitHub
curl -sSL https://raw.githubusercontent.com/yourusername/til/main/install.sh | bash