Skip to content

EficodeDemoOrg/copilot-cpp

Repository files navigation

C++ Weather CLI

Getting started on Windows? See WINDOWS_GETTING_STARTED.md — tool installation, build, tests, and VS Code setup in one place.

IDE Support: This project is configured for Visual Studio Code and works on Windows, macOS, and Linux. See VSCODE_SETUP.md for advanced features.

Requirements

Minimal system-level tools only — no package managers or virtual environments needed. All C++ library dependencies (GoogleTest, spdlog, CLI11, nlohmann/json, tl-expected) are automatically fetched at build time via CMake FetchContent.

Minimum requirements

  • CMake 3.20 or later
  • C++ Compiler with C++20 support:
    • Windows: GCC 11+ (via MinGW) — install with choco install mingw
    • macOS: GCC 11+ or Clang 14+ (via Homebrew)
    • Linux: GCC 11+ or Clang 14+
  • libcurl development library

Install by platform

Windows

REM First-time setup (as Administrator):
scripts\setup-windows.bat
REM Or manually:
choco install cmake mingw curl

macOS (Homebrew)

brew install cmake curl

Ubuntu/Debian

sudo apt-get install build-essential cmake libcurl4-openssl-dev

Optional (development) requirements

  • clang-format: Code formatting
  • clang-tidy: Static analysis
  • valgrind: Memory leak detection (Linux only)

macOS

brew install clang-format

Ubuntu/Debian

sudo apt-get install clang-format clang-tidy valgrind

What is this?

A modern C++20 command-line application that fetches and displays current weather for any city using the OpenMeteo API. Run it from the terminal to get temperature (Celsius or Fahrenheit), humidity, wind speed, and weather description.


Quick Start

Windows

REM Install tools (one-time, as Administrator):
scripts\setup-windows.bat

REM Build:
mingw32-make build

REM Run:
build\weather_cli.exe London

macOS/Linux

# Install tools
brew install cmake curl           # macOS
sudo apt-get install cmake libcurl4-openssl-dev   # Ubuntu/Debian

# Build
make build

# Run
./build/weather_cli London

Build

The project uses a cross-platform Makefile as the primary build entrypoint.

Command Windows macOS/Linux What it does
Build (debug) mingw32-make build make build Compile with debug symbols
Release mingw32-make release make release Optimised release build
Tests mingw32-make test make test Build and run all unit tests
Run mingw32-make run CITY=Paris make run CITY=Paris Build and run for a city
Clean mingw32-make clean make clean Delete build/ directory

Executable location (all platforms): build/weather_cli (Windows: build\weather_cli.exe)

Manual CMake build (without Makefile)

# Configure
cmake -B build -DCMAKE_BUILD_TYPE=Debug   # macOS/Linux
cmake -B build -G "Unix Makefiles" -DCMAKE_CXX_COMPILER=g++ -DCMAKE_MAKE_PROGRAM=mingw32-make -DCMAKE_BUILD_TYPE=Debug   # Windows

# Build
cmake --build build -j

Usage

REM Windows
build\weather_cli.exe London
build\weather_cli.exe "New York" --fahrenheit
build\weather_cli.exe Tokyo --extended
build\weather_cli.exe --help
# macOS/Linux
./build/weather_cli London
./build/weather_cli "New York" --fahrenheit
./build/weather_cli Tokyo --extended
./build/weather_cli --help

CLI options

Usage: weather_cli [OPTIONS] city

Arguments:
  city TEXT REQUIRED       Name of the city to get weather for

Options:
  -h,--help               Print this help message
  -v,--version            Show version
  -d,--debug              Enable debug logging
  -f,--fahrenheit         Show temperature in Fahrenheit
  -j,--json               Output as JSON
  -e,--extended           Show extended weather information

Supported cities: Any city in the world. The CLI uses OpenMeteo geocoding to resolve city names to coordinates.

No API key required. Uses the OpenMeteo API which is completely free with no registration.


Project Structure

copilot-cpp/
├── .github/
│   ├── copilot-instructions.md    # Project AI guidelines
│   ├── agents/                    # Custom agent definitions
│   ├── instructions/              # Language/test rules
│   └── prompts/                   # Reusable slash commands
├── .vscode/                       # VS Code configuration
│   ├── settings.json
│   ├── tasks.json
│   ├── launch.json
│   ├── extensions.json
│   └── c_cpp_properties.json
├── scripts/
│   └── setup-windows.bat          # One-time Windows tool installation
├── include/                       # Public headers
│   ├── weather_data.h
│   ├── weather_client.h
│   ├── weather_service.h
│   ├── config.h
│   └── exceptions.h
├── src/                           # Implementation
│   ├── main.cpp
│   ├── weather_client.cpp
│   ├── weather_service.cpp
│   ├── weather_data.cpp
│   ├── config.cpp
│   └── exceptions.cpp
├── tests/                         # Unit tests (GoogleTest)
│   ├── test_main.cpp
│   ├── test_config.cpp
│   ├── test_weather_client.cpp
│   ├── test_weather_service.cpp
│   └── CMakeLists.txt
├── Makefile                       # Cross-platform build entrypoint
├── CMakeLists.txt                 # CMake build configuration
├── .clang-format                  # Code style configuration
├── .gitignore
├── VSCODE_SETUP.md                # VS Code setup guide
├── WINDOWS_GETTING_STARTED.md     # Windows setup, build, and IDE guide
└── README.md                      # This file

Getting Started

Situation Read This Time
Windows, no tools installed WINDOWS_GETTING_STARTED.md 5–15 min
Want VS Code features VSCODE_SETUP.md 10 min
Architecture overview This file — Architecture section 5 min

Development Environment

VS Code (Recommended)

This project includes complete VS Code configuration:

  • Auto-configured IntelliSense for C++20
  • One-click build with Ctrl+Shift+B
  • Integrated debugging with breakpoints (F5)
  • CMake integration with auto-configuration
  • Test Explorer for running/debugging tests
  • Cross-platform support (Windows, macOS, Linux)

Quick start:

  1. Install recommended extensions: C/C++, CMake Tools, CMake
  2. Open the project folder in VS Code
  3. Press Ctrl+Shift+B to build
  4. Press F5 to debug

See VSCODE_SETUP.md for the full guide.

Command Line

make build               # macOS/Linux
mingw32-make build       # Windows

make test
make run CITY=London

Development Commands

Task Command
Build make build / mingw32-make build
Run tests make test / mingw32-make test
Run app make run CITY=Tokyo / mingw32-make run CITY=Tokyo
Clean make clean / mingw32-make clean
Format code clang-format -i src/*.cpp include/*.h tests/test_*.cpp
Static analysis clang-tidy src/*.cpp -- -std=c++20 -I include/

Testing

Uses GoogleTest framework (auto-downloaded via CMake FetchContent). GoogleMock is included for mocking the WeatherClient interface.

make test                                             # macOS/Linux
mingw32-make test                                     # Windows
ctest --test-dir build -V -R ConfigManagerTest        # specific test group
./build/tests/weather_cli_tests                       # binary directly (macOS/Linux)
build\tests\weather_cli_tests.exe                     # binary directly (Windows)

Testing approach:

  • Unit testing with GoogleMock — no real HTTP calls
  • Error path testing for all WeatherError enum values
  • Input validation — empty strings, invalid inputs
  • Dependency injectionMockWeatherClient injected into WeatherService

Code Style

  • clang-format for formatting, clang-tidy for static analysis
  • Maximum line length: 100 characters (configured in .clang-format)
  • C++ standard: C++20
  • Naming: classes PascalCase, methods PascalCase, members snake_case_ with trailing underscore

Architecture

3-Layer Architecture:

  • Entry Point (src/main.cpp): CLI argument parsing via CLI11, spdlog logging setup, error handling
  • Service Layer (weather_service.h/.cpp): Business logic with dependency injection
  • Client Layer (weather_client.h/.cpp): HTTP API abstraction via WeatherClient abstract class using libcurl
  • Data Models (weather_data.h): Immutable data structures with strong typing
  • Configuration (config.h/.cpp): Environment-based config management

Abstract Interface for Testing

class WeatherClient {  // Abstract
public:
    virtual std::expected<WeatherData, WeatherError>
    GetWeather(std::string_view city) const = 0;
};

Error Handling with std::expected

auto result = client.GetWeather("London");
if (!result) {
    handle_error(result.error());
} else {
    use_data(result.value());
}

Dependency Injection

WeatherService service(std::make_unique<MockWeatherClient>());

Enables unit testing without real API calls.


Features

  • Modern C++20: std::expected, std::string_view, std::optional, smart pointers
  • Structured logging with spdlog (--debug flag)
  • JSON output (--json flag)
  • Fahrenheit support (--fahrenheit flag)
  • Extended info (--extended flag)
  • No API key: Uses OpenMeteo free API

Security

  • API keys never appear in logs (redacted as "REDACTED")
  • HTTPS enforced for all API calls
  • Input validation on all user-supplied data
  • Compiled with -fstack-protector-strong

License

Same as main repository

About

Copilot C++ Training

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors