github.com/gocrane/crane@v0.11.0/docs/code-standards.md (about) 1 # Code standards 2 3 This doc describes the code standards and suggestion for crane project, mainly for new contributor of the project 4 5 ### import need to be organized 6 import should be categorized with blank line as system imports, community imports and crane apis and crane imports, like the following example 7 ```go 8 import ( 9 "reflect" 10 "sync" 11 "time" 12 13 vpa "k8s.io/autoscaler/vertical-pod-autoscaler/pkg/recommender/util" 14 15 "github.com/gocrane/api/prediction/v1alpha1" 16 17 "github.com/gocrane/crane/pkg/utils" 18 "github.com/gocrane/crane/pkg/prediction/config" 19 ) 20 ``` 21 22 ### logs standard 23 - logs are required for troubleshooting purpose 24 - log message should always start with capital letter 25 - log message should be a complete sentence that contains enough context, for example: object key, action, parameters, status, error message 26 - by default, you don't need to set log level 27 - set 4 for debug level. 28 - set 6 for more detail debug level. 29 - set 10 for massive data log level. 30 - can use klog.KObj() to contain object key to let we know which object the message is printed for 31 ```go 32 klog.Infof("Failed to setup webhook %s", "value") 33 klog.V(4).Infof("Debug info %s", "value") 34 klog.Errorf("Failed to get scale, ehpa %s error %v", klog.KObj(ehpa), err) 35 klog.Error(error) 36 klog.ErrorDepth(5, fmt.Errorf("failed to get ehpa %s: %v", klog.KObj(ehpa), err)) 37 ``` 38 39 ### event is needed for critical reconcile loop 40 - event is to let user know what happens on serverside, only print info we want user to know 41 - consider failure paths and success paths 42 - event do not need the object key 43 ```go 44 c.Recorder.Event(ehpa, v1.EventTypeWarning, "FailedGetSubstitute", err.Error()) 45 ``` 46 47 ### comment 48 - every interface should have comments to clarify 49 - comment should be a complete sentence 50 ```go 51 // Interface is a source of monitoring metric that provides metrics that can be used for 52 // prediction, such as 'cpu usage', 'memory footprint', 'request per second (qps)', etc. 53 type Interface interface { 54 // GetTimeSeries returns the metric time series that meet the given 55 // conditions from the specified time range. 56 GetTimeSeries(metricName string, Conditions []common.QueryCondition, 57 startTime time.Time, endTime time.Time, step time.Duration) ([]*common.TimeSeries, error) 58 59 // GetLatestTimeSeries returns the latest metric values that meet the given conditions. 60 GetLatestTimeSeries(metricName string, Conditions []common.QueryCondition) ([]*common.TimeSeries, error) 61 62 // QueryTimeSeries returns the time series based on a promql like query string. 63 QueryTimeSeries(queryExpr string, startTime time.Time, endTime time.Time, step time.Duration) ([]*common.TimeSeries, error) 64 65 // QueryLatestTimeSeries returns the latest metric values that meet the given query. 66 QueryLatestTimeSeries(queryExpr string) ([]*common.TimeSeries, error) 67 } 68 ``` 69 70 ### functions 71 - function name should clarify what do this function do, for example: verb + noun 72 - similar functions should be refactored, merge or divide them 73 - common functions should move to common folder like utils 74 75 ### variable 76 - variable name should clarify what do this variable does, better not use too short name and too simple name 77 - better to use more meaningful variable name for tmp variable, for example: foo loop 78 79 ### folder and file 80 - folder name should be letter with lower case and number 81 - file name should be letter and number and _ 82 83 ### unit test 84 - Test-driven developing 85 - Complex function that include condition decide should add unit test for it 86 87 ### don't forget to run `make fmt` before you submit code