github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/robots/coverage/cmd/diff/diff.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package diff
    18  
    19  import (
    20  	"fmt"
    21  	"io"
    22  	"os"
    23  
    24  	"github.com/spf13/cobra"
    25  	"k8s.io/test-infra/gopherage/pkg/util"
    26  	"k8s.io/test-infra/robots/coverage/diff"
    27  )
    28  
    29  type flags struct {
    30  	outputFile string
    31  	threshold  float32
    32  	jobName    string
    33  }
    34  
    35  // MakeCommand returns a `diff` command.
    36  func MakeCommand() *cobra.Command {
    37  	flags := &flags{}
    38  	cmd := &cobra.Command{
    39  		Use:   "diff [base-profile] [new-profile]",
    40  		Short: "Calculate the file level difference between two coverage profiles",
    41  		Long: `Calculate the file level difference between two coverage profiles.
    42  		Produce the result in a markdown table`,
    43  		Run: func(cmd *cobra.Command, args []string) {
    44  			run(flags, cmd, args)
    45  		},
    46  	}
    47  	cmd.Flags().StringVarP(&flags.outputFile, "output", "o", "-", "output file")
    48  	cmd.Flags().StringVarP(&flags.jobName, "jobname", "j", "", "prow job name")
    49  	cmd.Flags().Float32VarP(&flags.threshold, "threshold", "t", .8, "code coverage threshold")
    50  	return cmd
    51  }
    52  
    53  func run(flags *flags, cmd *cobra.Command, args []string) {
    54  	if len(args) != 2 {
    55  		fmt.Fprintln(os.Stderr, "Expected exactly two arguments: base-profile & new-profile")
    56  		cmd.Usage()
    57  		os.Exit(2)
    58  	}
    59  
    60  	if flags.threshold < 0 || flags.threshold > 1 {
    61  		fmt.Fprintln(os.Stderr, "coverage threshold must be a float number between 0 to 1, inclusive")
    62  		os.Exit(1)
    63  	}
    64  
    65  	baseProfilePath := args[0]
    66  	newProfilePath := args[1]
    67  
    68  	baseProfiles, err := util.LoadProfile(baseProfilePath)
    69  	if err != nil {
    70  		fmt.Fprintf(os.Stderr, "Failed to parse base profile file: %v.\n", err)
    71  		os.Exit(1)
    72  	}
    73  
    74  	newProfiles, err := util.LoadProfile(newProfilePath)
    75  	if err != nil {
    76  		fmt.Fprintf(os.Stderr, "Failed to parse new profile file: %v.\n", err)
    77  		os.Exit(1)
    78  	}
    79  
    80  	postContent, isCoverageLow := diff.ContentForGithubPost(baseProfiles, newProfiles, flags.jobName, flags.threshold)
    81  
    82  	var file io.WriteCloser
    83  	if flags.outputFile == "-" {
    84  		file = os.Stdout
    85  	} else {
    86  		file, err = os.Create(flags.outputFile)
    87  		if err != nil {
    88  			fmt.Fprintf(os.Stderr, "Failed to create output file: %v.", err)
    89  			os.Exit(1)
    90  		}
    91  		defer file.Close()
    92  	}
    93  
    94  	_, err = io.WriteString(file, fmt.Sprintf("isCoverageLow = %v\n", isCoverageLow))
    95  
    96  	if err != nil {
    97  		fmt.Fprintf(os.Stderr, "Failed to write low coverage check: %v.\n", err)
    98  		os.Exit(1)
    99  	}
   100  
   101  	_, err = io.WriteString(file, fmt.Sprintf("Post content:\n%v", postContent))
   102  	if err != nil {
   103  		fmt.Fprintf(os.Stderr, "Failed to write post content: %v.\n", err)
   104  		os.Exit(1)
   105  	}
   106  }