懒惰的开发者获取最新图书馆列表的方式

上次我分享了一些有关如何良好使用库的提示。 现在,我想更深入地研究其中之一: 知道您使用的是什么图书馆 。 上周,我着手为我们的产品创建了这样的嵌入式组件列表。 这是我们的安全开发生命周期 (SDL)的要求。 但是,这不是一个有趣的任务。 作为开发人员,我想编写代码,而不是更新文档! 因此,在詹金斯Confluence的帮助下,我求助于我的朋友GradleGroovy

Gradle依赖

我们使用Gradle构建产品,并且Gradle维护了对第三方组件的依赖关系

我们的构建定义了嵌入式组件的配置名称列表copyBundleConfigurations ,用于将其复制到分发目录。 从那里,我使用Groovy的collection方法了解外部依赖关系:

def externalDependencies() {
  copyBundleConfigurations.collectMany { 
    configurations[it].allDependencies 
  }.findAll {
    !(it instanceof ProjectDependency) && it.group &&
        !it.group.startsWith('com.emc')
  }
}

添加所需信息

但是,Gradle依赖项并不包含所有必需的信息。 例如,我们需要分发该库所依据的许可证,以便我们可以请求法务部门使用它的许可。 因此,我添加了一个简单的XML文件来保存其他信息。 使用Groovy的XML支持,可以轻松地将该信息与Gradle维护的依赖项结合起来:

ext.embeddedComponentsInfo = 'embeddedComponents.xml'

def externalDependencyInfos() {
  def result = new TreeMap()
  def componentInfo = new XmlSlurper()
      .parse(embeddedComponentsInfo)
  externalDependencies().each { dependency ->
    def info = componentInfo.component.find { 
      it.id == '$dependency.group:$dependency.name' &&
          it.friendlyName?.text() 
    }
    if (!info.isEmpty()) {
      def component = [
        'id': info.id,
        'friendlyName': info.friendlyName.text(),
        'version': dependency.version,
        'latestVersion': info.latestVersion.text(),
        'license': info.license.text(),
        'licenseUrl': info.licenseUrl.text(),
        'comment': info.comment.text()
      ]
      result.put component.friendlyName, component
    }
  }
  result.values()
}

然后,我创建了Gradle任务,将信息写入HTML文件。 我们的Jenkins构建会执行此任务,因此我们始终具有最新列表。 我使用Confluence的html-include将HTML文件包含在我们的Wiki中。 现在,我们的Wiki始终是最新的。

自动查找丢失的信息

下一个问题是用其他信息填充XML文件。 如果我们从一开始就拥有此文件,那么手动添加该信息就没什么大不了的了。 在我们的案例中,我们已经有一百多个依赖项,因此自动化是有条理的。 首先,我确定了缺少必需信息的组件:

def missingExternalDependencies() {
  def componentInfo = new XmlSlurper()
      .parse(embeddedComponentsInfo)
  externalDependencies().findAll { dependency ->
    componentInfo.component.find { 
      it.id == '$dependency.group:$dependency.name' && 
          it.friendlyName?.text() 
    }.isEmpty()
  }.collect {
    '$it.group:$it.name'
  }.sort()
}

接下来,我想自动查找缺少的信息并将其添加到XML文件(使用Groovy的MarkupBuilder )。 如果找不到所需的信息,构建将失败:

project.afterEvaluate {
  def missingComponents = missingExternalDependencies()
  if (!missingComponents.isEmpty()) {
    def manualComponents = []
    def writer = new StringWriter() 
    def xml = new MarkupBuilder(writer)
    xml.expandEmptyElements = true
    println 'Looking up information on new dependencies:'
    xml.components {
      externalDependencyInfos().each { existingComponent ->
        component { 
          id(existingComponent.id)
          friendlyName(existingComponent.friendlyName)
          latestVersion(existingComponent.latestVersion)
          license(existingComponent.license)
          licenseUrl(existingComponent.licenseUrl)
          approved(existingComponent.approved)
          comment(existingComponent.comment)
        }
      }
      missingComponents.each { missingComponent ->
        def lookedUpComponent = collectInfo(missingComponent)
        component {
          id(missingComponent)
          friendlyName(lookedUpComponent.friendlyName)
          latestVersion(lookedUpComponent.latestVersion)
          license(lookedUpComponent.license)
          licenseUrl(lookedUpComponent.licenseUrl)
          approved('?')
          comment(lookedUpComponent.comment)
        }
        if (!lookedUpComponent.friendlyName || 
            !lookedUpComponent.latestVersion || 
            !lookedUpComponent.license) {
          manualComponents.add lookedUpComponent.id
          println '    => Please enter information manually'
        }
      }
    }
    writer.close()
    def embeddedComponentsFile = 
        project.file(embeddedComponentsInfo)
    embeddedComponentsFile.text = writer.toString()
    if (!manualComponents.isEmpty()) {
      throw new GradleException('Missing library information')
    }
  }
}

现在,将来添加依赖项的任何人都必须添加所需的信息。 因此,剩下collectInfo()就是collectInfo()方法。 我用来查找所需信息的主要来源有两个: SpringSource Enterprise Bundle Repository保存公共库的OSGi bundle版本,而Maven Central保存常规jar。

从这些源中提取信息是下载和解析XML和HTML文件的问题。 使用Groovy的String.toURL()URL.eachLine()方法以及对正则表达式的支持,这非常容易。

结论

所有这些花费了我几天的时间,但是我觉得这笔投资是值得的,因为我不再需要担心二手图书馆的列表已经过时。

参考: Secure Software Development博客上我们JCG合作伙伴 Remon Sinnema的《懒惰的开发者获取最新图书馆列表的方法》

翻译自: https://www.javacodegeeks.com/2013/01/the-lazy-developers-way-to-an-up-to-date-libraries-list.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值