検索
ホームページバックエンド開発Golang初心者向け Go プロジェクト - Go でタスク ランナーを作成する

Beginner Go Project - Create a Task Runner in Go

これから構築するもの

このような単純な yaml ファイルを使用してタスクを実行できる make のようなツールを作成します。

tasks:
    build:
        description:  "compile the project"
        command:  "go build main.go"
        dependencies:  [test]
    test:
        description:  "run unit tests"
        command:  "go test -v ./..."

始めましょう。まず、行動方針の概要を説明する必要があります。タスク ファイルのスキーマはすでに定義されています。 yaml の代わりに json を使用することもできますが、このプロジェクトでは yml ファイルを使用します。

ファイルから、メインのタスクを進める前に、単一のタスクを保存するための構造体と、依存タスクを実行する方法が必要であることがわかります。まずはプロジェクトを開始しましょう。新しいフォルダーを作成して実行します:

go mod init github.com/vishaaxl/mommy

プロジェクトには好きな名前を付けることができますが、私はこの「ママ」という名前を使います。また、yaml ファイルを操作するためのパッケージをインストールする必要があります (基本的に、yaml ファイルをマップ オブジェクトに変換します)。次のパッケージをインストールしてください。

go get gopkg.in/yaml.v3

次に、新しい main.go ファイルを作成し、「Task」構造体の定義から始めます。

package main

import (
    "gopkg.in/yaml.v3"
)
// Task defines the structure of a task in the configuration file.
// Each task has a description, a command to run, and a list of dependencies
// (other tasks that need to be completed before this task).
type Task struct {
    Description  string   `yaml:"description"`  // A brief description of the task.
    Command      string   `yaml:"command"`      // The shell command to execute for the task.
    Dependencies []string `yaml:"dependencies"` // List of tasks that need to be completed before this task.
}

これは非常に説明不要です。これには、個々のタスクの値が保持されます。次に、タスクのリストを保存し、.yaml ファイルの内容をこの新しいオブジェクトにロードするために、もう 1 つの構造体が必要です。

// Config represents the entire configuration file,
// which contains a map of tasks by name.
type Config struct {
    Tasks map[string]Task `yaml:"tasks"` // A map of task names to task details.
}

// loadConfig reads and parses the configuration file (e.g., Makefile.yaml),
// and returns a Config struct containing the tasks and their details.
func loadConfig(filename string) (Config, error) {
    // Read the content of the config file.
    data, err := os.ReadFile(filename)
    if err != nil {
        return Config{}, err
    }

    // Unmarshal the YAML data into a Config struct.
    var config Config
    err = yaml.Unmarshal(data, &config)
    if err != nil {
        return Config{}, err
    }

    return config, nil
}

次に、単一のタスクを実行する関数を作成する必要があります。 os/exec モジュールを使用してシェルでタスクを実行します。 Golang では、os/exec パッケージはシェル コマンドと外部プログラムを実行する方法を提供します。

// executeTask recursively executes the specified task and its dependencies.
// It first ensures that all dependencies are executed before running the current task's command.
func executeTask(taskName string, tasks map[string]Task, executed map[string]bool) error {
    // If the task has already been executed, skip it.
    if executed[taskName] {
        return nil
    }

    // Get the task details from the tasks map.
    task, exists := tasks[taskName]
    if !exists {
        return fmt.Errorf("task %s not found", taskName)
    }

    // First, execute all the dependencies of this task.
    for _, dep := range task.Dependencies {
        // Recursively execute each dependency.
        if err := executeTask(dep, tasks, executed); err != nil {
            return err
        }
    }

    // Now that dependencies are executed, run the task's command.
    fmt.Printf("Running task: %s\n", taskName)
    fmt.Printf("Command: %s\n", task.Command)

    // Execute the task's command using the shell (sh -c allows for complex shell commands).
    cmd := exec.Command("sh", "-c", task.Command)
    cmd.Stdout = os.Stdout // Direct standard output to the terminal.
    cmd.Stderr = os.Stderr // Direct error output to the terminal.

    // Run the command and check for any errors.
    if err := cmd.Run(); err != nil {
        return fmt.Errorf("failed to execute command %s: %v", task.Command, err)
    }

    // Mark the task as executed.
    executed[taskName] = true
    return nil
}

これで、プログラムの構成要素がすべて揃ったので、それらを main 関数で使用して構成ファイルをロードし、自動化を開始できます。コマンドラインフラグを読み取るためにフラグパッケージを使用します。

func main() {
    // Define command-line flags
    configFile := flag.String("f", "Mommy.yaml", "Path to the configuration file") // Path to the config file (defaults to Makefile.yaml)
    taskName := flag.String("task", "", "Task to execute")                             // The task to execute (required flag)

    // Parse the flags
    flag.Parse()

    // Check if the task flag is provided
    if *taskName == "" {
        fmt.Println("Error: Please specify a task using -task flag.")
        os.Exit(1) // Exit if no task is provided
    }

    // Load the configuration file
    config, err := loadConfig(*configFile)
    if err != nil {
        fmt.Printf("Failed to load config: %v\n", err)
        os.Exit(1) // Exit if the configuration file can't be loaded
    }

    // Map to track which tasks have been executed already (avoiding re-execution).
    executed := make(map[string]bool)

    // Start executing the specified task (with dependencies)
    if err := executeTask(*taskName, config.Tasks, executed); err != nil {
        fmt.Printf("Error executing task: %v\n", err)
        os.Exit(1) // Exit if task execution fails
    }
}

全体をテストして、新しい Mommy.yaml を作成し、そこに yaml コードを最初から貼り付けてみましょう。タスクランナーを使用してプロジェクトのバイナリを作成します。実行:

go run main.go -task build

すべてがうまくいけば、フォルダーのルートに新しい .exe ファイルが表示されます。見事、タスクランナーが動作するようになりました。この .exe ファイルの場所をシステムの環境変数に追加し、次を使用してどこからでもこれを使用できます。

 mommy -task build

完全なコード

package main

import (
    "flag"
    "fmt"
    "os"
    "os/exec"
    "gopkg.in/yaml.v3"
)

// Task defines the structure of a task in the configuration file.
// Each task has a description, a command to run, and a list of dependencies
// (other tasks that need to be completed before this task).
type Task struct {
    Description  string   `yaml:"description"`  // A brief description of the task.
    Command      string   `yaml:"command"`      // The shell command to execute for the task.
    Dependencies []string `yaml:"dependencies"` // List of tasks that need to be completed before this task.
}

// Config represents the entire configuration file,
// which contains a map of tasks by name.
type Config struct {
    Tasks map[string]Task `yaml:"tasks"` // A map of task names to task details.
}

// loadConfig reads and parses the configuration file (e.g., Makefile.yaml),
// and returns a Config struct containing the tasks and their details.
func loadConfig(filename string) (Config, error) {
    // Read the content of the config file.
    data, err := os.ReadFile(filename)
    if err != nil {
        return Config{}, err
    }

    // Unmarshal the YAML data into a Config struct.
    var config Config
    err = yaml.Unmarshal(data, &config)
    if err != nil {
        return Config{}, err
    }

    return config, nil
}

// executeTask recursively executes the specified task and its dependencies.
// It first ensures that all dependencies are executed before running the current task's command.
func executeTask(taskName string, tasks map[string]Task, executed map[string]bool) error {
    // If the task has already been executed, skip it.
    if executed[taskName] {
        return nil
    }

    // Get the task details from the tasks map.
    task, exists := tasks[taskName]
    if !exists {
        return fmt.Errorf("task %s not found", taskName)
    }

    // First, execute all the dependencies of this task.
    for _, dep := range task.Dependencies {
        // Recursively execute each dependency.
        if err := executeTask(dep, tasks, executed); err != nil {
            return err
        }
    }

    // Now that dependencies are executed, run the task's command.
    fmt.Printf("Running task: %s\n", taskName)
    fmt.Printf("Command: %s\n", task.Command)

    // Execute the task's command using the shell (sh -c allows for complex shell commands).
    cmd := exec.Command("sh", "-c", task.Command)
    cmd.Stdout = os.Stdout // Direct standard output to the terminal.
    cmd.Stderr = os.Stderr // Direct error output to the terminal.

    // Run the command and check for any errors.
    if err := cmd.Run(); err != nil {
        return fmt.Errorf("failed to execute command %s: %v", task.Command, err)
    }

    // Mark the task as executed.
    executed[taskName] = true
    return nil
}

func main() {
    // Define command-line flags
    configFile := flag.String("f", "Makefile.yaml", "Path to the configuration file") // Path to the config file (defaults to Makefile.yaml)
    taskName := flag.String("task", "", "Task to execute")                             // The task to execute (required flag)

    // Parse the flags
    flag.Parse()

    // Check if the task flag is provided
    if *taskName == "" {
        fmt.Println("Error: Please specify a task using -task flag.")
        os.Exit(1) // Exit if no task is provided
    }

    // Load the configuration file
    config, err := loadConfig(*configFile)
    if err != nil {
        fmt.Printf("Failed to load config: %v\n", err)
        os.Exit(1) // Exit if the configuration file can't be loaded
    }

    // Map to track which tasks have been executed already (avoiding re-execution).
    executed := make(map[string]bool)

    // Start executing the specified task (with dependencies)
    if err := executeTask(*taskName, config.Tasks, executed); err != nil {
        fmt.Printf("Error executing task: %v\n", err)
        os.Exit(1) // Exit if task execution fails
    }
}

以上が初心者向け Go プロジェクト - Go でタスク ランナーを作成するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
DebianでLibofficeのセキュリティ設定を行う方法DebianでLibofficeのセキュリティ設定を行う方法May 16, 2025 pm 01:24 PM

Debianシステムの全体的なセキュリティを確保することは、Libofficeなどのアプリケーションの実行環境を保護するために重要です。システムセキュリティを改善するための一般的な推奨事項を次に示します。システムの更新は、システムを定期的に更新して、既知のセキュリティの脆弱性をパッチします。 Debian12.10は、いくつかの重要なソフトウェアパッケージを含む多数のセキュリティの脆弱性を修正するセキュリティアップデートをリリースしました。ユーザー許可管理は、潜在的なセキュリティリスクを減らすために、日常業務にルートユーザーを使用することを回避します。通常のユーザーを作成し、SUDOグループに参加して、システムへの直接アクセスを制限することをお勧めします。 SSHサービスセキュリティ構成は、SSHキーペアを使用して、ルートリモートログインを認証、無効にし、空のパスワードでログインを制限します。これらの措置は、SSHサービスのセキュリティを強化し、

DebianでRustコンピレーションオプションを構成する方法DebianでRustコンピレーションオプションを構成する方法May 16, 2025 pm 01:21 PM

Debianシステムでの錆コンピレーションオプションの調整は、さまざまな方法で実現できます。以下は、いくつかの方法の詳細な説明です:Rustupツールを使用してRustupを構成およびインストールします。Rustupをまだインストールしていない場合は、次のコマンドを使用してインストールできます。設定コンピレーションオプション:Rustupを使用して、さまざまなツールチェーンとターゲットのコンパイルオプションを構成できます。 RustupoverRideコマンドを使用して、特定のプロジェクトのコンピレーションオプションを設定できます。たとえば、プロジェクトに特定の錆バージョンを設定する場合

DebianでKubernetesノードを管理する方法DebianでKubernetesノードを管理する方法May 16, 2025 pm 01:18 PM

Kubernetes(k8s)ノードの管理Debianシステムのノードの管理には、通常、次の重要な手順が含まれます。1。Kubernetesコンポーネントコンポーネントの設定準備:すべてのノード(マスターノードとワーカーノードを含む)がインストールされ、Kubernetes Clusterをインストールするための基本的な要件を満たしていることを確認してください。スワップパーティションの無効化:Kubeletがスムーズに実行できるようにするには、Swap Partitionを無効にすることをお勧めします。ファイアウォールルールの設定:Kubelet、Kube-Apiserver、Kube-Schedulerなどが使用するポートなど、必要なポートを許可します。

DebianのGolangのセキュリティ設定DebianのGolangのセキュリティ設定May 16, 2025 pm 01:15 PM

DebianにGolang環境を設定する場合、システムセキュリティを確保することが重要です。安全なGolang開発環境を構築するのに役立つ重要なセキュリティセットアップの手順と提案を次に示します。セキュリティセットアップステップシステムの更新:Golangをインストールする前にシステムが最新であることを確認してください。次のコマンドを使用して、システムパッケージリストとインストールパッケージを更新します。sudoaptupdatesudoaptupgrade-yファイアウォール構成:システムへのアクセスを制限するためにファイアウォール(iptablesなど)をインストールして構成します。必要なポート(HTTP、HTTPS、SSHなど)のみが許可されます。 sudoaptininstalliptablessud

Kubernetesの展開のパフォーマンスをDebianで最適化する方法Kubernetesの展開のパフォーマンスをDebianで最適化する方法May 16, 2025 pm 01:12 PM

DebianでKubernetesクラスターのパフォーマンスを最適化および展開することは、複数の側面を含む複雑なタスクです。主要な最適化戦略と提案を次に示します。ハードウェアリソース最適化CPU:十分なCPUリソースがKubernetesノードとポッドに割り当てられていることを確認してください。メモリ:特にメモリ集約型アプリケーションのノードのメモリ容量を増加させます。ストレージ:高性能SSDストレージを使用し、レイテンシを導入する可能性のあるネットワークファイルシステム(NFSなど)の使用を避けます。カーネルパラメーター最適化編集 /etc/sysctl.confファイル、次のパラメーターを追加または変更します:net.core.somaxconn:65535net.ipv4.tcp_max_syn

PythonスクリプトによるDebianでタスクをスケジュールする方法PythonスクリプトによるDebianでタスクをスケジュールする方法May 16, 2025 pm 01:09 PM

Debianシステムでは、Cronを使用して時限タスクを手配し、Pythonスクリプトの自動実行を実現できます。まず、端子を開始します。次のコマンドを入力して、現在のユーザーのCrontabファイルを編集します。Crontab-Eルートアクセス許可を持つ他のユーザーのCrontabファイルを編集する必要がある場合は、編集するユーザー名にユーザー名を置き換えるために、sudocrontab-uusername-eを使用してください。 crontabファイルでは、次のように形式のタイミングされたタスクを追加できます:*****/path/to/your/python-script.pyこれら5つのアスタリスクは議事録(0-59)以降を表します

DebianでGolangネットワークパラメーターを構成する方法DebianでGolangネットワークパラメーターを構成する方法May 16, 2025 pm 01:06 PM

DebianシステムでGolangのネットワークパラメーターを調整することは、さまざまな方法で実現できます。以下はいくつかの実行可能な方法です。方法1:環境変数を設定することにより、環境変数を一時的に設定します。端末に次のコマンドを入力して、環境変数を一時的に設定します。この設定は、現在のセッションでのみ有効です。 ExportGodeBug = "GCTRACE = 1NETDNS = GO" GCTRACE = 1はガベージコレクション追跡をアクティブにし、NetDNS = GOはシステムのデフォルトではなく独自のDNSリゾルバーを使用します。環境変数を永続的に設定します:〜/.bashrcや〜/.profileなどのシェル構成ファイルに上記のコマンドを追加します

DebianのLibofficeのショートカットキーは何ですかDebianのLibofficeのショートカットキーは何ですかMay 16, 2025 pm 01:03 PM

DebianシステムでLibofficeをカスタマイズするためのショートカットキーは、システム設定を通じて調整できます。 Libofficeショートカットキーを設定するための一般的に使用される手順と方法を次に示します。Libofficeショートカットキーを設定するための基本的な手順オープンシステム設定:Debianシステムで、左上隅のメニュー(通常ギアアイコン)をクリックし、「システム設定」を選択します。 [デバイス]を選択します。[システム設定]ウィンドウで、[デバイス]を選択します。キーボードを選択します。デバイス設定ページで、キーボードを選択します。対応するツールへのコマンドを見つけます。キーボード設定ページで、下にスクロールして「ショートカットキー」オプションを表示します。クリックすると、ポップアップにウィンドウが表示されます。ポップアップウィンドウで対応するLibofficeワーカーを見つけます

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。