Skip to content

Commit

Permalink
Merge pull request #86 from openconfig/diff-cli
Browse files Browse the repository at this point in the history
CLI for doing diff against two different OpenConfig public repo commits
  • Loading branch information
wenovus authored Aug 8, 2023
2 parents 0d9f3d1 + 09a4782 commit c880ed2
Show file tree
Hide file tree
Showing 52 changed files with 12,377 additions and 176 deletions.
78 changes: 78 additions & 0 deletions cmd/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2023 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"fmt"
"os"

"github.com/openconfig/models-ci/openconfig-ci/ocdiff"
"github.com/openconfig/models-ci/yangutil"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

// diffCmd represents the diff command, which diffs two sets of OpenConfig YANG
// files.
var diffCmd = &cobra.Command{
Use: "diff",
Short: "Diff between two sets of OpenConfig YANG files",
Long: `Use this command to find what's different between two commits of openconfig/public:
openconfig-ci diff --oldp public_old/third_party --newp public_new/third_party --oldroot public_old/release --newroot public_new/release
`,
RunE: func(cmd *cobra.Command, args []string) error {
viper.BindPFlags(cmd.Flags())
oldfiles, err := yangutil.GetAllYANGFiles(viper.GetString("oldroot"))
if err != nil {
return fmt.Errorf("error while finding YANG files from the old root: %v", err)
}
newfiles, err := yangutil.GetAllYANGFiles(viper.GetString("newroot"))
if err != nil {
return fmt.Errorf("error while finding YANG files from the new root: %v", err)
}
report, err := ocdiff.NewDiffReport(viper.GetStringSlice("oldp"), viper.GetStringSlice("newp"), oldfiles, newfiles)
if err != nil {
return err
}

var opts []ocdiff.Option
if viper.GetBool("github-comment") {
opts = append(opts, ocdiff.WithGithubCommentStyle())
}

if viper.GetBool("disallowed-incompats") {
opts = append(opts, ocdiff.WithDisallowedIncompatsOnly())
if out := report.Report(opts...); out != "" {
fmt.Printf("-----------Breaking changes that need a major version increment (note that this check is not exhaustive)-----------\n%s", out)
os.Exit(1)
}
} else {
fmt.Printf(report.Report(opts...))
}
return nil
},
}

func init() {
rootCmd.AddCommand(diffCmd)

diffCmd.Flags().StringSlice("oldp", []string{}, "search path for old set of YANG files")
diffCmd.Flags().StringSlice("newp", []string{}, "search path for new set of YANG files")
diffCmd.Flags().StringP("oldroot", "o", "", "Root directory of old OpenConfig YANG files")
diffCmd.Flags().StringP("newroot", "n", "", "Root directory of new OpenConfig YANG files")
diffCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backward-incompatible changes. Note that the backward-incompatible checks are not exhausive.")
diffCmd.Flags().Bool("github-comment", false, "Show output suitable for posting in a GitHub comment.")
}
78 changes: 78 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// Copyright 2023 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
"fmt"
"os"

"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var cfgFile string

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "openconfig-ci",
Short: "OpenConfig Models Continuous Integration CLI",
Long: `Explore the subcommands.`,
// Uncomment the following line if your bare application
// has an action associated with it:
// Run: func(cmd *cobra.Command, args []string) { },
}

// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
}

func init() {
cobra.OnInitialize(initConfig)

// Here you will define your flags and configuration settings.
// Cobra supports persistent flags, which, if defined here,
// will be global for your application.

rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.openconfig-models-ci.yaml)")
}

// initConfig reads in config file and ENV variables if set.
func initConfig() {
if cfgFile != "" {
// Use config file from the flag.
viper.SetConfigFile(cfgFile)
} else {
// Find home directory.
home, err := os.UserHomeDir()
cobra.CheckErr(err)

// Search config in home directory with name ".openconfig-models-ci" (without extension).
viper.AddConfigPath(home)
viper.SetConfigType("yaml")
viper.SetConfigName(".openconfig-models-ci")
}

viper.AutomaticEnv() // read in environment variables that match

// If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil {
fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed())
}
}
44 changes: 35 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,17 +1,43 @@
module github.com/openconfig/models-ci

go 1.14
go 1.18

require (
github.com/Masterminds/semver/v3 v3.1.1
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0
github.com/google/go-cmp v0.4.1
github.com/golang/glog v1.1.0
github.com/golang/protobuf v1.5.3
github.com/google/go-cmp v0.5.9
github.com/google/go-github v17.0.0+incompatible
github.com/openconfig/gnmi v0.10.0
github.com/openconfig/goyang v1.4.1
github.com/openconfig/ygot v0.29.9
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.16.0
golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
golang.org/x/oauth2 v0.7.0
google.golang.org/protobuf v1.31.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be
github.com/openconfig/goyang v1.0.0
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
google.golang.org/protobuf v1.21.0
gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect
google.golang.org/grpc v1.58.0-dev // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)
Loading

0 comments on commit c880ed2

Please sign in to comment.