I can believe fly.

Monday, February 13, 2017

Apache+ldap配置

用途:设置目录权限,使用ladp账号访问


Options Indexes FollowSymLinks MultiViews
AllowOverride None
AuthType Basic
AuthName "Please input your account/password of hiido udb (without dw_ prefix)"
AuthBasicProvider ldap
AuthzLDAPAuthoritative on
AuthLDAPURL ldap://121.14.36.18:389/dc=dw,dc=com?cn?sub
AuthLDAPBindDN "cn=admin,dc=dw,dc=com"
AuthLDAPBindPassword 1q2w3e@163.com
require ldap-user zhangsan lisi 


Options Indexes FollowSymLinks MultiViews
AllowOverride None

AuthType Basic
AuthName "Please input your account/password of hiido udb (without dw_ prefix)"
AuthBasicProvider ldap
AuthzLDAPAuthoritative on
AuthLDAPURL ldap://121.14.36.18:389/dc=dw,dc=com?cn?sub
AuthLDAPBindDN "cn=admin,dc=dw,dc=com"
AuthLDAPBindPassword 1q2w3e@163.com
require ldap-user zhangsan lisi wangwu laoliu



落款2014.02.11

Thursday, March 17, 2016

iOS 静态代码分析

【问题类型】
1  retain和release的正确使用
2  未使用的实例变量
3  未初始化的变量
4  无法到达的代码路径
5  引用空指针
6  除0
7  类型不兼容
8  缺少dealloc
9  内存泄漏

【使用方式】
1. 使用xcodebuild ... clean build analyze  或者加上RUN_CLANG_STATIC_ANALYZER=YES
输出报告:各个模块会生成在自己的build目录下/Users/builder/Library/Developer/Xcode/DerivedData/YY2-ekfapvflopyuogfnccpmryrhzpbf/Build/Intermediates/Pods.build/Distribute-iphoneos/Pods-GTM.build/StaticAnalyzer/Pods/Pods-GTM/normal/armv7/Pods-GTM-dummy.plist  。但没找到解析后的html信息。试着带上CLANG_ANALYZER_OUTPUT_DIR,可以改变StaticAnalyzer的输出目录。

2. 在xcodebuild前使用scan-build
输出报告:可通过-o参数指定,然后基于它加上随机数自动生成CLANG_ANALYZER_OUTPUT_DIR = /data/DUOWAN_BUILD/mobile/mobile-ios_analyzer/checkReports/2014-03-05-173031-54544-1
命令格式:
Option Description
-oTarget directory for HTML report files. Subdirectories will be created as needed to represent separate "runs" of the analyzer. If this option is not specified, a directory is created in /tmp to store the reports.
-h
(or no arguments)
Display all scan-build options.
-k
--keep-going
Add a "keep on going" option to the specified build command.This option currently supports make and xcodebuild.
This is a convenience option; one can specify this behavior directly using build options.
-vVerbose output from scan-build and the analyzer. A second and third "-v" increases verbosity, and is useful for filing bug reports against the analyzer.
-VView analysis results in a web browser when the build command completes.
--use-analyzer Xcode
or
--use-analyzer [path to clang]
scan-build uses the 'clang' executable relative to itself for static analysis. One can override this behavior with this option by using the 'clang' packaged with Xcode (on OS X) or from the PATH.
说明:
1. 建议分析debug配置
2. 在模拟器进行
3. Don't sign code

例子:
$CLANG_HOME/scan-build -k -v -v --use-analyzer $CLANG_HOME/bin/clang -o ./clangScanBuildReports xcodebuild -workspace YY2.xcworkspace -scheme YY2 -configuration Debug -sdk iphonesimulator

3. jenkins集成 clang-scanbuild-plugin,需要设置Target/workspace/scheme/sdk/等信息
输出报告:/data/DUOWAN_BUILD/mobile/mobile-ios_analyzer/clangScanBuildReports/2014-03-05-165238-25536-1
说明:
1. 使用此插件需要配置Target或者scheme或者如果编译要求有workspace也要带上,如果应用多了,这些值信息不一样,要为每个配置不同的信息有点难维护。

【小知识】
1. xcode5默认的clang路径/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
2.  sudo ./set-xcode-analyzer --use-checker-build=$clang_path 可以重设xcode集成的clang  官方介绍:http://clang-analyzer.llvm.org/xcode.html
3. 使用sudo  ./set-xcode-analyzer 更改clang,如果要用回xcode,则直接使用--use-xcode-clang。如果使用--use-checker-build来指定xcode自带clang的路径,则你在xcodebuild前使用/opt/tools/checker/scan-build,过程数据是显示了CLANG_ANALYZER_EXEC = /opt/tools/checker/bin/clang,但在解析的过程还是直接使用了你指定xcode自带clang的路径。
4. 使用clang新版本解析会比使用xcode自带的clang找到更多的问题。
【FAQ】
问:使用xcodebuild可以添加RUN_CLANG_STATIC_ANALYZER=YES;问题:如何在jenkins显示解析的结果
答: 没找到如果使用xcodebuild来clang其完整的输出报告。想要集成jenkins显示解析结果:
1. 直接使用jenkins插件,然后增加构建步骤:Clang Scan-Build 


2. 如果不想配置Clang Scan-Build步骤,那么可以直接在原来xcodebuild的基础上加上scan-build,且输出报告指向jenkins插件能识别的目录./clangScanBuildReports

codesign fails with !use_frameworks

错误:▸ Building Pods/AFNetworking [(Release)]
⌦ Code Sign error: Provisioning profile does not match bundle identifier: The provisioning profile specified in your build settings (“100edututorhd_inhouse”) has an AppID of “com.100.enterprise.tutorstudenthd” which does not match your bundle identifier “org.cocoapods.AFNetworking”.

问题:Do I need to modify all the info.plist to match my AppID? Or is there a way to skip codesign for the frameworks?
解决:在podfile里加入以下配置关掉签名
post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['EXPANDED_CODE_SIGN_IDENTITY'] = ""
      config.build_settings['CODE_SIGNING_REQUIRED'] = "NO"
      config.build_settings['CODE_SIGNING_ALLOWED'] = "NO"
    end
  end
end




Friday, August 14, 2015

Gradle构建Android应用

Gradle构建Android应用

Gradle 介绍

Gradle 基于DSL(领域特定语言)语法的自动化构建工具。其所有task可由Groovy代码控制,因此相对Maven那套标准性的流程或模板来说,Gradle会更加灵活,扩展性更强。

安装

  1. 下载 http://services.gradle.org/distributions/gradle-2.4-all.zip
  2. 解压到安装目录,例如/opt/tools/Gradle
  3. 添加GRADLE_HOME/bin to your PATH environment variable

简单build.gradle

buildscript {
    repositories {
    mavenCentral()
    }

    dependencies {
    classpath 'com.android.tools.build:gradle:1.1.3'
    }
}

apply plugin: 'android'

android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"
}

wrapper

安装完后,在项目的当前目录下执行 gradle init wrapper
如果是在已有maven配置的项目,gradle会自动识别转换,但部分配置还需要自行修改。
负责人使用wrapper初始化环境,开发团员的其它成员就可以不用自己安装了。
自动生成gradlew,build.gradle,settings.gradle等文件和相关目录
$ ./gradlew build

Downloading https://services.gradle.org/distributions/gradle-2.3-bin.zip
建议:在gradle项目里,尽量使用gradlew来编译,它会自动下载对应的版本,这样团队的其他成员就不需要手动安装了且可以保持大家使用的版本一致。

映射目录 sourceSets

如果你的工程是Eclipse 结构,那在build.gradle需要映射目录处理
android {
    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            aidl.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        androidTest.setRoot('tests')
    }
}

依赖管理

设置从公司私服nexus下载依赖库

repositories {
      maven {
             url "http://127.0.0.1/nexus/content/groups/public"
    }
}

引用本地的aar库

repositories {
    flatDir {
    dirs 'libs'
    }
}

dependencies {
    compile(name:'cards', ext:'aar')
}

依赖jar

dependencies {
     compile group: 'com.duowan.mobile.uauth', name: 'yyauth', version:'1.7'
}
}

依赖so

dependencies {
         classpath 'com.nabilhachicha:android-native-dependencies:0.1+'
}

native_dependencies {
    artifact 'com.duowan.mobile.uauth:yyauth:1.7:armeabi'
    artifact 'com.duowan.mobile.uauth:yyauth:1.7:armeabi-v7a'
}

忽略lint的警告

lintOptions {
    abortOnError false
}

版本号设置

defaultConfig {
    versionCode System.getenv("BUILD_NUMBER") as Integer ?: 0     // 如果环境变量BUILD_NUMBER存在则读取,否则取0
    versionName version                                                                       //  version是gradle.propertise定义的属性
}

设置apk输出名称

方式1:设置archivesBaseName

defaultConfig {
    project.ext.set("archivesBaseName", "myAPP-" + versionName + "-" + versionCode);
}

方式2:获取输出文件名直接替换

defaultConfig {
    applicationVariants.all {
    variant -> changeApkName(variant)
}

def changeApkName(variant) {
    def apk = variant.outputs[0].outputFile
    def newName = ""
    newName = apk.name.replace(project.name, project.name + "-" + android.defaultConfig.versionName + "-" + android.defaultConfig.versionCode)
    if (variant.buildType.name == "release") {
        newName = newName.replace("-" + variant.buildType.name, "")
    }
    variant.outputs[0].outputFile = new File(apk.parentFile, newName)
    if (variant.outputs[0].zipAlign) {
        variant.outputs[0].zipAlign.outputFile = new File(apk.parentFile, newName.replace("-unaligned", ""))
    }
}

签名配置

android {
    signingConfigs {
        release
    }

    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
}

File signFile = file(System.getenv('HOME') + "/.android/sign.properties")
if( signFile.canRead() ) {
    Properties p = new Properties()
    p.load(new FileInputStream(signFile))

    if( p!=null
    && p.containsKey('key.store')
    && p.containsKey('key.store.password')
    && p.containsKey('key.alias')
    && p.containsKey('key.alias.password')
    ) {
        println "RELEASE_BUILD: Signing..."

        android.signingConfigs.release.storeFile = file( p['key.store'] )
        android.signingConfigs.release.storePassword = p['key.store.password']
        android.signingConfigs.release.keyAlias = p['key.alias']
        android.signingConfigs.release.keyPassword = p['key.alias.password']

    } else {
        println "RELEASE_BUILD: Required properties in signing.properties are missing"
        android.buildTypes.release.signingConfig = null
    }
    } else {
        println "RELEASE_BUILD: signing.properties not found"
        android.buildTypes.release.signingConfig = null
}

ndk-build

自动生成mk

defaultConfig {
    sourceSets {
        main {
            jni.srcDirs = []
        }
    }

    ndk {
        moduleName "singalsdk"
        abiFilter "armeabi-v7a,x86,armeabi"
        stl "stlport_shared"
    }
}

使用定制mk

task ndkBuild(type: Exec, description: 'Compile JNI source via NDK') {
    def androidMKfile = "$projectDir/jni/Android.mk"
    def applicationMKfile = "$projectDir/jni/Application.mk"
    def ndkDir = System.env.ANDROID_NDK_HOME
    if (Os.isFamily(Os.FAMILY_WINDOWS)) {
        def ndkbuildcmd = $ndkDir/ndk-build.cmd
    } else {
        def ndkbuildcmd = $ndkDir/ndk-build
    }
    def execmd = ["$ndkbuildcmd","-j16","NDK_PROJECT_PATH=$buildDir",
    "APP_BUILD_SCRIPT=$androidMKfile", "NDK_APPLICATION_MK=$applicationMKfile"]
    println(execmd)
    commandLine execmd
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn ndkBuild
}

利用productFlavor实现渠道包

初始化渠道包列表./../markets.list
productFlavors {
    def path="./../markets.list"
    file(path).eachLine { line->
        def channel = line
        if (!channel.trim().equals("")) {
            "$channel" {
                manifestPlaceholders=[channelname: channel]
            }
        }
    }
}

发布产物到Maven仓库(upload/publish)

Publishing artifacts(old)

Maven Publishing (new)

apply plugin: 'maven-publish'
apply plugin: 'signing'

def isReleaseBuild() {
    return version.contains("SNAPSHOT") == false
}

def getReleaseRepositoryUrl() {
    return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
    : "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
}

def getSnapshotRepositoryUrl() {
    return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
    : "https://oss.sonatype.org/content/repositories/snapshots/"
}

def getRepositoryUsername() {
    return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
}

def getRepositoryPassword() {
    return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
}

group = GROUP 

task androidJavadocs(type: Javadoc) {
    source = android.sourceSets.main.java.srcDirs
    classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
    exclude '**/*.so'
}

task androidJavadocsJar(type: Jar, dependsOn: androidJavadocs) {
    classifier = 'javadoc'
    from androidJavadocs.destinationDir
}

task androidSourcesJar(type: Jar) {
    classifier = 'sources'
    from android.sourceSets.main.java.sourceFiles
}

task androidNativeJar(type: Jar) {
    classifier = 'so'
    from(new File(buildDir, 'libs'))
    include("**/*.so")
}

task androidNativeZip(type: Zip) {
    classifier = 'so'
    from(new File(buildDir, 'libs'))
    include("**/*.so")
}


android.libraryVariants

publishing {
    publications {
        maven(MavenPublication) {
            artifact bundleRelease
            artifact androidJavadocsJar
        }
    }
}

publishing {
    repositories {
        maven {
            credentials {
                username = getRepositoryUsername()
                password = getRepositoryPassword()
            }

            if(isReleaseBuild()) {
                url getReleaseRepositoryUrl()
            } else {
                url getSnapshotRepositoryUrl()
            }
        }
    }
}

生成jar文件

task clearJar(type: Delete) {
    delete 'build/libs/' + POM_ARTIFACT_ID + '_' + VERSION_NAME + '.jar'
}

task makeJar(type: Copy) {
    from('build/intermediates/bundles/release/')
    into('release/')
    include('classes.jar')
    rename ('classes.jar', POM_ARTIFACT_ID + '_' + VERSION_NAME + '.jar')
}

makeJar.dependsOn(clearJar, build)

收集apk到target目录

task collectApks(type:Copy) {
description = "Copies APKs and Proguard mappings to the target directory"
from 'build/outputs/apk'
exclude '**/*-unaligned.apk'
into 'target'
}
assembleRelease.finalizedBy collectApks

常用命令

gradle --help
gradle tasks //列出task列表
gradle asD (gradle assembleDebug) //编译debug打包
gradle asR (gradle assembleRelease) //编译release打包
gradle asD --refresh-dependencies //强制刷新依赖
gradle asD --parallel //并行编译
gradle asD --parallel-threads 3
gradle clean

参考资料

Monday, May 6, 2013

Hudson使用指导--了解进阶篇

一、 hudson了解进阶篇

hudson是什么?

hudson是一款持续集成工具.它具备以下功能点:
1. 易于安装部署
2. 友好的脚本配置界面
3. 支持分布式构建
4. 远程监控外部定时任务
5. 插件方便管理
6. 支持用户管理
7. 支持构建队列控制
8. 集成RSS/E-mail/IM-通过RSS发布构建结果或当构建失败时通过e-mail实时通知。
9. 生成JUnit/TestNG测试报告

如何部署安装?

首先,部署服务器需要jdk环境支持,其次可以通过以下有两种方式部署:
1. 运行命令行:java -jar hudson.war
2. 通过tomcat部署:进入Tomcat Manager,找到war file to deploy部署hudson.war
部署好后访问形如http://192.168.1.1/hudson ,web平台如下:

Tuesday, January 3, 2012

win7登陆黑屏问题

现象:

登陆后黑屏 ctrl+alt+del 有用,启动任务管理器没用,安全模式正常,explorer不知出了什么毛病?

分析:

1. 在安全模式下,关掉启动项,问题仍旧

2. 在安全模式下,查毒(没网上说 tlntsvi.exe ),问题仍旧

3. 在安全模式下,重装显卡驱动,问题仍旧(估计没有卸载干净)

4. 在安全模式下,卸载可疑软件,问题仍旧

5. 在安全模式下,创建新账号尝试,问题仍旧

6. 看到一篇资料,地址http://support.microsoft.com/kb/929135。执行干净启动来查找问题,看上去挺靠谱的。

1) 首先用了诊断启动,可以正常登陆。进去后有选择的启动,排查服务,

2) 结果发现后面有50项服务同时启用,问题就仍旧存在。估计里面含有显卡驱动(这是后面猜测的),这又让我重新回到分析显卡驱动。

7. 继续折腾,进安全模式下卸载显卡驱动,这回先不安装,可以正常登陆。装上去就不正常了。

8. 把硬件管理员叫来,换了个显卡,问题仍旧。

就这样分析了一天,尽是找不到原因,实在是让人崩溃。原本排斥没找到原因就重装系统的心开始动摇了,突然又很不死心的跑到机器面前,打开“控制面板”->“程序和功能”,就想着看谁不顺眼就卸谁:

因为近期有升级YY,内测版,可能不稳定吧,先卸了吧;

还有dxsdk_apr2006,这个已经装两三个星期了,已经没用了,也卸了吧;

QQ电脑管家,好像之前也被我卸载了;

结果,电脑鬼始神差的好起来了。

结论:

不装显卡驱动有 SDK(2006)正常,有显卡驱动没SDK(2006)正常,有显卡驱动有SDK(2006)就不正常了。

处理:

卸载dxsdk_apr2006,就可以正常登陆。

后序:

早知道,要一个个的卸,一下子几个,很容易搞乱了谁跟谁有冲突。

为了搞清楚, 我就先装上YY,然后重启进入,em,很正常。

再次装了SDK(2006),哦,no,又进不去了。

好吧,只能继续去安全模式把它给卸了。

不解的是,SDK(2006)已装了几星期,为什么突然间发作呢?

这又让人作什么解释呢?