func (r *Runner) init() error {
	// Ensure default configuration values
	r.config = config.DefaultConfig().Merge(r.config)
	r.config.Finalize()

	// Print the final config for debugging
	result, err := json.Marshal(r.config)
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] (runner) final config: %s", result)

	// Create the clientset
	clients, err := newClientSet(r.config)
	if err != nil {
		return fmt.Errorf("runner: %s", err)
	}

	// Create the watcher
	watcher, err := newWatcher(r.config, clients, r.once)
	if err != nil {
		return fmt.Errorf("runner: %s", err)
	}
	r.watcher = watcher

	numTemplates := len(*r.config.Templates)
	templates := make([]*template.Template, 0, numTemplates)
	ctemplatesMap := make(map[string]config.TemplateConfigs)

	// Iterate over each TemplateConfig, creating a new Template resource for each
	// entry. Templates are parsed and saved, and a map of templates to their
	// config templates is kept so templates can lookup their commands and output
	// destinations.
	for _, ctmpl := range *r.config.Templates {
		tmpl, err := template.NewTemplate(&template.NewTemplateInput{
			Source:        config.StringVal(ctmpl.Source),
			Contents:      config.StringVal(ctmpl.Contents),
			ErrMissingKey: config.BoolVal(ctmpl.ErrMissingKey),
			LeftDelim:     config.StringVal(ctmpl.LeftDelim),
			RightDelim:    config.StringVal(ctmpl.RightDelim),
		})
		if err != nil {
			return err
		}

		if _, ok := ctemplatesMap[tmpl.ID()]; !ok {
			templates = append(templates, tmpl)
		}

		if _, ok := ctemplatesMap[tmpl.ID()]; !ok {
			ctemplatesMap[tmpl.ID()] = make([]*config.TemplateConfig, 0, 1)
		}
		ctemplatesMap[tmpl.ID()] = append(ctemplatesMap[tmpl.ID()], ctmpl)
	}

	// Convert the map of templates (which was only used to ensure uniqueness)
	// back into an array of templates.
	r.templates = templates

	r.renderEvents = make(map[string]*RenderEvent, numTemplates)
	r.dependencies = make(map[string]dep.Dependency)

	r.renderedCh = make(chan struct{}, 1)
	r.renderEventCh = make(chan struct{}, 1)

	r.ctemplatesMap = ctemplatesMap
	r.inStream = os.Stdin
	r.outStream = os.Stdout
	r.errStream = os.Stderr
	r.brain = template.NewBrain()

	r.ErrCh = make(chan error)
	r.DoneCh = make(chan struct{})

	r.quiescenceMap = make(map[string]*quiescence)
	r.quiescenceCh = make(chan *template.Template)

	if *r.config.Dedup.Enabled {
		if r.once {
			log.Printf("[INFO] (runner) disabling de-duplication in once mode")
		} else {
			r.dedup, err = NewDedupManager(r.config.Dedup, clients, r.brain, r.templates)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
func (r *Runner) init() error {
	
	r.config = config.DefaultConfig().Merge(r.config)
	r.config.Finalize()

	
	result, err := json.Marshal(r.config)
	if err != nil {
		return err
	}
	log.Printf("[DEBUG] (runner) final config: %s", result)

	
	clients, err := newClientSet(r.config)
	if err != nil {
		return fmt.Errorf("runner: %s", err)
	}

	
	watcher, err := newWatcher(r.config, clients, r.once)
	if err != nil {
		return fmt.Errorf("runner: %s", err)
	}
	r.watcher = watcher

	numTemplates := len(*r.config.Templates)
	templates := make([]*template.Template, 0, numTemplates)
	ctemplatesMap := make(map[string]config.TemplateConfigs)

	
	
	
	
	for _, ctmpl := range *r.config.Templates {
		tmpl, err := template.NewTemplate(&template.NewTemplateInput{
			Source:        config.StringVal(ctmpl.Source),
			Contents:      config.StringVal(ctmpl.Contents),
			ErrMissingKey: config.BoolVal(ctmpl.ErrMissingKey),
			LeftDelim:     config.StringVal(ctmpl.LeftDelim),
			RightDelim:    config.StringVal(ctmpl.RightDelim),
		})
		if err != nil {
			return err
		}

		if _, ok := ctemplatesMap[tmpl.ID()]; !ok {
			templates = append(templates, tmpl)
		}

		if _, ok := ctemplatesMap[tmpl.ID()]; !ok {
			ctemplatesMap[tmpl.ID()] = make([]*config.TemplateConfig, 0, 1)
		}
		ctemplatesMap[tmpl.ID()] = append(ctemplatesMap[tmpl.ID()], ctmpl)
	}

	
	
	r.templates = templates

	r.renderEvents = make(map[string]*RenderEvent, numTemplates)
	r.dependencies = make(map[string]dep.Dependency)

	r.renderedCh = make(chan struct{}, 1)
	r.renderEventCh = make(chan struct{}, 1)

	r.ctemplatesMap = ctemplatesMap
	r.inStream = os.Stdin
	r.outStream = os.Stdout
	r.errStream = os.Stderr
	r.brain = template.NewBrain()

	r.ErrCh = make(chan error)
	r.DoneCh = make(chan struct{})

	r.quiescenceMap = make(map[string]*quiescence)
	r.quiescenceCh = make(chan *template.Template)

	if *r.config.Dedup.Enabled {
		if r.once {
			log.Printf("[INFO] (runner) disabling de-duplication in once mode")
		} else {
			r.dedup, err = NewDedupManager(r.config.Dedup, clients, r.brain, r.templates)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
func ( r * Runner ) init ( ) error { // Ensure default configuration values r . config = config . DefaultConfig ( ) . Merge ( r . config ) r . config . Finalize ( ) // Print the final config for debugging result , err := json . Marshal ( r . config ) if err != nil { return err } log . Printf ( " " , result ) // Create the clientset clients , err := newClientSet ( r . config ) if err != nil { return fmt . Errorf ( " " , err ) } // Create the watcher watcher , err := newWatcher ( r . config , clients , r . once ) if err != nil { return fmt . Errorf ( " " , err ) } r . watcher = watcher numTemplates := len ( * r . config . Templates ) templates := make ( [ ] * template . Template , 0 , numTemplates ) ctemplatesMap := make ( map [ string ] config . TemplateConfigs ) // Iterate over each TemplateConfig, creating a new Template resource for each // entry. Templates are parsed and saved, and a map of templates to their // config templates is kept so templates can lookup their commands and output // destinations. for _ , ctmpl := range * r . config . Templates { tmpl , err := template . NewTemplate ( & template . NewTemplateInput { Source : config . StringVal ( ctmpl . Source ) , Contents : config . StringVal ( ctmpl . Contents ) , ErrMissingKey : config . BoolVal ( ctmpl . ErrMissingKey ) , LeftDelim : config . StringVal ( ctmpl . LeftDelim ) , RightDelim : config . StringVal ( ctmpl . RightDelim ) , } ) if err != nil { return err } if _ , ok := ctemplatesMap [ tmpl . ID ( ) ] ; ! ok { templates = append ( templates , tmpl ) } if _ , ok := ctemplatesMap [ tmpl . ID ( ) ] ; ! ok { ctemplatesMap [ tmpl . ID ( ) ] = make ( [ ] * config . TemplateConfig , 0 , 1 ) } ctemplatesMap [ tmpl . ID ( ) ] = append ( ctemplatesMap [ tmpl . ID ( ) ] , ctmpl ) } // Convert the map of templates (which was only used to ensure uniqueness) // back into an array of templates. r . templates = templates r . renderEvents = make ( map [ string ] * RenderEvent , numTemplates ) r . dependencies = make ( map [ string ] dep . Dependency ) r . renderedCh = make ( chan struct { } , 1 ) r . renderEventCh = make ( chan struct { } , 1 ) r . ctemplatesMap = ctemplatesMap r . inStream = os . Stdin r . outStream = os . Stdout r . errStream = os . Stderr r . brain = template . NewBrain ( ) r . ErrCh = make ( chan error ) r . DoneCh = make ( chan struct { } ) r . quiescenceMap = make ( map [ string ] * quiescence ) r . quiescenceCh = make ( chan * template . Template ) if * r . config . Dedup . Enabled { if r . once { log . Printf ( " " ) } else { r . dedup , err = NewDedupManager ( r . config . Dedup , clients , r . brain , r . templates ) if err != nil { return err } } } return nil }
// init() creates the Runner's underlying data structures and returns an error
// if any problems occur.
init () creates the Runner s underlying data structures and returns an error if any problems occur .