Example #1
0
// Generate calls all the service generators associated with this plugin and
// consolidates their output.
//
// Any conflicts in the generated files will result in a failure.
func (msg MultiServiceGenerator) Generate(req *api.GenerateServiceRequest) (*api.GenerateServiceResponse, error) {
	var (
		lock      sync.Mutex
		files     = make(map[string][]byte)
		usedPaths = make(map[string]string) // path -> plugin name
	)

	err := concurrent.Range(msg, func(_ int, sg ServiceGenerator) error {
		res, err := sg.Generate(req)
		if err != nil {
			return err
		}

		lock.Lock()
		defer lock.Unlock()

		pluginName := sg.Handle().Name()
		for path, contents := range res.Files {
			if takenBy, taken := usedPaths[path]; taken {
				return fmt.Errorf("plugin conflict: cannot write file %q for plugin %q: "+
					"plugin %q already wrote to that file", path, pluginName, takenBy)
			}

			usedPaths[path] = pluginName
			files[path] = contents
		}

		return nil
	})

	return &api.GenerateServiceResponse{Files: files}, err
}
Example #2
0
// Handle gets a MultiHandle to all the plugins in this list or nil if the
// list is empty.
//
// The returned handle MUST be closed by the caller if error was nil.
func (fs Flags) Handle() (MultiHandle, error) {
	var (
		lock  sync.Mutex
		multi MultiHandle
	)

	err := concurrent.Range(fs, func(_ int, f Flag) error {
		h, err := f.Handle()
		if err != nil {
			return err
		}

		lock.Lock()
		defer lock.Unlock()

		multi = append(multi, h)
		return nil
	})

	if err == nil {
		return multi, nil
	}

	return nil, internal.CombineErrors(err, multi.Close())
}
Example #3
0
// Close closes all Handles associated with this MultiHandle.
func (mh MultiHandle) Close() error {
	return concurrent.Range(mh, func(_ int, h Handle) error {
		return h.Close()
	})
}