本文整理汇总了Golang中github.com/docker/docker/builder/parser.Parse函数的典型用法代码示例。如果您正苦于以下问题:Golang Parse函数的具体用法?Golang Parse怎么用?Golang Parse使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了Parse函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的Golang代码示例。
示例1: TestReplaceLastFrom
func TestReplaceLastFrom(t *testing.T) {
tests := []struct {
original string
image string
want string
}{
{
original: `# no FROM instruction`,
image: "centos",
want: ``,
},
{
original: `FROM scratch
# FROM busybox
RUN echo "hello world"
`,
image: "centos",
want: `FROM centos
RUN echo "hello world"
`,
},
{
original: `FROM scratch
FROM busybox
RUN echo "hello world"
`,
image: "centos",
want: `FROM scratch
FROM centos
RUN echo "hello world"
`,
},
}
for i, test := range tests {
got, err := parser.Parse(strings.NewReader(test.original))
if err != nil {
t.Errorf("test[%d]: %v", i, err)
continue
}
want, err := parser.Parse(strings.NewReader(test.want))
if err != nil {
t.Errorf("test[%d]: %v", i, err)
continue
}
replaceLastFrom(got, test.image)
if !reflect.DeepEqual(got, want) {
t.Errorf("test[%d]: replaceLastFrom(node, %+v) = %+v; want %+v", i, test.image, got, want)
t.Logf("resulting Dockerfile:\n%s", dockerfile.ParseTreeToDockerfile(got))
}
}
}
开发者ID:johnmccawley,项目名称:origin,代码行数:51,代码来源:docker_test.go
示例2: Parse
// Parse parses an input Dockerfile
func (_ *parser) Parse(input io.Reader) (Dockerfile, error) {
buf := bufio.NewReader(input)
bts, err := buf.Peek(buf.Buffered())
if err != nil {
return nil, err
}
parsedByDocker := bytes.NewBuffer(bts)
// Add one more level of validation by using the Docker parser
if _, err := dparser.Parse(parsedByDocker); err != nil {
return nil, fmt.Errorf("cannot parse Dockerfile: %v", err)
}
d := dockerfile{}
scanner := bufio.NewScanner(input)
for {
line, ok := nextLine(scanner, true)
if !ok {
break
}
parts, err := parseLine(line)
if err != nil {
return nil, err
}
d = append(d, parts)
}
return d, nil
}
开发者ID:dctse,项目名称:openshift-cucumber,代码行数:28,代码来源:parser.go
示例3: Parse
// Parse parses an input Dockerfile
func (_ *parser) Parse(input io.Reader) (Dockerfile, error) {
b, err := ioutil.ReadAll(input)
if err != nil {
return nil, err
}
r := bytes.NewReader(b)
// Add one more level of validation by using the Docker parser
if _, err := dparser.Parse(r); err != nil {
return nil, fmt.Errorf("cannot parse Dockerfile: %v", err)
}
if _, err = r.Seek(0, 0); err != nil {
return nil, err
}
d := dockerfile{}
scanner := bufio.NewScanner(r)
for {
line, ok := nextLine(scanner, true)
if !ok {
break
}
parts, err := parseLine(line)
if err != nil {
return nil, err
}
d = append(d, parts)
}
return d, nil
}
开发者ID:ncantor,项目名称:origin,代码行数:32,代码来源:parser.go
示例4: FromImage
// FromImage updates the builder to use the provided image (resetting RunConfig
// and recording the image environment), and updates the node with any ONBUILD
// statements extracted from the parent image.
func (b *Builder) FromImage(image *docker.Image, node *parser.Node) error {
SplitChildren(node, command.From)
b.RunConfig = *image.Config
b.Env = b.RunConfig.Env
b.RunConfig.Env = nil
// Check to see if we have a default PATH, note that windows won't
// have one as its set by HCS
if runtime.GOOS != "windows" && !hasEnvName(b.Env, "PATH") {
b.RunConfig.Env = append(b.RunConfig.Env, "PATH="+defaultPathEnv)
}
// Join the image onbuild statements into node
if image.Config == nil || len(image.Config.OnBuild) == 0 {
return nil
}
extra, err := parser.Parse(bytes.NewBufferString(strings.Join(image.Config.OnBuild, "\n")))
if err != nil {
return err
}
for _, child := range extra.Children {
switch strings.ToUpper(child.Value) {
case "ONBUILD":
return fmt.Errorf("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
case "MAINTAINER", "FROM":
return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", child.Value)
}
}
node.Children = append(extra.Children, node.Children...)
// Since we've processed the OnBuild statements, clear them from the runconfig state.
b.RunConfig.OnBuild = nil
return nil
}
开发者ID:RomainVabre,项目名称:origin,代码行数:37,代码来源:builder.go
示例5: TestNextValuesOnbuild
// TestNextValuesOnbuild tests calling nextValues with ONBUILD instructions as
// input.
func TestNextValuesOnbuild(t *testing.T) {
testCases := map[string][]string{
`ONBUILD ADD . /app/src`: {".", "/app/src"},
`ONBUILD RUN echo "Hello universe!"`: {`echo "Hello universe!"`},
}
for original, want := range testCases {
node, err := parser.Parse(strings.NewReader(original))
if err != nil {
t.Fatalf("parse error: %s: %v", original, err)
}
if len(node.Children) != 1 {
t.Fatalf("unexpected number of children in test case: %s", original)
}
// The Docker parser always wrap instructions in a root node.
// Look at the node representing the instruction following
// ONBUILD, the one and only one in each test case.
node = node.Children[0].Next
if node == nil || len(node.Children) != 1 {
t.Fatalf("unexpected number of children in ONBUILD instruction of test case: %s", original)
}
node = node.Children[0]
if got := nextValues(node); !reflect.DeepEqual(got, want) {
t.Errorf("nextValues(%+v) = %#v; want %#v", node, got, want)
}
}
}
开发者ID:RomainVabre,项目名称:origin,代码行数:28,代码来源:dockerfile_test.go
示例6: TestNextValues
// TestNextValues tests calling nextValues with multiple valid combinations of
// input.
func TestNextValues(t *testing.T) {
testCases := map[string][]string{
`FROM busybox:latest`: {"busybox:latest"},
`MAINTAINER [email protected]`: {"[email protected]"},
`LABEL version=1.0`: {"version", "1.0"},
`EXPOSE 8080`: {"8080"},
`VOLUME /var/run/www`: {"/var/run/www"},
`ENV PATH=/bin`: {"PATH", "/bin"},
`ADD file /home/`: {"file", "/home/"},
`COPY dir/ /tmp/`: {"dir/", "/tmp/"},
`RUN echo "Hello world!"`: {`echo "Hello world!"`},
`ENTRYPOINT /bin/sh`: {"/bin/sh"},
`CMD ["-c", "env"]`: {"-c", "env"},
`USER 1001`: {"1001"},
`WORKDIR /home`: {"/home"},
}
for original, want := range testCases {
node, err := parser.Parse(strings.NewReader(original))
if err != nil {
t.Fatalf("parse error: %s: %v", original, err)
}
if len(node.Children) != 1 {
t.Fatalf("unexpected number of children in test case: %s", original)
}
// The Docker parser always wrap instructions in a root node.
// Look at the node representing the first instruction, the one
// and only one in each test case.
node = node.Children[0]
if got := nextValues(node); !reflect.DeepEqual(got, want) {
t.Errorf("nextValues(%+v) = %#v; want %#v", node, got, want)
}
}
}
开发者ID:RomainVabre,项目名称:origin,代码行数:35,代码来源:dockerfile_test.go
示例7: BuildFromConfig
// BuildFromConfig will do build directly from parameter 'changes', which comes
// from Dockerfile entries, it will:
//
// - call parse.Parse() to get AST root from Dockerfile entries
// - do build by calling builder.dispatch() to call all entries' handling routines
func BuildFromConfig(d *daemon.Daemon, c *runconfig.Config, changes []string) (*runconfig.Config, error) {
ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
if err != nil {
return nil, err
}
// ensure that the commands are valid
for _, n := range ast.Children {
if !validCommitCommands[n.Value] {
return nil, fmt.Errorf("%s is not a valid change command", n.Value)
}
}
builder := &builder{
Daemon: d,
Config: c,
OutStream: ioutil.Discard,
ErrStream: ioutil.Discard,
disableCommit: true,
}
for i, n := range ast.Children {
if err := builder.dispatch(i, n); err != nil {
return nil, err
}
}
return builder.Config, nil
}
开发者ID:j-stew,项目名称:git_sandbox,代码行数:34,代码来源:job.go
示例8: TestRun
func TestRun(t *testing.T) {
f, err := os.Open("../../../../../images/dockerregistry/Dockerfile")
if err != nil {
t.Fatal(err)
}
node, err := parser.Parse(f)
if err != nil {
t.Fatal(err)
}
b := NewBuilder()
from, err := b.From(node)
if err != nil {
t.Fatal(err)
}
if from != "openshift/origin-base" {
t.Fatalf("unexpected from: %s", from)
}
for _, child := range node.Children {
step := b.Step()
if err := step.Resolve(child); err != nil {
t.Fatal(err)
}
if err := b.Run(step, LogExecutor); err != nil {
t.Fatal(err)
}
}
t.Logf("config: %#v", b.Config())
t.Logf(node.Dump())
}
开发者ID:Xmagicer,项目名称:origin,代码行数:29,代码来源:builder_test.go
示例9: Run
// Run the builder with the context. This is the lynchpin of this package. This
// will (barring errors):
//
// * call readContext() which will set up the temporary directory and unpack
// the context into it.
// * read the dockerfile
// * parse the dockerfile
// * walk the parse tree and execute it by dispatching to handlers. If Remove
// or ForceRemove is set, additional cleanup around containers happens after
// processing.
// * Print a happy message and return the image ID.
//
func (b *Builder) Run(context io.Reader) (string, error) {
if err := b.readContext(context); err != nil {
return "", err
}
defer func() {
if err := os.RemoveAll(b.contextPath); err != nil {
log.Debugf("[BUILDER] failed to remove temporary context: %s", err)
}
}()
filename := path.Join(b.contextPath, "Dockerfile")
fi, err := os.Stat(filename)
if os.IsNotExist(err) {
return "", fmt.Errorf("Cannot build a directory without a Dockerfile")
}
if fi.Size() == 0 {
return "", ErrDockerfileEmpty
}
f, err := os.Open(filename)
if err != nil {
return "", err
}
defer f.Close()
ast, err := parser.Parse(f)
if err != nil {
return "", err
}
b.dockerfile = ast
// some initializations that would not have been supplied by the caller.
b.Config = &runconfig.Config{}
b.TmpContainers = map[string]struct{}{}
for i, n := range b.dockerfile.Children {
if err := b.dispatch(i, n); err != nil {
if b.ForceRemove {
b.clearTmp()
}
return "", err
}
fmt.Fprintf(b.OutStream, " ---> %s\n", utils.TruncateID(b.image))
if b.Remove {
b.clearTmp()
}
}
if b.image == "" {
return "", fmt.Errorf("No image was generated. Is your Dockerfile empty?\n")
}
fmt.Fprintf(b.OutStream, "Successfully built %s\n", utils.TruncateID(b.image))
return b.image, nil
}
开发者ID:TencentSA,项目名称:docker-1.3,代码行数:71,代码来源:evaluator.go
示例10: addBuildParameters
// addBuildParameters checks if a Image is set to replace the default base image.
// If that's the case then change the Dockerfile to make the build with the given image.
// Also append the environment variables and labels in the Dockerfile.
func (d *DockerBuilder) addBuildParameters(dir string) error {
dockerfilePath := filepath.Join(dir, "Dockerfile")
if d.build.Spec.Strategy.DockerStrategy != nil && len(d.build.Spec.Source.ContextDir) > 0 {
dockerfilePath = filepath.Join(dir, d.build.Spec.Source.ContextDir, "Dockerfile")
}
f, err := os.Open(dockerfilePath)
if err != nil {
return err
}
// Parse the Dockerfile.
node, err := parser.Parse(f)
if err != nil {
return err
}
// Update base image if build strategy specifies the From field.
if d.build.Spec.Strategy.DockerStrategy.From != nil && d.build.Spec.Strategy.DockerStrategy.From.Kind == "DockerImage" {
// Reduce the name to a minimal canonical form for the daemon
name := d.build.Spec.Strategy.DockerStrategy.From.Name
if ref, err := imageapi.ParseDockerImageReference(name); err == nil {
name = ref.DaemonMinimal().String()
}
err := replaceLastFrom(node, name)
if err != nil {
return err
}
}
// Append build info as environment variables.
err = appendEnv(node, d.buildInfo())
if err != nil {
return err
}
// Append build labels.
err = appendLabel(node, d.buildLabels(dir))
if err != nil {
return err
}
// Insert environment variables defined in the build strategy.
err = insertEnvAfterFrom(node, d.build.Spec.Strategy.DockerStrategy.Env)
if err != nil {
return err
}
instructions := dockerfile.ParseTreeToDockerfile(node)
// Overwrite the Dockerfile.
fi, err := f.Stat()
if err != nil {
return err
}
return ioutil.WriteFile(dockerfilePath, instructions, fi.Mode())
}
开发者ID:Waxolunist,项目名称:origin,代码行数:60,代码来源:docker.go
示例11: NewDockerfile
func NewDockerfile(contents string) (Dockerfile, error) {
if len(contents) == 0 {
return nil, fmt.Errorf("Dockerfile is empty")
}
node, err := parser.Parse(strings.NewReader(contents))
if err != nil {
return nil, err
}
return dockerfileContents{node, contents}, nil
}
开发者ID:hloganathan,项目名称:origin,代码行数:10,代码来源:sourcelookup.go
示例12: TestTraverseAST
func TestTraverseAST(t *testing.T) {
tests := []struct {
name string
cmd string
fileData []byte
expected int
}{
{
name: "dockerFile",
cmd: dockercmd.Entrypoint,
fileData: []byte(dockerFile),
expected: 1,
},
{
name: "dockerFile no newline",
cmd: dockercmd.Entrypoint,
fileData: []byte(dockerFileNoNewline),
expected: 1,
},
{
name: "expectedFROM",
cmd: dockercmd.From,
fileData: []byte(expectedFROM),
expected: 2,
},
{
name: "trSlashFile",
cmd: dockercmd.Entrypoint,
fileData: []byte(trSlashFile),
expected: 0,
},
{
name: "expectedtrSlashFile",
cmd: dockercmd.Cmd,
fileData: []byte(expectedtrSlashFile),
expected: 1,
},
}
var buf *bytes.Buffer
for _, test := range tests {
buf = bytes.NewBuffer([]byte(test.fileData))
node, err := parser.Parse(buf)
if err != nil {
log.Println(err)
}
howMany := traverseAST(test.cmd, node)
if howMany != test.expected {
t.Errorf("Wrong result, expected %d, got %d", test.expected, howMany)
}
}
}
开发者ID:jhadvig,项目名称:origin,代码行数:53,代码来源:docker_test.go
示例13: TestExposedPorts
// TestExposedPorts tests calling exposedPorts with multiple valid combinations
// of input.
func TestExposedPorts(t *testing.T) {
testCases := map[string]struct {
in string
want [][]string
}{
"empty Dockerfile": {
in: ``,
want: nil,
},
"EXPOSE missing argument": {
in: `EXPOSE`,
want: nil,
},
"EXPOSE no FROM": {
in: `EXPOSE 8080`,
want: nil,
},
"single EXPOSE after FROM": {
in: `FROM centos:7
EXPOSE 8080`,
want: [][]string{{"8080"}},
},
"multiple EXPOSE and FROM": {
in: `# EXPOSE before FROM should be ignore
EXPOSE 777
FROM busybox
EXPOSE 8080
COPY . /boot
FROM rhel
# no EXPOSE instruction
FROM centos:7
EXPOSE 8000
EXPOSE 9090 9091
`,
want: [][]string{{"8080"}, nil, {"8000", "9090", "9091"}},
},
}
for name, tc := range testCases {
node, err := parser.Parse(strings.NewReader(tc.in))
if err != nil {
t.Errorf("%s: parse error: %v", name, err)
continue
}
got := exposedPorts(node)
if !reflect.DeepEqual(got, tc.want) {
t.Errorf("exposedPorts: %s: got %#v; want %#v", name, got, tc.want)
}
}
}
开发者ID:RomainVabre,项目名称:origin,代码行数:51,代码来源:dockerfile_test.go
示例14: TestInsertInstructionsPosOutOfRange
// TestInsertInstructionsPosOutOfRange tests calling InsertInstructions with
// invalid values for the pos argument.
func TestInsertInstructionsPosOutOfRange(t *testing.T) {
original := `FROM busybox
ENV PATH=/bin
`
node, err := parser.Parse(strings.NewReader(original))
if err != nil {
t.Fatalf("parse error: %v", err)
}
for _, pos := range []int{-1, 3, 4} {
err := InsertInstructions(node, pos, "")
if err == nil {
t.Errorf("InsertInstructions(node, %d, \"\"): got nil; want error", pos)
}
}
}
开发者ID:RomainVabre,项目名称:origin,代码行数:17,代码来源:dockerfile_test.go
示例15: InsertInstructions
// InsertInstructions inserts instructions starting from the pos-th child of
// node, moving other children as necessary. The instructions should be valid
// Dockerfile instructions. InsertInstructions mutates node in-place, and the
// final state of node is equivalent to what parser.Parse would return if the
// original Dockerfile represented by node contained the instructions at the
// specified position pos. If the returned error is non-nil, node is guaranteed
// to be unchanged.
func InsertInstructions(node *parser.Node, pos int, instructions string) error {
if node == nil {
return fmt.Errorf("cannot insert instructions in a nil node")
}
if pos < 0 || pos > len(node.Children) {
return fmt.Errorf("pos %d out of range [0, %d]", pos, len(node.Children)-1)
}
newChild, err := parser.Parse(strings.NewReader(instructions))
if err != nil {
return err
}
// InsertVector pattern (https://github.com/golang/go/wiki/SliceTricks)
node.Children = append(node.Children[:pos], append(newChild.Children, node.Children[pos:]...)...)
return nil
}
开发者ID:RomainVabre,项目名称:origin,代码行数:22,代码来源:dockerfile.go
示例16: FromDockerfile
// FromDockerfile generates an ImageRef from a given name, directory, and context path.
// The directory and context path will be joined and the resulting path should be a
// Dockerfile from where the image's ports will be extracted.
func (g *imageRefGenerator) FromDockerfile(name string, dir string, context string) (*ImageRef, error) {
// Look for Dockerfile in repository
file, err := os.Open(filepath.Join(dir, context, "Dockerfile"))
if err != nil {
return nil, err
}
node, err := parser.Parse(file)
if err != nil {
return nil, err
}
ports := dockerfile.LastExposedPorts(node)
return g.FromNameAndPorts(name, ports)
}
开发者ID:RomainVabre,项目名称:origin,代码行数:18,代码来源:imageref.go
示例17: processImageFrom
func (b *builder) processImageFrom(img *image.Image) error {
b.image = img.ID
if img.Config != nil {
b.Config = img.Config
}
// The default path will be blank on Windows (set by HCS)
if len(b.Config.Env) == 0 && daemon.DefaultPathEnv != "" {
b.Config.Env = append(b.Config.Env, "PATH="+daemon.DefaultPathEnv)
}
// Process ONBUILD triggers if they exist
if nTriggers := len(b.Config.OnBuild); nTriggers != 0 {
word := "trigger"
if nTriggers > 1 {
word = "triggers"
}
fmt.Fprintf(b.ErrStream, "# Executing %d build %s...\n", nTriggers, word)
}
// Copy the ONBUILD triggers, and remove them from the config, since the config will be committed.
onBuildTriggers := b.Config.OnBuild
b.Config.OnBuild = []string{}
// parse the ONBUILD triggers by invoking the parser
for _, step := range onBuildTriggers {
ast, err := parser.Parse(strings.NewReader(step))
if err != nil {
return err
}
for i, n := range ast.Children {
switch strings.ToUpper(n.Value) {
case "ONBUILD":
return fmt.Errorf("Chaining ONBUILD via `ONBUILD ONBUILD` isn't allowed")
case "MAINTAINER", "FROM":
return fmt.Errorf("%s isn't allowed as an ONBUILD trigger", n.Value)
}
if err := b.dispatch(i, n); err != nil {
return err
}
}
}
return nil
}
开发者ID:rajurs,项目名称:docker,代码行数:48,代码来源:internals.go
示例18: readDockerfile
// Reads a Dockerfile from the current context. It assumes that the
// 'filename' is a relative path from the root of the context
func (b *Builder) readDockerfile(origFile string) error {
filename, err := symlink.FollowSymlinkInScope(filepath.Join(b.contextPath, origFile), b.contextPath)
if err != nil {
return fmt.Errorf("The Dockerfile (%s) must be within the build context", origFile)
}
fi, err := os.Lstat(filename)
if os.IsNotExist(err) {
return fmt.Errorf("Cannot locate specified Dockerfile: %s", origFile)
}
if fi.Size() == 0 {
return ErrDockerfileEmpty
}
f, err := os.Open(filename)
if err != nil {
return err
}
b.dockerfile, err = parser.Parse(f)
f.Close()
if err != nil {
return err
}
// After the Dockerfile has been parsed, we need to check the .dockerignore
// file for either "Dockerfile" or ".dockerignore", and if either are
// present then erase them from the build context. These files should never
// have been sent from the client but we did send them to make sure that
// we had the Dockerfile to actually parse, and then we also need the
// .dockerignore file to know whether either file should be removed.
// Note that this assumes the Dockerfile has been read into memory and
// is now safe to be removed.
excludes, _ := utils.ReadDockerIgnore(filepath.Join(b.contextPath, ".dockerignore"))
if rm, _ := fileutils.Matches(".dockerignore", excludes); rm == true {
os.Remove(filepath.Join(b.contextPath, ".dockerignore"))
b.context.(tarsum.BuilderContext).Remove(".dockerignore")
}
if rm, _ := fileutils.Matches(b.dockerfileName, excludes); rm == true {
os.Remove(filepath.Join(b.contextPath, b.dockerfileName))
b.context.(tarsum.BuilderContext).Remove(b.dockerfileName)
}
return nil
}
开发者ID:shodan11,项目名称:docker,代码行数:49,代码来源:evaluator.go
示例19: checkDockerfile
func checkDockerfile(fs *test.FakeFileSystem, t *testing.T) {
if fs.WriteFileError != nil {
t.Errorf("%v", fs.WriteFileError)
}
if fs.WriteFileName != "upload/src/Dockerfile" {
t.Errorf("Expected Dockerfile in 'upload/src/Dockerfile', got %v", fs.WriteFileName)
}
if !strings.Contains(fs.WriteFileContent, `ENTRYPOINT ["./run"]`) {
t.Errorf("The Dockerfile does not set correct entrypoint:\n %s\n", fs.WriteFileContent)
}
buf := bytes.NewBuffer([]byte(fs.WriteFileContent))
if _, err := parser.Parse(buf); err != nil {
t.Errorf("cannot parse new Dockerfile: " + err.Error())
}
}
开发者ID:johnmccawley,项目名称:origin,代码行数:17,代码来源:onbuild_test.go
示例20: CmdBuildConfig
func (b *BuilderJob) CmdBuildConfig(job *engine.Job) engine.Status {
if len(job.Args) != 0 {
return job.Errorf("Usage: %s\n", job.Name)
}
var (
changes = job.GetenvList("changes")
newConfig runconfig.Config
)
if err := job.GetenvJson("config", &newConfig); err != nil {
return job.Error(err)
}
ast, err := parser.Parse(bytes.NewBufferString(strings.Join(changes, "\n")))
if err != nil {
return job.Error(err)
}
// ensure that the commands are valid
for _, n := range ast.Children {
if !validCommitCommands[n.Value] {
return job.Errorf("%s is not a valid change command", n.Value)
}
}
builder := &Builder{
Daemon: b.Daemon,
Engine: b.Engine,
Config: &newConfig,
OutStream: ioutil.Discard,
ErrStream: ioutil.Discard,
disableCommit: true,
}
for i, n := range ast.Children {
if err := builder.dispatch(i, n); err != nil {
return job.Error(err)
}
}
if err := json.NewEncoder(job.Stdout).Encode(builder.Config); err != nil {
return job.Error(err)
}
return engine.StatusOK
}
开发者ID:viirya,项目名称:docker,代码行数:46,代码来源:job.go
注:本文中的github.com/docker/docker/builder/parser.Parse函数示例整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论