Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
C
cocoapods
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
gengmeiios
cocoapods
Commits
9c4baa84
Commit
9c4baa84
authored
Apr 21, 2012
by
Fabio Pelosin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[Pod:Command::Spec] lint checks for build errors
parent
88ce67b9
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
162 additions
and
54 deletions
+162
-54
spec.rb
lib/cocoapods/command/spec.rb
+158
-54
podfile.rb
lib/cocoapods/podfile.rb
+4
-0
No files found.
lib/cocoapods/command/spec.rb
View file @
9c4baa84
...
@@ -49,35 +49,61 @@ module Pod
...
@@ -49,35 +49,61 @@ module Pod
end
end
def
lint
def
lint
all_valid
=
true
is_repo
=
repo_with_name_exist
(
@name_or_url
)
if
is_repo
if
is_repo
=
@name_or_url
&&
(
config
.
repos_dir
+
@name_or_url
).
exist?
files
=
(
config
.
repos_dir
+
@name_or_url
).
glob
(
'**/*.podspec'
)
files
=
(
config
.
repos_dir
+
@name_or_url
).
glob
(
'**/*.podspec'
)
else
else
name
=
@name_or_url
name
=
@name_or_url
files
=
name
?
[
Pathname
.
new
(
name
)]
:
Pathname
.
pwd
.
glob
(
'*.podspec'
)
files
=
name
?
[
Pathname
.
new
(
name
)]
:
Pathname
.
pwd
.
glob
(
'*.podspec'
)
end
end
puts
puts
lint_specs_files
(
files
,
is_repo
)
end
private
def
repo_with_name_exist
(
name
)
name
&&
(
config
.
repos_dir
+
name
).
exist?
end
# Takes an array of podspec files and lints them all
#
# It returns true if **all** the files passed validation
#
def
lint_specs_files
(
files
,
is_repo
)
tmpdir
=
Pathname
.
new
(
'/tmp/CocoaPods'
).
mkpath
all_valid
=
true
files
.
each
do
|
file
|
files
.
each
do
|
file
|
file
=
file
.
realpath
spec
=
Specification
.
from_file
(
file
)
spec
=
Specification
.
from_file
(
file
)
print
" ->
#{
spec
}
\r
"
unless
config
.
silent?
||
is_repo
spec
.
validate!
spec
.
validate!
warnings
=
warnings_for_spec
(
spec
,
file
,
is_repo
)
warnings
=
warnings_for_spec
(
spec
,
file
,
is_repo
)
deprecations
=
deprecation_notices_for_spec
(
spec
,
file
,
is_repo
)
deprecations
=
deprecation_notices_for_spec
(
spec
,
file
,
is_repo
)
# TODO: check that the dependencies of the spec exist
if
deprecations
.
empty?
&&
warnings
.
empty?
if
is_repo
puts
" -> "
.
green
+
"
#{
spec
}
passed validation"
unless
is_repo
||
config
.
silent?
build_errors
,
file_errors
=
[],
[]
else
else
puts
" -> "
.
red
+
spec
.
to_s
unless
config
.
silent?
build_errors
=
Dir
.
chdir
(
'/tmp/CocoaPods'
)
{
build_errors_for_spec
(
spec
,
file
,
is_repo
)
}
file_errors
=
Dir
.
chdir
(
'/tmp/CocoaPods'
)
{
file_errors_for_spec
(
spec
,
file
,
is_repo
)
}
end
end
types
=
[
"WARN"
,
"DPRC"
]
# This overwrites the previous printed text
messages
=
[
warnings
,
deprecations
]
is_valid
=
deprecations
.
empty?
&&
warnings
.
empty?
&&
file_errors
.
empty?
unless
config
.
silent?
if
is_valid
puts
" -> "
.
green
+
"
#{
spec
}
passed validation"
unless
is_repo
else
puts
" -> "
.
red
+
spec
.
to_s
all_valid
=
false
end
end
types
=
[
"WARN"
,
"DPRC"
,
"XCDB"
,
"ERFL"
]
messages
=
[
warnings
,
deprecations
,
build_errors
,
file_errors
]
types
.
each_with_index
do
|
type
,
i
|
types
.
each_with_index
do
|
type
,
i
|
unless
messages
[
i
].
empty?
unless
messages
[
i
].
empty?
messages
[
i
].
each
{
|
msg
|
puts
" -
#{
type
}
|
#{
msg
}
"
}
unless
config
.
silent?
messages
[
i
].
each
{
|
msg
|
puts
" -
#{
type
}
|
#{
msg
}
"
}
unless
config
.
silent?
all_valid
=
false
end
end
end
end
puts
unless
config
.
silent?
||
(
is_repo
&&
messages
.
flatten
.
empty?
)
puts
unless
config
.
silent?
||
(
is_repo
&&
messages
.
flatten
.
empty?
)
...
@@ -85,55 +111,125 @@ module Pod
...
@@ -85,55 +111,125 @@ module Pod
all_valid
all_valid
end
end
private
# It checks a spec for minor non fatal defects
#
def
warnings_for_spec
(
spec
,
file
,
all
)
# It returns a array of messages
#
def
warnings_for_spec
(
spec
,
file
,
is_repo
)
license
=
spec
.
license
license
=
spec
.
license
source
=
spec
.
source
source
=
spec
.
source
warnings
=
[]
warnings
=
[]
unless
path_matches_name?
(
file
,
spec
);
warnings
<<
"The name of the spec should match the name of the file"
;
end
warnings
<<
"The name of the spec should match the name of the file"
unless
path_matches_name?
(
file
,
spec
)
unless
license
&&
license
[
:type
];
warnings
<<
"Missing license[:type]"
;
end
warnings
<<
"Missing license[:type]"
unless
license
&&
license
[
:type
]
if
source
&&
source
[
:git
]
=~
/github.com/
&&
source
[
:git
]
!~
/.*\.git/
;
warnings
<<
"Github repositories should end in `.git'"
;
end
warnings
<<
"Github repositories should end in `.git'"
if
source
&&
source
[
:git
]
=~
/github.com/
&&
source
[
:git
]
!~
/.*\.git/
if
spec
.
description
&&
spec
.
description
!~
/.*\./
;
warnings
<<
"The description should end with a dot"
;
end
warnings
<<
"The description should end with a dot"
if
spec
.
description
&&
spec
.
description
!~
/.*\./
if
spec
.
summary
!~
/.*\./
;
warnings
<<
"The summary should end with a dot"
;
end
warnings
<<
"The summary should end with a dot"
if
spec
.
summary
!~
/.*\./
unless
all
||
license
&&
(
license
[
:file
]
||
license
[
:text
]);
warnings
<<
"Missing license[:file] or [:text]"
;
end
warnings
<<
"Missing license[:file] or [:text]"
unless
is_repo
||
license
&&
(
license
[
:file
]
||
license
[
:text
])
#TODO: the previous ´
all' is here only because at the time of 0.6.0rc1 it would trigger in all specs of if lint all is called
#TODO: the previous ´
is_repo' check is there only because at the time of 0.6.0rc1 it would be triggered in all specs
warnings
warnings
end
end
def
deprecation_notices_for_spec
(
spec
,
file
,
all
)
def
path_matches_name?
(
file
,
spec
)
file
.
basename
.
to_s
==
spec
.
name
+
'.podspec'
end
# It reads a podspec file and checks for strings corresponding
# to a feature that are or will be deprecated
#
# It returns a array of messages
#
def
deprecation_notices_for_spec
(
spec
,
file
,
is_repo
)
text
=
file
.
read
text
=
file
.
read
deprecations
=
[]
deprecations
=
[]
if
text
.
=
~
/config\..os?/
deprecations
<<
"`config.ios?' and `config.osx' will be removed in version 0.7"
if
text
.
=
~
/config\..os?/
deprecations
<<
"`config.ios?' and `config.osx' will be removed in version 0.7"
deprecations
<<
"Currently there is no known reason to use the `post_install' hook"
if
text
.
=
~
/post_install/
end
deprecations
deprecations
end
end
# It creates a podfile in memory and builds a library containing
# the pod for all available platfroms with xcodebuild.
#
# It returns a array of messages
#
def
build_errors_for_spec
(
spec
,
file
,
is_repo
)
messages
=
[]
platform_names
(
spec
).
each
do
|
platform_name
|
config
.
silent
=
true
config
.
integrate_targets
=
false
config
.
project_root
=
Pathname
.
pwd
podfile
=
podfile_from_spec
(
spec
,
file
,
platform_name
)
Installer
.
new
(
podfile
).
install!
config
.
silent
=
false
output
=
Dir
.
chdir
(
'Pods'
)
{
`xcodebuild 2>&1`
}
clean_output
=
proces_xcode_build_output
(
output
).
map
{
|
l
|
"
#{
platform_name
}
:
#{
l
}
"
}
messages
+=
clean_output
end
messages
end
def
path_matches_name?
(
file
,
spec
)
def
podfile_from_spec
(
spec
,
file
,
platform_name
)
file
.
basename
.
to_s
==
spec
.
name
+
'.podspec'
podfile
=
Pod
::
Podfile
.
new
do
platform
platform_name
dependency
spec
.
name
,
:podspec
=>
file
.
realpath
.
to_s
end
end
end
def
suggested_ref_and_version
(
repo
)
def
proces_xcode_build_output
(
output
)
tags
=
Octokit
.
tags
(
:username
=>
repo
[
'owner'
][
'login'
],
:repo
=>
repo
[
'name'
]).
map
{
|
tag
|
tag
[
"name"
]}
output_by_line
=
output
.
split
(
"
\n
"
)
versions_tags
=
{}
selected_lines
=
output_by_line
.
select
do
|
l
|
tags
.
each
do
|
tag
|
l
.
include?
(
'error'
)
||
l
.
include?
(
'warning'
)
&&
!
l
.
include?
(
'warning generated.'
)
clean_tag
=
tag
.
gsub
(
/^v(er)? ?/
,
''
)
versions_tags
[
Gem
::
Version
.
new
(
clean_tag
)]
=
tag
if
Gem
::
Version
.
correct?
(
clean_tag
)
end
end
version
=
versions_tags
.
keys
.
sort
.
last
||
'0.0.1'
data
=
{
:version
=>
version
}
if
version
==
'0.0.1'
branches
=
Octokit
.
branches
(
:username
=>
repo
[
'owner'
][
'login'
],
:repo
=>
repo
[
'name'
])
master_name
=
repo
[
'master_branch'
]
||
'master'
master
=
branches
.
select
{
|
branch
|
branch
[
'name'
]
==
master_name
}.
first
data
[
:ref_type
]
=
':commit'
data
[
:ref
]
=
master
[
'commit'
][
'sha'
]
else
data
[
:ref_type
]
=
':tag'
data
[
:ref
]
=
versions_tags
[
version
]
end
end
# It checks that every file pattern specified in a spec yields
# at least one file. It requires the pods to be alredy present
# in the current working directory under Pods/spec.name
#
# It returns a array of messages
#
def
file_errors_for_spec
(
spec
,
file
,
is_repo
)
Dir
.
chdir
(
'Pods/'
+
spec
.
name
)
do
messages
=
[]
messages
+=
check_spec_files_exists
(
spec
,
:source_files
)
messages
+=
check_spec_files_exists
(
spec
,
:resources
)
spec
.
clean_paths
.
each
do
|
pattern
|
messages
<<
"clean_paths = '
#{
pattern
}
' -> did not match any file"
if
Pathname
.
pwd
.
glob
(
pattern
).
empty?
end
messages
.
compact
end
end
def
check_spec_files_exists
(
spec
,
accessor
)
result
=
[]
platform_names
(
spec
).
each
do
|
platform_name
|
patterns
=
spec
.
send
(
accessor
)[
platform_name
]
unless
patterns
.
empty?
patterns
.
each
do
|
pattern
|
result
<<
"
#{
platform_name
}
:
#{
accessor
}
= '
#{
pattern
}
' -> did not match any file"
if
Pathname
.
pwd
.
glob
(
pattern
).
empty?
end
end
end
result
end
def
platform_names
(
spec
)
spec
.
platform
.
name
||
[
:ios
,
:osx
]
end
# Templates and github information retrival for spec create
def
default_data_for_template
(
name
)
data
=
{}
data
[
:name
]
=
name
data
[
:version
]
=
'0.0.1'
data
[
:summary
]
=
"A short description of
#{
name
}
."
data
[
:homepage
]
=
"http://EXAMPLE/
#{
name
}
"
data
[
:author_name
]
=
`git config --get user.name`
.
strip
data
[
:author_email
]
=
`git config --get user.email`
.
strip
data
[
:source_url
]
=
"http://EXAMPLE/
#{
name
}
.git"
data
[
:ref_type
]
=
':tag'
data
[
:ref
]
=
'0.0.1'
data
data
end
end
...
@@ -152,17 +248,25 @@ module Pod
...
@@ -152,17 +248,25 @@ module Pod
data
.
merge
suggested_ref_and_version
(
repo
)
data
.
merge
suggested_ref_and_version
(
repo
)
end
end
def
default_data_for_template
(
name
)
def
suggested_ref_and_version
(
repo
)
data
=
{}
tags
=
Octokit
.
tags
(
:username
=>
repo
[
'owner'
][
'login'
],
:repo
=>
repo
[
'name'
]).
map
{
|
tag
|
tag
[
"name"
]}
data
[
:name
]
=
name
versions_tags
=
{}
data
[
:version
]
=
'0.0.1'
tags
.
each
do
|
tag
|
data
[
:summary
]
=
"A short description of
#{
name
}
."
clean_tag
=
tag
.
gsub
(
/^v(er)? ?/
,
''
)
data
[
:homepage
]
=
"http://EXAMPLE/
#{
name
}
"
versions_tags
[
Gem
::
Version
.
new
(
clean_tag
)]
=
tag
if
Gem
::
Version
.
correct?
(
clean_tag
)
data
[
:author_name
]
=
`git config --get user.name`
.
strip
end
data
[
:author_email
]
=
`git config --get user.email`
.
strip
version
=
versions_tags
.
keys
.
sort
.
last
||
'0.0.1'
data
[
:source_url
]
=
"http://EXAMPLE/
#{
name
}
.git"
data
=
{
:version
=>
version
}
if
version
==
'0.0.1'
branches
=
Octokit
.
branches
(
:username
=>
repo
[
'owner'
][
'login'
],
:repo
=>
repo
[
'name'
])
master_name
=
repo
[
'master_branch'
]
||
'master'
master
=
branches
.
select
{
|
branch
|
branch
[
'name'
]
==
master_name
}.
first
data
[
:ref_type
]
=
':commit'
data
[
:ref
]
=
master
[
'commit'
][
'sha'
]
else
data
[
:ref_type
]
=
':tag'
data
[
:ref_type
]
=
':tag'
data
[
:ref
]
=
'0.0.1'
data
[
:ref
]
=
versions_tags
[
version
]
end
data
data
end
end
...
...
lib/cocoapods/podfile.rb
View file @
9c4baa84
...
@@ -64,7 +64,11 @@ module Pod
...
@@ -64,7 +64,11 @@ module Pod
# Returns a path, which is relative to the project_root, relative to the
# Returns a path, which is relative to the project_root, relative to the
# `$(SRCROOT)` of the user's project.
# `$(SRCROOT)` of the user's project.
def
relative_to_srcroot
(
path
)
def
relative_to_srcroot
(
path
)
if
config
.
integrate_targets
(
config
.
project_root
+
path
).
relative_path_from
(
xcodeproj
.
dirname
)
(
config
.
project_root
+
path
).
relative_path_from
(
xcodeproj
.
dirname
)
else
"Pods"
end
end
end
def
relative_pods_root
def
relative_pods_root
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment